I am using jQuery validation plugin, and after I added focus() and blur()event handlers to delete and set pre populated value,if I try to submit form without changing default value, value is replaced with empty string, where desired is to leave value untouched and run validate().
JS code is as follows:
$.validator.addMethod("mobileHR", function(phone_number, element) {
phone_number = phone_number.replace(/\(|\)|\s+|-/g, "");
return this.optional(element) || phone_number.length > 9 &&
phone_number.match(/^\+[0-9]{1,3}\.[0-9]{1,14}$/);
}, "Unesite broj u fromatu: +385.111234567");
$(document).ready(function () {
// append help block below input
$('.controls').append('<span id="helpBlock" class="help-block">Format broja: +385.11123456789</span>');
// clear pre populated value on focus
var value = $("input[name='contactdetails[Registrant][Phone]']").val();
$("input[name='contactdetails[Registrant][Phone]']").focus(function() {
if ($(this).val() == value)
{
$(this).val("");
}
}).blur(function(event) {
if($(this).val() == "")
{
$(this).val(value);
}
});
// initialize validation
$('.form-horizontal').validate({
// set immediate validation, on event code 9
onkeyup: function (element, event) {
if (event.which === 9 && this.elementValue(element) === "") {
return;
} else {
this.element(element);
}
},
rules: {
"contactdetails[Registrant][Phone]": {
required: true,
mobileHR: true
}
},
messages: {
"contactdetails[Registrant][Phone]": {
required: "Molimo unesite broj telefona"
}
}
});
// check if form is valid then enable submit button
$('.form-horizontal input').on('keyup blur', function () {
if ($('.form-horizontal').valid()) {
$('.btn-primary').removeClass('btn-disabled');
} else {
$('.btn-primary').addClass('btn-disabled');
}
});
//do we valid form on document.ready?
//$('.form-horizontal').valid();
});
Fiddle is here.
After little research, I've found why is value changing on form submit:
$("input[name='contactdetails[Registrant][Phone]']").focus(function() {...});
After form is submitted, validate() is run, and as field is empty, input field is focused, so focus() is triggered again, and value of input field is "".
Changing event to click input field get focused, but value is untouched, as now function is fired on click event.
Related
If I create the click events and their handler on my own, it is no problem for me to execute event.preventdefault() at the right place. But if there is an element, which already has registered click events and corresponding handler, I want to deactivate its further working (e.g. submitting) in a certain case.
This is the example:
There is a submit button on the page, with registered click elements (maybe about hundred validation routines.. ) and a variable (al) with a certain value. Be the instantaneous value of this variable = 5 (it is not the desired certain case -> with value = 3).
HTML
// other form elements
<input type="submit" name="next" value="go"/>
JavaScript with jQuery
var al = 3;
$("input[type='submit'][name='next']").click(
function(event) {
if (al != 3) {
alert (al+': Not OK');
event.preventDefault();
} else {
alert ('OK');
}
}
);
In this example I cannot prevent the form is being submitted. What is my mistake?
EDIT: event.preventDefault ist not the problem, sublime (my editor) corrects it anyway.
----- I WANT TO SIMPLIFY THE QUESTION ---------
That is a SubmitButon (this time from yii in the original context):
VIEW
echo CHtml::submitButton(
Yii::t ('Somethin', 'next'),
array(
'name' => 'next',
'onclick' => "checkDetails()"
));
JS
checkDetails() {
PREVENT_SUBMITTING
}
How should PREVENT_SUBMITTING look? What would prevent submitting in this case, without any condition?
change
event.preventdefault();
to
event.preventDefault();
you have to write the "D" as capital letter.
You can do this two ways
$("input[type='submit'][name='next']").click(
function(event) {
if (al != 3) {
alert (al+': Not OK');
event.preventDefault();
} else {
alert ('OK');
}
}
);
or
$("input[type='submit'][name='next']").click(
function(event) {
if (al != 3) {
alert (al+': Not OK');
return false;
} else {
alert ('OK');
return true;
}
}
);
Now I have a working solution:
VIEW
echo PHtml::submitButton(Yii::t('Something', 'next'),
array(
'name' => 'next',
'onclick' => "return checkDetails(event)",
)
);
jQuery
function checkDetails (event) {
event.preventDefault();
event.returnValue =false; // for IE
return false;
}
$("input[type='submit'][name='next']").click(
function(event) {
if (al != 3) {
alert (al+': Not OK');
event.preventDefault();
} else {
alert ('OK');
}
}
);
Try this Change event.preventDefault();
$("input[type='submit'][name='next']").click(
function(event) {
if (al != 3) {
alert (al+': Not OK');
event.preventDefault();
} else {
alert ('OK');
}
}
);
I recently needed to use .off() instead of .preventDefault(). I needed to intercept and block one event handler while still allowing the main click event to bubble up. Might be what you need.
Besides from this problem I ll suggestion you to separate the validation part e. g
Add another form input e.g proceed
<input type="hidden" name="proceed" value="0"/>
<input type="submit" name="next" value="go"/>
Add custom validation method
jQuery.validator.addMethod("validateSteps", function(value, element) {
return value == 3 ? false : true;
}, "*");
Add validation rule to you form
$("#your_form_id").validate({
rules: {
"proceed": {
validateSteps: true
}
},
messages: {
"proceed": {
validateSteps: "custom message"
}
}
});
You have to set proper value to proceed input field before. This way you do not need to wade through event issues. And its more customizable e.g if you have ten steps with different validation requirements on each step
I would like to add a custom rule to jQuery validate, and while I have checked the docs I have not been able to find out how to do this.
I want to loop over a set of hidden form fields. If the fields value is "X", then I would like to append an error class to a field.
So essentially this, but added as a rule to jQuery validate.
$(".myHiddenField").each( function() {
if($(this).val() == "x") {
$(this).closest(".foo").appendClass("error");
}
});
You may use addMethod()
$.validator.addMethod('yourRuleName', function (value, element, param) {
//Your Validation Here
return isValid; // return bool here if valid or not.
}, 'Your error message!');
$('#myform').validate({
rules: {
field1: {
yourRuleName: true
}
}
});
If you want to show some custom error messages without adding an actual rule then you can use the showErrors() method, but if you are working on a hidden field it may not work
var validator = $( "<form-selector>" ).validate();
var errors = {};
$(".myHiddenField").each( function() {
var $this = $(this);
if($this.val() == "x") {
errors[$this.attr('name')] = 'Some error message';
}
});
validator.showErrors(errors);
$.validator.addMethod("NOTx", function(element,value) {
return value != "x";
}, 'warning word"!');
This is a validation script
This code runs when the user presses the submit button on a form
It loops thru all mandatory fields (entered in an array) and...
1. checks if the element is hidden
2. if not is it empty?
3. if not is it false? (I use false as a value for non selectable options)
And all this sets a variable to true or false.
// when submitting the registration form
function mandatoryCheck() {
jQuery('.tx-powermail-pi1_formwrap_1723 form.tx_powermail_pi1_form').submit(function(event) {
var success = false;
var element;
jQuery.each(mandatoryFields, function(index, value) {
element = jQuery('#powermaildiv_uid'+value+' input, #powermaildiv_uid'+value+' select')
element.each(function() {
// add class required to all fields
jQuery(this).addClass('required');
// is the element hidden, return true
if(jQuery(this).hasClass('fieldHidden') == true || jQuery(this).is(':disabled')) {
success = true;
} else {
// is the input field empty, return false
if(jQuery(this).val().length === 0) {
success = false;
// is the input field not empty, return true
} else {
// is the input field false, return false
if(jQuery(this).val() == 'disabled') {
success = false;
} else {
success = true;
}
}
}
// For each element add/remove validation class
if(success == false) {
jQuery(this).addClass('validation-failed').removeClass('validation-passed');
} else {
jQuery(this).addClass('validation-passed').removeClass('validation-failed');
}
});
});
// if succes is false, show error message and return false
if(success == false) {
jQuery('#c1799').fadeIn().css('display', 'block');
event.preventDefault();
return false;
} else {
jQuery('#c1799').fadeOut();
}
});
}
It works in firefox, chrome ie9 but not ie 7 or 8.
IE7 or 8 adds classes to the elements all random.
It seems like if I validate a select element it passes but an input field fails
What can be wrong?
Edit:
Here is the page: http://asdf.patrikelfstrom.se/index.php?id=267
Enter 1234 if in the little form that shows up
JS: http://asdf.patrikelfstrom.se/typo3conf/ext/gc_fm/res/js/ShowAndHideFields.js
If you press submit (absenden) the field Türnummer should be green (as it is in chrome, firefox etc.) but in ie7/8 it is red.
If you click on Wähle... (The select box) and choose Wohnung the fields under it becomes enabled and if you press submit now Türnummershould be red since the element is visible and empty.
This seems to work but if you click on the select box again and choose einfamilienhaus.
The fields are disabled and should now be green when submitting but this is not the case in IE7/8.
I think you need to loop through element, as it will be a collection of objects, so you would do...
// is the element hidden, return true
element.each(function() {
if($(this).hasClass('fieldHidden') == true) {
...
})
Well, just to show the point, depends on your code what you need to actually change
Remove the (value="false") from your selects.
I'm doing some jQuery form validation and I came up with an issue. I have the following code so far:
// catch any form submission
$('form').submit(function () {
'use strict';
// if the browser doesn't support HTML5's required attribute
if (!Modernizr.input.required) {
// catch any field that should be required
$(this).find('input[required]').each(function () {
// if is empty
if ($(this).val() === '') {
// create a span that contains a warning to the user
var requiredFieldWarning = document.createElement('span');
requiredFieldWarning.text = 'This field is required.';
// display the span next to the current field
}
});
}
});
I'm trying to "attach" or display a span next to any input of the submitted form that doesn't validate, but I don't know how to. I want to do this unobtrusively, that's why I create the said span inside JavaScript.
Also, how can I prevent the form from being submitted if any of the fields of the submitted form doesn't validate?
why reinvent the wheel? you should use the jquery form validation plugin..
edit: added code to prevent submition of invalid form.
to answer your question:
$('form').submit(function (e) {
'use strict';
var valid = true;
var $form = $(this);
$form.find("span.error").remove();
// if the browser doesn't support HTML5's required attribute
if (!Modernizr.input.required) {
// catch any field that should be required
$form.find(':input[required]').each(function () {
// if is empty
var $this = $(this);
if ($.trim($this.val()) === '') {
// create a span that contains a warning to the user
$this.after("<span class='error'>This field is required.</span>");
valid = false;
}
});
}
if(!valid){
e.preventDefault();
}
});
here is a shorter version:
$('form').submit(function (e) {
'use strict';
Modernizr.input.required ? e[$(this).find("span.error").remove().end()
.find(':input[required][value=""]')
.after("<span class='error'>This field is required.</span>")
.length ? 'preventDefault': 'isDefaultPrevented']() : null;
});
I am adding a span tag after the input. Before the form is revalidated it removes these spans and recreates only if needed. If any of these spans are added the form isn't submitted.
$('form').submit(function (event) {
'use strict';
$('.invalid-error', $(this)).remove();
// remove any old spans
var submit_form = true;
// form submits by default
// if the browser doesn't support HTML5's required attribute
if (!Modernizr.input.required) {
// catch any field that should be required
$(this).find('input[required]').each(function () {
// if is empty
if ($(this).val() === '') {
$(this).after('<span="invalid-error">This field is required.</span>');
// add span after input
submit_form = false;
}
});
}
if(!submit_form) event.preventDefault();
// stop form from submitting
});
jsFiddle ( http://jsfiddle.net/4KxzB/10/ )
Here is my working example, works as expected in chrome.
To stop the form from submitting, just return false;
<form>
<input type="text" required/>
<input type="submit" value="submit"/>
</form>
<script>
$('form').submit(function ()
{
'use strict';
// if the browser doesn't support HTML5's required attribute
if (!Modernizr.input.required)
{
var validInput = true;
// catch any field that should be required
$(this).find('input[required]').each(function ()
{
// if is empty
if ($(this).val() === '')
{
// create a span that contains a warning to the user
var requiredFieldWarning = document.createElement('span');
requiredFieldWarning.text = 'This field is required.';
// Cancels form submit
validInput = false;
}
});
return validInput;
}
});
</script>
var flag = 0;
if ($(this).val() === '') {
flag = 1;
var warningblock = '<span class="warning">This field is required.</span>';
$(this).after(warningblock);
}
//end of each loop
if(flag){ //put this block out side the loop
return false; //form wont submit
}
return true;
CSS
.warning{
/**add styles for warning here***/
}
I doing a field validation using jquery to check if it is empty. If it is I want to display a message and then refocus on the field so the user can enter some data. Code:
$('#fieldId').blur(function() {
var fieldValue = $(this).val();
if(fieldValue == null || fieldValue.length == 0) {
$(this).addClass('error');
// show error message
$('#errorDivId')
.text('You must enter a value in this field')
.show();
$(this).focus();
}
else {
if ($(this).is('.error')) {
$(this.removeClass('error');
$('#errorDivId').hide()
}
}
});
It sort of works but it moves the cursor to the next field and not the one I refocused on.
You can try this:
$('#fieldId').blur(function(evt) {
var fieldValue = $(this).val();
if(fieldValue == null || fieldValue.length == 0) {
$(this).addClass('error');
// show error message
$('#errorDivId')
.text('You must enter a value in this field')
.show();
this.focus();
evt.preventDefault();
}
else {
if ($(this).is('.error')) {
$(this.removeClass('error');
$('#errorDivId').hide()
}
}
});
However that may not completely solve the problem, as some browsers might be confused. As an alternative, wrap your "focus" call up as a timeout and run it after the current event finishes:
var self = this;
setTimeout(function() { self.focus(); }, 1);
It's kind-of a hack but it should also work.
edit — #Gus is right about which "focus()" to call
The blur event is triggered during a focus change (as the control you are validating loses focus). This could cause weird behaviour if you try to alter the focus while it is already changing. Instead of blur, try attaching the validation to the change event.
Also, there's no need to call the jQuery version of focus: $(this).focus(), you can just call this.focus().
$('#fieldId').change(function() {
var fieldValue = $(this).val();
if(fieldValue == null || fieldValue.length == 0) {
$(this).addClass('error');
// show error message
$('#errorDivId').text('You must enter a value in this field').show();
this.focus();
} else {
if ($(this).is('.error')) {
$(this).removeClass('error');
$('#errorDivId').hide()
}
}
});