I have a form which has an error message as shown in the example below:
http://codepen.io/anon/pen/dYWyEM?editors=101
Steps to reproduce the problem is as follows:
After opening the codepen link,
Focus in the input field
Press submit button
Since, blur event is triggered first, the error message is made hidden first, thus the position of the submit button is changed. Thus the click event is not registered at all and I need another click to submit the form.
Is there any way to send the submit event first?
Somehow I need to detect the target that triggers the blur event.
It seems that relatedTarget enables us to figure out the element that triggered the blur event. However, this does not work in Firefox.
Is there way to figure out the relatedTarget in all browsers?
If your intention is to perform field validation on blur, you still need a way to check to see if there are any validation errors on form submit, so that you avoid submitting the form while there are validation errors.
I'm therefore suggesting an alternative approach instead of a workaround/fix to your exact problem because I think the current model might be troublesome to begin with.
Why don't you perform all field validations on form submit instead of field blur and then prevent the submission when any of the fields have a validation error?
Based on what was told in this answer I came with this solutio. Listen to the mousedown event that triggers before blur and check if the user can submit the form based on if the error message is visible or not.
form.on('mousedown','input[type="submit"]', function(e) {
if(!errorMsg.hasClass("hidden")){
e.preventDefault();
alert("Can't submit until the error message is gone");
}
});
I have updated your CodePen.
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'm developing an app in SAP Fiori with form in it.
Input value change triggers event (change borrowed from sap.m.InputBase so event is triggered on focus change or by enter key press). Event provides user some info. There is also button that sends data to backend.
But there is a case when user changes input value and clicks send button without pressing enter nor changing focus before action.
What happens is change event is triggered but send event is blocked and not triggered at all. User clicks save again and now send event is triggered twice (which make duplicates).
Here's the demo of problem I'm facing:
jsfiddle:
https://jsfiddle.net/o2zLa534/1/
I expect that input change event will be triggered and:
1) nothing will happend and after clicking send only one send event will be triggered or
2) send event will be triggered right after change event has been complited.
I know what the problem is but I cannot find a way out.
Thanks for help.
The issue is with the alerts.
If you check your fiddle, modifying to something else, other than using an alert, it'll work normally as expected. This issue is due to the alert usage itself, you should not be using an alert in a ui5 application, no matter what to be honest.
https://jsfiddle.net/cbL9z6rh/6/
onInputChange: function(evt){
evt.getSource().setValue("testing");
},
onSubmit: function(){
alert("Submitted!");
},
If you now put anything into your input, and press the button "Send", you'll see that your input will be changed to "testing", and your submit alert will display.
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.
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 have an asp.net program in which I place a marker on a google map when the address in a textbox is changed. This Javascript is triggered by the onchange event. However I have noticed that if the user does not 'tab' out of the box before clicking submit, the event does not fire. Is there a way I can fix this?
I think what you are trying to achieve is impossible. the onchange event, happens only when you lose focus on the element. You could use onkeypress, onkeydown or onkeyup to get that change quicker. The problem here is that the value of the textbox is going to be changed by the click of an external element and therefore, you cannot bind it directly to the textbox.
If you know exactly what the clickable elements would be, you could add a click event to each one of them, pointing to a function that would test the textbox current value against the latest known value and if they were different, do whatever you want to do. But i don't think that's the case...
following your comment, you should add a submit event to the form, that would compare the current state of the textbox before submitting the form...