I am trying to trigger a mouse click event programmatically using Javascript on a div, but only after the value of an input is updated, also using Javascript.
It is updating the value successfully but the mouse click event is not taking place.
Please note that the input is not contained inside the div that I am trying to click on.
Please also note that there are multiple inputs and the following code is inside a loop for all the inputs.
// input node reference
const inputElem = document.querySelectorAll("input[type='number']")[index];
// bind "change" event listener
inputElem.addEventListener('change', e => console.log(e.target.value));
// programmatically change the input's value
inputElem.value = 5;
// simulate mouse click
var someDiv = document.getElementById("root");
var clickEvent = new MouseEvent("click", {
"view": window,
"bubbles": true,
"cancelable": false
});
someDiv.dispatchEvent(clickEvent);
P.S. - This is for a chrome extension, to manipulate the inputs of a webpage, and those inputs require mouse click outside input (or enter key press), for the cart to update.
P.P.S - The console does say Appboy: Trigger event custom_event did not match any trigger conditions. All I know is this message is related to React JS. So this page possibly has React applied to the inputs that I am trying to manipulate.
Related
Trying to trigger JavaScript 'change' event on an element that is present in the iframe. Below is my code trail
// get the iframe window
var iframeDoc = document.getElementsByTagName("iframe")[0].contentWindow.document;
// get the target element
var targetElement = iframeDoc.querySelector("#some_id");
// add a listener to the target element to make sure the event is fired
targetElement.addEventListener("onchange", function(){console.log("change event triggered");});
// set value in the target element
targetElement.value = "abc";
// now build the custom event
var customEvent = iframeDoc.createEvent("HTMLEvents");
customEvent.intEvent("change", false, true);
// trigger the event on the element
targetElement.dispatchEvent(customEvent)
// now click on the save button
We are not getting any error after the last line execution and see the message in the console. However, the value entered by selenium is not retaining when clicking on Save button in the form.
Tech stack:
Java, IE 11, selenium 3.141.59
Disabled Native Events
Stated that a minimal reproducible example would help a lot (you are speaking abouot some values, some buttons and some form about we know nothing),
onchange is DOM element property to listen for a change event, the actual event name is change.
Hope this helps.
On my page, I have multiple text boxes and need at least one of those boxes to always have focus. Is there a js event listener I can call that will detect when nothing on the page has focus, so I can give it focus?
If you want to know if an element from a list of tags is focused :
function hasFocus(selector) {
return Array
.from(document.querySelectorAll(selector))
.some(function(el){
return el === document.activeElement
});
}
// usage
console.log(hasFocus('input, select, textarea'))
You can also attach a focusout handler to the document which checks the focusable elements every time a focusout event bubbles up. Then force focus on an element other than the source of the blur event, if none have it.
Edited per comment.
Please check out my solution on this link: https://codesandbox.io/s/nostalgic-lovelace-f9hei
When you load the page, the first input get focus. Everytime you click out. A random input get focused.
blur event will not bubble up by default. So make it bubble up by changing usecapture to true.
const inputs = document.querySelectorAll('input')
document.querySelector('input').focus()
document.addEventListener('blur', (e) => {
console.log(e)
if (e.isTrusted) {
const random = Math.round(Math.random() * (inputs.length-1));
console.log(random)
Array.from(inputs)[random].focus()
}
},true)
I am trying to automate a website that was built using GWT. My automation uses jQuery to select an appropriate element and then call the jQuery click() function to trigger a click event.
However, the expected action doesn't take place. Clicking the element with the mouse brings up a dialog box, but using jQuery does nothing. If I use jQuery to add a new click handler, I see the new handler executed in both cases, but the original handler only in the "real" click case.
Stepping into the Javascript code, I see very complicated code dealing with stack depth, leading me to think doing this automation may not be directly possible.
Does anyone know of a way to programmatically fire an event on a GWT-generated element? Or should this be working normally, and this site uses uniquely complicated code?
Edit: The code I'm using is quite simple:
var searchButton = jQuery('div.GH1CUEEFLB.GH1CUEEMLB:first');
if (searchButton && searchButton.length > 0) {
searchButton.click();
}
Stepping through the code shows that it selects the correct element, and proceeds to call click(). The existing event handler for the widget, according to Chrome's debugger, is complicated. Stepping through the process leads to a rabbit hole that is quite difficult to follow:
function(){
var stackIndex, returnTemp;
$stack_0[stackIndex = ++$stackDepth_0] = null;
try {
returnTemp = entry0(($location_0[stackIndex] = '57' , jsFunction), this, arguments);
$stackDepth_0 = stackIndex - 1;
return returnTemp;
}
catch (e) {
throw $location_0[stackIndex] = '63' , e;
}
$stackDepth_0 = stackIndex - 1;
}
The solution in this case was to trigger the click event on one of the child elements within the div. The event handler was attached to a particular div surrounding all the components of the button (label, icon, borders, etc). Triggering the event on that parent element did nothing. However, if I instead selected one of the leaf nodes in that subtree (say, the label itself), then triggering the click event brought up the dialog box as desired.
I guess the event handler's code was actively determining the exact element that triggered the event, but was not expecting the parent div to be that trigger source.
var searchButton = jQuery('div.GH1CUEEJT:first');
The above selects the leaf node upon which to trigger the event, even though the parent node 'div.GH1CUEEFLB.GH1CUEEMLB' held the event handler.
I want to add an event listener to the windowObj that on keydown, calls a function. I can not get this to work on the window object; however, I can get it working after a child of the window object (a button for example), has been clicked. I've also tried clicking on the window area around the button, thinking that maybe the window needed to be active, but this did not work. Oddly enough, this test worked when I changed "keydown" to "click".
The way I want it to work:
When the ScriptUI window displays, on keydown, a function is called.
Below is code of a simplified example of what I want to happen:
#target Photoshop
var w = new Window ("dialog");
var buttonPositions = w.add ("group");
var top = buttonPositions.add ("button", undefined, "Button");
w.addEventListener ("keydown", function (k) {handle(k)});
function handle (k) {
alert (k.keyName);
}
w.show ();
Displays when script runs
Alert box with key name displays on keydown
tl;dr: Set the active property of any control that accepts keystrokes and is a descendent in the registered element's hierarchy to true:
btn.active = true;
win.addEventListener("keydown", function (e) { alert(e.keyName); });
The Window object isn't designed to detect keydown events. This can be demonstrated by intermingling panel, statictext, and group elements with controls such as radiobutton, button, and checkbox. Pressing the tab key skips any elements that ignore keydown events, and sets the focus to the first control in line that accepts keydown events. The first control residing in the listener's hierarchy that receives focus will trigger your callback on the next keypress.
Per the Photoshop Scripting Reference (emphasis mine):
An active control is the one with keyboard focus - that is, the one that accepts keystrokes, or in the case of a Button, is selected when the user types Return or Enter in Windows, or the space bar in Mac OS.
Keydown events can propagate through a Window (or Panel, or Group element, for that matter) as part of the event registration and capture phase, but to trigger a keydown event, the actual target needs to accept that type of event.
function showDialog() {
var win = new Window("dialog");
var btn = win.add("button", undefined, "Cancel");
// Sets initial focus to a control that accepts `ev: KeyboardEvent`,
// and is a descendent in the registered `this: Window` hierarchy.
btn.active = true;
win.addEventListener("keydown", function (e) { alert(e.keyName); });
return win.show() ? 0 : 1;
}
More info at: event callbacks/listeners and control objects.
I have an application containing a form with five input fields. When the user clicks on an input field a tooltip should be displayed, which works fine. The problem comes when I try to remove the tooltip, which happens if the user clicks on another input field. Below is a piece of code from my application, and I hope it's enough to understand how it works.
The arguments that are passed to "showTooltip()" are a DOM reference to the clicked input field, the text that is displayed in the tooltip, and a number (0-4) that is used to find the containing div that's surrounding the clicked input field (all input fields are inside their own div).
The application works fine, but after I've clicked around a couple of times on the fields the following message is displayed in the console: "Node was not found - inputDiv.removeChild(tooltip). I've found out that the reason for this is that the function "hideTooltip()" is sometimes called twice, but I can't find out the reason why this happens.
Any clues?
showTooltip: function(inputField, tooltipText, divNr){
var container = document.getElementById('container');
var inputDiv = container.getElementsByTagName('div');
var inputDiv = inputDiv[divNr];
var tooltip = document.createElement('div');
tooltip.className = "tooltip";
var text = document.createTextNode(tooltipText);
tooltip.appendChild(text);
inputDiv.appendChild(tooltip);
inputField.addEventListener('blur', function() { hideTooltip(inputField, inputDiv, tooltip, inputNode);});
},
hideTooltip: function(inputField, inputDiv, tooltip, nr){
inputDiv.removeChild(tooltip);
validateField(inputField);
}
unbind is jquery function, so it will not work unless you are using jquery. You will need to use the removeEventListener function without jquery. If you do decide to use jquery, I would recommend the one (http://api.jquery.com/one/) function that executes an event only once per element. I am not sure if you will need to check to see if the event exists before you call removeEventListener.
var blurEvent = function() { hideTooltip(inputField, inputDiv, tooltip, inputNode); };
inputField.removeEventListener('blur', blurEvent);
inputField.addEventListener('blur', blurEvent);
Every time an input field is clicked you're binding the 'blur' event to that field. Click again another event is bound to that field. This is why it's getting called more than once because you're binding everytime. You can unbind first, then add again. There might be a better solution, but this will work:
inputField.unbind('blur');
inputField.addEventListener('blur', function() { hideTooltip(inputField, inputDiv, tooltip, inputNode);});
Note: This will remove ALL event functions bound to 'blur' on that element
In your ShowTooltip function, you are adding an Event Listener that triggers hideTooltip on blur. If you show the tooltip more than once, you are setting more than one onBlur event listener, which means that next time you blur, you will trigger the hideTooltip function twice.
One solution is to unbind the event listener from the inputField when hideTooltip is run.
Good luck.