Всплывающее окно фильтра типов Excel для Jqgrid - PullRequest
1 голос
/ 14 ноября 2011

Мне нужно иметь фильтр (как в листе Excel) для встраивания в всплывающее диалоговое окно «jquery». в этом случае мне нужно показать все уникальные значения в столбце и флажок перед этим значением, чтобы выбрать для пользователя. когда пользователь нажал кнопку фильтра, мне нужно отфильтровать только те значения, которые пользователь запросил через флажки.

Может кто-нибудь, пожалуйста, дайте мне любой подход, которому я должен следовать. Заранее благодарим за помощь и драгоценное время.

1 Ответ

0 голосов
/ 28 ноября 2011

Мне удалось разработать базовую сетку с функцией фильтра Excel.Любой, кто столкнется с этим типом требования, может использовать этот ответ в качестве основы.

Я использую этот ответ Олега, чтобы встроить всплывающий экран фильтра в базовый jqgrid..

на странице jqgrid объявите этот массив с атрибутами (столбцами), которые должны отображать всплывающее окно фильтра.

var applyFilterColumnNames = ['Id','Type','custId','UserId'];

и модель столбца должна выглядеть следующим образом -

 colModel :[ 
          {name:'Id', index:'Id',hidden: true,sortable: true},
          {name:'custId', index:'custId', width:140,align:"left",sortable: true,search : false},
          {name:'Type', index:'Type', width:120,align:"left",sortable: true,search : false},
          {name:'UserId', index:'UserId', width:150,align:"left",sortable: true,search : false},
         ],

использовал этот ссылочный ответ для встраивания функции кнопки фильтра.

    gr.closest("div.ui-jqgrid-view").find("div.ui-jqgrid-hdiv table.ui-jqgrid-htable tr.ui-jqgrid-labels > th.ui-th-column > div.ui-jqgrid-sortable")

.each(function () {
    var idPrefix = "jqgh_" + gr[0].id + "_";

    var idIndex = (this.id).substr(idPrefix.length,this.id.length) ;

    if(includeInArray(applyFilterColumnNames,idIndex)){

        jq('<button id=btn_'+idIndex+'>').css({float: "right", height: "17px"}).appendTo(this).button({

                icons: {

                    primary: "ui-icon-gear"

                },

                text: false

            }).click(function (e) {

                var idPrefix = "jqgh_" + gr[0].id + "_";

                // thId will be like "jqgh_list_name"
                var thId = jq(e.target).closest('div.ui-jqgrid-sortable')[0].id ;



                if (thId.substr(0, idPrefix.length) === idPrefix) {

                    var colName = thId.substr(idPrefix.length);
                    //alert('Clicked the button in the column "' + colName + '"');
                    constructFilter(colName);

                    return false;

                }



            });
        //}
    }
});

Ниже приведен скрипт, который я использовал для фильтрации jqgrid в соответствии с фильтрами

    //Variables that use in filtering operation
    var originalData = null;
    var filteredData;
    var selectedFilters = new Object();
    var chkBoxElement;
    var firstSortColumn;


    function constructFilter(columnName){

        // for the first initiation of the filter populate current grid data to an array
        if(originalData == null || originalData == 'null'){
            try{
                // this array will hold the initail data set of the grid
                originalData  = gr.jqGrid('getGridParam','data');
                // set the first sorting grid column
                firstSortColumn = columnName;
                // check if column is associated with a formatter. if so format the originalData values accordingly.
                formatGridData(columnName);
            }catch(e){}
        }


        var colData = new Array();

        var filterDataSet;

        // if current column is equal to initial sorted column set all posible values to the check boxes in the 
        // filter screen to select. ( since this is the master sorting column and other columns will filter according to that)
        if(columnName == firstSortColumn){
            filterDataSet = originalData;
        }else{
            // set current grid data set to show as checkboxes in the filter page
            filterDataSet = gr.jqGrid('getCol',columnName,false);
        }

            for(key in filterDataSet){
                // check box element object that will hold the checkbox label and its state ( true / false)
                chkBoxElement = new Object();
                chkBoxElement.id = getValueFromArray(filterDataSet[key],columnName);

                if(typeof(chkBoxElement.id)== 'undefined'){
                    break;
                }
                // if this id is saved in previous filtering event checked option will set to true.
                 if(typeof(selectedFilters[columnName]) != 'undefined'){

                    if (includeInArray(selectedFilters[columnName],chkBoxElement.id)){
                        chkBoxElement.selected = true;
                     }else{
                         chkBoxElement.selected = false;
                     }
                } 

                colData.push(chkBoxElement);

            }

        // removing duplicates  
        var uniqueValues = removeDuplicates(colData);

        // sort the array without duplicate with the custom comparator
        uniqueValues.sort(sortComparator);

        // open the filter screen. return type will captured in the 'seletedElements' variable as pipe separated string
        seletedElements = window.showModalDialog(filterUrl,uniqueValues,"dialogWidth:400px;dialogHeight:250px;center:yes;resizable:no;status:no;help:no;");


        if(seletedElements != null && seletedElements != 'null'){
            // get selected values to the array
            selectedFilters[columnName] = seletedElements.split("|");
        }else{
            //user just close the popup (using close button) will return without doing anything
            return;
        }


        if(columnName == firstSortColumn){
            // refine filter with the non filtered data set
            refillGrid(seletedElements,columnName,originalData);
        }else{
            // send current data set to refine
            var currentDataSet  = gr.jqGrid('getGridParam','data');
            refillGrid(seletedElements,columnName,currentDataSet);
        }

    }


    function formatGridData(columnName){

        var isFormatter = gr.jqGrid("getColProp",columnName);

        if(typeof isFormatter.formatter !== 'undefined') {
                if(jq.isFunction( isFormatter.formatter ) ) {

                    for(key in originalData){

                        var plainValue = originalData[key][columnName];
                        var formattedVal = isFormatter.formatter.call(null,plainValue,null,null,null);
                        originalData[key][columnName] = formattedVal;
                    }
                } 
        }
    }


    function resetFilters(){
        for(key in applyFilterColumnNames){

             jq("#btn_"+applyFilterColumnNames[key]).button("option", { 
                    //icons: { primary: this.checked ? 'ui-icon-check' : 'ui-icon-closethick' }
                    icons: { primary: 'ui-icon-gear'}

                });
        }

        gr.jqGrid("setCaption",gridCaption);
        refreshGrid(originalData);
        originalData = null;
        firstSortColumn = null;
        selectedFilters = new Object();
    }


    function refillGrid(seletedElements,columnName,filterDataSet){
        var filteredData= new Array();
        var elementsArray;
        try{
            elementsArray = seletedElements.split("|"); 
        }catch(e){
            // this exception happens when user simply open the filter screen 
            // do nothing and close it.
            trace('Error in filter splitting -'+e);
            return;
        }

        // When user de-select all check boxes from the popup screen
        if(elementsArray == ""){
            refreshGrid(originalData);
            return;
        }
        // refine the grid data according to the filters
        var mydata = filterDataSet;

            for(i=0;i<elementsArray.length;i++){
                 var filterElement = elementsArray[i]; 

                    for(j = 0;j<mydata.length;j++){
                        if(filterElement==getValueFromArray(mydata[j],columnName)){
                            filteredData.push(mydata[j]);
                        }
                    }
            }

            // change the button icon to indicate that the column is filtered
            changeButtonIcon(columnName);
            // update the column header to indicate sort by column
            changeGridCaption(columnName);
            // fill the grid according to the passed array
            refreshGrid(filteredData);

    }

    function changeGridCaption(columnName){
        // get columns name array
        var columnNames = gr.jqGrid('getGridParam','colNames');
        // get column model array
        var colModel = gr.jqGrid('getGridParam','colModel');
        var colModelIndex=null;

        if (firstSortColumn == columnName){
            for(key in colModel){
                try{
                    if (colModel[key].name == firstSortColumn){
                        colModelIndex = key;
                        break;
                    }   
                }catch(e){}
            }

        if(colModelIndex != null){
            var columnName = columnNames[colModelIndex];
            gr.jqGrid("setCaption",gridCaption + " - Filtered based on : "+columnName);
        }   


        }
    }

    function changeButtonIcon(columnName){
         //change the button Icon
    jq("#btn_"+columnName).button("option", { 
            //icons: { primary: this.checked ? 'ui-icon-check' : 'ui-icon-closethick' }
        icons: { primary: 'ui-icon-link'}

        });
    }


    function getValueFromArray(obj,columnName){
        if(obj !=null && typeof(obj)!='undefined'){
            // if obj param is string just return it
            if(typeof obj =='string'){
                return obj;
            }else{
                return obj[columnName];

            }
        }
    }

    function sortComparator(a,b){
        try{
            var aId = a.id.toLowerCase();
            var bId = b.id.toLowerCase();
            if (aId < bId) {return 1}
            if (aId > bId) {return -1}
        }catch(e){
            return 0;   
        }
    }

    function includeInArray(arr,obj) {
        //alert(arr);
    return (arr.indexOf(obj) != -1);
    }


    function refreshGrid(results) {
    gr.jqGrid('clearGridData')
     .jqGrid('setGridParam', { data: results })
     .trigger('reloadGrid');
    }

    function removeDuplicates(valueArray){
        var arr = {};
        for ( i=0; i < valueArray.length; i++ ){
            if(valueArray[i].id != null){
                arr[valueArray[i].id] = valueArray[i];
            }

        }

        valueArray = new Array();
        for ( key in arr ){
            valueArray.push(arr[key]);
        }



return valueArray;
}

Есличто-то здесь не так, пожалуйста, дайте мне знать. Это решение работает нормально.но я действительно ценю комментарии в терминах производительности и лучших практик кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...