How do you make a kendo datepicker do date validation for a minimum date? - validation

I have the following control:
#(Html.Kendo().DatePickerFor(model => model.Attributes.DueDate)
.HtmlAttributes(new {
ID = "idSurvey_DueDate",
#data_bind = "value: DueDate",
#Class = "report-label datepicker surveyAttributesData",
TabIndex = 3 })
.Min(DateTime.Now)
)
And the following jquery:
$("#idSurvey_DueDate").kendoValidator({
rules: {
dateValidation: function (e) {
var currentDate = kendo.parseDate($(e).val());
// Check if date parse was successful
if (!currentDate) {
return false;
}
return true;
}
},
messages: {
dateValidation: "Invalid Date!",
min: "Date must not be in the past!"
}
});
When I test this out and enter in an invalid date the message I get isn't what I expect. Instead it is "The field DueDate must be a date." Where is this mystery message coming from and why isn't it using the messages property I put in the validator? All I want is for non-valid date formats to not be allowed and for the date to not be in the past. So a minimum must be enforced.

This code seems to work fine:
$("form").kendoValidator({
rules: {
dateValidation: function(element) {
var value = $(element).val();
var date = kendo.parseDate(value);
if (!date) {
return false;
}
return true;
},
minDate: function(element) {
var value = $(element).val();
var date = kendo.parseDate(value);
var result = date >= new Date();
return result;
}
},
messages: {
dateValidation: "You must enter a date",
minDate: "The date must not be in the past"
}
});
Here is a live demo: http://jsbin.com/EvoroRe/1/edit

I suggest to add the mvcdate rule:
rules: {
mvcdate: function (input) {
var datarole = $(input).data('role');
if (datarole === 'datepicker') {
var value = $(input).val();
if (value) {
var date = kendo.parseDate(value, 'ddd, MMM d');
if (!date) {
return false;
}
}
}
return true;
}
},
messages: {
mvcdate: function (intput) {
return intput.attr('data-val-date');
}
}
Unfortunatelly dateValidation rule has a lower priority that date and mvcdate just because they are default and nor custom one. As I have understood the mvcdate rule has the highest priority because:
dateValidation rule has been skipped for the certain control and I got the 'must be a date' error
date rule has been passed with the TRUE result but I still got the 'must be a date' error
mvcdate rule has helped me alone.
You always can look to the kendoValidator in the console:

I'm not sure if the kendo validator changed since the accepted answer, but you'll want to filter out and only apply date validation to datepicker inputs. Otherwise a textbox or other input will generate an error message about an invalid date. The rules should look like
$("#modForm").kendoValidator({
rules: {
dateValidation: function (input) {
if (input.is('[data-role="datepicker"]')) {
var value = $(input).val();
var date = kendo.parseDate(value);
if (!date) {
return false;
}
}
return true;
}
},
messages: {
dateValidation: "You must enter a date",
}
});

Related

Adding custom validation on checkout field country

I need to add a validation on the country field in all place where it can be used.
For registration or address editing it work fine but in checkout I tried several method but nothing worked. I want the validation on the field of the new shipping address form.
I add my validation in an js file countryValidation.js :
Same script for registration or edit address and it work fine
define([
'jquery',
'jquery/ui',
'mage/validation',
'mage/translate',
'domReady!'
], function($){
'use strict';
return function(validator) {
$.validator.addMethod(
"validate-country",
function(value, element) {
if (value === "FR") {
var zipValue = $('input[name="postcode"]').val();
if (zipValue) {
return !(zipValue.startsWith("97") || zipValue.startsWith("98"));
}
}
return true;
},
$.mage.__("You cannot choose France for DOM-TOM Zip Code")
);
return validator;
}
});
I registered it in requirejs-config.js in my module :
var config = {
config: {
mixins: {
'Magento_Ui/js/lib/validation/validator': {
'Gone_Customer/js/countryValidation': true
}
}
}
};
For adding validation to checkout method I tried different method
-> Method A : With a plugin
class AddCountryValidation
{
public function afterProcess(
\Magento\Checkout\Block\Checkout\LayoutProcessor $subject,
array $jsLayout
) {
// Country ID
$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']['country_id']['validation']['validate-country'] = true;
return $jsLayout;
}
}
-> Method B : add validation rule in attribute
In customer_eav_attribute in attribute country_id for validate_rules I added {"validate-country": true}
When I validate the form I have no validation error when I should have one.
Can you tell me if I'm missing something please?
Thank you for your response in the meantime I found something that worked.
I had to do a seperate js validation only for checkout :
define(['mage/translate', "jquery"], function($t, $) {
'use strict';
return function(rules) {
rules['validate-country'] = {
handler: function (value) {
if (value === "FR") {
var zipValue = $('input[name="postcode"]').val();
if (zipValue) {
return !(zipValue.startsWith("97") || zipValue.startsWith("98"));
}
}
return true;
},
message: $t('You cannot choose France for DOM-TOM Zip Code')
};
return rules;
};
});
And in my mixin I change Magento_Ui/js/lib/validation/validator for Magento_Ui/js/lib/validation/rules then my plugin method was working !
Please try this
define([
'jquery',
'jquery/validate'
], function($){
'use strict';
return function(validator) {
validator.addRule(
"validate-country",
function(value) {
if (value === "FR") {
var zipValue = $('input[name="postcode"]').val();
if (zipValue) {
return !(zipValue.startsWith("97") || zipValue.startsWith("98"));
}
}
return false;
},
$.mage.__("You cannot choose France for DOM-TOM Zip Code")
);
return validator;
}
});
I have used return false you can modify according to your need.Tested on version 2.2.2

Date format in SlickGrid

SlickGrid launches the calendar using a default US date format of mm/dd/yyyy. I store dates in my database in Australian format dd/mm/yyyy. how can I change the format of the calendar to take dd/mm/yyyy?
You can use the DatePicker of your choice by writing a new custom editor. The default date editor uses jQueryUI DatePicker.
Personally (I'm in Australia too), I use the default with the following settings:
function DateFormatter(rowIndex, cell, value, columnDef, grid, dataProvider) {
if (value == null || value === "") { return "-"; }
return moment.utc(value).format('ddd, D MMM YYYY');
}
... using moment.js to format the date, and in the DateEditor ...
$input.datepicker({
showOn: "button",
changeMonth: true,
changeYear: true,
dateFormat: 'd/m/yy',
buttonImageOnly: true,
buttonImage: "../images/calendar.gif"
});
Also you could just localise
You can write formatter for row (i use moment.js too):
function dateTimeFormatter (row, cell, value, columnDef, dataContext) {
var dateTime = Date.parse(value);
var result = moment(dateTime);
return result.format('DD.MM.YYYY hh:mm:ss');
}
First, add code to the slick.formatters.js file in your local library:
Add the custom date formatter in two spots:
$.extend(true, window, {
"Slick": {
"Formatters": {
"PercentComplete": PercentCompleteFormatter,
"PercentCompleteBar": PercentCompleteBarFormatter,
"YesNo": YesNoFormatter,
"Checkmark": CheckmarkFormatter,
"Checkbox": CheckboxFormatter,
"Date": Dateformatter //<< this one
}
}
});
and on the end of the file:
function Dateformatter(row, cell, value, columndef, datacontext) {
if (value === null) {
return "";
} else {
var d = new Date(value);
var m = d.getMonth() + 1;
return (d.getDate() + "/" + m + "/" + d.getFullYear());
}
}
})(jQuery); //<< this line is already present
Now you can add the date formatter in your column definitions:
{
id: "lastLoginDate", name: "LastLoginDate", field: "lastLoginDate", formatter: Slick.Formatters.Date
},

Kendo UI validation for Root

I have to validate a textbox(for root) in which the string should be started with "/" but should not be ended with "/".
I have gone through regular expression for that but couldn't get any perfect solution.
I have used following code to define rule for that.
var validatorRules = {
rules: {
customRule1: function (input) {
var chars = [];
if (input != "") {
chars = input.split('');
if (chars[0]!="/" && chars[input.lenght-1]=="/") {
return true;
}
}
}
},
messages: {
customRule1: "Provide proper root"
}
};

Kendo Grid DatePicker Editor Template DateTime Change Value not working

Consider the following code i want to set the grid datePicker column empty if date validation fails WorkOrderDate< task date , any help would be higly appreciable.
***********Grid***************
columns.Bound(c => c.WorkOrderDetailsDate)
.Title("Estimated Start Date")
.EditorTemplateName("WorkOrderDetailsDate")
***********Editor**************
#model DateTime?
#(Html.Kendo().DatePicker()
.Name("WorkOrderDetailsDate")
.Value(Model == null ? DateTime.Now.Date : ((DateTime)#Model).Date)
.Events(d=>d.Change("TaskDateValidate"))
)
*************JavaScript***********
function TaskDateValidate(e)
{
if ($("#workOrder_EstStartDate").val() != null && $("#workOrder_EstStartDate").val() != "") {
var workDate = kendo.parseDate($("#workOrder_EstStartDate").val());
var taskDate = kendo.parseDate(kendo.toString(this.value(), 'd'));
if (taskDate < workDate)
{
showMessage("Task date should be after work order Date");
this.value(""); <-----this is not working want to set to empty to force user to select date again
this.value("28/02/2014");<---this is not working as well...
}
}
}
please advise on this problem
reagrds
Shaz
found the solution my self...
//Add validation on Grid
(function ($, kendo) {
$.extend(true, kendo.ui.validator, {
rules: {
greaterdate: function (input) {
if (input.is("[data-val-greaterdate]") && input.val() != "") {
var date = kendo.parseDate(input.val()),
earlierDate = kendo.parseDate($("[name='" + input.attr("data-val-greaterdate-earlierdate") + "']").val());
return !date || !earlierDate || earlierDate.getTime() < date.getTime();
}
return true;
},//end of greaterdate
shorterdate: function (input) {
if (input.is("[data-val-shorterdate]") && input.val() != "") {
var date = kendo.parseDate(input.val()),
laterDate = kendo.parseDate($("[name='" + input.attr("data-val-shorterdate-laterdate") + "']").val());
return !date || !laterDate || laterDate.getTime() > date.getTime();
}
return true;
},//end of shorter date
// custom rules
taskdate: function (input, params) {
if (input.is("[name=WorkOrderDetailsDate]")) {
//If the input is StartDate or EndDate
var container = $(input).closest("tr");
var tempTask = container.find("input[name=WorkOrderDetailsDate]").data("kendoDatePicker").value();
var tempWork = $("#workOrder_EstStartDate").val();
var workDate = kendo.parseDate(tempWork);
var taskDate = kendo.parseDate(tempTask);
if (taskDate < workDate) {
return false;
}
}
//check for the rule attribute
return true;
}
}, //end of rule
messages: {
greaterdate: function (input) {
return input.attr("data-val-greaterdate");
},
shorterdate: function (input) {
return input.attr("data-val-shorterdate");
},
taskdate: function (input) {
return "Task date must be after work date!";
},
}
});
})(jQuery, kendo);

How do I make a Textarea field with Spring Webflow and Dojo(dijit)

I been trying to find out how to make a textarea field in my Spring Webflow project we are using Dojo (dijit) for the forms. can someone please help. below is my code!
<td valign="top"><form:input path="bio" class="value" /> <script
type="text/javascript">
Spring.addDecoration(new Spring.ElementDecoration({
elementId : "name",
widgetType : "dijit.form.ValidationTextBox",
widgetAttrs : {
promptMessage : "Please enter your name from 2 to 10 characters",
invalidMessage : "A 2 to 10 characters value is required.",
required : true,
regExp : "^[a-zA-Z]{2,10}$"
}
}));
</script> <br />
<p></td>
this should work:
<form:textarea id="bio" path="bio" />
<script type="text/javascript">
Spring.addDecoration(new Spring.ElementDecoration({
elementId : "bio",
widgetType : "dijit.form.SimpleTextarea",
</script>
[EDIT] I just checked and textArea's don't seem to have any kind of validation, so I created one for you based on ValidationTextBox.
just put this somewhere in your javascript file:
dojo.provide("dijit.form.ValidationTextArea");
dojo.require("dojo.i18n");
dojo.require("dijit.form.TextBox");
dojo.require("dijit.Tooltip");
dojo.requireLocalization("dijit.form", "validate");
/*=====
dijit.form.ValidationTextBox.__Constraints = function(){
// locale: String
// locale used for validation, picks up value from this widget's lang attribute
// _flags_: anything
// various flags passed to regExpGen function
this.locale = "";
this._flags_ = "";
}
=====*/
dojo.declare(
"dijit.form.ValidationTextArea",
dijit.form.TextBox,
{
// summary:
// Base class for textbox widgets with the ability to validate content of various types and provide user feedback.
// tags:
// protected
templateString: "<textarea name=${name} ${nameAttrSetting} dojoAttachPoint='focusNode,containerNode,textbox' autocomplete='off'></textarea>",
baseClass: "dijitTextArea",
attributeMap: dojo.delegate(dijit.form._FormValueWidget.prototype.attributeMap, {
rows:"textbox", cols: "textbox"
}),
// rows: Number
// The number of rows of text.
rows: "3",
// rows: Number
// The number of characters per line.
cols: "20",
// required: Boolean
// User is required to enter data into this field.
required: false,
// promptMessage: String
// If defined, display this hint string immediately on focus to the textbox, if empty.
// Think of this like a tooltip that tells the user what to do, not an error message
// that tells the user what they've done wrong.
//
// Message disappears when user starts typing.
promptMessage: "",
// invalidMessage: String
// The message to display if value is invalid.
invalidMessage: "$_unset_$", // read from the message file if not overridden
// constraints: dijit.form.ValidationTextBox.__Constraints
// user-defined object needed to pass parameters to the validator functions
constraints: {},
// regExp: [extension protected] String
// regular expression string used to validate the input
// Do not specify both regExp and regExpGen
regExp: "(.|[\r\n])*",
regExpGen: function(/*dijit.form.ValidationTextBox.__Constraints*/constraints){
// summary:
// Overridable function used to generate regExp when dependent on constraints.
// Do not specify both regExp and regExpGen.
// tags:
// extension protected
return this.regExp; // String
},
// state: [readonly] String
// Shows current state (ie, validation result) of input (Normal, Warning, or Error)
state: "",
// tooltipPosition: String[]
// See description of `dijit.Tooltip.defaultPosition` for details on this parameter.
tooltipPosition: [],
_setValueAttr: function(){
// summary:
// Hook so attr('value', ...) works.
this.inherited(arguments);
this.validate(this._focused);
},
validator: function(/*anything*/value, /*dijit.form.ValidationTextBox.__Constraints*/constraints){
// summary:
// Overridable function used to validate the text input against the regular expression.
// tags:
// protected
return (new RegExp("^(?:" + this.regExpGen(constraints) + ")"+(this.required?"":"?")+"$")).test(value) &&
(!this.required || !this._isEmpty(value)) &&
(this._isEmpty(value) || this.parse(value, constraints) !== undefined); // Boolean
},
_isValidSubset: function(){
// summary:
// Returns true if the value is either already valid or could be made valid by appending characters.
// This is used for validation while the user [may be] still typing.
return this.textbox.value.search(this._partialre) == 0;
},
isValid: function(/*Boolean*/ isFocused){
// summary:
// Tests if value is valid.
// Can override with your own routine in a subclass.
// tags:
// protected
return this.validator(this.textbox.value, this.constraints);
},
_isEmpty: function(value){
// summary:
// Checks for whitespace
return /^\s*$/.test(value); // Boolean
},
getErrorMessage: function(/*Boolean*/ isFocused){
// summary:
// Return an error message to show if appropriate
// tags:
// protected
return this.invalidMessage; // String
},
getPromptMessage: function(/*Boolean*/ isFocused){
// summary:
// Return a hint message to show when widget is first focused
// tags:
// protected
return this.promptMessage; // String
},
_maskValidSubsetError: true,
validate: function(/*Boolean*/ isFocused){
// summary:
// Called by oninit, onblur, and onkeypress.
// description:
// Show missing or invalid messages if appropriate, and highlight textbox field.
// tags:
// protected
var message = "";
var isValid = this.disabled || this.isValid(isFocused);
if(isValid){ this._maskValidSubsetError = true; }
var isValidSubset = !isValid && isFocused && this._isValidSubset();
var isEmpty = this._isEmpty(this.textbox.value);
if(isEmpty){ this._maskValidSubsetError = true; }
this.state = (isValid || (!this._hasBeenBlurred && isEmpty) || isValidSubset) ? "" : "Error";
if(this.state == "Error"){ this._maskValidSubsetError = false; }
this._setStateClass();
dijit.setWaiState(this.focusNode, "invalid", isValid ? "false" : "true");
if(isFocused){
if(isEmpty){
message = this.getPromptMessage(true);
}
if(!message && (this.state == "Error" || (isValidSubset && !this._maskValidSubsetError))){
message = this.getErrorMessage(true);
}
}
this.displayMessage(message);
return isValid;
},
// _message: String
// Currently displayed message
_message: "",
displayMessage: function(/*String*/ message){
// summary:
// Overridable method to display validation errors/hints.
// By default uses a tooltip.
// tags:
// extension
if(this._message == message){ return; }
this._message = message;
dijit.hideTooltip(this.domNode);
if(message){
dijit.showTooltip(message, this.domNode, this.tooltipPosition);
}
},
_refreshState: function(){
// Overrides TextBox._refreshState()
this.validate(this._focused);
this.inherited(arguments);
},
//////////// INITIALIZATION METHODS ///////////////////////////////////////
constructor: function(){
this.constraints = {};
},
postMixInProperties: function(){
// Copy value from srcNodeRef, unless user specified a value explicitly (or there is no srcNodeRef)
if(!this.value && this.srcNodeRef){
this.value = this.srcNodeRef.value;
}
this.inherited(arguments);
this.constraints.locale = this.lang;
this.messages = dojo.i18n.getLocalization("dijit.form", "validate", this.lang);
if(this.invalidMessage == "$_unset_$"){ this.invalidMessage = this.messages.invalidMessage; }
var p = this.regExpGen(this.constraints);
this.regExp = p;
var partialre = "";
// parse the regexp and produce a new regexp that matches valid subsets
// if the regexp is .* then there's no use in matching subsets since everything is valid
if(p != ".*"){ this.regExp.replace(/\\.|\[\]|\[.*?[^\\]{1}\]|\{.*?\}|\(\?[=:!]|./g,
function (re){
switch(re.charAt(0)){
case '{':
case '+':
case '?':
case '*':
case '^':
case '$':
case '|':
case '(':
partialre += re;
break;
case ")":
partialre += "|$)";
break;
default:
partialre += "(?:"+re+"|$)";
break;
}
}
);}
try{ // this is needed for now since the above regexp parsing needs more test verification
"".search(partialre);
}catch(e){ // should never be here unless the original RE is bad or the parsing is bad
partialre = this.regExp;
console.warn('RegExp error in ' + this.declaredClass + ': ' + this.regExp);
} // should never be here unless the original RE is bad or the parsing is bad
this._partialre = "^(?:" + partialre + ")$";
},
filter: function(/*String*/ value){
// Override TextBox.filter to deal with newlines... specifically (IIRC) this is for IE which writes newlines
// as \r\n instead of just \n
if(value){
value = value.replace(/\r/g,"");
}
return this.inherited(arguments);
},
_setDisabledAttr: function(/*Boolean*/ value){
this.inherited(arguments); // call FormValueWidget._setDisabledAttr()
this._refreshState();
},
_setRequiredAttr: function(/*Boolean*/ value){
this.required = value;
dijit.setWaiState(this.focusNode,"required", value);
this._refreshState();
},
postCreate: function(){
if(dojo.isIE){ // IE INPUT tag fontFamily has to be set directly using STYLE
var s = dojo.getComputedStyle(this.focusNode);
if(s){
var ff = s.fontFamily;
if(ff){
this.focusNode.style.fontFamily = ff;
}
}
}
this.inherited(arguments);
if(dojo.isIE && this.cols){ // attribute selectors is not supported in IE6
dojo.addClass(this.textbox, "dijitTextAreaCols");
}
},
reset:function(){
// Overrides dijit.form.TextBox.reset() by also
// hiding errors about partial matches
this._maskValidSubsetError = true;
this.inherited(arguments);
},
_onBlur: function(){
this.displayMessage('');
this.inherited(arguments);
},
_previousValue: "",
_onInput: function(/*Event?*/ e){
// Override TextBox._onInput() to enforce maxLength restriction
if(this.maxLength){
var maxLength = parseInt(this.maxLength);
var value = this.textbox.value.replace(/\r/g,'');
var overflow = value.length - maxLength;
if(overflow > 0){
if(e){ dojo.stopEvent(e); }
var textarea = this.textbox;
if(textarea.selectionStart){
var pos = textarea.selectionStart;
var cr = 0;
if(dojo.isOpera){
cr = (this.textbox.value.substring(0,pos).match(/\r/g) || []).length;
}
this.textbox.value = value.substring(0,pos-overflow-cr)+value.substring(pos-cr);
textarea.setSelectionRange(pos-overflow, pos-overflow);
}else if(dojo.doc.selection){ //IE
textarea.focus();
var range = dojo.doc.selection.createRange();
// delete overflow characters
range.moveStart("character", -overflow);
range.text = '';
// show cursor
range.select();
}
}
this._previousValue = this.textbox.value;
}
this.inherited(arguments);
}
}
);
you can use it the way you use ValidationTextBox, just use ValidationTextArea instead.

Resources