Kendo UI validation for Root - kendo-ui

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"
}
};

Related

Multiple filter in ng-repeat

I need help with filtering data in ng-repeat. I've tried to do few things but I can't find solution that works in my case. I need to to something like this:
sensor in sensors | filter: { group: group.id, (name: search || description: search) }
Search is ng-model (text input) and group.id is ID of group that are genereted in ng-repeat (I have two nested ng-repeat). I've tried to do my filter:
$scope.search = '';
$scope.searchFilter = function() {
return function (p) {
if ($scope.search!='') {
for (var i in p) {
console.log("p.name: "+p.name+", search: "+$scope.search);
if (p.name == $scope.search || p.description == $scope.search) {
return p;
}
}
} else {
return p;
}
}
}
Almost works. It filters my data but only if I write correct name. For example I want to find "engine". If I start writing "en" there is no data but if I write "engine" it will display correct data. So I need to work on that too. I hope you understand what I want to do.
I've found solution!
sensor in sensors filter: { group: group.id } | filter: searchFilter()
And this:
$scope.search = '';
$scope.searchFilter = function() {
return function (p) {
if ($scope.search!='') {
for (var i in p) {
var re = new RegExp($scope.search, 'i'); // This I've add
if (p.name.match(re) || p.description.match(re) ) { // This I've change
return true;
}
}
} else {
return true;
}
}
}

p:selectOneMenu filter not working with accented characters

I use PrimeFaces SelectOneMenu advanced. Filter is wrong working when I input the i and ı character.
For example http://www.primefaces.org/showcase/ui/input/oneMenu.xhtml demo advanced one menu I search arI and arİ strings and it finds Aristo element.
In my application, my menu contains Isparta element. I input Isp and İsp and filter finds Isparta.
How can I solve this problem?
I resolve this problem with autocomplete component. Primefaces autocomplete component with dropdown="true" property works like one menu and this component don't have Turkish character problem.
Reported to PrimeFaces Team: https://github.com/primefaces/primefaces/issues/9629
Fixed for 13.0.0 but MonkeyPatch provided here:
if (PrimeFaces.widget.SelectOneMenu) {
PrimeFaces.widget.SelectOneMenu.prototype.normalize = function(string, lowercase) {
if (!string) return string;
var result = string.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
return lowercase ? result.toLowerCase() : result;
}
PrimeFaces.widget.SelectOneMenu.prototype.filter = function(value) {
this.cfg.initialHeight = this.cfg.initialHeight || this.itemsWrapper.height();
var filterValue = this.normalize(PrimeFaces.trim(value), !this.cfg.caseSensitive);
if (filterValue === '') {
this.items.filter(':hidden').show();
this.itemsContainer.children('.ui-selectonemenu-item-group').show();
} else {
var hide = [];
var show = [];
for (var i = 0; i < this.options.length; i++) {
var option = this.options.eq(i),
itemLabel = this.normalize(option.text(), !this.cfg.caseSensitive),
item = this.items.eq(i);
if (item.hasClass('ui-noselection-option')) {
hide.push(item);
} else {
if (this.filterMatcher(itemLabel, filterValue)) {
show.push(item);
} else if (!item.is('.ui-selectonemenu-item-group-children')) {
hide.push(item);
} else {
itemLabel = this.normalize(option.parent().attr('label'), !this.cfg.caseSensitive);
if (this.filterMatcher(itemLabel, filterValue)) {
show.push(item);
} else {
hide.push(item);
}
}
}
}
$.each(hide, function(i, o) {
o.hide();
});
$.each(show, function(i, o) {
o.show();
});
hide = [];
show = [];
//Toggle groups
var groups = this.itemsContainer.children('.ui-selectonemenu-item-group');
for (var g = 0; g < groups.length; g++) {
var group = groups.eq(g);
if (g === (groups.length - 1)) {
if (group.nextAll().filter('.ui-selectonemenu-item-group-children:visible').length === 0)
hide.push(group);
else
show.push(group);
} else {
if (group.nextUntil('.ui-selectonemenu-item-group').filter('.ui-selectonemenu-item-group-children:visible').length === 0)
hide.push(group);
else
show.push(group);
}
}
$.each(hide, function(i, o) {
o.hide();
});
$.each(show, function(i, o) {
o.show();
});
}
var firstVisibleItem = this.items.filter(':visible:not(.ui-state-disabled):first');
if (firstVisibleItem.length) {
this.highlightItem(firstVisibleItem);
PrimeFaces.scrollInView(this.itemsWrapper, firstVisibleItem);
}
if (this.itemsContainer.height() < this.cfg.initialHeight) {
this.itemsWrapper.css('height', 'auto');
} else {
this.itemsWrapper.height(this.cfg.initialHeight);
}
this.alignPanel();
}
};
From PrimeFaces 13 normalization can be applied on both the item label and the filter value by setting the filterNormalize attribute to true. You can do the same in older versions using a filterFunction. For example:
<script>
function searchable(string) {
return !string ? '' : string.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase();
}
function customFilter(itemLabel, filterValue) {
return searchable(itemLabel).includes(searchable(filterValue));
}
</script>
<p:selectOneMenu filter="true" filterMatchMode="custom" filterFunction="customFilter"
.../>
See also:
https://primefaces.github.io/primefaces/12_0_0/#/components/selectonemenu?id=filtering

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 you make a kendo datepicker do date validation for a minimum date?

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",
}
});

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