Why is a form's onsubmit function only called once? - javascript

Pretty much what it says on the tin. This snippet demonstrates the problem:
function check(e) {
console.log($('input[name="myinput"]').val());
if ($('input[name="myinput"]').val() == "123") {
return true;
} else {
$('input[name="myinput"]')[0].setCustomValidity("Invalid");
return false;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<form onsubmit="return check()">
<input name="myinput">
<input type="submit">
</form>
</div>
When the form loads, enter 1 into the input field and submit the form. Submission fails because the input field's value was not 123, and the value "1" is logged in the console. Now change the value to anything else and resubmit the form; there is no extra line in the console and the "Invalid" form validity remains even if the value entered is 123.
Why is the onsubmit handler only called once?

Because a form in an "invalid" state (because an input inside the form is in "invalid" state) won't submit.
Form validity is created not to be changed on submit events because, as you noticed, you won't get any new submit. You must change the form validity before submitting it. Usually, form validity is checked individually on each input. From here is on your own taste. I would recommend checking the validity of each input on blur:
$('input[name="myinput"]').on("blur", () => {
// Do your checks and setCustomValidity depending on if is valid or not
});
This way, you only will receive a submit event if all inputs are valid. By the way, for this to work, you must set all inputs to an invalid state on startup, to avoid empty submits without touching any input.
Another way could be to disable the submit button if all inputs are empty. For this, you will also need JavaScript and check the change or input events on all inputs.

Related

EventListener that triggers when text input, but NOT when input is deleted

Background:
I'm adding event listeners to a HTML form, that check if the input in each field is valid. For example:
inputElement.addEventListener("input", function(event) {
if (!isValid(input.value)) {
input.setCustomValidity("Input is invalid");
} else {
input.setCustomValidity("");
}
});
However, the form field in question is not mandatory - the user can submit the form with the field empty, but they can't submit it with invalid input.
Problem:
If the user submits the form without ever touching that input (leaving it blank) the "input" event never occurs, and the form can be submitted. (Good)
If the user enters incorrect input and submits the form, they get a warning message "input is invalid". (Good)
But, if they enter invalid input, get the warning message, and then delete the input, the warning message will appear and the form will now submit. (Bad)
This happens because the act of deleting the input triggers the input event.
Progress:
I've tried using the textInput event instead but I get the same behaviour. I've checked for other available events but I can't see one that would fix this problem.
I could make it work by modifying my isValid function to return true if given an empty string, but I'd like to avoid that if possible. The reason being: I've simplified the example here but in reality that function is actually isValidServiceId and technically an empty string is not a valid service id.
You can modify your conditional logic to say "If the input is populated and invalid", rather than just "If the input is invalid"...
inputElement.addEventListener("input", function(event) {
if (input.value.length && !isValid(input.value)) {
input.setCustomValidity("Input is invalid");
} else {
input.setCustomValidity("");
}
});

How to manually trigger bootstrap "required" tooltip alert?

When you submit a form via <input type="submit">
and some input with required attribute was empty, a little box appears near to the missing input box saying "Please fill out this field" or something similar (I use it in Italian so I don't know the exact wording used in English).
I need to manually trigger this tooltip alert using JavaScript, any idea how to achieve this?
The form validation is provided by HTML5, it's not related with Bootstrap, to disable the default form validation provided by the browser you have to work with the form containing the input, for example using the attribute novalidate will disable the default form validation provided by the browser. If then you want to use a custom form validation function you can use the onsubmit event on the form, so for example you will have something like:
<form onsubmit='return submitForm(this);' novalidate='novalidate'>
<input type='text' required>
<input type='submit'>
</form>
By doing this when the form is submitted you are passing the function submitForm the submitted form, so that this function is able to iterate through the elements of the form to check them.
Something like:
function submitForm(formToValidate){
var formValid=true;
var inputs = formToValidate.getElementsByTagName("input");
var errorDescription;
for(var i=0; i<inputs.length; i++)
{
var inputValid=true;
switch(inputs[i].type)
{
case "number":
if(inputs[i].hasAttribute("required")&&inputs[i].value=="")
{
inputValid=false;
errorDescription="Required field";
}
/*Check other attributes here (max, min, step, etc.)*/
break;
/*Check other types of input here*/
}
if(!inputValid)
{
markInputAsNotValid(inputs[i],errorDescription);
formValid=false;
break;
}
}
return formValid;
}
Note that the value returned by the function submitForm is used by the browser to determine if the submission was successful.
For more information: https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Form_validation

Ajax form submit after validating input elements

I have a form which collects some information using text boxes. Some text boxes have a strick pattern, e.g. few input boxes take only numbers.
I was able to add validation using pattern attribute of input field. http://www.w3schools.com/tags/att_input_pattern.asp
However, when user submits the form I need to do a ajax post request to a different end point. So, I think I have to make a call to preventDefault() method to prevent default form submit.
But when I call preventDefault(), it also disables validating input fields.
How can I achieve validating fields and make a ajax request, only if the input fields pass the validation.
You can either way use this:
First change the input[type="submit"] to this:
<button onclick="submitThis()">Save</button>
function submitThis() {
var firstInput = $("#idoffirstinput).val(); // basic validation
if(firstInput == "correctinput") {
$.ajax({
// send the ajax form
})
}
}
You can seperately validate each input using the technique provided there, or the one I provided. The jQuery error will be same; I mean the validation.
Use this:
if(firstInput == "correctinput") {
// ajax form
} else {
// show the error popup!
}
The plus point for this one is that you can style the error dialouge popup too. Like
$("#errordiv").css("border", "1px solid #hexcode");
And everything else is same!
HTML and jQuery:
<form id="details">
Phone no: <input type="text" id="phone_no" pattern="[A-Za-z]{3}">
<input type="submit" id="submit">
</form>
var input = $('#phone_no').val();
if(input != '')
{
var YOUR_URL = 'www.example.com';
var formData = $('#details').serialize();// If you want to pass that data to that URL
$.post(YOUR_URL,formData,function(result){
});
}
else
{
return false;
}

How do I use jQuery to disable a form's submit button until every required field has been filled?

I have a form with multiple inputs, select boxes, and a textarea. I would like to have the submit button be disabled until all of the fields that I designate as required are filled with a value. And after they are all filled, should a field that WAS field get erased by the user, I would like the submit button to turn back to disabled again.
How can I accomplish this with jQuery?
Guess my first instinct would be to run a function whenever the user starts modifying any of the inputs. Something like this:
$('#submitBtn').prop('disabled', true);
$('.requiredInput').change(function() {
inspectAllInputFields();
});
We then would have a function that checks every input and if they're validated then enable the submit button...
function inspectAllInputFields(){
var count = 0;
$('.requiredInput').each(function(i){
if( $(this).val() === '') {
//show a warning?
count++;
}
if(count == 0){
$('#submitBtn').prop('disabled', false);
}else {
$('#submitBtn').prop('disabled', true);
}
});
}
You may also want to add a call to the inspect function on page-load that way if the input values are stored or your other code is populating the data it will still work correctly.
inspectAllInputFields();
Hope this helps,
~Matt
Here's something comprehensive, just because:
$(document).ready(function() {
$form = $('#formid'); // cache
$form.find(':input[type="submit"]').prop('disabled', true); // disable submit btn
$form.find(':input').change(function() { // monitor all inputs for changes
var disable = false;
$form.find(':input').not('[type="submit"]').each(function(i, el) { // test all inputs for values
if ($.trim(el.value) === '') {
disable = true; // disable submit if any of them are still blank
}
});
$form.find(':input[type="submit"]').prop('disabled', disable);
});
});
http://jsfiddle.net/mblase75/xtPhk/1/
Set the disabled attribute on the submit button. Like:
$('input:submit').attr('disabled', 'disabled');
And use the .change() event on your form fields.
Start with the button disabled (obviously). Bind an onkeyup event to each required text input, and an onchange or onclick to the select boxes (and any radio buttons/checkboxes), and when it fires, check whether all required inputs are filled. If so, enable the button. If not, disable it.
There is one loophole here, though. Users can delete the value of a text field without triggering the onkeyup event by using the mouse to "cut" the text out, or by holding down the delete/backspace key once they have deleted it all, and clicking the button before deleting it.
You can get around the second by either
disabling the button with onkeydown and checking if it is ok on onkeyup
checking for validity when the button is clicked
An idea from me:
Define a variable -with global scope- and add the value true- Write a submit function within your check the value above varibale. Evalue the the submit event only, if the value is true.
Write a function which ckecks all value from input fields and select fields. Checking the length of value to zero. if the value length of one field zero then change the value of the global variable to false.
After that, add to all input fields the event 'onKeydown' or 'onKeyUp' and to all select boxes the event 'onChange'.
I recommend taking a slightly different approach and using jquery's validation http://docs.jquery.com/Plugins/validation. The tactic you are suggesting is prone to security holes. The user could easily using firebug enable that button and then submit the form.
Using jquery validation is clean and it allows you to show error messages under the required fields if so desired on submit.

Adding submit event on form prevents submit parameter from being included in HTTP POST

Just what the question title says. I'm using SpringMVC, but that's irrelevant really. I just need to be able to pass the submit button name=value along with the rest of the form parameters for validation and control purposes. Example below for clarification:
The HTML I'm using:
<form action='somepage.htm' method='post'>
<input name='somename' value='bob' />
<input type='submit' name='mybutton' value='click me' />
</form>
The JavaScript (with jQuery) I'm using:
$('form').submit(function() {
$('input[type="submit"]', this).attr('disabled','disabled');
return true;
}
And so the HTTP POST request looks like this without the JavaScript event binding:
somepage.htm?somename=bob&mybutton=click%20me
And with the bound event, it excludes the button parameter as such:
somepage.htm?somename=bob
I need to be able to disable the buttons and still send the button value to the server for processing.
Thanks!
SOLUTION:
The code I actually used to solve this problem is:
$(document).ready(function() {
$('input[type="submit"]').click(function() {
var clone = $(this).clone();
$(clone).attr("type","hidden");
$(this).attr('disabled','disabled');
$(clone).appendTo($(this).parents('form')[0]);
return true;
});
});
And in case anyone was wondering, pressing Enter on a field in the form does in fact trigger the click event on the first submit button in the form!
Disabled inputs cannot be submitted.
http://www.w3.org/TR/html4/interact/forms.html#h-17.12
So maybe the way to go is to add a hidden element <input type='hidden' value='foo' name='bar'/> to stimulate the validation methods on the other end.
I think, if the submit button is clicked, then it's values will also be submitted, like rest of the form.

Categories