can jqgrid support dropdowns in the toolbar filter fields
Asked Answered
L

4

35

i am using jqgrid and the toolbar filter. by default its just gives you a textbox to enter data into. Does it support a dropdown select combobox where i can give it a list of values to choose from to them filter on ??

Lakeshialakey answered 16/3, 2011 at 16:2 Comment(0)
T
68

There are some common rules for all types of sorting in jqGrid

{
    name: 'Category', index: 'Category', width: 200, formatter:'select', 
    stype: 'select', searchoptions:{ sopt:['eq'], value: categoriesStr }
}

where categoriesStr are defined as

var categoriesStr = ":All;1:sport;2:science";

Here additionally to the standard "1:sport;2:science" values are inserted ":All" string which allow you don't filter the the column. You can of course use ":" or ":Select..." and so on.

On the demo prepared for the answer you can see the close results.

UPDATED: I find your question interesting and made the demo. It shows how one can build the select comboboxes which can be used in the search toolbar or in the advanced searching dialog based on the text contain of the corresponding column. For one column I use additionally jQuery UI autocomplete. You can modify the code to use more different powerful options of the autocomplete. Here is the code of the code:

var mydata = [
        {id:"1", Name:"Miroslav Klose",     Category:"sport",   Subcategory:"football"},
        {id:"2", Name:"Michael Schumacher", Category:"sport",   Subcategory:"formula 1"},
        {id:"3", Name:"Albert Einstein",    Category:"science", Subcategory:"physics"},
        {id:"4", Name:"Blaise Pascal",      Category:"science", Subcategory:"mathematics"}
    ],
    grid = $("#list"),
    getUniqueNames = function(columnName) {
        var texts = grid.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) {
        grid.jqGrid('setColProp', columnName,
                    {
                        stype: 'select',
                        searchoptions: {
                            value:buildSearchSelect(getUniqueNames(columnName)),
                            sopt:['eq']
                        }
                    }
        );
    };

grid.jqGrid({
    data: mydata,
    datatype: 'local',
    colModel: [
        { name:'Name', index:'Name', width:200 },
        { name:'Category', index:'Category', width:200 },
        { name:'Subcategory', index:'Subcategory', width:200 }
    ],
    sortname: 'Name',
    viewrecords: true,
    rownumbers: true,
    sortorder: "desc",
    ignoreCase: true,
    pager: '#pager',
    height: "auto",
    caption: "How to use filterToolbar better locally"
}).jqGrid('navGrid','#pager',
          {edit:false, add:false, del:false, search:false, refresh:false});

setSearchSelect('Category');
setSearchSelect('Subcategory');

grid.jqGrid('setColProp', 'Name',
            {
                searchoptions: {
                    sopt:['cn'],
                    dataInit: function(elem) {
                        $(elem).autocomplete({
                            source:getUniqueNames('Name'),
                            delay:0,
                            minLength:0
                        });
                    }
                }
            });

grid.jqGrid('filterToolbar',
            {stringResult:true, searchOnEnter:true, defaultSearch:"cn"});

Is this what you want?

UPDATED: One more option could be the usage of select2 plugin which combines the advantages of dropdown and comfortable searching by Autocomplete. See the answer and this one (see the demo) for demos (this one and this one) and code examples.

UPDATED 2: The answer contains the modification of above code to work with jqGrid 4.6/4.7 or with free jqGrid 4.8.

Tollbooth answered 16/3, 2011 at 17:11 Comment(21)
@Tollbooth - thanks . . i was hoping that the grid could figure the dropdown list from the distinct set of data in the column but this is fine . .Lakeshialakey
@Tollbooth - why does All have a number(1) and sport have a number (2) but science doesnt ??Lakeshialakey
@ooo: It is a good idea to have the behavior close to Excel filter! I'll try to made the demo for you.Tollbooth
@ooo: "sport" has the number 1, "science" has the number 2 and "All" has nothing, So if you choose "All" no filter on the column will set.Tollbooth
@Tollbooth - ah, i read it wrong . . on a seperate note, your code above doesn't appear to be in the demo . . it seems to use editoptions as opposed to value inside of searchoptionsLakeshialakey
@Tollbooth - very cool new demo . . the one issue i have is that i dont have my data during initialization as i am getting my data from a ajax call. do you know if there is any way to run this code after data gets returned from an ajax call? . .Lakeshialakey
@ooo: You can build the select properties of search per ajax. You can use dataUrl and optional addtionally buildSelect to build the values of select box on the server. Look at here for an example.Tollbooth
@ooo: I modified the code from the demo a) to use more correctly unique names in the select; b) to use jQuery UI autocomplete for the first column. The demo uses, like the first demo, local datatype.Tollbooth
@Tollbooth - so to be clear, is it possible to use the stype: 'select' and have the list be populated by ajax, I took my main code (which is all text search) and just added stype: 'select' and searchoptions:{ sopt:['eq'] } and it still just shows a textbox. is there some additional plugin i need ??Lakeshialakey
@ooo: To have the behavior which you need you should define stype: 'select', searchoptions:{ sopt:['eq'], dataUrl: 'myGetSelectUrl'} where myGetSelectUrl answer on HTTP GET with the HTML data fragment <select><option val="val1">option1</option>...</select>. If you don't have on the server and method which can provide you HTML data you can also call another server method which post back the information enough to build <select> statement. You define in searchoptions:{...} one more method buildSelect which convert the server data to the <select> statement which jqGrid need.Tollbooth
@Tollbooth - ok, i am sooo close now. I now see the dropdown items but my only issue is, for example, when i select "Active" from a dropdown list in the search bar, the filter that gets sent to the server is passing along "Field: Status, op: 'eq', Value: 2. My issue is that its not passing the actual string but rather the select value. I tried passing a string 'Active" into the value field but rather the '2'. If i try to return a string in id/value pair of dataUrl: it then doesn't show the dropdown select at all . .any suggestions ??Lakeshialakey
@ooo: In the case you should just build select with the options having the same value as the option contain - both should has the same string. In the example from the answer The server return the list of strings List<string> as JSON and inside of buildSelect event handle I build select having '<option value="item">item</option>'. Is it not an option for you?Tollbooth
@Oleg: Thanks for the pointers here. This goes a long way to understanding a lot of concepts both directly related to jqGrid and jQuery.Fitzhugh
@oleg is there a way to default some of the checkbox selections to being checked?Disfeature
@mrshickadance: I'm not sure that I understand correctly your question. Do you mean formatter: "checkbox" or edittype: "checkbox"? Both have options: editoptions and formatoptions. There are defaultValue property which can be helpful in some scenarios, but you should exactly describe what you need. Probably it's better if you ask new question where you describe all in details.Tollbooth
Sorry, I meant the checkboxes in the ui-multiselect. I was able to do it in the dataInitMultiselect function by setting the .selected = true for the appropriate values.Disfeature
@mrshickadance: You should really post new question where you describe in details your problem. The demo with the test case description will be the best. I still don't understand what you mean and what problem you have. I know multiple plugins under the name "ui-multiselect". The version of the plugin, the version of jqGrid (or free jqGrid) can be very important to know too.Tollbooth
Sorry @Oleg, I thought I had it figured out but ran into some other problems. Posted a new question here: #29348181Disfeature
@Tollbooth this has been a huge help and a starting point for me to filter the grid. I have a question though. the dropdown has just "All" value in it but not the rest, I tried the functions inside loadcomplete and also after the grid loads, either way it doesn't work. Please Help.Halogenate
@HappyLee: Sorry, but I don't understand your question. Probably you should post separate question where you describe the problem in details.Tollbooth
@Tollbooth - Thanks for the response- here is the link to my question -#34458657Halogenate
V
2

I had a similar situation. Thanks to Oleg's excellent example above, it almost solved the problem. There was one slight improvement I needed. My grid is a loadonce grid that had around 40 rows, 10 per page. getCol method used above only returned the current page's column values. But I wanted to populate the filter with unique values across the entire dataset. So here's a slight modification to the function getUniqueNames:

var getUniqueNames = function(columnName) {

// Maybe this line could be moved outside the function           
// If the data is really huge then the entire segregation could
// be done in a single loop storing each unique column
// in a map of columnNames -> unique values
var data = grid.jqGrid('getGridParam', 'data');
var uniqueTexts = [], text, textsMap = {}, i;

for (i = 0; i < data.length; i++) {

                 text = data[i][columnName];

                 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);
                 }
             }

         // Object.keys(textsMap); Does not work with IE8: 
             return uniqueTexts;
}
Velasco answered 24/10, 2011 at 14:32 Comment(0)
P
1

I just did this myself. It felt a little bit like a hack, but it works!

  1. Created a new "navButtonAdd" and for the "caption", added html code for a dropdown.
  2. The onclickButton function contains nothing.
  3. Then I created an onchange function to handle the grid's reload when it's value changed.

        $('#myGrid').jqGrid('navButtonAdd', '#myGrid_toppager', {
            caption: "<select id='gridFilter' onchange='ChangeGridView()'><option>Inbox</option><option>Sent Messages</option></select>",
            title: "Apply Filter",
            onClickButton: function () {                 
            }
        });
    
        function ChangeGridView() {
            var gridViewFilter = $("#gridFilter").val();
            $('#myGrid').setGridParam({ datatype: 'json', url: '../../Controller/ActionJSON', postData: { msgFilter: gridViewFilter } });
            $('#myGrid').trigger("reloadGrid"); 
        }; 
    

    Hope this helps!

Person answered 2/8, 2012 at 14:59 Comment(0)
A
0

category is column name.

loadComplete: function () {
    $("#" + TableNames).setColProp('Category', {
        formatter: 'select', edittype: "select",
        editoptions: { value: "0:MALE;1:FEMALE;2:other;" }
    });
},
Abnormity answered 10/2, 2015 at 8:25 Comment(1)
category is the column nameAbnormity

© 2022 - 2024 — McMap. All rights reserved.