【问题标题】:SlickGrid column typeSlickGrid 列类型
【发布时间】:2013-05-21 01:45:20
【问题描述】:

我想为 SlickGrid 过滤器做自己的过滤功能,通常会统一并且可以在 99 % 中使用。我在 Slickgrid 中错过了什么 - 列中使用了哪种类型的数据?也许它已经存在了,但是在查看了我没有找到的来源之后。如果存在的话-如果您将我引向真正的道路,我将不胜感激。 Slick.Editors 类型 ?但是如果列不用于编辑? ...
在 SlickGrid 的示例中通常使用不允许数据类型的过滤器,仅存在一些具有具体字段 ID 的示例。通常数据是字符、日期、布尔值和数字。 对于 nums 类型,我想改进带有 和其他数字操作数符号的过滤器,同样可以使用日期类型来完成。此时我只能使用字段 ID 来执行此操作 - 我可以使用 fieldIds 和类型来指导自己的全局数组,然后从中识别列的类型。但是这个解决方案并不清楚 - 如果从网格中检测列类型会更好。

非常感谢您的任何帮助和想法!

添加:

经过一番搜索发现,我可以使用 SlickGrid 数据值类型。我是 Javascript 的新手,所以欢迎任何关于改进以下源代码的帮助和建议... :-)

这是我的来源:

 function filter( item ) 
  {
     for ( var columnId in colFilt ) 
     {
        if ( columnId !== undefined && colFilt[ columnId ] !== "" ) 
        {
           var c   = grid.getColumns()[ grid.getColumnIndex( columnId ) ];
           var typ = varType( item[ c.field ] );
           if ( typ == "N" || typ == "D" ) 
           {
              var arr = date_num_filter( colFilt[ columnId ] )
              if ( arr.length > 0 )
              {
                 if ( arr.length == 2 )
                 {
                    switch ( arr[ 0 ] )
                    {
                       case "<" : 
                          if ( item[ c.field ] >= arr[ 1 ] )
                              return false;
                          break;
                       case ">" : 
                          if ( item[ c.field ] <= arr[ 1 ] )
                             return false;
                          break;
                       case "<=" :
                          if ( item[ c.field ] > arr[ 1 ] )
                             return false;
                          break;
                       case ">=" :   
                          if ( item[ c.field ] < arr[ 1 ] )
                             return false;
                          break;
                       default :
                          return false;                          
                    }
                 }   
                 else
                 {
                    if ( item[ c.field ] < arr[ 1 ] || item[ c.field ] > arr[ 3 ] ) 
                       return false;
                 }
              }   
              else
              {
                 if ( item[ c.field ] != colFilt[ columnId ] )
                    return false;
              }      
           }
           if ( typ == "C" ) // item[ c.field ].substring 
           {
              if ( item[ c.field ].toLowerCase().indexOf( colFilt[ columnId ] ) == -1 ) // item[ c.field ] != colFilt[ columnId ] && 
                 return false;
           }
        }   
     }
     return true;
  }

  function varType( o ) 
  {
     if ( o.toFixed )
        return "N";
     if ( o.substring )
        return "C";
     if ( o.getMonth )
        return "D";
     if ( o == true || o == false )
        return "L";
     return "U";
  }

  function date_num_filter( cVal )
  {
     var ret_arr = [];
     var p       = -1;
     var n1,n2,n3

     if ( cVal.length == 0 )
        return ret_arr;

     n1 = cVal.indexOf( ".." );
     n2 = cVal.indexOf( "<" );
     n3 = cVal.indexOf( ">" );
     if ( n1 >= 0 || n2 >= 0 || n3 >= 0 )
     {
        p = cVal.indexOf( ".." );
       if ( p >= 0 && cVal.length > 2 )
        {
           if ( p == 0 || p == cVal.length - 2 )
           {
              ret_arr[ 0 ] = ( p == 0 ? "<=" : ">=" );
              ret_arr[ 1 ] = ( p == 0 ? cVal.substr( 2 ) : cVal.substr( 0, p ) );
           }
           else
           {
              ret_arr[ 0 ] = ">=";
              ret_arr[ 1 ] = cVal.substr( 0, p );
              ret_arr[ 2 ] = "<=";
              ret_arr[ 3 ] = cVal.substr( p + 2 );
           }                  
           return ret_arr;
        }

        n1 = cVal.indexOf( "<=" );
        n2 = cVal.indexOf( ">=" );
        if ( n1 == 0 || n2 == 0 )
        {
           if ( cVal.length > 2 );
           {
              ret_arr[ 0 ] = cVal.substr( 0, 2 );
              ret_arr[ 1 ] = cVal.substr( 2 );
              return ret_arr;
           }
        }   
        n1 = cVal.indexOf( "<" );
        n2 = cVal.indexOf( ">" );
        if ( n1 == 0 || n2 == 0 ) 
        {
           if ( cVal.length > 1 );
           {
              ret_arr[ 0 ] = cVal.substr( 0, 1 );
              ret_arr[ 1 ] = cVal.substr( 1 );
              return ret_arr;
           }   
        }
     }   
     return ret_arr;
  }

提前致谢!

【问题讨论】:

    标签: javascript slickgrid


    【解决方案1】:

    您的英语有点难以理解,但我相信您正在尝试使用像这样的一些条件( > 100, != 100, 100 )进行过滤,我在我的项目中使用 2 个函数完成了它。原理是它会从检查第一个字符开始,如果找到这 4 个符号中的任何一个(、!、=),那么我们知道它是一个条件过滤器,然后它会抓住那个条件直到找到一个空格,所以你会捕捉到任何带有 1 或 2 个字符(、!= 等)的符号。条件还首先检查它是否是数字,因为对字符串和数字执行 > 1 会产生 2 个不同的结果。

    这是我的两个功能:

    function myFilter(item) {
        // Regex pattern to validate numbers
        var patRegex_no = /^[$]?[-+]?[0-9.,]*[$%]?$/; // a number negative/positive with decimals with/without $, %
    
        for (var columnId in columnFilters) {
            if (columnId !== undefined && columnFilters[columnId] !== "") {
                var c = grid.getColumns()[grid.getColumnIndex(columnId)];
                var filterVal = columnFilters[columnId].toLowerCase();
                var filterChar1 = filterVal.substring(0, 1); // grab the 1st Char of the filter field, so we could detect if it's a condition or not
    
                if(item[c.field] == null)
                    return false;
    
                // First let see if the user supplied a condition (<, <=, >, >=, !=, <>, =, ==)
                // Substring on the 1st Char is enough to find out if it's a condition or not
                // if a condition is supplied, we might have to transform the values (row values & filter value) before comparing
                // for a String (we'll do a regular indexOf), for a number (parse to float then compare), for a date (create a Date Object then compare)
                if( filterChar1 == '<' || filterChar1 == '>' || filterChar1 == '!' || filterChar1 == '=') {
                    // We found a Condition filter, find the white space index position of the condition substring (should be index 1 or 2)
                    var idxFilterSpace = filterVal.indexOf(" ");
    
                    if( idxFilterSpace > 0 ) {
                        // Split the condition & value of the full filter String
                        var condition = filterVal.substring(0, idxFilterSpace);
                        filterNoCondVal = columnFilters[columnId].substring(idxFilterSpace+1);
    
                        // Which type are the row values? We'll convert to proper format before applying the condition
                        // Then apply the condition comparison: String (we'll do a regular indexOf), number (parse to float then compare)
                        if( patRegex_no.test(item[c.field]) ) {                             
                            if( testCondition(condition, parseFloat(item[c.field]), parseFloat(filterNoCondVal)) == false ) 
                                return false;
                        // whatever is remain will be tested as a regular String format     
                        }else {                             
                            if ( testCondition(condition, item[c.field].toLowerCase(), filterNoCondVal.toLowerCase()) == false )
                                return false;
                        }
                    } 
                }else{
                    if (item[c.field].toLowerCase().indexOf(columnFilters[columnId].toLowerCase()) == -1)
                        return false;
                }
            }
        }
        return true;
    }
    
    /** Test a filter condition that is passed into String, since eval() function is a performance killer
     * I have created a switch case for all possible conditions. Performance is irrelevent this way 
     * @var String condition: condition to filter with
     * @var any value1: 1st value to compare, the type could be anything (number, String or even Date)
     * @var any value2: 2nd value to compare, the type could be anything (number, String or even Date)
     * @return boolean: a boolean result of the tested condition (true/false)
     */
    function testCondition(condition, value1, value2){
        switch(condition) {
            case '<':   return (value1 < value2);
            case '<=':  return (value1 <= value2);
            case '>':   return (value1 > value2);
            case '>=':  return (value1 >= value2);
            case '!=':  
            case '<>':  return (value1 != value2);
            case '=':   
            case '==':  return (value1 == value2);
        }
        return resultCond;
    }
    

    【讨论】:

    • 谢谢!您的解决方案更优雅。很好..:-)
    • 如果这确实回答了您的问题,欢迎您..您能否投票并使其成为有效答案,谢谢:)
    猜你喜欢
    • 2015-03-13
    • 2011-11-09
    • 2012-01-15
    • 2012-04-30
    • 2012-03-31
    • 2012-03-16
    • 2014-03-31
    • 2013-11-04
    • 2012-06-22
    相关资源
    最近更新 更多