skip to Main Content

im trying the below code but im getting undifined "length" cuz the element in the select is not yet created that cuz im using a plugin and this element is inside this plugin template and the plugin take a litte more time to load after the DOM loads.what can i do to wait for the element to load?

what i want to do

var select = document.getElementsByClassName("pp_pricing_options")[0];
var plan = localStorage.getItem("Plan");
plan = plan.replaceAll(/s+/g, '');
plan = plan.toLowerCase();
plan = plan.charAt(0).toLocaleUpperCase() + plan.substring(1);
for(var i = 0; i < select.length; i++)
{
    if(select[i].text.includes(plan)){
        select[i].selected = true;
    }
}

what i have tried

document.addEventListener("DOMContentLoaded", () => {
    var select = document.getElementsByClassName("pp_pricing_options")[0];
    var plan = localStorage.getItem("Plan");
    plan = plan.replaceAll(/s+/g, '');
    plan = plan.toLowerCase();
    plan = plan.charAt(0).toLocaleUpperCase() + plan.substring(1);
    for(var i = 0; i < select.length; i++)
    {
      if(select[i].text.includes(plan)){
         select[i].selected = true;
      }
    }
});
window.onload = function(){
     var select = document.getElementsByClassName("pp_pricing_options")[0];
     var plan = localStorage.getItem("Plan");
     plan = plan.replaceAll(/s+/g, '');
     plan = plan.toLowerCase();
     plan = plan.charAt(0).toLocaleUpperCase() + plan.substring(1);
     for(var i = 0; i < select.length; i++)
     {
      if(select[i].text.includes(plan)){
          select[i].selected = true;
      }
     }
}

i have also tried the document ready function using jquery

i also tried the solutions in this link but my await keeps waiting with no response
How to wait until an element exists?

the code i typed

$(document).ready(function () {
        async function waitForElm(selector) {
            return new Promise(resolve => {
                    if (document.querySelector(selector)) {
                            return resolve(document.querySelector(selector));
                    }

                    const observer = new MutationObserver(mutations => {
                            if (document.querySelector(selector)) {
                                    observer.disconnect();
                                    resolve(document.querySelector(selector));
                            }
                    });

                    // If you get "parameter 1 is not of type 'Node'" error, see https://stackoverflow.com/a/77855838/492336
                    observer.observe(document.body, {
                            childList: true,
                            subtree: true
                    });
            });
    }

    async function start(){
        var select = await waitForElm("pp_pricing_options");
        var plan = localStorage.getItem("Plan");
        plan = plan.replaceAll(/s+/g, '');
        plan = plan.toLowerCase();
        plan = plan.charAt(0).toLocaleUpperCase() + plan.substring(1);
        for(var i = 0; i < select.length; i++)
        {
            if(select[i].text.includes(plan)){
                select[i].selected = true;
            }
        }
    } 
    start();
});

i belive the last one is the right solution but i cant get it to work for some reason. but please if you have better/easier solutions tell me.

2

Answers


  1. You can use a timeout or perhaps just load the script at the end of <body>

    //Timeout Method
    setTimeout ( function() {
        var select = document.getElementsByClassName("pp_pricing_options")[0];
        var plan = localStorage.getItem("Plan");
        plan = plan.replaceAll(/s+/g, '');
        plan = plan.toLowerCase();
        plan = plan.charAt(0).toLocaleUpperCase() + plan.substring(1);
        for(var i = 0; i < select.length; i++)
        {
            if(select[i].text.includes(plan)){
                select[i].selected = true;
            }
        }
    }, 1000); //change 1000 to the time delay you would like in milliseconds
    
    Login or Signup to reply.
  2. I recommend using a repeating setTimeout(). This way, you can check quickly and frequently only until the element loads:

    {
     var check = () => {
      var select = document.getElementsByClassName("pp_pricing_options")[0];
      
      // Here you can check if any element was found.
      // If one wasn't found, call another setTimeout and cancel the rest of the code.
      if(!select) return setTimeout(check, 50);
    
      var plan = localStorage.getItem("Plan");
      plan = plan.replaceAll(/s+/g, '');
      plan = plan.toLowerCase();
      plan = plan.charAt(0).toLocaleUpperCase() + plan.substring(1);
      for(var i = 0; i < select.length; i++) {
       if(select[i].text.includes(plan)) {
        select[i].selected = true;
       }
      }
     };
    
     // Start the first Timeout
     setTimeout(check, 50);
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search