Situation: I have a form for the user to change their profile.
The form has input fields with event listeners attached for the onchange event so I can tell if the user has made any changes to the form. One of those fields is a password field.
In the case where the browser is set to remember passwords, when the form loads, it fills in the password field and triggers my listener.
Workaround:
I have set a timeout to reset my dataChanged flag after the page loads. Not very elegant. It seems that crawling the event.callee.caller stack is not recommended, non-standard, and unlikely to distinguish user- from browser-initiated events.
Question:
Is there a way I can determine events triggered by the user interaction (and javascript) only?
I don't want to cancel the event though, I just want to ignore it.
Clarification on choice of event:
This code is in our form-handling js library used throughout numerous applications. We need to know if the field has actually changed its contents so we can warn the user on leaving the form that data has not been saved. It is also used to trigger recalculation of other co-dependent fields.
Using onkeyup/onkeypress will trigger when the user presses non-editing keys like Tab, cursor-arrow, Shift etc. We want to avoid having to store the contents as loaded, and compare that to the content after onkeyup to determine whether the contents have actually changed.
Browsers also trap conditions where the user edits the field, changes their mind and presses ESC or CTRL-Z - onchange is not triggered. Event onkeypress fires many times during that process.
Therefore we would want to stick to onchange as the event of choice since it designed for our purpose - fire when content actually changes, once only when user exits the field.
Maybe you can set autocomplete="off" on the username and/or password field to stop the browser from auto-filling them
You can simply use onkeyup to handle this:
While loading your window you don't need to attach events to the
onchange of the fields so they can be autofilled by the browser.
And onkeyup of a field you will attach the event to its onchange so
the onchange event will only fire only if the user really changed
this field value.
For example:
HTML:
<input type="password" onkeyup="giveOnchangeEvent(this)"/>
JS:
function giveOnchangeEvent(input) {
input.onchange = function() {
//give the actions you need to do here
}
}
And that should do the trick.
EDIT:
To solve all the problems stated in your EDIT, you can use onfocus instead of onkeyup and append the onchange listener only and only if the input is focused by the user, and this way the browser auto filling actions will not count anymore.
Just change the onkeyup with onfocus in your input:
<input type="password" onfocus="giveOnchangeEvent(this)"/>
Note:
This approach avoids only the first onchange (of the browser) which is fired when the window loads.
Related
I would like to add an event listener for when a user tries to submit a <form> that has validation errors.
Is there a way to do that in a reliable and accessible way?
Solutions I considered (none of them are good):
Adding 'submit' event listener to <form>.
This doesn't work since 'submit' is only fired for valid forms.
An 'invalid' event is fired by HTML <input> elements that have validation errors when
the user tries to submit a form.
The event does not bubble, so I can't listen to it like this: form.addEventListener('invalid', callback);
Thus, listening for 'invalid' event requires adding 'invalid' event listener for each <input> inside the form when that field is created. It is easy to forget to add an event listener to a field, since fields are created dynamically in many different .js and .tsx files, thus this solution is error-prone and far from ideal.
Listening for 'click' event on the submit button and in the callback checking if form.checkValidity() is false.
This solution is also not ideal as screen reader software and other assistive technologies won't necessarily trigger the 'click' event when trying to submit the form.
Is there any good way to know if a user tries to submit an invalid form?
I am fine with a solution that involves React, jQuery or native JavaScript.
If there is no good to this problem, please consider my use case and tell if there is an alternative approach:
I need to add styling to invalid form fields only after the user tried to submit a form.
I am trying to fill a website with the help of a greasemonkey script.
This website has some required fields and I can't submit the form when they are not filled in.
Now, I have the following problem:
I fill the required fields using jQuery's .val. When I now click the submit button - even manually with the mouse - then it says that some of the required fields are not filled in.
When I click in one of the affected fields with the mouse and then click the submit button again, it accepts the value and proceeds.
My question is:
How do I figure out which event the website listens to? Or:
How can I trigger the validation of the fields from my script?
Update: I tried the following command directly in Chrome's developer tools' console:
jQuery('#ext-comp-1080').click().focus().focusin()
.val('my value').change().blur().focusout()
Most often, the validation is tied to a blur event.
In jQuery, you would use:
$('#thingToBlur').blur();
That said -- I have never triggered events through a UserScript, so I'm not sure if they will correctly hit the element in unsafeWindow.
If you need to force-ably run JavaScript on the page (and that includes firing the events there), see this question:
UserScripts & Greasemonkey: calling a website's JavaScript functions
Since after you change the file by using .val() and then you click into a field and click submit it most likely listens on change or blur event.
// set value
$(selector).val(value);
// trigger click
$(selector).click();
// trigger change or blur
$(selector).change();
You could also do method chaining if you wanted.
I'm using jQuery to alter things when a user enters text into an input. This works fine with .keydown() or .change() when typing.
I'm unable to capture an event when the user selects from the browser stored inputs for that field. This is the dropdown that appears when typing or on click when the element already has focus and the browser has previously entered items for this input.
Anyone know what event I can use to capture the population of the input by the browser from a stored list of previous inputs when the user clicks on one or uses the keyboard?
EDIT: As requested an example would be https://launchpad.37signals.com/highrise/signin (the Username and password, not openID). This hides the label for pasting, selecting from previous inputs or typing. I want to emulate this.
Thanks,
Denis
There's not one event triggered. As you said, it depends on how the user is using it : keyboard or mouse.
If I can remember well, keyboard approach triggers nothing. You should bind on the blur() event.
The mouseup should work for the mouse approach.
But whatever since you can bind several event at once thanks to
$("#id").bind("blur mouseup", function(){
alert("bound !");
});
The change event will fire as well, but when the element looses focus.. (like it normally does)
You would have the same issue even without the browser cache, if someone use the right-mouse-click -> paste of something they had in the clipboard ...
What about mouseup event? did you try it on the input?
$(document).ready(function() {
$("input[id^='question']").live('keyup',function(ev){
id=this.id.substr(8);
if (ajaxCallTimeoutID != null)
clearTimeout(ajaxCallTimeoutID);
ajaxCallTimeoutID = setTimeout(function(){subjectivecheck(id)}, 1000);
});
});
There is a problem. When a user pastes text into an input field, the function above can not be fired. How to solve this problem?
The onchange event is what you want here. It fires when the textbox loses focus (blur) and has had its value changed since it received focus. It takes care of the paste problem.
So instead of .live('keyup', use live('change'.
This is as good as it gets, without using some ridiculous interval polling. And just for the purpose of context, be aware that any user can disable Javascript in the browser whenever they feel like it.
The Paste (onpaste) event is not standard - it is AFAIK supported only in Internet Explorer (see: http://msdn.microsoft.com/en-us/library/ms536955(VS.85).aspx)
The change (onchange handlder) event is standard - but that will only fire if the value of the textbox changed in the time between gaining and losing focus - i.o.w. detecting change requires the textbox to lose focus.
What you could do, is use setInterval() (http://www.w3schools.com/jsref/met_win_setinterval.asp) to poll the value of the textbox, and compare it with the previous value.
At the onfocus event on the field, you can start a timer to check if the field value has changed.
And at onblur, clear that timer.
The paste with ctrl+v is ok with onkeyup, but not with the mouse right click or with a browser undo.
That's not the only problem. Even if you could catch cut and paste reliably on all browsers, which you can't, there are still more ways of putting content in a form field. For example on some platforms dragging a file to an input will put the pathname in, with no event for you to catch. Or a user might do right-click-Undo to change the contents. Or Delete. Or select some text from the input or another input and drag-and-drop it in. And probably many more I haven't thought of.
If you want to be informed of all changes to a form field more quickly than onchange, I'm afraid there is no alternative but to constantly monitor the value of the element in a polling setInterval.
I have an .ASP page that uses the onChange event to trigger a database lookup of information.
(After a Code is entered, the system validates the code and places the description next to it. I.E. GP1234 returns GP1234-Rubber Duck or GP1234-Invalid Code). The problem I am having is that my users that have the AutoComplete active get a list of previously used codes presented. If they use one of the codes in the list, the data is enteres, but not event is triggered to direct the page to verify the data. I have tried OnChasnge, OnBlur, and onMouseOut.
Any suggestions?
From Using AutoComplete in HTML Forms on MSDN:
To determine when a user updates the
content of a field from the
AutoComplete dialog box, use the
onpropertychange event, rather than
the onchange event, because the
onchange event does not fire.
Note that the onpropertychange event is proprietary to Internet Explorer so you'll still need handling for other browsers, and that it fires after every keystroke so it's not directly compatible with the onchange event.
Setting autocomplete="off" on the input will prevent it presenting previously entered values.
If you don't want to do that, the events you're likely looking for are onkeyup (for arrow/enter on the options) and onmouseup (for clicking on the options) events.