This question already has an answer here:
Can't trigger click with jQuery in a Chrome extension
(1 answer)
Closed 7 years ago.
I'm trying to submit a field with jquery, normally in the page you would click on a submit button or press enter in the field.
I'm doing this in a chrome script.
Now if I type:
$('#myButton').click()
In the Console, this actually works fine, but when i call the same code from my script function, it doesn't work.
I tried also to use this:
var e = jQuery.Event("keydown");
e.which = 50;
e.keyCode = 50;
$("#myButotn").trigger(e);
but still no results.
To be specific, the button that i'm willing to click has an onClick="submitFunction()"
Here is a much better way to trigger a click on keypress.
$(window).keydown(function (e) {
if ( e.which === 50 ) {
$("#myButton").click();
}
});
Demo: http://jsfiddle.net/bc7r3vq1/1/
By the way, keycode 50 is the number 2
Now, i've found a solution, but i'm not sure which one was the problem.
First of all I started using tampermonkeys, from there i used
$('#textField').submit();
and it worked fine.
I'm going to check now if I had to use this method, or if it was just something related with my extension.
EDIT: It works only if I use tampermonkeys, as they saied..
I believe your issue comes from the browser policy preventing your code from faking a user action. Chrome only allows you to fake a user action if its called directly from another user action handler like an actual user click of keydown. Try your code from within a click handler and if it works its because of this policy block.
Related
See an example here: https://large-platinum-ethernet.glitch.me.
Using Google Chrome (using v81 as of May 2020):
Open your console.
Select a value other than "Option 0."
Click "Submit."
Press "Back" in your browser.
The value of the select element will be updated to the value of the select when you submitted the form. If you check the console, though, you'll see the value is "Option 0" initially, and it is updated to the value prior to navigation some time between DOMContentLoaded and window.onload.
Does anybody know if it's possible to listen for when Chrome makes this change? No change or input event is fired. I've tried using a setTimeout inside the DOMContentLoaded handler, and that seems to work, but seems hacky and potentially inconsistent.
Edit: It looks like the short answer is "no, there isn't an event that's triggered when Chrome changes the values." It is possible instead to see if the page was loaded after a navigation event. If it was, any form values set by window.onload can be assumed to have been set by the browser.
Looks like pageshow is buggy.
performance.getEntriesByType("navigation")[0].type === 'back_forward
(Deprecated value) window.performance.navigation.type === 2
You can also use autocomplete=off on your form inputs
EDIT: pageshow doesn't work as of 5/6/2020 on Chrome 81
pageshow/pagehide events to detect loading from bfcache, which is where the form values are loaded from.
https://github.com/adobe/webkit/blob/master/Websites/webkit.org/blog-files/pageshow-pagehide-example.html
https://developers.google.com/web/updates/2018/07/page-lifecycle-api
https://developer.mozilla.org/en-US/docs/Web/API/Window/pageshow_event
function pageShown(evt)
{
if (evt.persisted)
; // do things to your forms
else
; // no need to do anything
}
function pageHidden(evt)
{
if (evt.persisted)
; // do things to your forms
else
; // no need to do anything
}
window.addEventListener("pageshow", pageShown, false);
window.addEventListener("pagehide", pageHidden, false);
This question already has answers here:
Clear all fields in a form upon going back with browser back button
(7 answers)
Closed 4 years ago.
There is a pretty similar question here but I'm doing something different. In my case when submitting the form if something fails I'm doing a history.back() to keep all values in the form, but in the case of the input files the file name remains there but there is actually no file in there. So to avoid confusion and let the user know it needs to upload the file again I want to clear the value of that element only, and another input text that has the file description.
Adding autocomplete="off" attribute to it does the trick since prevent the browser to cache that value, but this works in Chrome but not in IE11.
I can also do it using JQuery like $input_file.val('').end(); but since I'm trying to do it after history.back() is not working not sure why.
<script>
alert("Error");
window.history.back();
$('input[id="Attachment"]').val('').end();
</script>
Any other idea on how to accomplish this is welcome.
There is a trigger called pageShow that gets fired when the transition animation has completed.
jQuery( ".selector" ).on( "pageshow", function( event ) { ... } )
In your case, you'd want to do the following
<script>
alert("Error");
window.history.back();
$(window).bind("pageshow", function() {
//debugger; you can check and see if this block of code gets triggered
$('input[id="Attachment"]').val('').end();
});
</script>
Note: The triggering of this event is deprecated as of jQuery Mobile 1.4.0. It will no longer be triggered in 1.6.0.
The replacement for pageshow is the pagecontainer widget's pagecontainershow event. In jQuery Mobile 1.4.0, the two events are identical except for their name and the fact that pagecontainershow is triggered on the pagecontainer, whereas pageshow is triggered on the page.
jQuery Reference to the event
examples
Before I get rushed telling me to search first.. I've tried. Without any luck and after trying multiple solutions.
This link looked as though it should work, but it does not.
Stackoverflow link to preventing backspace
I tried using that script. I also tried catching the key myself (using keyup, keydown, keypress) and returning false, preventDefault, stopPropagation, etc. Nothing seems to work.
Catching the key event does prevent it from navigating back when any other element is focused or simply the body being focused. This helps, but does not solve my issue.
I found another solution using pure javascript without jquery and it has the same effect (still navigated when select is focused and open).
If a user selects an option and then presses backspace it does not navigate back, but for some reason if the SELECT is still open, it directs them away from the page.
One solution I have considered is using a body onunload event to prompt the user if they want to leave the page, but then I have to deal with that when they submit to form or click a link on the page which is not an ideal solution.
The current code(of many different attempts):
$(document).on('keyup keydown keypress', function(e){
var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
if(key == 8){
console.log('backspace');
e.preventDefault();
e.stopPropagation();
return false;
} else {
console.log('keypress');
}
});
Any help is genuinely appreciated. Thanks.
[Edit] I am using Google Chrome Version 48.0.2564.116 m
I had a similar problem; i'm not sure why, but select elements weren't being captured by the $(document) selector.
try ('*').on('keydown', function(e){...});, this worked for me.
I'm trying to implement a search bar on my website. I already have the back end processing working correctly, and I have the html and CSS in place for the search bar, all I have left to do is get my JavaScript to trigger the search to execute. Here is the html for the search bar:
<div id="search_field_container">
<input type="text" name="search_field" id="search_field" maxlength="100" placeholder="Search by item name or #tag" value="Search by item name or #tag" onclick="value=''" />
<button id="search" name="search_button">s</button>
</div>
What I'm trying to do is set up jQuery event handlers to trigger a JavaScript function called search when the user either presses enter while the text bar is focused or when they click the search button. However, I absolutely cannot seem to get the event handlers to trigger. Here is my JavaScript:
//Search function
$(document).ready(function(){
console.log("In anonymous function.");
$("#search").on('click', function(event){
alert("In click handler");
search();
});
});
$("#search_field").bind('keyup', function(event){
alert("In keyup handler");
if(event.keyCode == 13){
alert("In enter handler");
search();
}
});
function search(){
alert("Something happened!");
var searchTerm = $("#search_field").val();
alert("You're trying to search for "+searchTerm);
}
Currently, nothing happens when I either hit enter with the cursor in the text bar or press the search button. I know it isn't JavaScript errors preventing execution of everything, because all of the other JavaScript on the page executes perfectly fine.
I know the search function works and that the at least the search_field id on the text input is correct because if I add an onclick to the button and call search through that, it executes correctly and it always echoes the value from the text field correctly.
The search bar is in a separate header file so I don't have to include it in the html of every page, but that shouldn't make a difference because I'm including the file with PHP, so it should already be in place before the file even gets to the user. Just in case though, I've already tried using .bind and document.ready as you can see, as well as .on and an anonymous wrapper function, to no avail.
I don't get any error messages in the console or anything, it just silently fails. I know there are tons of similar questions on this site, but I've already tried every solution I could find to about a dozen of them. If anyone knows what the problem is and how to fix it, or even just additional tests to help figure out why this is failing so I can narrow my searches down, that would be greatly appreciated.
EDIT:
Huangism created this JSfiddle using my code and showed that the code works properly, so there must be something about the context of my site causing it to not function.
Fiddle - http://jsfiddle.net/3m5Mp/
I added a fiddle to your question. You should move #search_field handler inside of doc ready. In fiddle it works because it is already assuming doc ready. The click works for me in the fiddle.
Which browser are you testing on?
For enter
code= (e.keyCode ? e.keyCode : e.which);
if (code == 13) alert('Enter key was pressed.');
Got this from another question
Here is a fiddle with the handlers all in doc ready and not assuming doc ready
http://jsfiddle.net/PFcnx/2/
It seems to work in FF, please test in other browsers and see if it works
Your js error probably has something to do with the extra comma at the end
$("#grid").masonry({
itemSelector : '.entry',
isFitWidth : 'true',
isResizable : 'true',
});
remove comma after the last 'true'
Use event.which instead. I'm also not 100% sure, but you may want to try .keydown or .keypress instead. I am looking at some JS code on a site of mine where I trap enter key presses and I only use those two. I remember having trouble with .keyup for some stuff.
This is driving me nuts. Its a tough one to explain but I'll have a go.
I have one input text field on the front page of my site. I have coded a keydown event observer which checks the keyCode and if its ENTER (or equiv), itll check the input value (email). If the email is valid and unique in the DB itll submit the form. Basic stuff, or so you would think.
If I type my email address in the field and hit enter, it works fine in all browsers. However, if I type the first couple of letters, and then use the arrow keys to select the email from the history dropdown box (hope you know what I mean here), and then press enter the result is different. The value of the form field is being captured as just the couple of letters I typed, and therefore the validation is failing. It seems that when I press the enter key to "select" the email from the history dropdown, the browser is interrupting that as if I was typing.
In Chrome and Safari it works as it should. As it should means that when you press enter to "select" the email from the history dropdown, all it does is puts that email address into the text box. Only on the second ENTER key press does it then trigger the event observer, and the email is validated.
Hope somebody can shed some light on why this is happening... My gut feeling is its a browser thing and will be something I cant fix.
Thanks
Lee
EDIT:
To add clarification to my question let me add that Im using the "keydown" event to capture the moment when the enter key is pressed. I have tried the "keyup" event and this solved my problem above, but then I cant seem to stop the form submitting by itself. The "keyup" event triggers AFTER the default behaviour, therefore its not the right choice for this.
FURTHER EDIT:
Thank you again, and btw, your English is excellent (in response to your comment about bad English).
I have changed my event handler from this:
$("emailInputBox").observe("keydown", function(event) {
return submitViaEnter(event, submitSignupFormOne);
});
to this:
$("emailInputBox").observe("keydown", function(event) {
setTimeout(submitViaEnter.curry(event, submitSignupFormOne),0);
});
submitViaEnter:
function submitViaEnter(event, callback) {
var code = event.keyCode;
if (code == Event.KEY_RETURN) {
event.stop();
return callback(event);
}
return true;
}
Seems to work but the problem now is that the browser is permitted to carry out the default action before running the submitViaEnter function which means the form is being submitted when I hit ENTER.
Answer to the original question
Yeah, it's a Gecko bug (not Mac-specific though).
The last part of this comment contains the description of the work-around: use the time-out.
[edit] since you asked for the clarification of the bug
When you press Enter and the auto-complete is active, Firefox (erroneously) first fires the page's key handler, then the browser's internal key handler that closes the autocomplete popup and updates the text area value, while it arguably should just fire it at the autocomplete popup and only let the page know the textbox value changed.
This means that when your key handler is called, the autocomplete's handler hasn't run yet -- the autocomplete popup is still open and the textbox value is like it was just before the auto-completion happened.
When you add a setTimeout call to your key handler you're saying to the browser "hey, run this function right after you finished doing stuff already in your P1 to-do list". So the autocomplete's handler runs, since it's already in the to-do list, then the code you put on a time-out runs -- when the autocomplete popup is already closed and the textbox's value updated.
[edit] answering the question in "Further edit"
Right. You need to cancel the default action in the event handler, not in the timeout, if you want it to work:
function onKeyPress(ev) {
if (... enter pressed ...) {
setTimeout(function() {
... check the new textbox value after letting autocomplete work ...
}, 0);
// but cancel the default behavior (submitting the form) directly in the event listener
ev.preventDefault();
return false;
}
}
If you still wanted to submit the form on Enter, it would be a more interesting exercise, but it doesn't seem you do.
ok sorted it. Thanks so much for your help. It was the curry function that I was missing before. I was trying to work on the event inside the scope of the setTimeout function.
This works below. The submitViaEnter is called from the eventobserver and responds to the keyDown event:
function submitViaEnter(event, callback) {
var code = event.keyCode;
if (code == Event.KEY_RETURN) {
event.stop();
setTimeout(callback.curry(event),0);
// return callback(event);
// return false;
}
return true;
}
Stopping the default action inside the eventObserver meant that no characters could be typed. So I stuck inside the if ENTER key clause.