Clear jquery.validate error messages on change/hide of disabled attributes - javascript

Trying to clear the error messages when the disabled fields are toggled on and off on my form using jquery.validate. Right now I have it working where on change or on click fields are showing and changing the prop from disabled. So it works for what I need which is hiding the fields that are not necessary and not validating them when they are in a disabled state. However, when I toggle these fields back to their disabled state ad hide them, the error messages are still showing until I click submit again. I tried adding the .valid() call to the toggleDisabled function and it does not make the messages disappear when they go back to a hidden/disabled state. Anyone see what can be added to make the messages disappear when the fields do?
Here is the working fiddle with what I have so far:
JS Fiddle
And I am using jquery.validate from :
jQuery.Validate
HTML:
<form id="myform">
<input type="text" name="field1" />
<br/>
<br />
<input type="text" id="toggleInput" name="toggleInputName" disabled style="display:none" />
<input type="button" id="toggleButton" value="Toggle Disabled" />
<div id="tickets">
<label for="group1">Number of Tickets: <span class="req">*</span></label>
<select class="group1_dropdown" id="group1" name="group1">
<option value="0">-- Please select --</option>
<option value="1">Member</option>
<option value="2">Member + 1 Guest</option>
<option value="3">Member + 2 Guests</option>
<option value="4">Member + 3 Guests</option>
</select>
</div>
<input type="text" id="payMethod" name="payMethodName" disabled style="display:none" />
<input type="submit" />
</form>
JS:
$(document).ready(function () {
$('#myform').validate({
onblur: true,
onkeyup: false,
ignore: ":disabled",
rules: {
field1: {
required: true,
minlength: 5
},
payMethodName: {
required: true,
minlength: 5
},
toggleInputName: {
required: true,
minlength: 5
}
},
submitHandler: function (form) { // for demo
alert('valid form');
return false;
}
});
});
//used for toggling/showing disabled fields - will display and make not disabled on same click event
(function ($) {
$.fn.toggleDisabled = function () {
return this.each(function () {
var $this = $(this);
if ($this.prop('disabled')) {
$this.prop('disabled', false).show();
} else {
$this.prop('disabled', true).hide();
}
});
};
})(jQuery);
$(function () {
$('#toggleButton').click(function () {
$('#toggleInput').toggleDisabled();
});
});
$(function () {
$("#group1").change(function () {
var str = "";
str = parseInt($(this).val());
if(str == 2)
$("#payMethod").toggleDisabled();
else
$("#payMethod").toggleDisabled();
});
});

I have changed your plugin a little to do what you want.
Fiddle Demo
(function ($) {
$.fn.toggleDisabled = function () {
return this.each(function () {
var $this = $(this),
id = $this.attr('id'), //get the id of input
label = $this.next('label[for="' + id + '"]'); //find the next label which is added by jQuery Validator
if ($this.prop('disabled')) {
label.show(); //show the label
$this.prop('disabled', false).show();
} else {
label.hide();//hide the label
$this.prop('disabled', true).hide();
}
});
};
})(jQuery);
Update
Another way without changing your plugin
Fiddle Demo
$(document).ready(function () { //place your all DOM ready code in one DOM ready handler
var validator = $('#myform').validate({ //assign validate to a variable
//validator code here
});
$('#toggleButton').click(function () {
validator.resetForm();//reset Form validation
$('#toggleInput').toggleDisabled();
});
});

Related

Minimum collective value of several inputs with jquery validate

I have several text inputs with the same name and I'm trying to prevent the form from submitting if the collective value of all the inputs is less than 1. E.g. the user can't put 0 on all of them, but must at least put 1 on one of them so the collective value of all inputs is at least 1.
I have created a method in jquery validate to check if the value is greater than 0 of the selected inputs
<td><input class='{nbTeams: true} nbTeamsVal' type="text" class="form-control" id="nbTeamsMiniSoccer_20" name="nbTeams[]"></td>
<td><input class='{nbTeams: true} nbTeamsVal' type="text" class="form-control" id="nbTeamsYouthMale_20" name="nbTeams[]"></td>
This is the method:
$.validator.addMethod("nbTeams", function(value, elem, param) {
return $(".nbTeamsVal").value > 0;
},"Collective value must be more than 1!"
);
This is my rule and custom message
$(document).ready(function () {
$('#myForm').validate({
rules: {
"nbTeams[]":{
required: true
}
},
messages: {
"nbTeams[]":"This group of fields can only contain numbers and one must contain a value of at least 1."
},
errorElement : 'div',
errorLabelContainer: '.errorTxt',
submitHandler: function (form) {
form.submit();
}
});
});
i edit your code try this :
$.validator.addMethod("nbTeams", function(value, elem) {
var sumOfVals = 0;
$(".nbTeamsVal").each(function () {
sumOfVals = sumOfVals + parseInt($(this).val());
});
return sumOfVals>0;
},"Collective value must be more than 1!"
);
$('#myForm').validate({
rules: {
"nbTeams[]":"nbTeams"
},
errorElement : 'div',
errorLabelContainer: '.errorTxt',
submitHandler: function (form) {
alert('valid form submitted'); // for demo
return false; // for demo
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.0/jquery.validate.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.0/additional-methods.js"></script>
<form id="myForm" method="post" action="#">
<td><input class='{nbTeams: true} nbTeamsVal' type="text" class="form-control" id="nbTeamsMiniSoccer_20" name="nbTeams[]" value="0"></td>
<td><input class='{nbTeams: true} nbTeamsVal' type="text" class="form-control" id="nbTeamsYouthMale_20" name="nbTeams[]" value="0"></td>
<div class="errorTxt"></div>
<button type="submit">Submit</button>
</form>

Hiding element in IE causing form submit

I am getting some strange behaviour within IE which I was hoping someone might be able to explain. I have a simple form with an address lookup input
<form action="http://localhost:8000/processForm" method="post">
<label for="input_1" class="form-control-label col-xs-12">
Postcode
</label>
<div class="col-xs-12">
<div class="input-group">
<input type="text" name="questions[1]" autocomplete="off" id="input_1" class="form-control address" value="" >
<a class="btn btn-xs input-group-addon address-button" id="input_address_addon" role="button" tabindex="0">
<img src="http://localhost:8000/images/glyphicons-243-map-marker.png">
Search
</a>
</div>
<div class="col-xs-12 col-sm-8 col-sm-offset-4 col-md-7">
<select class="form-control selectpicker addSelect" id="input_address_select" style="display: none;">
<option value="">Enter above</option>
</select>
</div>
</div>
<button type="submit" class="btn submit btn-navigation">
Continue
</button>
</form>
The address is entered into the input, then the search button is clicked. This makes a call to an API to return addresses and populate the a select input with them. This all works fine in all browsers, but noticed something strange with IE. This is the Javascript that handles the API call and populating of the select.
!function ($, window) {
$(function () {
init();
});
var getAddresses = function (postcode, callback) {
var $xhr = $.getJSON('/lookupPostcode/' + postcode);
$xhr.done(function (data) {
callback(data);
});
$xhr.error(function () {
callback([]);
})
};
var init = function () {
$("input.address").each(function () {
var $input = $(this);
var $icon = $input.next('.address-button');
var $select = $input.parents('.row').eq(0).find("select");
$select.css("display", "none");
var onKeyUp = function (e) {
if (e.keyCode === 13) {
e.preventDefault();
e.stopPropagation();
$icon.trigger("click");
}
};
var onKeyDown = function(e) {
if (e.keyCode === 13) {
e.preventDefault();
e.stopPropagation();
}
};
$input.on("keyup", onKeyUp);
$input.on("keydown", onKeyDown);
$icon.on("keyup", onKeyUp);
$icon.on("keydown", onKeyDown);
$select.on("keyup", onKeyUp);
$icon.on("click", function () {
getAddresses($input.val(), function (addresses) {
//populate select options with addresses
});
});
$select.on('change', function (event) {
var ua = window.navigator.userAgent;
var is_ie = /MSIE|Trident/.test(ua);
if ( !is_ie ) {
$select.css("display", "none");
}
/*$select.css("display", "none");*/
});
});
};
}(jQuery, window);
So when an address is selected from the select input, I hide the select input. On IE, this hiding of this element seems to make the form submit. You can see above that I have added some code to check that it is not IE and only hide on these devices, and keeping the select in place on IE works fine. Also, if I put an alert at the top of the change event, this also seems to stop the form submitting in IE.
So I was wondering what may be causing this to submit in IE if I hide the select? I have read that IE does not like buttons to be used as form submits, but not sure if this is the issue?
Is there any way to get the select hiding in IE?
Thanks
So I was wondering what may be causing this to submit in IE if I hide
the select? I have read that IE does not like buttons to be used as
form submits, but not sure if this is the issue?
I can't reproduce your problem, everything works well on my side (IE 11.1.17340.0 version).
Please try to use the following code: (based on your code, please note the part of code with comment)
<head runat="server">
<title></title>
<script src="Scripts/jquery-1.10.2.min.js"></script>
<script type="text/javascript">
!function ($, window) {
$(function () {
init();
});
var getAddresses = function (postcode, callback) {
//var $xhr = $.getJSON('/lookupPostcode/' + postcode);
//$xhr.done(function (data) {
// callback(data);
//});
//$xhr.error(function () {
// callback([]);
//})
//using the following array to populate the select.
var datalist = [{ "ID": "1", "ParentID": "0", "Name": "Parent1" }, { "ID": "2", "ParentID": "0", "Name": "Parent2" },
{ "ID": "3", "ParentID": "1", "Name": "Child 1.1" }, { "ID": "4", "ParentID": "1", "Name": "Child 1.2" },
{ "ID": "5", "ParentID": "3", "Name": "SubChild 1.1.1" }, { "ID": "6", "ParentID": "2", "Name": "Child 2.1" }];
callback(datalist);
};
var init = function () {
$("input.address").each(function () {
var $input = $(this);
var $icon = $input.next('.address-button');
//you are using the .row class to find the select control, but from your form, I can't find this class.
var $select = $input.parents('.row').eq(0).find("select");
//debugger;
$select.css("display", "none");
var onKeyUp = function (e) {
if (e.keyCode === 13) {
e.preventDefault();
e.stopPropagation();
$icon.trigger("click");
}
};
var onKeyDown = function (e) {
if (e.keyCode === 13) {
e.preventDefault();
e.stopPropagation();
}
};
$input.on("keyup", onKeyUp);
$input.on("keydown", onKeyDown);
$icon.on("keyup", onKeyUp);
$icon.on("keydown", onKeyDown);
$select.on("keyup", onKeyUp);
$icon.on("click", function () {
$select.empty();
$select.append("<option value=''>Enter above</option>");
getAddresses($input.val(), function (addresses) {
//populate select options with addresses
$.each(addresses, function (index, item) {
//debugger;
$select.append("<option value='" + item.ID + "'>" + item.Name + "</option>");
});
$select.css("display", "block");
});
});
$select.on('change', function (event) {
var ua = window.navigator.userAgent;
var is_ie = /MSIE|Trident/.test(ua);
//get the selected text and populate the input text.
$input.val($(this).find("option:selected").text());
//hide the select control
if (!is_ie) {
$select.css("display", "none");
}
$select.css("display", "none");
});
});
};
}(jQuery, window);
</script>
</head>
<body>
<form action="http://localhost:8000/processForm" method="post">
<label for="input_1" class="form-control-label col-xs-12">
Postcode
</label>
<div class="col-xs-12 row">
<div class="input-group">
<input type="text" name="questions[1]" autocomplete="off" id="input_1" class="form-control address" value="" />
<a class="btn btn-xs input-group-addon address-button" id="input_address_addon" role="button" tabindex="0">
<img src="http://i.imgur.com/H9FIags.jpg" style="height:10px;width:10px" />
Search
</a>
</div>
<div class="col-xs-12 col-sm-8 col-sm-offset-4 col-md-7">
<select class="form-control selectpicker addSelect" id="input_address_select" >
<option value="">Enter above</option>
</select>
</div>
</div>
<button type="submit" class="btn submit btn-navigation">
Continue
</button>
</form>
</body>
The output as below:
The reason why your form submits is the fact that you have a button of type "submit" in your form.
<button type="submit"...>
Whenever you press enter, this will cause your form to submit.
You need to change your submit button to another type like "button" and add a Javascript event handler to it (for example onClick="submit()").
<button type="button" class="btn submit btn-navigation" onClick="submit(this.form)">
Continue
</button>
function submit(form){
form.submit();
}

Change a requiered value from input with jquery or javascript

I need to change the required value from a input base on a check box selection, here is what I have so far.... thanks
<input type="checkbox" id="no_land_line" name="no_land_line" value="”/> // if no land line check here
<script>
$(document).ready(function () {
$('#no_land_line').change(function () {
if (!this.checked)
{
$('#no_land_line_div').fadeOut('slow');
document.getElementById("land_line").setAttribute("required", true);
document.getElementById("cellphone").setAttribute("required", false);
}
else {
document.getElementById("land_line").setAttribute("required", false);
document.getElementById("cellphone").setAttribute("required", true);
$('#no_land_line_div').fadeIn('slow');
}
});
});
</script>
<input type="text" name="land_line" id="land_line" required="true"/> // landline number
<input type="tel" name="cellphone" id="cellphone" required="false"/> // cellphone number
<div id="no_land_line_div”>some text</div>
UPDATE WITH A WORKING CODE
required is not a javascript property.
Change
getElementById("land_line").required = false,
getElementById("cellphone").required = true;
to
$("#land_line").attr("required",false);
$("#cellphone").attr("required",true);
Here's the entire script code :
$(document).ready(function () {
$('#no_land_line').change(function () {
if (!this.checked)
{
$('#no_land_line_div').fadeOut('slow'),
$("#land_line").attr("required",false);
$("#cellphone").attr("required",true);
}
else {
$('#no_land_line_div').fadeIn('slow'),
$("#land_line").attr("required",true);
$("#cellphone").attr("required",false);
}
});
});
Working example : https://jsfiddle.net/23rdtjwq/4/
Following your use of javascript:
document.getElementById("land_line").setAttribute("required", false);
document.getElementById("cellphone").setAttribute("required", true);

JavaScript Validation

I am using the following code to check if at least one checkbox is selected from my checkboxlist in asp.net. I am using jGrowl to throw up a message which works, but the message is still displayed if a selection is made. Any ideas? Also, story_type is an asp label, I am using the code below, but I can't get the jGrowl message to display...
var story_type = document.getElementById('story_type').value;
var agile_list = document.getElementById('agile_factors');
var arrayOfCheckBoxes = agile_list.getElementsByTagName("input");
for (counter = 0; counter < arrayOfCheckBoxes.length; counter++) {
if (arrayOfCheckBoxes[counter].checked) {
return true;
} else {
(function($) {
$.jGrowl("Please Choose up to 3 Agile Factors", { theme: 'smoke', closer: true });
})(jQuery);
return false;
}
}
if (story_type == "[SELECT TYPE]") {
(function($) {
$.jGrowl("Please Select Story Type", { theme: 'smoke', sticky: true, closer: true })
return false;
})(jQuery);
return true;
}
Since you have jQuery you can do this to simplify your code a bit:
<div id="options">
<input type="checkbox" name="opt1" /> Option 1
<input type="checkbox" name="opt2" /> Option 2
<input type="checkbox" name="opt3" /> Option 3
<input type="checkbox" name="opt4" /> Option 4
</div>
<div>
validate
</div>
<script type="text/javascript">
;(function() {
$("#validate").click(function() {
validateInputs();
});
function validateInputs() {
alert($("#options input:checked").length + " checked");
}
})();
</script>
Here is a jsFiddle of the above code; http://jsfiddle.net/rvXHG/

How do you handle a form change in jQuery?

In jQuery, is there a simple way to test if any of a form's elements have changed?
Say I have a form and I have a button with the following click() event:
$('#mybutton').click(function() {
// Here is where is need to test
if(/* FORM has changed */) {
// Do something
}
});
How would I test if the form has changed since it was loaded?
You can do this:
$("form :input").change(function() {
$(this).closest('form').data('changed', true);
});
$('#mybutton').click(function() {
if($(this).closest('form').data('changed')) {
//do something
}
});
This rigs a change event handler to inputs in the form, if any of them change it uses .data() to set a changed value to true, then we just check for that value on the click, this assumes that #mybutton is inside the form (if not just replace $(this).closest('form') with $('#myForm')), but you could make it even more generic, like this:
$('.checkChangedbutton').click(function() {
if($(this).closest('form').data('changed')) {
//do something
}
});
References: Updated
According to jQuery this is a filter to select all form controls.
http://api.jquery.com/input-selector/
The :input selector basically selects all form controls.
If you want to check if the form data, as it is going to be sent to the server, have changed, you can serialize the form data on page load and compare it to the current form data:
$(function() {
var form_original_data = $("#myform").serialize();
$("#mybutton").click(function() {
if ($("#myform").serialize() != form_original_data) {
// Something changed
}
});
});
A real time and simple solution:
$('form').on('keyup change paste', 'input, select, textarea', function(){
console.log('Form changed!');
});
You can use multiple selectors to attach a callback to the change event for any form element.
$("input, select").change(function(){
// Something changed
});
EDIT
Since you mentioned you only need this for a click, you can simply modify my original code to this:
$("input, select").click(function(){
// A form element was clicked
});
EDIT #2
Ok, you can set a global that is set once something has been changed like this:
var FORM_HAS_CHANGED = false;
$('#mybutton').click(function() {
if (FORM_HAS_CHANGED) {
// The form has changed
}
});
$("input, select").change(function(){
FORM_HAS_CHANGED = true;
});
Looking at the updated question try something like
$('input, textarea, select').each(function(){
$(this).data("val", $(this).val());
});
$('#button').click(function() {
$('input, textarea, select').each(function(){
if($(this).data("val")!==$(this).val()) alert("Things Changed");
});
});
For the original question use something like
$('input').change(function() {
alert("Things have changed!");
});
$('form :input').change(function() {
// Something has changed
});
Here is an elegant solution.
There is hidden property for each input element on the form that you can use to determine whether or not the value was changed.
Each type of input has it's own property name. For example
for text/textarea it's defaultValue
for select it's defaultSelect
for checkbox/radio it's defaultChecked
Here is the example.
function bindFormChange($form) {
function touchButtons() {
var
changed_objects = [],
$observable_buttons = $form.find('input[type="submit"], button[type="submit"], button[data-object="reset-form"]');
changed_objects = $('input:text, input:checkbox, input:radio, textarea, select', $form).map(function () {
var
$input = $(this),
changed = false;
if ($input.is('input:text') || $input.is('textarea') ) {
changed = (($input).prop('defaultValue') != $input.val());
}
if (!changed && $input.is('select') ) {
changed = !$('option:selected', $input).prop('defaultSelected');
}
if (!changed && $input.is('input:checkbox') || $input.is('input:radio') ) {
changed = (($input).prop('defaultChecked') != $input.is(':checked'));
}
if (changed) {
return $input.attr('id');
}
}).toArray();
if (changed_objects.length) {
$observable_buttons.removeAttr('disabled')
} else {
$observable_buttons.attr('disabled', 'disabled');
}
};
touchButtons();
$('input, textarea, select', $form).each(function () {
var $input = $(this);
$input.on('keyup change', function () {
touchButtons();
});
});
};
Now just loop thru the forms on the page and you should see submit buttons disabled by default and they will be activated ONLY if you indeed will change some input value on the form.
$('form').each(function () {
bindFormChange($(this));
});
Implementation as a jQuery plugin is here https://github.com/kulbida/jmodifiable
var formStr = JSON.stringify($("#form").serializeArray());
...
function Submit(){
var newformStr = JSON.stringify($("#form").serializeArray());
if (formStr != newformStr){
...
formChangedfunct();
...
}
else {
...
formUnchangedfunct();
...
}
}
You need jQuery Form Observe plugin. That's what you are looking for.
Extending Udi's answer, this only checks on form submission, not on every input change.
$(document).ready( function () {
var form_data = $('#myform').serialize();
$('#myform').submit(function () {
if ( form_data == $(this).serialize() ) {
alert('no change');
} else {
alert('change');
}
});
});
$('form[name="your_form_name"] input, form[name="your_form_name"] select').click(function() {
$("#result").html($(this).val());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>Form "your_form_name"</h2>
<form name="your_form_name">
<input type="text" name="one_a" id="one_a" value="AAAAAAAA" />
<input type="text" name="one_b" id="one_b" value="BBBBBBBB" />
<input type="text" name="one_c" id="one_c" value="CCCCCCCC" />
<select name="one_d">
<option value="111111">111111</option>
<option value="222222">222222</option>
<option value="333333">333333</option>
</select>
</form>
<hr/>
<h2>Form "your_other_form_name"</h2>
<form name="your_other_form_name">
<input type="text" name="two_a" id="two_a" value="DDDDDDDD" />
<input type="text" name="two_b" id="two_b" value="EEEEEEEE" />
<input type="text" name="two_c" id="two_c" value="FFFFFFFF" />
<input type="text" name="two_d" id="two_d" value="GGGGGGGG" />
<input type="text" name="two_e" id="two_f" value="HHHHHHHH" />
<input type="text" name="two_f" id="two_e" value="IIIIIIII" />
<select name="two_g">
<option value="444444">444444</option>
<option value="555555">555555</option>
<option value="666666">666666</option>
</select>
</form>
<h2>Result</h2>
<div id="result">
<h2>Click on a field..</h2>
</div>
In addition to above #JoeD's answer.
If you want to target fields in a particular form (assuming there are more than one forms) than just fields, you can use the following code:
$('form[name="your_form_name"] input, form[name="your_form_name"] select').click(function() {
// A form element was clicked
});
Try this:
<script>
var form_original_data = $("form").serialize();
var form_submit=false;
$('[type="submit"]').click(function() {
form_submit=true;
});
window.onbeforeunload = function() {
//console.log($("form").submit());
if ($("form").serialize() != form_original_data && form_submit==false) {
return "Do you really want to leave without saving?";
}
};
</script>
First, I'd add a hidden input to your form to track the state of the form. Then, I'd use this jQuery snippet to set the value of the hidden input when something on the form changes:
$("form")
.find("input")
.change(function(){
if ($("#hdnFormChanged").val() == "no")
{
$("#hdnFormChanged").val("yes");
}
});
When your button is clicked, you can check the state of your hidden input:
$("#Button").click(function(){
if($("#hdnFormChanged").val() == "yes")
{
// handler code here...
}
});

Categories

Resources