Click <select> and <input> after page load

Viewed 533

I am writing a Greasemonkey script to interact with orders on Shipstation.com.

The script will select certain values in <select> and <input> elements of the order modal based on certain criteria.

Thus, the script must be able to interact with these elements.

However, I cannot figure out how to do so.

So far, I have tried to do the following and have been unable to trigger a click on the element:

  • Set the value of the element using JS .value
  • Set the value of the element using jQuery .val
  • Trigger a click event on the element using JS .click()
  • Trigger a click event on the element using this code:
function triggerMostButtons (jNode) {
    triggerMouseEvent (jNode, "mouseover");
    triggerMouseEvent (jNode, "mousedown");
    triggerMouseEvent (jNode, "mouseup");
    triggerMouseEvent (jNode, "click");
}

function triggerMouseEvent (node, eventType) {
    var clickEvent = document.createEvent('MouseEvents');
    clickEvent.initEvent (eventType, true, true);
    node.dispatchEvent (clickEvent);
}

triggerMostButtons(jNode);

It appears that Shipstation is locking the value of <select> and <input> values.

Here are examples of the SO questions I have read to try and figure this out. I haven't been able to trigger a click on these elements using any of these approaches:

How else can I trigger a click on these elements?

Alternatively, how can I set the value of these fields using JS? Do I have to find the data model in the JS and edit the value directly? Or find a way to hijack the functions that are triggered when a user clicks on these elements?

enter image description here

3 Answers

Maybe the values are loaded dynamically from the server, so you need to wait until the full page is loaded by adding a load event.

Then grab the select elements by a document.getElementById (or querySelector) and set your desired value (If I understood correctly, you don't need a click event).

You didn't provide an example I can work with, but I tried it with this https://www.shipstation.com/step1/ Notice how after the page loads, the country will be set to Canada:

// ==UserScript==
// @name     Unnamed Script 933923
// @version  1
// @grant    none
// @match *://*.shipstation.com/*
// ==/UserScript==


window.addEventListener('load', (event) => {
  
  document.getElementById('country').value = "CA";
  document.getElementById('howdidyouhearaboutus').value = "Banner Ad";
  
});

you can select an option by doing this

function selectItemInDropdownList(selectElement, ov) {
  const optionToSelect = '' + ov
  const options = selectElement.getElementsByTagName('option')
  for (const optionEle of options) {
    if (optionToSelect === optionEle.innerText || optionToSelect === optionEle.value) {
      optionEle.selected = true // selects this option
      return true
    }
  }
  return false // failed
}

/*
const dropdownEle = document.getElementById('whatever')
const status = selectItemInDropdownList(dropdownEle, "WHAT") 
console.log(status ? 'success' : 'failed')
*/

I think main issue is its a popup form and the select element 'may' not be available in DOM tree at first. so make sure to call this function when its available.

This solution works well in 2022. No jQuery is used.

Auto expand select options in element cb:

cb.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }))

Input focus on element cb (tested on Safari), watch the compatibility note on MDN:

cb.focus()

Below are the working solution for you to copy and run on a browser. (Since input focus feature is failed to run in the code snippet here, while the feature auto expand the select options still works.)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <select id="select-1">
        <option value="1">Option 1</option>
        <option value="2">Option 2</option>
    </select>

    <input id="input-1" type="text"/> 

    <script>
        window.onload = function() {
            const select = document.getElementById('select-1');
            const input = document.getElementById('input-1');

            input.focus();
            setTimeout(function() {
                select.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }));
            }, 1000);
        }
    </script>
</body>
</html>

Related