Script to fill out a form is faster than onchange () can show form parameters

I use the Javascript bookmarklet to automatically fill out the form on the page. Some of the options given are drop-down options that show different options depending on what is selected using onchange (). I have code similar to this:

/* Gets first drop down and sets value to first in list */ var dropDown1 = document.getElementById("dropDown1Name"); dropDown1.value = "option1InDropDown"; dropDown1.onchange(); /* Sets value of second drop down to option that is available when first option in first drop down is selected */ var dropDown2 = document.getElementById("dropDown2Name"); dropDown2.value = "optionRevealedByDropDown1Change"; 

However, this does not work, because onchange () does not populate the second from the bottom by the time I set it to a value. By the time the script completes, dropDown2 has no value. I tried several methods so that the code "waited", but I could not find the right solution. Any suggestions are welcome.

+6
source share
2 answers

As noted in the comments, one of the problems is the incorrect triggering of the change event. Another part of the problem may be that the parameters for the second drop-down list can only be populated after receiving the result of some async action (for example, using XMLHttpRequest). In this case, even if the change event fires correctly, your code still needs to wait for the drop-down list to populate it before setting its value. One approach can be based on regular checks if the drop-down menu is filled with values ​​(for example, using setInterval or setTimeout ). A more elegant approach would be to use MutationObserver to wait for a dropdown to populate it with values. Take a look at this snippet:

 var sel1 = document.querySelector('#sel'), sel2 = document.querySelector('#sel2'); // Onchange code sel1.addEventListener('change', function() { sel2.disabled = false; // emulate async request for dropdown options setTimeout(function populateSecondSelect() { ['', 'dynamic1', 'dynamic2'].forEach(function(val) { var opt = document.createElement('option'); opt.setAttribute('value', val); opt.textContent = val || '-'; sel2.appendChild(opt); }); }, 2000); }); // Code to trigger events (based on http://stackoverflow.com/a/2490876/2671392) function triggerEvent(type, element) { var event; // The custom event that will be created if (!!window.Event) { event = new Event(type); } else if (document.createEvent) { event = document.createEvent("HTMLEvents"); event.initEvent(type, true, true); } else { event = document.createEventObject(); event.eventType = type; } event.eventName = type; if (document.createEvent) { element.dispatchEvent(event); } else { element.fireEvent("on" + event.eventType, event); } } document.querySelector('#btn').addEventListener('click', function() { sel1.value = sel1.value === '1' ? '2' : '1'; // trigger change event triggerEvent('change', sel1); // set MutationObserver for second dropdown var observer = new MutationObserver(function(mutations) { sel2.value = 'dynamic2'; observer.disconnect(); }); // only observe changes in the list of children var observerConfig = { childList: true }; observer.observe(sel2, observerConfig); }); 
 <div> <input type="button" id="btn" value="Select values" /> <select id="sel"> <option value="" selected>-</option> <option value="1">Option 1</option> <option value="2">Option 2</option> </select> <select id="sel2" disabled> </select> </div> 

But keep in mind that MutationObserver not available in older browsers.

+2
source

Bind the first <select> to the input event, which is similar to change , except that it fires immediately. To synchronize the first <select> value with the second <select> parameter and value, use the selectedIndex property in the event handler.

SNIPPET

 var s1 = document.getElementById('s1'); var s2 = document.getElementById('s2'); s1.addEventListener('input', function(e) { var idx = this.selectedIndex; var data = idx.value; s2.selectedIndex = idx; }, false); 
 label { margin-left: 6ex; } 
 <fieldset> <legend>Binding Input Event</legend> <select id='s1'> <option>---</option> <option value='1'>1</option> <option value='2'>2</option> <option value='3'>3</option> </select> <select id='s2'> <option>---</option> <option value='A'>A</option> <option value='B'>B</option> <option value='C'>C</option> </select> </fieldset> 
+3
source

All Articles