Quick filter on Slick grid

2019-08-10 02:14发布

I am new to jquery and slickgrid. I need some help to add quick text filter using quick text filter on slick grid.

I tried to follow the example given on : https://github.com/mleibman/SlickGrid/blob/gh-pages/examples/example-header-row.html and http://mleibman.github.io/SlickGrid/examples/example-header-row.html

But I kind of messed it up. Couldn't get the filter working.

Here is my code.

JSP:

<div>
        <div id="carfactory"  class="  ui-state-default"    style="width: 860px; text-align: left;">
                <div id="carGrid"></div>
                <div id="carPager" style="height: 30px;" class="ui-widget"></div>
            </div>
        </div>
        <c:if test="${info == null or empty info}">
            <div class="ui-widget style="float:center">
                <strong>No results found !</strong>
            </div>
            <br>
        </c:if>
</div>

Jquery:

<script type="text/javascript"> 


    function carfactory(){
        var holder=new Array();
        var i=0;
         <c:forEach var="message" items="${info}" >
         holder[i]={
                    id: i,
                    createdon: '<c:out value="${message.createdOn}"/>',
                    modifiedon:'<c:out value="${message.modifiedOn}"/>',
                    status:'<c:out value="${message.status}"/>',
                    username:'<c:out value="${message.username}"/>'
                    }
            i++;       
          </c:forEach>
           return holder;
         }

var columns = [];
      var columnFilters = {};

        function filter(item) {
            for (var columnId in columnFilters) {
              if (columnId !== undefined && columnFilters[columnId] !== "") {
                var c = grid.getColumns()[grid.getColumnIndex(columnId)];
                if (item[c.field] != columnFilters[columnId]) {
                  return false;
                }
              }
            }
            return true;
          }
        (function($) {   

         function createGrid(grid) {
                   if ( grid.grid ==undefined ) {
                       grid.dataView = new Slick.Data.DataView();
                       grid.grid = new Slick.Grid(grid.element, grid.dataView, grid.columns, grid.options);
                       if ( grid.pagerElement != undefined ) {
                           grid.pager = new Slick.Controls.Pager(grid.dataView, grid.grid, grid.pagerElement);
                       }
                       grid.dataView.onRowCountChanged.subscribe(function (e, args){ grid.grid.updateRowCount(); grid.grid.render();  });
                        grid.dataView.onRowsChanged.subscribe(function (e, args){ grid.grid.invalidateRows(args.rows); grid.grid.render(); });
                        grid.grid.onSort.subscribe(function (e, args){ grid.dataView.fastSort(args.sortCol.field, args.sortAsc); });

 $(grid.grid.getHeaderRow()).delegate(":input", "change keyup", function (e) {
                            var columnId = $(this).data("columnId");
                            if (columnId != null) {
                              columnFilters[columnId] = $.trim($(this).val());
                              dataView.refresh();
                            }
                          });
                          grid.grid.onHeaderRowCellRendered.subscribe(function(e, args) {
                              $(args.node).empty();
                              $("<input type='text'>")
                                 .data("columnId", args.column.id)
                                 .val(columnFilters[args.column.id])
                                 .appendTo(args.node);
                          });

                       grid.dataView.beginUpdate();
                       if ( grid.data != undefined ) grid.dataView.setItems(grid.data);
                       if ( grid.data != undefined ) grid.dataView.setFilter(filter);
                       if ( grid.pager != undefined ) grid.dataView.setPagingOptions({ pageSize: 15, pageNum: 1 });
                       grid.dataView.endUpdate();



                   }
                   return grid;
               }

         var carFactoryGrid = createGrid({

             element: $("#carGrid"),
             pagerElement: $("#carPager"),
             columns: [


                 {id: "createdOn", name: "Created On", field: "createdon", sortable: true, width: 200}, 
                 {id: "modifiedon", name: "Modified On", field: "modifiedon", sortable: true, width: 200},
                 {id: "status", name: "Status", field: "status", sortable: true, width: 50},
                 {id: "username", name: "Username", field: "username", sortable: true, width: 150}
                 ],
             options: { enableColumnReorder: false, autoHeight: true, rowHeight: 20  },             
             data:carfactory()
         });
        })(jQuery);
</script>

1条回答
可以哭但决不认输i
2楼-- · 2019-08-10 02:39

There are a few areas in the code which prevent the header filters from appearing and functioning. I've explained them below with refrences to the fiddle http://jsfiddle.net/rg8n7vc2/ which resolves them. Please note for test purposes I commented out the JSP code which populates the grid and replaced it with random test data.

Filter function accessing grid

The grid variable named carFactoryGrid is defined within the closure, yet the filter function is attempting to access it outside of the closure. Declaring the variable carFactoryGrid outside of the closure allows the filter function to access it (similar to the example you linked). Alternatively you could move the filter function inside the closure if you wish.

The changes for Fix 1 highlighted in the Fiddle are:

//Line 44 - Delcare carFactoryGrid outside closure
var carFactoryGrid;

//Line 51 - Amend filter function to use carFactoryGrid variable
var c =  carFactoryGrid.grid.getColumns()[carFactoryGrid.grid.getColumnIndex(columnId)];

//Line 102 - Remove declaration from inside closure (remove var)
carFactoryGrid = createGrid({

Grid options and initialization

To view the filter header row as shown in the example you must include the relevant options when initialising SlickGrid (showHeaderRow and headerRowHeight). Additionally the the grid must be initialised manually after subscribing to the onHeaderRowCellRendered event to ensure the header row is constructed correctly. To do this the option explicitInitialization must be set to true and grid.init(); manually called to initialize the grid once you've subscribed to the events.

The changes for Fix 2 highlighted in the Fiddle are:

//Line 96 - Initialize grid
grid.grid.init();

//Line 117 - Additional options for grid
showHeaderRow: true,
headerRowHeight: 34,
explicitInitialization: true

Filtering Notes

The filter function in the code matches the whole string and is case sensitive. You must therefore type the full word with the correct case into the filter (e.g. 'Chris' into Username) for matched results to appear. If you'd like to match as you type then you'll need to amend the function using .indexOf(). An updated version of the fiddle using an example of indexOf is http://jsfiddle.net/rg8n7vc2/2/ which has the updates below:

//Line 54
//Filtering amendments
//Check for null value
if (!item[c.field] && columnFilters[columnId]){
    return false;
}

//Convert the value to a string in case it is a date using toString()
//If you are just passing strings instead of dates then .toString is not necessary
//If you are using dates then ideally you'd call the relevant formatter here to get the correct format
//Converts all to upper case then checks for existence of filter value in value using indexOf
if (item[c.field].toString().toUpperCase().indexOf(columnFilters[columnId].toUpperCase()) == -1) {
    return false;
}
查看更多
登录 后发表回答