Search code examples
jqgridjquery-ui-multiselect

JQGrid MultiSelect Filter option populate based on column's distinct value


I am using JQGrid with Multiselect filter to filter individual columns. Currently I am populating filters(e.g. SkillCategory column) using database master values

{
 name: 'SkillCategory', index: 'SkillCategory', width: '5%', sortable: true, resizable: true, stype: 'select',
  searchoptions: {
  clearSearch: false,
   sopt: ['eq', 'ne'],
    dataUrl: 'HttpHandler/DemandPropertyHandler.ashx?demprop=skillcat',
    buildSelect: createSelectList,
     attr: { multiple: 'multiple', size: 4 },
     position: {
      my: 'left top',
         at: 'left bottom'
        },
     dataInit: dataInitMultiselect
      }
    },

This approach is populating all available master list(for SkillCategory) in to filter. I would like to show only available filter value based on those are present in available rows for particular column(for SkillCategory). This should show "Programming" and "Data" as option for SkillCategory filter as rows contains only "Programming" and "Data" value for that column.

enter image description here

enter image description here

I found below code(sorry forgot the link)

getUniqueNames = function (columnName) {
            var texts = $("#listTableSupply").jqGrid('getCol', columnName), uniqueTexts = [],
            textsLength = texts.length, text, textsMap = {}, i;
            for (i = 0; i < textsLength; i++) {
                text = texts[i];
                if (text !== undefined && textsMap[text] === undefined) {
                    // to test whether the texts is unique we place it in the map.
                    textsMap[text] = true;
                    uniqueTexts.push(text);
                }
            }
            return uniqueTexts;
        }
        buildSearchSelect = function (uniqueNames) {
            var values = ":All";
            $.each(uniqueNames, function () {
                values += ";" + this + ":" + this;
            });
            return values;
        }
        setSearchSelect = function (columnName) {
            $("#listTableSupply").jqGrid('setColProp', columnName,
                    {
                        searchoptions: {
                            sopt: ['eq', 'ne'],
                            value: buildSearchSelect(getUniqueNames(columnName)),
                            attr: { multiple: 'multiple', size: 3 },
                            dataInit: dataInitMultiselect
                        }
                    }
        );
        }

Calling setSearchSelect("SkillCategory")

....  caption: 'Supply',
                emptyrecords: "No records to view",
                loadtext: "Loading...",
                refreshtext: "Refresh",
                refreshtitle: "Reload Grid",
                loadComplete: loadCompleteHandler1,
                ondblClickRow: function (rowid) {
                    jQuery(this).jqGrid('viewGridRow', rowid);
                },
                beforeRequest: function () //loads the jqgrids state from before save
                {
                    modifySearchingFilter.call(this, ',');
                }
            }).jqGrid('bindKeys');
            $('#listTableSupply').bind('keydown', function (e) {
                if (e.keyCode == 38 || e.keyCode == 40) e.preventDefault();
            });
            setSearchSelect("SkillCategory");
            $('#listTableSupply').jqGrid('navGrid', '#pagerSupply', {
                cloneToTop: true,
                refresh: true, refreshtext: "Refresh", edit: false, add: false, del: false, search: false
            }, {}, {}, {}, {
                multipleSearch: true,
                multipleGroup: true,
                recreateFilter: true
            }); .....

But seems its not working. Only "All" value is populated. enter image description here

Any idea how can I achieve this.

Update1:

As per Oleg's suggestion below is the working code which worked for me.

initializeGridFilterValue = function () {

            //jQuery("#listTableSupply").jqGrid('destroyGroupHeader');
            setSearchSelect("SkillCategory");

            jQuery("#listTableSupply").jqGrid("filterToolbar", {
                stringResult: true,
                searchOnEnter: true,
                defaultSearch: myDefaultSearch,
                beforeClear: function () {
                    $(this.grid.hDiv).find(".ui-search-toolbar .ui-search-input>select[multiple] option").each(function () {
                        this.selected = false; // unselect all options
                    });

                    $(this.grid.hDiv).find(".ui-search-toolbar button.ui-multiselect").each(function () {
                        $(this).prev("select[multiple]").multiselect("refresh");
                    }).css({
                        width: "98%",
                        marginTop: "1px",
                        marginBottom: "1px",
                        paddingTop: "3px"
                    });
                }
            });
            jQuery("#listTableSupply").jqGrid('setGridHeight', 300);
        }

And setting it from loadComplete event like below:

function loadCompleteHandler1() {
            initializeGridFilterValue();
        }

Solution

  • I see that you use the code from my old answer. About your problem: I suppose that you first call filterToolbar which creates the filter toolbar and only later you call setSearchSelect which set new searchoptions.value property. Another possible problem is that you call setSearchSelect before the data will be loaded in the grid. If you use datatype: "local" with data parameter then the data are filled in the grid during creating of the grid. If you use datatype: "json" then you should first load the data from the server and then call setSearchSelect and filterToolbar inside of loadComplete. For example if you use loadonce: true then you can test the value of datatype parameter inside of loadComplete. If the value is "json" then you made initial loading of the data. So you should call setSearchSelect, then if required call destroyFilterToolbar and finally call filterToolbar to create filter toolbar which selects will have all required values.