I have a Dojo 1.6.1 (dijit) form with a connection on the submit event.
The form will be submitted with AJAX.
The problem is that when i use dojo.stopEvent on the submit event it stops the triggering of the onChange events for the other inputs (dijits).
In other words: after the submit event occurs I explicitly stop it and send the data with AJAX. After that the onChange event for the inputs cannot be triggered neither by changing the inputs value or programmatically calling dijit.byId('someDijit').onChange().
Any ideas what is the cause of this?
I'm sorry, my bad. The function was called correctly, however another function executed in the onChange wasn't firing.
EDIT:
And the fault was a function with the same name(as the function to be called inside onChange), introduced later in the script.
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 write a userscript which creates a text input on a website, however in the website's javascript code, a function called on keypress or something else calls e.preventDefault() which prevents text input. I do not have access and cannot change that function. Is there any way to bypass that?
We have to register an event listener to be able to call preventDefault or stopPropagation. If the methods are called, I believe there's no way negating the effect after the default was prevented or the propagation stopped.
The only chance would be: register you own listener before the website has a chance to register it's own. Which probably happens in a script and if you can find that, you can inject your own script before that. Then your handler would be called first and that could work for you. (you could call stopPropagation and the other listener wouldn't be called anymore)
In the following code (JSFiddle here):
<form>
<button>ok</button>
</form>
$(function(){
$('form').submit(false) ;
$('button').click(function(){ $('form').remove() }) ;
}) ;
When you click the button in Google Chrome 48, it triggers a form submission.
If you do it in Firefox 43, however, there is no form submission.
It seems to me that the Firefox behavior should be the correct one, but since I don't have such a deep knowledge of the standard, I don't really know.
Is either behavior wrong or buggy?
Follow up:
I just found out that the same test case but without using jQuery doesn't trigger a form submission in neither browser.
<form onsubmit="return false">
<button onclick="form.remove()">ok</button>
</form>
This could not be a timing issue because there's no thread concurrency in Javascript. Event threads will always run in sequence, so the button event handler must finish before the form event handler starts.
I'm blind here. jQuery must be doing some weird cumbersome stuff for this to happen in Chrome.
Follow up 2:
It's not a jQuery problem. At the jQuery bug tracker I was told that inline event handlers don't follow the same specification as those attached with addEventListener, so a true functionally equivalent code should be like this:
<form>
<button>ok</button>
</form>
<script>
document.querySelector('form').addEventListener('submit',function(){ return false }) ;
document.querySelector('button').addEventListener('click',function(evt){ evt.target.form.remove() }) ;
</script>
And this does behave like the jQuery version.
Your first code adds a returnFalse jQuery event listener:
$('form').submit(false);
In a jQuery event listener, return false is equivalent to
event.stopPropagation();
event.preventDefault();
The later should prevent the submission of the form.
However, before the submit event is fired, you use $.fn.remove. This not only removes the form from the document, it also cleans its jQuery data, including the event listener.
Therefore, when the browser fires the submit event to the form, it is not canceled.
Then browsers behave differently (demo):
Firefox doesn't submit removed forms
Chrome doesn't care whether the form has been removed and submits it anyway
If you don't want to remove jQuery data, you should remove the form using vanilla-js methods instead of $.fn.remove.
In your second code, you cancel the event in a vanilla-js event handler.
Since it's not jQuery data, $.fn.remove does not remove it, so the submit event is canceled and the form is not submitted.
In your third code, you you remove the form using vanilla-js methods, so its jQuery data is not cleaned.
This does not matter because the submit event listener is added with vanilla-js too.
However, the event is not canceled. That's because, unlike vanilla-js event handlers and jQuery event listeners, the value returned in a vanilla-js event listener is completely ignored.
So at the end the result is the same than in the first code, but they are not equivalent.
If you want to cancel an event using a vanilla-js event listener, you should use
event.preventDefault();
This would make it behave like the second code.
I think that it is implementation dependent and not guarantee identical behaviour
Both Chromium and Firefox does not call form.onsubmit handler installed by $('form').submit(...) when $('form').remove() called. So this mean that form is checked as destroyed (or realy destroyed) before to call onsubmit in both Chromium and Firefox.
I think that Chromium does not check that form marked as destroyed when process default submit action emitted by button pressing. But Chromium do checking preventDefault flag where default action of button is form submit. So it is possible to add event.preventDefault() before or after $('form').remove().
In opposite Firefox ignore preventDefault of button pressing event and pass control to form.onsubmit.
So behaviour of this two browsers concerning preventDefault and onsubmit is exactly opposite.
As far as fact of form submiting when form is marked as destroyed it is possible to imagine software design where object actually deleted after communication is finished and not before. But seems to me that it is bug. Need to know what developers think. Does they know about it and is this bug or feature.
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.
I have a form that requires a Submit, now for design reasons I have had to relocate the code for the submit of these forms and use JS to actually submit them.
This has been workig fine, no problems until I hvae found a form that also does a further peice of JS that no longer fires...
My submit JS is as follows:
function submitform()
{
document.details.submit();
}
This works great. However this is another piece of JS that does work when using the HTML Button:
$('form').submit(function(){
$('#sortdata').val($( "#sortable" ).sortable("serialize"));
return true;
});
Any help/advice would be brilliant as am just going round in circles with changing the names of elements in the JS. This surely has to be possible no?
Use the jQuery submit method to trigger event handlers attached with jQuery:
$(document.details).submit(); //shorthand for .trigger('submit')
Demo
This will submit the form in the same fashion, but also trigger the submit event handlers bound to that element with jQuery before doing so.
The issue was that the native HTMLFormElement.submit() method is not warranted to trigger event handlers bound with jQuery (or any event handler at all):
The form's onsubmit event handler (for example, onsubmit="return false;") will not be triggered when invoking this method from Gecko-based applications. In general, it is not guaranteed to be invoked by HTML user agents.
In other hand, jQuery's .submit()/.trigger('submit') will always¹ execute the event handlers attached through jQuery to that element.
jQuery .trigger() reference
¹ Except if event.stopImmediatePropagation() was called previously for the given event but that's a completely different topic.