【问题标题】:slickgrid validate column with regexslickgrid 使用正则表达式验证列
【发布时间】:2012-02-29 03:37:11
【问题描述】:

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

    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

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

【问题讨论】:

    标签: javascript regex slickgrid


    【解决方案1】:

    无论如何,在我看来,解决这个问题的最佳方法是编写您自己的编辑器,您将把它添加到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 的选项,这让我可以更灵活地添加我想要的任何选项、模式, 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());

      收件人: var validationResults = args.column.validator($input.val(), $input);

      这会将您的验证器方法签名更改为:

      function requiredFieldValidator(value, input)
      

      这样,您可以使用input.attr('validation-expression')input.data... 或其他任何方式从输入中获取您想要的任何属性。

      【讨论】:

      • 当然,你可以编辑它来传递你想要的任何东西。就像在某处向 args.column 添加验证设置对象并将其传递给 args.column.validator 的第二个参数而不是 $input。
      • 没有得到它。 slick.editors.js 中有标准验证器。我需要指定我自己的吗?以及代码的外观而不是validator: requiredFieldValidator
      • 默认情况下,slickGrid 仅将输入的值传递给自定义验证器方法,因此args.column.validator($input.val()); 当前仅将值传递给您的requiredFieldValidator。您的代码仍然看起来像 validator: requiredFieldValidator,但它会引用 function requiredFieldValidator(value, input) 您希望首先将正则表达式定义为输入中的属性。
      • 以及如何为不同的列不同的正则表达式字符串指定regex 属性?
      【解决方案3】:

      为了扩展@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 };
          }
       }
      

      【讨论】:

        【解决方案4】:

        这很有帮助。我正在为每种可能的条目创建不同的输入类型——电子邮件、电话、邮编等等。 要使用 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)
        }
        

        【讨论】: