Existing Validator inside Custom Validator

Tags: #<Tag:0x00007f8b2511edd0>

Hello, I want to apply the logic of the dropdown validator to a custom validator of unique values in a column that I found in this link https://github.com/handsontable/handsontable/issues/3102. I know that there is a way to apply a existing renderer to a custom renderer (Handsontable.renderers.TextRenderer.apply(this, arguments);), but how can I do this with a validator?

This is the validator:

myUniqueValidator: function (value, callback) {
// This doesn’t work
// Handsontable.validators.DropdownValidator.apply(this, arguments);
var data = this.instance.getDataAtCol(this.col);
var index = data.indexOf(value);
var valid = true;
if (index > -1 && this.row !== index) {
valid = false;
}
return callback(valid);
},

Hi @hnz70586

validators do not inherit anything - they’re build as a separate functions https://github.com/handsontable/handsontable/blob/65dc03147e411df27e6c2699b93fdc7ade9bad67/src/validators/numericValidator.js
Renderers inherit methods from a BaseRenderer https://github.com/handsontable/handsontable/blob/d0aac96b07497347eba7d8307c5b70e0081410f4/src/renderers/textRenderer.js#L19

Thanks, could you provide me the link for the dropdown validator like you did with the numeric validator, or an a idea of how to merge the logic of the dropdown validator and the unique validator that I pasted in the firs comment.

Hi @hnz70586

here’s an AutocompleteValidator https://github.com/handsontable/handsontable/blob/bb6871349289add4f4692ebe6627c408b6bce251/src/validators/autocompleteValidator.js as you can see here https://github.com/handsontable/handsontable/blob/bb6871349289add4f4692ebe6627c408b6bce251/test/e2e/cellTypes/index.spec.js it is used for dropdown and autocomplete cell types.

Thanks, I have applied the logic of the autocomplete validtor to my custom validator, do you think that this is right way to do it? Anyway, it works fine.

myDropdownUniqueValidator: function (value, callback) {
// unique validator logic
var data = this.instance.getDataAtCol(this.col);
var index = data.indexOf(value);
var uniqueValue = true;
if (index > -1 && this.row !== index) {
uniqueValue = false;
}
// dropdown validator logic
let valueToValidate = value;
if (valueToValidate === null || valueToValidate === void 0) {
valueToValidate = ‘’;
}
if (this.allowEmpty && valueToValidate === ‘’) {
callback(true);
return;
}
if (this.strict && this.source) {
if (typeof this.source === ‘function’) {
this.source(valueToValidate, HTCustom.process(valueToValidate, callback, uniqueValue));
} else {
HTCustom.process(valueToValidate, callback, uniqueValue)(this.source);
}
} else {
callback(true);
}
},
process: function (value, callback, uniqueValue) {
const originalVal = value;
return function (source) {
let found = false;
for (let s = 0, slen = source.length; s < slen; s++) {
if (originalVal === source[s]) {
found = true; // perfect match
break;
}
}
//also check if is a uniquevalue
callback(found && uniqueValue);
};
},

If you use this structure

    if (condition) {
          callback(true);
    } else {
          callback(false);
    }

it is the proper way to do it.

At first glance, I do not see any issues with your code, and I’m glad to hear that you’ve made it work as expected.