jQuery Validate seems to pass invalid form to submitHandler - javascript

I am trying to use jQuery Validate to prevent my ajax form submit when three fields contain any characters other than digits. Apparently I'm doing something wrong, but I can't see what.
EDIT: There seem to be two errors. My validation rules use the field ID instead of the field name. However, after fixing that problem, the form still validates unexpectedly..
This is my jQuery code:
(function() {
$(document).ready(function() {
formSubmits();
/**
* Handles all the form submits that go on.
* This is primarily the ID search and the form submit.
*/
function formSubmits() {
/*** SAVE RECIPE ***/
// validate form
$("#category-editor").validate({
rules: {
"time-prep": {number: true}, /* not sure why validation doesn't work.. */
"time-total": {number: true}, /* according to this, it should: http://goo.gl/9z2odC */
"quantity-servings": {number: true}
},
submitHandler: function(form) {
// submit changes
$.getJSON("setRecipe.php", $(form).serialize() )
.done(function(data) {
// de-empahaize submit button
$('.footer input[type=submit]')
.removeClass('btn-primary')
.addClass('btn-default');
});
// prevent http submit
return false;
}
});
}
});
})(jQuery);
Here's what I see in the inspector when I put a breakpoint inside the submitHandler. It is getting to the submitHandler despite bad input (a value of 'dsdfd' instead of '123')
This is the relevant markup:
<form id="category-editor" class="form-inline" method="get">
....
<div class='form-group'>
<div>
<label for="time-prep">Prep time (min):</label>
<input value="" id="time-prep" name="activeTime" class="form-control min-calc jqValidateNum" data-calc-dest="time-prep-desc" type="number">
<input value="" id="time-prep-desc" name="activeTimeDesc" class="form-control subtle" type="text">
</div>
</div>
<div class='form-group'>
<div>
<label for="time-total">Total time (min):</label>
<input value="" id="time-total" name="totalTime" class="form-control min-calc jqValidateNum" data-calc-dest="time-total-desc" type="number">
<input value="" id="time-total-desc" name="totalTimeDesc" class="form-control subtle" type="text">
</div>
</div>
<div class='form-group'>
<div>
<label for="quantity-servings">Servings:</label>
<input value="" id="quantity-servings" name="servings" class="form-control jqValidateNum" type="number">
</div>
</div>
....
</form>

You've got your rules set up with the "id" values for the <input> elements instead of their "name" values. Should be:
rules: {
"activeTime": {number: true},
"totalTime": {number: true},
"servings": {number: true}
},
edit — now that you've fixed that, I think the problem is that the "value" properties of the input elements are empty, because you've declared them type=number. Firefox and Chrome let you type anything into the fields, but they won't have a non-empty value unless the fields really do contain numbers.
If you also mark the fields as required, then it works. fiddle

Related

Remove class of submit button based on valid email

I have a submit button for an unsubscribe page, I would like to remove a "disabled" class to the button when user inputs a valid email. As of now I have the class being toggled based on "input" which kind of works but I would rather the user have to input a valid email to remove the "disabled" class. I am using jquery validation for the validation I'm just not sure how to base the buttons class toggle with jquery validate input. Any Ideas?
HTML:
<div class="form-group">
<input type="email" class="form-control email-input input-lg"
name="email">
</div>
<button id="unsubscribe-submit"
class="disabled">
<span class="btn-text>Submit</span>
</button>
jQuery:
$($emailInput).on('input', function() {
$('#unsubscribe-submit').toggleClass('disabled', this.value.trim().length === 0);
});
jQuery Validation:
($unsubscribeForm.length) {
$unsubscribeForm.validate({
errorClass: 'has-error',
errorElement: 'span',
debug: true,
rules: {
email: {
required: true,
email: true
}
},
messages: {
email: {
required: 'An email address is required.',
email: 'Please provide a valid email address.'
}
}
});
}
As you are already using the HTML input type "email", you can make use of modern browsers' integrated form validation. Calling checkValidity() on an input element will tell you whether its current value is regarded as valid or invalid by the browser. Use this to either remove or add the class to the button. In this demonstration, I also showed how to add/remove the disabled attribute. It would be preferrable to simply using a class, because you can still click the button even if it has the disabled class.
$(document.querySelector('input[type="email"]')).on('input', function() {
// use this to add/remove a class
$('#unsubscribe-submit')[this.value.length && this.checkValidity() ? 'removeClass' : 'addClass']('disabled');
// or this to add/remove the disabled attribute
$('#unsubscribe-submit').attr('disabled', this.value.length && !this.checkValidity());
});
.disabled,
button[disabled] {
opacity: 0.5;
cursor: not-allowed;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-group">
<input type="email" class="form-control email-input input-lg" name="email">
</div>
<button id="unsubscribe-submit" class="disabled" disabled>
<span class="btn-text">Submit</span>
</button>
You do not even need JavaScript to change the button with HTML5 validation. Use input email and set it to be required. When it is not valid, the form is invalid which you can target the button to set your style
form:invalid button {
color: red;
}
<form>
<input type="email" required>
<button> submit</button>
</form>

OnInvalid html event triggering after Required modifier removed through JS

I have three input fields I am attempting to enforce validity on. Currently, I have them all set as required, but removing the modifier with Javascript on submit if one of them is filled out; essentially, one must fill out at least one, but not none of these fields.
Here is an example of the fields:
jQuery(function ($) {
var $inputs = $('input[name=Input1],input[name=Input2], input[name=Input3]');
$inputs.on('input', function () {
// Set the required property of the other input to false if this input is not empty.
$inputs.not(this).prop('required', $(this).val().length > 0 && $(this).val() != 0)
});
});
jQuery(function ($) {
$("#Input1, #Input2").oninvalid = (function() {
$(this).setCustomValidity("Please enter a valid Input1, Input2, or Input3")
});
});
var Input3default = document.getElementById('Input3')
if (Input3.value.length == 0) Input3.value = "0";
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="input-group mb-3">
<form action="" method="get" autocomplete="off">
<div class="row" style="text-align:justify; width: 100%; display:inline">
<div class="">
<label for="text3">Input1:</label>
<input type="text" id="Input1" name="Input1" required oninvalid="this.setCustomValidity('Please enter a valid Input1, Input2, or Input3')" />
</div>
<div class="">
<label for="text4">Input2:</label>
<input type="text" id="Input2" name="Input2" required oninvalid="this.setCustomValidity('Please enter a valid Input1, Input2, or Input3')"/>
</div>
<div class="">
<label for="text5">Input3:</label>
<input type="text" id="Input3" name="Input3" required placeholder="0" pattern="[0-9]*" onsubmit="Input3default" oninvalid="this.setCustomValidity('Please enter a valid Input3')"/>
</div>
</div>
<p>
<input type="submit" value=" Submit " />
</p>
</form>
</div>
</div>
This seems to work fine if I leave it default; I have Input1 and Input2 empty by default, and Input3 has a value of "0" by default. If I enter Input1 or Input2, my submission goes through just fine. However, the problems begin if I alter Input3.
Problem 1: Any time I enter Inputs 1 and 2 but leave 3 blank, it triggers invalidity; my Input3default never seems to trigger, and it is passed blank and caught by the oninvalid tag.
Problem 2: Along with that, if I do not specify an Input2 along with my Input1 while Input3 is blank, it triggers invalidity on Input2. Using Chrome Debugger, I can see that the Required tag is removed, but my OnInvalid pop-up still comes up no matter what is remedied.
Essentially, I am trying to solve the second problem: When I remove the required html tag from my input, after invalidating another input with a Javascript-enforced default, my inputs refuse to validate on the front end.
I appreciate any advice and conjecture as to why this may be the case, and believe that the two problems are connected.
EDIT: Upon adding an = to my original oninvalid JQuery function, I removed a JS error. It appears that my Input3 default function triggers on pageload, but not on submit; I added an onsubmit function to input3, but am still receiving oninvalid events for input2.
I was able to fix this issue on my own, using the OnInput event.
The setCustomValidity function, when triggered, does not allow a submission while a CustomValidity is set. In order to fix this, I edited my inputs as so:
<input type="text" id="Input1" name="Input1" required oninvalid="this.setCustomValidity('Please enter a valid Input1, Input2, or Input3')" oninput="this.setCustomValidity('')"/>
I still have a few kinks to iron out, but this fixed my main problem in that the validity of an input was not being reset.
I'll leave this answer unaccepted at first to allow others to pitch in.

Valid inputs and use animation untill page load

I need to validate filled inputs and on submit if all inputs are valid show load animation till next page will shown. I can check for validation one by one, but do not know how to collect them all in one. Maybe there are more simple way to check inputs validation? Also I did all validations inside inputs in code below.
Here is my inputs type which i need to validate and on success show load animation until page refresh to another page:
<form action="" method="POST" enctype="multipart/form-data" name="formz" >
<div>
<label>Name: </label>
<input type="text" onkeydown="return keyDown.call(this,event)" onchange="value = value.replace(/^\s+/,'')" pattern=".{3,20}" name="name" required>
</div>
<div>
<label>Surname: </label>
<input type="text" onkeydown="return keyDown.call(this,event)" onchange="value = value.replace(/^\s+/,'')" pattern=".{3,20}" name="surname" required>
</div>
<div>
<label>Unic Number: </label>
<input type="text" onkeydown="return keyDown.call(this,event)" onchange="value = value.replace(/^\s+/,'')" pattern=".{7,7}" maxlength='7' name="unicnumb" required />
</div>
<div>
<label>Select:</label>
<select name="select" id="select" required>
<OPTION VALUE="0" selected disabled >Select</OPTION>
<OPTION VALUE="1">Select1</OPTION>
<OPTION VALUE="2">Select2</OPTION>
</select>
</div>
<div>
<label>phone: </label>
<input type="text" name="phone" id="phone" placeholder="+XXX(XX) XXX-XX-XX" required>
</div>
<div>
<label for="epoct">E-mail</label>
<input type="email" pattern="[a-zA-Z0-9.-_]{1,}#[a-zA-Z.-]{2,}[.]{1}[a-zA-Z]{2,}" class="form-control input-sm" name="epoct" id="epoct" required>
</div>
<button type="submit" name="button" id="button">Done</button>
</form>
This is the outline for how I've handled successive form validation with jQuery:
$(document).ready(function() {
$( "#button" ).submit(function( event ) {
if ( /* validation fails for first form element */ ) {
// stop form submission
event.preventDefault();
// display an error message
$( "#firstFormFieldId" ).append("<span>Incorrect entry</span>");
// break out of function to ensure validation continues if and only if this condition is met
return false;
}
if ( /* validation fails for second form element */ ) {
// stop form submission
event.preventDefault();
// display an error message
$( "#secondFormFieldId" ).append("<span>Incorrect entry</span>");
// break out of function to ensure validation continues if and only if this condition is met
return false;
}
if ( /* validation fails for third form element */ ) {
// stop form submission
event.preventDefault();
// display an error message
$( "#thirdFormFieldId" ).append("<span>Incorrect entry</span>");
// break out of function to ensure validation continues if and only if this condition is met
return false;
}
// ... repeat for as many form fields that need validation
// if all validation criteria are met, you can deploy loading animation here :)
/* loading animation goes here */
});
});
You can probably already imagine some variations to this template. For instance, rather than appending the <span>s, you could add empty <span>s intended to contain the error messages to your HTML. If an error message needs to be displayed, you then use jQuery to add the text of the error message to the corresponding <span>. The actual implementation will depend on you, but this style has worked well for me.

Trigger html form submit as if you clicked on button (but without a button)?

If you have a <form> and a <button type='submit'> and you click on the submit button, it will do the default form validation, such as checking whether an <input> is required or not. It would normally say Please fill out this field.
However, if I programmatically submit the form through $("form").submit() for example, it would submit it without performing any checks.
Is there a simpler way to perform the default form validations using native JavaScript? There seems to be only checkValidity() on the form element which return true or false. And if I call the same native function on the input itself, it doesn't really do anything.
Here is a demo code of what I mean:
http://jsfiddle.net/totszwai/yb7arnda/
For those still struggling:
You can use the Constraint validation API - https://developer.mozilla.org/en-US/docs/Web/API/Constraint_validation
<div id="app">
<form>
<input type="text" required placeholder="name">
<input type="text" required placeholder="email">
</form>
<button id="save">Submit</button>
</div>
const form = document.querySelector("form");
document.getElementById("save").addEventListener("click", e => {
e.preventDefault();
if (form.checkValidity()) {
console.log("submit ...");
} else {
form.reportValidity();
}
});
Check out and play here: https://stackblitz.com/edit/js-t1vhdn?file=index.js
I hope it helps or gives you ideas. :)
I think this might be the answer you are looking for :
JavaScript :
document
.getElementById('button')
.addEventListener("click",function(e) {
document.getElementById('myForm').validate();
});
HTML :
<form id="myForm" >
First name: <input type="text" name="FirstName" required><br>
Last name: <input type="text" name="LastName" required><br>
<button id="button">Trigger Form Submit</button>
</form>
Demo : http://jsfiddle.net/2ahLcd4d/2/

JQuery validate triggered every time the browser gets the focus

I am using jquery validation plugin to validate my form. I have one field that I don't want to validate but in some way it is validated anyway and I get the error message "Please enter no more than 5 characters."
The field that is validated is a type=file field and I use it together with the Fynework jQuery MultiForm plugin. It's not validated when I try to submit the form, only when I chose file that has a name longer than 5 characters (I think, short names work long doesn't).
I have tried adding the class .ignore to the field that is validated and added that the ignore rule to my validat(), not difference in behaviour.
What can the problem be?
Here is my validat() method, I also include the point at which I add that method:
function addNewTicketValidation(){
$("#newticketform").validate({
ignore: ".ignore",
errorContainer: "#messageBox1",
errorLabelContainer: "#messageBox1 ul",
wrapper: "li",
debug:true,
rules: {
title: "required",
description: "required"
},
messages: {
title: "Titel saknas",
description: "Beskrivning saknas"
}
});
}
$("#newticketmanu").live('click',function(event){
$("#adminarea").load("http://" + hostname + "/" + compdir + "/modules/core/newticket/newticket.php", function(){
$('#my_file_element').MultiFile();
addNewTicketValidation();
});
});
My form:
<form method="post" enctype="multipart/form-data" id="newticketform" class="MultiFile-intercepted" novalidate="novalidate">
<input type="hidden" value="2000000" name="MAX_FILE_SIZE">
<label for="title">Rubrik</label> <input type="text" name="title" id="title"><br><br>
<label for="description">Beskrivning</label> <textarea name="description" id="description" cols="50" rows="15"></textarea><br>
<div id="my_file_element_wrap" class="MultiFile-wrap"><input type="file" maxlength="5" name="file[]" id="my_file_element" class="multi ignore MultiFile-applied" value=""><div id="my_file_element_wrap_list" class="MultiFile-list"></div></div>
<div id="files_list"></div>
<input type="submit" value="Upload" name="upload">
</form>
What can the problem be and how to fix it?
Thanks!
Remove the maxlength="5" attribute from the file input. This is read by the validation plugin and added as a rule (line 812 here https://github.com/jzaefferer/jquery-validation/blob/1.9.0/jquery.validate.js). Checking the specifications (http://www.blooberry.com/indexdot/html/tagpages/i/inputfile.htm), max length still means character length even on a file input, so if you want to limit the user to 5 file uploads you'll need some other method of achieving this.

Categories

Resources