使用正则表达式验证SlickGrid列

3

这是一个带有列验证的简单示例:

    function requiredFieldValidator(value) {
      if (value == null || value == undefined || !value.length) {
        return {valid: false, msg: "This is a required field"};
      } else {
        return {valid: true, msg: null};
      }
    }

要验证列,只需要添加以下选项:validator: requiredFieldValidator

但是如果我需要传递额外参数-正则表达式字符串,该如何使用regex函数呢?

4个回答

6
在我看来,最好的方法是编写自己的编辑器,并将其作为另一个新的自定义编辑器添加到 slick.editor.js 中。这个文件也是为此而制作的。我已经实现了正则表达式测试,效果很好。
以下是我的新编辑器,它不仅适用于正则表达式,还适用于各种条件类型,例如选项 min:2 将需要至少 2 个数字,而 minLength:2 将要求输入至少为 2 个字符的字符串等。现在,您真正寻找的就是我的代码定义中的 pattern 类型。 因此,您将不得不在 slick.editor.js 中包含此代码:
ConditionalCellEditor : function(args) {            
    var $input;
                var defaultValue;
                var scope = this;
    var condObj = null;

                this.init = function() {
                        $input = $("<INPUT type='text' class='editor-text' />")
                                .appendTo(args.container)
                                .bind("keydown.nav", function(e) {
                                        if (e.keyCode === $.ui.keyCode.LEFT || e.keyCode === $.ui.keyCode.RIGHT) {
                                                e.stopImmediatePropagation();
                                        }
                                })
                                .focus()
                                .select();
                };

                this.destroy = function() {
                        $input.remove();
                };

                this.focus = function() {
                        $input.focus();
                };

                this.getValue = function() {
                        return $input.val();
                };

                this.setValue = function(val) {
                        $input.val(val);
                };

                this.loadValue = function(item) {
                        defaultValue = item[args.column.field] || "";
                        $input.val(defaultValue);
                        $input[0].defaultValue = defaultValue;
                        $input.select();
                };

                this.serializeValue = function() {
                        return $input.val();
                };

                this.applyValue = function(item,state) {
                        item[args.column.field] = state;
                };

                this.isValueChanged = function() {
                        return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
                };

                this.validate = function() {
        var condObj = args.column.editorOptions;
        var returnMsg = null;
        var returnValid = true;

        if(typeof condObj.min != 'undefined') {

            if( parseFloat($input.val()) < parseFloat(condObj.min) ) {
                returnMsg = "Value should not be less then "+condObj.min;
                returnValid = false;
            }
        }
        if(typeof condObj.max != 'undefined') {
            if( parseFloat($input.val()) > parseFloat(condObj.max) ) {
                returnMsg = "Value should not be over "+condObj.max;
                returnValid = false;
            }
        }
        if(typeof condObj.minLength != 'undefined') {

            if($input.val().length < condObj.minLength) {
                returnMsg = "Value length should not be less then "+condObj.minLength;
                returnValid = false;
            }
        }
        if(typeof condObj.maxLength != 'undefined') {
            if($input.val().length > condObj.maxLength) {
                returnMsg = "Value length should not be over "+condObj.maxLength;
                returnValid = false;
            }
        }
        if(typeof condObj.pattern != 'undefined') {
            if( condObj.pattern.test($input.val()) != true ) {
                returnMsg = (condObj.msg) ? condObj.msg : "Value is invalid following a regular expression pattern";
                returnValid = false;
            }
        }               
        if(typeof condObj.required != 'undefined') {
            if($input.val().length == "" && condObj.required) {
                returnMsg = "Required field, please provide a value";
                returnValid = false;
            }
        }

        // Now let's return our boolean results and message if invalid
        return {
            valid: returnValid,
            msg: returnMsg
        }
                };

                this.init();
},

在我的SlickGrid列定义内,我调用了新的编辑器并传递一些选项。我决定将这些选项作为对象传递给editorOptions,这样就可以更灵活地添加任何选项,例如pattern、msg、minLength等等。下面是一个验证电子邮件正则表达式模式的示例。

columns1 = [
...
{id:"email", field:"email", name:"Em@il", width:145, editor:ConditionalCellEditor, editorOptions:{pattern:/^([0-9a-zA-Z]+([_.-]?[0-9a-zA-Z]+)*@[0-9a-zA-Z]+[0-9,a-z,A-Z,.,-]*(.){1}[a-zA-Z]{2,4})+$/, msg:"Must be a valid email"} },
...];

看,好像是个魔法一样的效果!!! 我几乎不再使用 editor:TextCellEditor 了,因为我的新的 ConditionalCellEditor 编辑器给了我更多的灵活性。希望能有所帮助,让我知道它的效果如何...


2

默认情况下,您无法将更多参数传递到validator方法中,但您可以轻松编辑源代码以允许它。

slick.editors.js中查找:

this.validate = function () {
  if (args.column.validator) {
    var validationResults = args.column.validator($input.val());
    if (!validationResults.valid) {
      return validationResults;
    }
  }

  return {
    valid: true,
    msg: null
  };
};

更改为: var validationResults = args.column.validator($input.val(), $input);

这将更改您的验证方法签名,类似于:

function requiredFieldValidator(value, input)

通过这样,您可以使用input.attr('validation-expression')input.data...等方式获取输入中所需的任何属性。


当然,你可以编辑它以传递任何你想要的东西。比如在args.column的某个地方添加一个验证设置对象,并将其传递到args.column.validator的第二个参数中,而不是$input。 - Mike Gwilt
我不明白。在slick.editors.js中有标准验证器,我需要指定自己的吗?如果不使用validator: requiredFieldValidator,代码会是什么样子? - Iurii Dziuban
默认情况下,slickGrid仅将输入的值传递到自定义验证器方法中,因此args.column.validator($input.val());目前仅将值传递到您的requiredFieldValidator。您的代码仍将类似于validator: requiredFieldValidator,但这将引用function requiredFieldValidator(value, input)。您需要首先将正则表达式定义为输入属性。 - Mike Gwilt
我该如何针对不同的列指定不同的正则表达式字符串来设置 regex 属性? - Iurii Dziuban

1
为了扩展@mike-gwilt的答案,您可以使用cellAttrs列选项来指定(在列定义中)要报告的正则表达式和消息,如下所示:
... { id: "columnId", name: "columnName", validator: RegexValidator, cellAttrs: {"reg":"^\\d{1,2}$", "msg": "The value should be a number of two digits."} ...

然后生成的HTML大致如下:
<div class="slick-cell l9 r9 active editable selected" reg="^\d{1,3}$" msg="The value should be a number of two digits."><input type="text" class="editor-text" value=""></div>

最后,由于您可以在验证函数内部访问输入元素,因此请像这样定义它:
 function RegexValidator(value, input) {
    var msg = input.parent().attr('msg');
    var reg = new RegExp(input.parent().attr('reg'));
    if (!reg.exec(value)) {
        return { valid: false, msg: msg};
    } else {
        return { valid: true, msg: null };
    }
 }

0
这非常有帮助。我正在为每种可能的输入类型创建不同的输入类型 - 电子邮件、电话、邮编等等。要使用JSON实现这一点,您需要修改slick.grid.js文件以评估这些条目并使它们成为对象调用。
if (d) {
  if(m.formatter){
    m.formatter=eval(m.formatter)
    } // make it an object call instead of string

if(m.editor) {
    m.editor=eval(m.editor)
    }

if(m.editorOptions) {
    m.editorOptions=eval(m.editorOptions)
    }

    }

让你的 JSON 列有这个更新:
\"editor\": \"Slick.Editors.Conditional\", 
\"editorOptions\": 
   {\"pattern\":\"email\", \"msg\":\"Must be a valid email\",  \"required\":\"1\"}

让你的 slick.editors.js 看起来像这样:

(function ($) {
 $.extend(true, window, {
  "Slick": {
  "Editors": {
  "Conditional": Conditional, 

inside -> function Conditional(args){

if(typeof condObj.pattern != 'undefined') {
    if(condObj.pattern=='email'){
        pattern=/^([0-9a-zA-Z]+([_.-]?[0-9a-zA-Z]+)*@[0-9a-zA-Z]+[0-9,a-z,A-Z,.,-]*(.){1}[a-zA-Z]{2,4})+$/;
        val=$input.val();
      if(pattern.test(val) != true && val!='')  {
           returnMsg = (condObj.msg) ? condObj.msg : "Value is invalid";
           returnValid = false;
      }
 } 
}
if(!returnValid){
   alert(returnMsg)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接