Knockout date validation ob - validation

My question is in reference to an older question on Stack Overflow:
Knockout validation
The question is regarding date validation in knockout.js and knockout.validation.js.
Does anyone have a good example of knockout binding in MVC 4 that validates a date entry?
Using the above link I implemented the following sample:
ko.validation.rules['simpleDate'] = {
validator: function (val, validate) {
return ko.validation.utils.isEmptyVal(val) || moment(val, 'MM/DD/YYYY').isValid();
},
message: 'Invalid date'
};
next, I bound the rules:
self.ChildDateOfBirth = ko.observable().extend({ simpleDate: true });
The whole idea behind this is if the user enters 14/02/2009 then loses focus then a message should popup next to the box as invalid date.
I must be doing something wrong...

Did you call ko.validation.registerExtenders(); after you added the validation rule?
According to the documentation you need to call it.
It's working in my jsfiddle.

Related

MVC 4 adding a custom unobtrusive validator

I have a form with elements that may be contained within collapsed accordion divs. When someone submits the form and the unobtrusive validator catches an error on one or more of these "hidden" form elements, I want the collapsed accordion to open so they can see their errors.
After doing a little research, I found a suggestion here, Using unobtrusive validation in ASP.NET MVC 3, how can I take action when a form is invalid? which says to make my own unobtrusive adapter. So I did, it is here:
$.validator.unobtrusive.adapters.add(
'collapsevalidation',
function () {
var tabs = $('.collapse').not('.in');
//console.log("tabs.length: " + tabs.length);
$(tabs).each(function () {
if ($(this).has('.field-validation-error').length) {
id = "#" + $(this).attr('id');
//console.log("id: " + id);
$("[data-target='" + id + "']").collapse('show');
}
});
}(jQuery));
The adapter plugin has been added to my page and now I am trying to figure out how to "hook" it in but I cannot seem to do so. So far I have added the following to my page:
jQuery.validator.unobtrusive.adapters.add("collapsevalidation");
This however does not seem to be working. When I produce an error on submit, the console.log lines to not write.
I understand that this is a custom adapter because it does not apply to a specific element and does not return anything, like a bool.
Can someone help complete this, please. Thanks!
While I did not find an answer directly to the above, I did get my desired result using the following:
$("form").bind("invalid-form.validate", function () {
//My code here
}

jQuery validate plugin with datepicker - invalid date causes datepicker popup on submit

I have a simple MVC3 form that has a date field and client side validation enabled (jquery.validate / jquery.validate.unobtrusive). I've added code to attach a datepicker (jQuery UI) to the date field per the documentation. However, if the datepicker is the last thing I click prior to clicking the submit button and the date field is invalid, it causes the datepicker for that field to automatically show itself. I don't want this. How can I disable?
Edit:
After reviewing the code for the validation plugin, it looks like it tries to manually focus on the last active input control using the focusInvalid() function below:
focusInvalid: function() {
if( this.settings.focusInvalid ) {
try {
$(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])
.filter(":visible")
.focus()
// manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
.trigger("focusin");
} catch(e) {
// ignore IE throwing errors when focusing hidden elements
}
}
},
There appear to be 2 options for dealing with this. One is to set the focusInvalid setting on the validator itself to false. I opted to monkey patch the focusInvalid function instead because it allows me to focus on the FIRST invalid element in the form, not necessarily the last active element.
$('form').data('validator').focusInvalid = function () {
$(this.currentForm).find('.input-validation-error').first().focus();
};
I'd be interested to hear any other approaches to this problem, however.
If acceptable in your case, you could show the datepicker only using a button, using the following datepicker options:
showOn: 'button', showButtonPanel: true, buttonImage: '<your image file>',
buttonImageOnly: true,
buttonText: 'Choose a Date',
If you do it this way the datepicker won't automatically display in case validation fails when submitting the form.

Jquery validation question, how to validate the empty field?

I am using Jquery validation plugin for my form validation.
I just use this one as sample.
http://jquery.bassistance.de/validate/demo/milk/
there's one problem. first time you load the form. click on the first field, dont put anything there, then click on the "tab" button to move to the next input field, the error message is not showing, but that field is labeled as "required".
is there a way to fix it? or that is how it supposed to be it.
According to the Validate plugin's reference for onblur:
If nothing is entered, all rules are skipped, except when the field was already marked as invalid.
But you can force it to validate yourself by binding the inputs' blur event:
$("#signupform input").blur(function() {
$(this.form).validate().element(this);
});
$('#id).filter(function() { return $(this).val() == ""; });
You can get fields with empty value and ca validate.
You can also add class and can get all empty fields of that class i.e.
$('.className).filter(function() {
return $(this).val() == "";
});

jQuery disable rule validation on a single field

I am using MVC to create forms that are generated at runtime. For validation, I am trying my hand at the jQuery validation library which is very convenient to use. I have the validation expression of each field in the cdata attribute of the tag
<input type="text" name="xyz" id="xyz" class="defaultTextBox"
cdata="{validate:{required:true, decimal:true, messages:
{required:'Please enter an decimal value',
decimal:'Please enter a valid decimal'}}}">
This works beautifully. Now one more requirement I have is that some fields are being shown and hidden according to the logic on the page and I need to disable the validation on the hidden fields such that they do not interfere with the form submission. Just toggling the required:true to false and back to true should be enough. Only i do not know how.
Anyone has any experience with that?
Just add the ignore rule and define the selector.
In this example, the validation will ignore all elements that have the class="ignore"
$("#myform").validate({
ignore: ".ignore"
})
If you're using ASP.NET MVC Unobtrusive JQuery validation you need to set the settings in this way. This is because of the way Microsoft actually calls jQuery validate. This should be safe to do inside a ready method.
Edit: Please see Cory's comment below before copy pasting this. This is my original code
$("form").data("validator").settings.ignore = ".data-val-ignore, :hidden, :disabled";
Then I just apply .data-val-ignore class to things not to validate.
Note that you'll probably want to add :hidden which is actually the default ignore behavior defined in jquery.validate.js. I like to add :disabled too.
$.extend($.validator, {
defaults: {
messages: {},
groups: {},
rules: {},
errorClass: "error",
validClass: "valid",
errorElement: "label",
focusInvalid: true,
errorContainer: $([]),
errorLabelContainer: $([]),
onsubmit: true,
ignore: ":hidden", // default for ignore in jquery.validate.js
ignoreTitle: false,
onfocusin: function( element, event ) {
this.lastActive = element;
And finally you may want to style it - especially useful during debugging.
.data-val-ignore
{
background: #eee;
}
Following on Gabe's answer, you can also set the ignore value as a default, so you don't have to set it on each form.
$.validator.setDefaults({ignore: ".ignore"});
Also note, the ignore field is a jQuery selector that is used in the jQuery not() function so any valid selector can be used, not just simple classes.
See also http://docs.jquery.com/Plugins/Validation/validate#toptions for details on other default values that can be set.
I had a better time with $('.multiselect').rules('remove');
in my case for whatever reason adding .cancel or .data-val-ignore
to both the $.validator.setDefaults and $('.multiselect') did not fix it.
I also tried
$('select[multiple][data-val]').removeAttr('data-val').removeAttr('data-val-number').addClass('data-val-ignore').validate({ ignore: "[multiple]" });
$.validator.setDefaults({ ignore: ":hidden,:disabled,.data-val-ignore" });
$('.multiselect').closest('form').data('validator').settings.ignore = ":hidden,:disabled,.data-val-ignore, .data-val-ignore *";
$('.multiselect').data('validator').settings.ignore = "[multiselect]"
each of those... and combinations of them
my jquery.validate.js was
/*! jQuery Validation Plugin - v1.11.0 - 2/4/2013
* https://github.com/jzaefferer/jquery-validation
* Copyright (c) 2013 Jörn Zaefferer; Licensed MIT */
jquery was
jQuery JavaScript Library v1.9.1 - Date: 2013-2-4
You can remove a rule from a single field by doing the following:
$("#field").rules('remove', 'required');
Where the second parameter is the rule name. I also remove the attribute associated with this rule to avoid any confusion:
$("#field").removeAttr('required');

How to solve problem when use jquery datepicker and validation in the same time

When I used datepicker with trigger icon so that users could choose date from clicking this icon or type directly in textbox (txtDate), I also used jquery validation to require textbox must be not empty.
But when a user submit the form with empty textbox (txtDate.Text=""), the error message of validation push trigger icon to the right. Could you tell me the solution? Thank you very much!
$('#some_form').validate({
rules: {...},
messages: {...},
errorPlacement: function(error, element) { //solve you problem
var trigger = element.next('.ui-datepicker-trigger');
error.insertAfter(trigger.length > 0 ? trigger : element);
}
});
The errorPlacement function receives two parameters - the error message and the validated element. Use the latter to decide whether or not to customize the placement for your fields (for example, by adding a class):
$('form').validate({
rules: {...},
errorPlacement: function(error, element) {
if (element.hasClass('customError')) {
// custom error placement
}
else {
element.after(error); // default error placement
}
}
});

Resources