I am trying to simulate an keyinput in JavaScript on a textbox, in Firefox. The textbox has an onfocus=" this.value='' " attribute. A simulation + my code can be found at
Working code:
var divy = document.getElementById("eventListener");
divy.focus();
var inputText = '';
for(var i = 0; i < ('asd').length; i++)
{
var event = document.createEvent('KeyboardEvent');
event.initKeyEvent ('keydown', true, true, null, false, false, false, false, 0, 0)
divy.dispatchEvent(event);
inputText += ('asd').charAt(i);
var event = document.createEvent('KeyboardEvent');
event.initKeyEvent ('keypress', true, true, null, false, false, false, false, 0, ('asd').charCodeAt(i))
divy.dispatchEvent(event);
divy.value = inputText;
var event = document.createEvent('KeyboardEvent');
event.initKeyEvent ('keyup', true, true, null, false, false, false, false, 0, 0)
divy.dispatchEvent(event);
}
divy.blur();
My question is, how to properly simulate the input (without jquery!) so that the second textbox doesn't have an empty value. And also as the focus event is only once thrown, why gets the value erased each time.
UPDATE:
As I thought that the divy.focus(); Method might need some time to execute the onfocus event in attributes, I set up a timeout to send the key events, using:
windows.setTimeout("fireKeys2()", 5000);
But this also does not seem to work. The test is located here
http://jsfiddle.net/hPBNA/23/
UPDATE 2:
I figured out the problem myself, it seems like if element.value has been set to '' this way (element.value = '') element.setAttribute('value', someText) is not able to change it. Accessing the element.value property instead gave me the right results.
Tested in Firefox 22. Don't know if its reproducible on other versions.
I figured out the problem myself, it seems like if element.value has been set to '' this way (element.value = ''), element.setAttribute('value', someText) is not able to change it. Accessing the element.value property instead gave me the right results.
Tested in Firefox 22. Don't know if its reproducible on other versions.
John
Related
Solved, see answer below
I test a React app with selenium.
I need to change the value of an input field, which is linked to the state of the object. In short (relevant parts of the code), a change in this input allows it's value to be submited only if it is not empty:
# react object
render: function(){
<input ... onChange={this.handleTextChange} className="myInput" />
<button onClick={this.handleSubmit}>Submit</button>
},
handleTextChange: function(e) {
this.setState({text: e.target.value});
},
handleSubmit: function() {
if(this.state.text.length > 0) {
// relevant code that is never executed
// because although we change the value of the input, the state does not update
}
},
The code works but I cannot find a way to test it because I cannot find any js manipulation which would update the input AND reflect in the state of the object.
I tried the following solutions
# value update
self.selenium.execute_script("var input = document.querySelectorAll('input.myInput')[0]; form.value = 'New message!'");
The word 'New message!' actually appears in the input but does not update the state of the object.
I then tried focusing on the input and triggering a keyup event, without success
# try focus and keyUp
# source https://stackoverflow.com/questions/596481/simulate-javascript-key-events
self.selenium.execute_script("""
var form = document.querySelectorAll("input.messageFormInput")[0];
form.focus();
var keyboardEvent = document.createEvent("KeyboardEvent");
var initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? "initKeyboardEvent" : "initKeyEvent";
keyboardEvent[initMethod](
"keydown", // event type : keydown, keyup, keypress
true, // bubbles
true, // cancelable
window, // viewArg: should be window
false, // ctrlKeyArg
false, // altKeyArg
false, // shiftKeyArg
false, // metaKeyArg
40, // keyCodeArg : unsigned long the virtual key code, else 0
0 // charCodeArgs : unsigned long the Unicode character associated with the depressed key, else 0
);
document.dispatchEvent(keyboardEvent);
""")
I tried the same solution with jQuery as explained here (Is it possible to simulate key press events programmatically?), but it does not work either.
Any idea is very welcome. Thanks!
My bad, I was not aware of
self.selenium.find_elements_by_class_name('myClass')[0].send_keys("hello")
Which actually solves the issue. Thanks to Chris Hawkes for sending me in the right direction.
I am trying the following code to fire click event on a textbox while clicking on a button as the focus() function is not working in IE8
function simulateClick(elm) {
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
var canceled = !elm.dispatchEvent(evt);
if(canceled) {
// A handler called preventDefault
// uh-oh, did some XSS hack your site?
} else {
// None of the handlers called preventDefault
// do stuff
}
}
This code works fine if the element is of type checkbox but not textbox, is there anything I might need to add?
This is the code for focus
function ResponseEnd(sender, args) {
if (args.get_eventArgument().indexOf("Filter") != -1) {
var grid = document.getElementById("<%= radGridEnquiries.ClientID %>");
var label = $(grid).children("table").children("tbody").children(".rgRow").children("td:has(span)").children("span")[0];
if (label != null) {
label.focus();
}
else {
var noRecTemp = $(grid).children("table").children("tbody").children("tr.rgNoRecords").children("td:has(div)").children("div");
noRecTemp.focus();
}
}
if (postInProgress)
postInProgress = false;
}
The real scenario is I have some textboxes set as filters in a Telerik RadGrid and having no filter icons but when the user posts a filter and the request is finished in IE8 the filter textbox is still with focus preventing the user to input new filters unless clicks on the textbox manually again
P.S. Sorry if this post is seen as answer but couldn't update this question with proper indented code. Thanks
I've got some code which works fine in IE but unfortunately not in Google Chrome/Firefox.
It relies upon calling a click() event on a button from javascript. Reading around it seems that this is an IE specific extension (doh). Is there any way I can do a similar thing in chrome + firefox? To clarify, it's executing the click event on a specific button, not handling what happens when the user clicks on a button.
Thanks
The code for those who asked for it:
function getLinkButton(actionsDiv)
{
var hrefs = actionsDiv.getElementsByTagName("a");
for (var i=0; i<hrefs.length; i++)
{
var id = hrefs[i].id;
if (id !=null && id.endsWith("ShowSimilarLinkButton"))
{
return hrefs[i];
}
}
return null;
}
function doStuff()
{
//find the specific actions div... not important code...
var actionsDiv = getActionsDiv();
var linkButton = getLinkButton(actionsDiv);
if (linkButton != null)
{
if (linkButton.click)
{
linkButton.click();
}
else
{
alert("Cannot click");
}
}
}
I don't really want to use jQuery unless absolutely necessary
I think you're looking for element.dispatchEvent:
function simulateClick() {
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
var cb = document.getElementById("checkbox");
var canceled = !cb.dispatchEvent(evt);
if(canceled) {
// A handler called preventDefault
alert("canceled");
} else {
// None of the handlers called preventDefault
alert("not canceled");
}
}
I read your question as "I'm trying to fire the onclick event for my button", whereas everyone else seems to have read it as "I'm trying to handle an onclick event for my button". Please let me know if I've got this wrong.
Modifying your code, a proper x-browser implementation might be:
if (linkButton != null)
{
if (linkButton.fireEvent)
linkButton.fireEvent("onclick");
else
{
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
linkButton.dispatchEvent(evt);
}
}
onclick attribute should be crossbrowser:
<input type="button" onclick="something()" value="" />
EDIT
And there was this question that seems to be about the same problem: setAttribute, onClick and cross browser compatibility
onclick="methodcall();" works for me fine...
you can use onClick attribute or if you need more functionality have a look at jQuery and events it offers: http://api.jquery.com/category/events/
I want to create a custom message without using the modal popup in jqgrid. Is there a way to disable it? Or is there a way to change the contents of the modal?
Can you be more specific? If you want your own modal dialog, you could just add an event handler (on an Edit button, for example) that when fired will open your own custom dialog. You can use the jQuery UI dialog for this purpose, and just have it open to your own custom form.
Update
After inspecting the jqGrid source code, info_dialog is the function that is used to display this particular dialog. There is a separate call to display the "Loading..." popup. Offhand there does not seem to be a simple way to disable info_dialog. However, you could modify the jqGrid source to accomplish what you need. You could either:
Return immediately from info_dialog - which may be extreme because it could report other errors you need - or,
Find and comment out the call that is displaying this particular ajax error. There is some trial-and-error involved, but with only 18 calls to this function it will not take you long to track down. In fact, start by commenting out this instance, since it is called from the error function of an ajax call:
info_dialog(a.jgrid.errors.errcap,e.status+" : "+e.statusText+"<br/>"+u,a.jgrid.edit.bClose);
Obviously such a modification is a last resort, but once it works you might consider rolling a patch for the jqGrid team to disable the alert.
Search for div.loadingui div.msgbox { ... } somewhere in css files. I think editing this css class will get the job done.
i have changed the z-index of modal popup on runtime once you can access to it you can do any customization
editoptions: { size: 20, maxlength: 10,
dataEvents: [
{ type: 'keypress',
fn: function (e) {
if (e.keyCode == 13) {
**$("#info_dialog").css('z-index', '100000');**
}
}
}
]
} }
Also, if you can do it on another place if you have server response such as error
onCellSelect: function (rowid, iCol, aData) {
currentRow = rowid;
if (rowid && rowid !== lastsel) {
if (lastsel) jQuery('#ppGrid').jqGrid('restoreRow', lastsel);
$("#ppGrid").jqGrid('editRow', rowid, true, null, null, null, {}, reload,OnError);
lastsel = rowid;
}
else if (rowid && rowid === lastsel)
{ $("#ppGrid").jqGrid('editRow', rowid, true, null, null, null, {}, reload,OnError); }
}
Yes you can do it. you can make visible property to false [$("#info_dialog").visible(false);] of the modal box, and you can call what ever your custom modal box.
editrules: { custom: true, custom_func: validate_edit }
function validate_edit(posdata, colName) {
var message = "";
if (posdata != '' && $.isNumeric(posdata))
return [true, ""];
if (posdata == '')
message = colName + " field is required"
if (!$.isNumeric(posdata))
message = posdata + " is not a number";
alert(message);
$("#info_dialog").visible(false);
return [false, ""];
}
I know this is out of the topic, but have you tried SlickGrid https://github.com/mleibman/SlickGrid/wiki/examples
In IE, I can just call element.click() from JavaScript - how do I accomplish the same task in Firefox? Ideally I'd like to have some JavaScript that would work equally well cross-browser, but if necessary I'll have different per-browser JavaScript for this.
The document.createEvent documentation says that "The createEvent method is deprecated. Use event constructors instead."
So you should use this method instead:
var clickEvent = new MouseEvent("click", {
"view": window,
"bubbles": true,
"cancelable": false
});
and fire it on an element like this:
element.dispatchEvent(clickEvent);
as shown here.
For firefox links appear to be "special". The only way I was able to get this working was to use the createEvent described here on MDN and call the initMouseEvent function. Even that didn't work completely, I had to manually tell the browser to open a link...
var theEvent = document.createEvent("MouseEvent");
theEvent.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
var element = document.getElementById('link');
element.dispatchEvent(theEvent);
while (element)
{
if (element.tagName == "A" && element.href != "")
{
if (element.target == "_blank") { window.open(element.href, element.target); }
else { document.location = element.href; }
element = null;
}
else
{
element = element.parentElement;
}
}
Using jQuery you can do exactly the same thing, for example:
$("a").click();
Which will "click" all anchors on the page.
element.click() is a standard method outlined by the W3C DOM specification. Mozilla's Gecko/Firefox follows the standard and only allows this method to be called on INPUT elements.
Are you trying to actually follow the link or trigger the onclick? You can trigger an onclick with something like this:
var link = document.getElementById(linkId);
link.onclick.call(link);
Here's a cross browser working function (usable for other than click handlers too):
function eventFire(el, etype){
if (el.fireEvent) {
el.fireEvent('on' + etype);
} else {
var evObj = document.createEvent('Events');
evObj.initEvent(etype, true, false);
el.dispatchEvent(evObj);
}
}
I used KooiInc's function listed above but I had to use two different input types one 'button' for IE and one 'submit' for FireFox. I am not exactly sure why but it works.
// HTML
<input type="button" id="btnEmailHidden" style="display:none" />
<input type="submit" id="btnEmailHidden2" style="display:none" />
// in JavaScript
var hiddenBtn = document.getElementById("btnEmailHidden");
if (hiddenBtn.fireEvent) {
hiddenBtn.fireEvent('onclick');
hiddenBtn[eType]();
}
else {
// dispatch for firefox + others
var evObj = document.createEvent('MouseEvent');
evObj.initEvent(eType, true, true);
var hiddenBtn2 = document.getElementById("btnEmailHidden2");
hiddenBtn2.dispatchEvent(evObj);
}
I have search and tried many suggestions but this is what ended up working. If I had some more time I would have liked to investigate why submit works with FF and button with IE but that would be a luxury right now so on to the next problem.