JQuery Validation Problem - javascript

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()
}
}
});

Related

Shift tab not retaining the element focus

Javascript version code -- Link
if (el.value.length > 1) {
el.value = el.value[el.value.length - 1];
}
try {
if (el.value == null || el.value == "") {
this.foucusOnInput(el.previousElementSibling);
} else {
this.foucusOnInput(el.nextElementSibling);
}
} catch (e) {
console.log(e);
}
AngularJS version code - Link
if (ele.currentTarget.value.length >= 1) {
ele.currentTarget.value = ele.currentTarget.value[ele.currentTarget.value.length - 1];
}
try {
if (ele.currentTarget.value === null || ele.currentTarget.value === "") {
foucusOnInput(ele.currentTarget.previousElementSibling);
} else {
foucusOnInput(ele.currentTarget.nextElementSibling);
}
} catch (e) {
console.log(e);
}
Not able to implement the javascript version of
Tab & Shift+Tab
functionality in AngularJS. Let me know what am missing here!
Requirement - Once you enter the value to the input text the next input text element should be focused; On Shift-Tab previous input text element should be focused.
The keyup event gets triggered for every key up including tab and shift. This is the difference between your javascript solution angularjs solution.
I'm not sure if there is an equivalent to oninput in angularjs. 'keyup', 'keydown', 'input' all work differently. There is ng-change in angularjs but it requires ng-model on the input element and I don't think $event works with ng-change.
Anyway, there is a working solution. Try this:
$scope.readKey = function(ele) {
console.log(ele);
if(ele.shiftKey) return;
if (ele.currentTarget.value.length >= 1) {
ele.currentTarget.value = ele.currentTarget.value[ele.currentTarget.value.length - 1];
}
try {
if (ele.currentTarget.value === null || ele.currentTarget.value === "" ) {
foucusOnInput(ele.currentTarget.previousElementSibling);
} else {
foucusOnInput(ele.currentTarget.nextElementSibling);
}
} catch (e) {
console.log(e);
}
};
This code, as listened on keyup instead of input, will not allow to go to next input field if current input field is empty. In your javascript example, the code in input handler never gets executed and so you can move to next input field if current one is empty.
If you want to achieve the same thing in angularjs solution as well, then try changing the condition to this:
if(ele.shiftKey || ele.keyCode === 9) return;
This prevents the code from getting executed if its shift key or tab key. 9 is the keycode for TAB.
Working solution -- Link
if(ele.key != "Tab" && ele.key != "Shift" ){
if (ele.currentTarget.value.length >= 1) {
ele.currentTarget.value = ele.currentTarget.value[ele.currentTarget.value.length - 1];
}
try {
if (ele.currentTarget.value === null || ele.currentTarget.value === "") {
foucusOnInput(ele.currentTarget.previousElementSibling);
} else {
foucusOnInput(ele.currentTarget.nextElementSibling);
}
} catch (e) {
console.log(e);
}
}

How to show native validation error for specific input on change event?

I have a classic HTML5 form. I would like using jquery/javscript to show the browser native error tooltip when the user change a specific input value. I would like to avoid the user try to submit the form to see all errors.
For that, I tried with the functions checkValidity() and reportValidity() but it works only if I add alert('test'); in my condition...so weird
JS script
myInputJqueryObject.on('change', function() {
if ( !this.checkValidity() ) {
this.setCustomValidity( 'Custom error !!!' );
var $form = $('#my-form');
if( $form[0].checkValidity() === false) {
$form[0].reportValidity();
//alert('test'); <-- works only if I active this line code
return true;
}
}
});
You do not need to check the form validity when you know that the input is invalid. You can omit if( $form[0].checkValidity() === false). Also you can reportValidity on the input itself.
And setCustomValidity takes some time to be applied to the input field. So you have to wrap reportValidity into setTimeout:
$('input').on('change', function() {
var self = this;
if (!self.checkValidity()) {
self.setCustomValidity('Custom error !!!');
setTimeout(function() {
self.reportValidity();
self.setCustomValidity('');
}, 1);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="my-form"><input value="del me" required></form>
Based on 'Kosh Very' answer, I found the solution. It sounds good without bugs.
JS Script :
$('input').on('focusout', function() {
var self = this;
var validity = self.checkValidity();
if( !validity ){
if( self.validity.patternMismatch ){ //<-- Optionnal : Condition to keep others native message errors except Pattern.
self.setCustomValidity( 'Custom Error about pattern!!!' );
}
setTimeout(function() {
self.reportValidity();
self.setCustomValidity( '' ); //<-- Important to reinit
}, 1);
}
});

Why is on form submit default value deleted?

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.

Checkbox is still showing true when unchecked jQuery

Ok, so I'm currently having an issue with the $.prop('checked') functionality. When unchecking some of my boxes, and using this function to read the checkboxes, all of them are still showing up as true when some of them should be showing up as unchecked. The part of the function that checks this is below, but some background: I'm using a table with input values in each td element and due to the way it's written, I'm having to gather all the info / validate / and check by using a td.each() function.
$("td", ele).each(function(idx){
var before = $('.e_content', this),
b_name = $('input:last[type!="hidden"], textarea:last, checkbox:last, select:last', this).attr('name'),
b_val = $('input[name="'+b_name+'"], select:last, textarea[name="'+b_name+'"]', this).val(),
b_chx = $('input:checkbox[name="'+b_name+'"]', this).prop('checked'),
after = function(){
before.hide();
$(ele).css("background", color);
$('td.edit', ele).show();
$('td.save', ele).hide();
$('span', this)
// WORKING ON TAKING THE VALUE OF THE .e_content FORM AND REPLACING THE SPAN WITH IT
.html(function(){
console.log(b_name+' : '+b_chx);
if(b_val != undefined && b_val != ''){
if(b_name == 'StageType'){
if(b_val == 1){ return 'Voice'; }
if(b_val == 2){ return 'Text'; }
if(b_val == 3){ return 'Email'; }
}
else if(b_name == 'qtrhour') {
return $('select', before).find(':selected').text();
}
else if(b_chx == true) { return '&check;'; }
else if(b_chx == false) { return '&cross;'; }
else {
if(before.find('input:last').prop('type') != 'checkbox')
return b_val.replace(/\n\r?/g, '<br />');
}
}
})
.show();
};
$(this).html(after);
});
The problem is with this line:
b_chx = $('input:checkbox[name="'+b_name+'"]', this).prop('checked'),
It's coming up always as true even when the checkbox has been unchecked before the save button is hit. This function fires on the .save click event. Hopefully this is enough to determine what might be going wrong.
You can try the following,
$('input:checkbox[name="'+b_name+'"]', this).is(':checked');
To avoid issues regarding to checking or unchecking checkboxes, I normally use jQuery.attr()
$(...).attr('checked')
$(...).attr('checked','checked')
$(...).removeAttr('checked')
Also sometimes I check or uncheck them binding or triggering a .click() function.

Clear default search text on submit

I have the following code to put helper text in a search input box that is removed when you click in the box and returned if you click anywhere else without changing it:
$('#search-form input[type="text"]').each(function(){
var defaultVal = 'Category Search';
$(this).focus(function(){
if ($(this).val() == defaultVal){
$(this).removeClass('active').val('').css('color', '#000');;
}
})
.blur(function(){
if ($(this).val() == ''){
$(this).addClass('active').val(defaultVal).css('color', '#CCC');
}
})
.blur().addClass('active');
});
But if the user clicks submit without clicking in the input box, the site will search for the helper value (Category Search).
What I need to do is on submit check the value and if it's Category Search then do the following things:
Change helper text to Please enter a category
Don't submit the form.
I tried this but it stopped my default value (Category Search) from working all together:
$('#search-form input[type="submit"]').click(function() {
if ($(this).val() == "Category Search")
//do stuff here
});​
jsBin demo
var defaultVal = 'Category Search';
var enterCat = 'Please enter a category';
$('#search-form input[type="text"]').each(function(){
$(this).focus(function(){
if ($(this).val() == defaultVal || $(this).val() == enterCat){
$(this).removeClass('active').val('').css('color', '#000');
}
})
.blur(function(){
if ($.trim($(this).val()) === ''){
$(this).addClass('active').val(defaultVal).css('color', '#CCC');
}
})
.blur().addClass('active');
});
$('#search-form').submit(function(e) {
if ( $(this).find('[type="text"]').val() === defaultVal){
e.preventDefault();
$(this).find('[type="text"]').prop('value', enterCat);
}
});
and use also $.trim() (whitespaces) before searching for blank inputs :)
HTML5 placeholder is what you should use for browsers that support it, there would be no code to write to remove it.
For browsers that do not support it, there are plenty of plugins that make it work.
And why do you not just ignore the default value on the server? Seems like a logical place to filter it out.
The reason why your code fails is this is the submit button, not the form fields!
$('#search-form input[type="submit"]').click(function() {
if ($(this).val() == "Category Search") <-- this is the submit button, not the input
//do stuff here
});​
You need to change it to point to the inputs
$('#search-form').on("submit",function() {
$('#search-form input[type="text"]').each( function() {
//do comparison here, you could use defaultValue attribute
} );
});​
I agree on using placeholder, but this is the answer to your question:
$('#search-form input[type="submit"]').click(function() {
if ($('#search-form input[type="text"]') == "Category Search")
$('#search-form input[type="text"]').val("Please enter a category");
return false;
});​
I, personally, would create an error box near to the search field rather than change the text already in it - otherwise you're going to have problems with people submitting 'please enter a category'...
You are trying to get the .val() of the submit button
$('#search-form input[type="submit"]').click(function() {
if ($('#search-form input[type="text"]').val() == "Category Search")
//do stuff here
});​
but you should probably hook it to submit event of the form itself, but that would depend on how your implementation actually works.
$('#search-form').submit(function() {
if ($('#search-form input[type="text"]').val() == "Category Search")
//do stuff here
});​
If you can't use the placeholder (and you really should if you can), then you could simply set the field to disabled:
$('#search-form input[type="submit"]').click(function() {
if ($(this).val() == "Category Search") {
$(this).prop('disabled',true);
}
});​
The disabled attribute essentially guarantees that the field is 'not successful', and thus won't be submitted to the server.
A successful control is "valid" for submission. Every successful control has its control name paired with its current value as part of the submitted form data set. A successful control must be defined within a FORM element and must have a control name.
However:
Controls that are disabled cannot be successful...
Citation: http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2.
Much simpler: Most new browsers will allow this:
<input type="text" placeholder="your prompt here" />
But for older browsers you can do this:
$(function() {
if ($.browser.msie) {
$('#search-form input[type="text"]').each(function(){
$(this).val($(this).attr("placeholder"));
});
}
$("#search-form").on("submit",function() {
var cnt=0,empty++;
$("#search-form input[type='text']").each(function(){
var box = $(this),val = box.val();
if (val == box.attr("placeholder")){
box.val("");
}
else {
box.val($.trim(val));
}
if (box.val()=="") empty++;
cnt++;
});
if (empty==cnt) return false;
});
});

Categories

Resources