Handsontable - Required Field - validation

I have handsontable and I don't know what event that I need to validate a specific cell if its empty or not.
technically I have specific cell to be a required cell, if the cell is empty then it will call a callback or return false after executing a post.
I have used beforeChange() function before and I think it is not appropriate event for the issue.
Here's an image link.

What you want to do is use the validator option in the columns setting.
Here is some more information on validators and an example but below is the code that would go with it.
emptyValidator = function(value, callback) {
if (isEmpty(value)) { // isEmpty is a function that determines emptiness, you should define it
callback(false);
} else {
callback(true);
}
}
Then in the columns setting, supply each column and if that column should have all its cells be non-empty, supply this as the validator, just like they show in the handonstable example page.

Here is my work around: http://jsfiddle.net/Yulinwu/s6p39uje/
Firstly, you can add a custom property named required to the column settings.
hot = new Handsontable(container, {
...
columns: [{
...
}, {
type: 'numeric',
format: '$ 0,0.00',
required: true, // Add a new setting named required
validator: Handsontable.NumericValidator
}]
});
Then, you can add a listener to beforeValidate event using addHook, which returns false if a cell is required but empty.
hot.addHook('beforeValidate', function(value, row, prop, source) {
var ifRequired = this.getCellMeta(row, prop).required;
console.log(ifRequired);
if (ifRequired && value === '') {
return false
} else {
return 0
}
});

Use allowEmpty:false for that column like:-
{
data: 'EmpNo',
type: 'numeric',
allowInvalid: false,
allowEmpty:false
}
And in the setting of handsontable use afterValidate as below-
afterValidate: function (isValid, value, row, prop, source) {
if (!isValid) {
$("#submitBtn").prop("disabled", true);
alert('Only non empty numbers are allowed');
}
else {
$("#submitBtn").prop("disabled", false);
}
}

Related

Polymer paper-input custom validator issue

I am trying to implement a custom validator for a paper-input. In this particular case, the control should accept positive numbers. However, not only only will the control only accept positive numbers, it will also run some other custom validation logic to determine if the entry falls within a constantly changing (dynamic & calculated) upper and lower limit. Ideally, the paper-input control's error-message text will also change depending on what part of the custom validator check failed.
In the past, I was able to implement this sort of thing with the gold-email-input element. In that case, the control checks for an entry that matches a regular expression for email addresses (i.e. implements a type-check). It also calls a backend api to see if the email address entered (as it is being typed), already exists in a database. If it exists in the database, the control fails validation and updates the control's validation error-message with a custom message. If it does not exist, it passes validation. As you might have imagined by this description, this was for a user registration UI element whereby the provided email should not already exist in the current list of user accounts. Here is an excerpt of that working code below for your reference:
<gold-email-input id="userEmail" label="Email" required auto-validate value="{{userEmail}}" error-message$="{{_getEmailErrorMsg(0)}}" invalid="{{_emailInvalid}}" validator="_validateEmail"></gold-email-input>
<iron-signals on-iron-signal-email-used="_accountFound" on-iron-signal-email-available="_accountNotFound"></iron-signals>
<script>
var emailErrors = ["Provide a valid email address", "Address already used"];
// Register the polymer element
Polymer({
properties: {
userEmail: {type: String, value: null},
validated: {type: Boolean, notify: true}, //overall validity state of entire element
_emailInvalid: {type: Boolean, value: true, observer: "_validityChanged"}, // validity state of email input itself
},
ready: function() {
// Called before attached
this.$.userEmail.validate = this._validateEmail.bind(this);
},
_accountFound: function() {
// Listener function intended to fire when the user email address/account was found
console.log(this.nodeName + " accountFound listener called\n");
this.$.userEmail.errorMessage = this._getEmailErrorMsg(1);
this._emailInvalid = true;
},
_accountNotFound: function() {
// Listener function intended to fire when the user email address/account was not found
console.log(this.nodeName + " accountNotFound listener called\n");
this.$.userEmail.errorMessage = this._getEmailErrorMsg(0);
this._emailInvalid = false;
},
_checkAccountExistance: function() {
if (this.userEmail !== undefined && this.userEmail != null) {
this.$.user.checkEmailAvailability(this.userEmail);
} else {
this._emailInvalid = true;
}
},
_getEmailErrorMsg: function(code) {
if (code !== undefined && code != null) {
return emailErrors[code];
} else {
return "";
}
},
_validateEmail: function() {
// Custom validator function for email input (also checks if email has already been associated to any user accounts)
console.log(this.nodeName + " validateEmail validator called\n");
// Check if proper email address format (W3C Spec Regex used)
var validEntry = /^[a-zA-Z0-9.!#$%&�*+/=?^_`{|}~-]+#[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/.test(this.userEmail);
if (validEntry) {
this._emailInvalid = false;
this._checkAccountExistance();
} else {
this._emailInvalid = true;
}
}
_validityChanged: function(newVal, oldVal) {
// set the containing/parent element's overall validity state
this.validated = (!this._nameInvalid && !this._pwInvalid && !this._phoneInvalid && !this._emailInvalid && !this._countryInvalid && !this._regionInvalid && !this._cityInvalid);
},
});
</script>
Now, if I try to implement a similar approach with the paper-input component, it does not work. The custom validator function does not get called at any point. Is there something inherently different with paper-input compared to gold-email-input? Should it not treat validation the same way?
<paper-input id="xpos" label="Horizontal Position" required auto-validate value="{{XPos}}" error-message="Provide the x position" invalid="{{_xInvalid}}" validator="_validatePosition"></paper-input>
<script>
// Register the polymer element
Polymer({
properties: {
xPos: {type: Number},
validated: {type: Boolean, notify: true}, //overall validity state of entire element
_xInvalid: {type: Boolean, value: true, observer: "_validityChanged"}, // validity state of xpos input itself
},
ready: function() {
// Called before attached
this.$.xpos.validate = this._validatePosition.bind(this);
},
_validatePosition: function() {
console.log(this.nodeName + " validatePosition validator called\n");
// perform some validation code here like the gold-email-input example above
}
});
</script>

Mongoose conditional required validation

I'm using mongoose and trying to set a custom validation that tells the property shall be required (ie. not empty) if another property value is set to something. I'm using the code below:
thing: {
type: String,
validate: [
function validator(val) {
return this.type === 'other' && val === '';
}, '{PATH} is required'
]}
If I save a model with {"type":"other", "thing":""} it fails correctly.
If I save a model with {"type":"other", "thing": undefined} or {"type":"other", "thing": null} or {"type":"other"} the validate function is never executed, and "invalid" data is written to the DB.
As of mongoose 3.9.1, you can pass a function to the required parameter in the schema definition. That resolves this problem.
See also the conversation at mongoose: https://github.com/Automattic/mongoose/issues/941
For whatever reason, the Mongoose designers decided that custom validations should not be considered if the value for a field is null, making conditional required validations inconvenient. The easiest way I found to get around this was to use a highly unique default value that I consider to be "like null".
var LIKE_NULL = '13d2aeca-54e8-4d37-9127-6459331ed76d';
var conditionalRequire = {
validator: function (value) {
return this.type === 'other' && val === LIKE_NULL;
},
msg: 'Some message',
};
var Model = mongoose.Schema({
type: { type: String },
someField: { type: String, default: LIKE_NULL, validate: conditionalRequire },
});
// Under no condition should the "like null" value actually get persisted
Model.pre("save", function (next) {
if (this.someField == LIKE_NULL) this.someField = null;
next()
});
A complete hack, but it has worked for me so far.
Try adding this validation to the type attribute, then adjust your validation accordingly. E.g.:
function validator(val) {
val === 'other' && this.thing === '';
}
thing: {
type: String,
required: function()[{
return this.type === 'other';
}, 'YOUR CUSTOM ERROR MSG HERE']
}

Kendo grid data("kendoValidator").validate() method always returns true

$("#mygrid").kendoValidator().data("kendoValidator").validate() method always returns true even if there are validation errors for some of the input fields in the grid. On first time load the validation works fine but during edit the next time it does not show the tooltip, please help me resolve this issue.
I have added a validation template using schema of the grid:
schema: {
model: {
id: "AuctionID",
fields: {
AuctionID: {
editable: false,
type: "number"
},
AuctionName: {
type: "string",
validation: {
required: { message: "An Auction Name is Required!" },
validateAuctionName: function (input) {
if (input.attr("data-bind") == "value:AuctionName") { // check if this is the element to validate
alert(input.val().length);
if (input.val().length > 10) {
input.attr("data-validateAuctionName-msg", "AuctionName can only have a maximum of 10 characters.");
return false;
}
else
return true;
}
return true;
}
}
}
}
}
}
The method you are using is not triggering validation as it interrogates "this" and validates it if it is a kendo widget with validation enabled.
I found this way to force validation - get hold of model and trigger change on property you want to validate:
model.trigger("set", { field: "FinishTime", value: model.FinishTime });

jquery validate when changing tab without submit

I have a form with 4 tabs and I want to be able to validate the current tab before it switches to the new tab when the user clicks on any other tab. This is what I have so far:
$("#tabs").tabs({
beforeActivate: function(event, ui) {
var tab = ui.oldTab.index();
var valid = true;
if (tab == 0 && ($('#txbYPSchool').val() == "" || $('#txbYPSubjectDesc').val() == "")) {
valid = false;
};
if (!valid) {
//alert('not valid');
event.preventDefault();
}
else {
alert('valid');
}
}
});
The above function prevents the user from selecting a different tab if some fields are not filled in. I also have validate function setup as follows:
$("#form1").validate({
rules: {
txbYPSchool: { required: true, nowhitespace: true },
txbYPSubjectDesc: { required: true, nowhitespace: true }
},
messages: {
txbYPSchool: "*This field is mandatory. If not in school, type 'Not in School'",
txbYPSubjectDesc: "*This field is mandatory"
},
ignore: ""
});
How can I get the validation to run and display the error messages when a user tries to change tabs when there are incomplete fields still on the present tab? I want to be able to do this without a button click and only when a user tries to change tabs but I dont know how to incorporate the validation function into the first function.
Am using jquery 1.9.1 and the latest validation plugin.
Thanks
You can possibly use the plugin's .valid() method.
Replace this...
if (!valid) {
with this...
if !($("#form1").valid()) {
Then since the plugin is checking validity, you can get rid of all this...
var valid = true;
if (tab == 0 && ($('#txbYPSchool').val() == "" || $('#txbYPSubjectDesc').val() == "")) {
valid = false;
};

jqGrid change search filters on submit

I would like to alter the search filters after a user has submitted them. Normally jqGrid returns name in colmodel as the value for field, I would like to change this behavior for a specific column:
I would like to change:
{"groupOp":"AND","rules":[{"field":"available","op":"eq","data":"true"}]}
to
{"groupOp":"AND","rules":[{"field":"s.trait.available","op":"eq","data":"true"}]}
I have tried altering the submitted form in the ways below; firebug shows that the functions are never being called.
var searchOptions = {
multipleSearch:true, multipleGroup:false, closeOnEscape:true, closeAfterSearch:true,
sopt:['ge', 'eq', 'le'],
beforeSubmit:function (params, postdata) {
//alterations would be here
}
,
onclickSubmit:function (params, postdata) {
//alterations would be here
}
}
This approach works for editOptions and delOptions, I am not sure why I cannot get this to work for searching.
If you use the searching toolbar you can use beforeSearch callback to modify the postData.filter. In case of Singe Field searching or Advanced Searching you can use onSearch.
In the answer you can see how the postData.filter can be modified.
UPDATED: You did something wrong in your tests. The only problem is that the current implementation of searching don't initialize this to the grid, but it's not explicitly documented somewhere.
I created the demo for you which demonstrate that you do can modify the filter before relaoding of the grid will be started. If you would search in the grid for 'Client' equal to 300 the search request will be modified to 'amount' equal to 300 and you would see the results
The corresponding code is
$('#list').jqGrid('navGrid', '#pager', {add: false, edit: false, del: false}, {}, {}, {},
{
multipleSearch: true,
overlay: 0,
onSearch: function () {
var i, l, rules, rule, $grid = $('#list'),
postData = $grid.jqGrid('getGridParam', 'postData'),
filters = $.parseJSON(postData.filters);
if (filters && typeof filters.rules !== 'undefined' && filters.rules.length > 0) {
rules = filters.rules;
for (i = 0; i < rules.length; i++) {
rule = rules[i];
if (rule.field === 'name') {
// make modifications only for the 'contains' operation
rule.field = 'amount';
}
}
postData.filters = JSON.stringify(filters);
}
}});

Resources