Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
442 views
in Technique[技术] by (71.8m points)

jquery - jqGrid: Multi-word search with global search

Using phpGrid, I have created a single grid with a number of customizations, including a global search similar to Oleg's example here: Universal search field for jqgrid

Now, I am attempting to implement multi-word search (e.g. JQGrid Toolbar Searching: search for multiple words for a column) with the global search, but haven't been able to get it working. Submitting multiple words (i.e. tricolor rat terrier) should search all of these words. Submitting multiple words in quotes (i.e. "rat terrier") should search the exact term.

Note that I have not yet implemented highlighted search terms, however I do plan to.

Code snippet:

    // Add global search
$("#data_toppager_center table tbody tr").append($("<td><div class="fieldcontainer"><input type="text" name="gs" id="gs" class="searchfield" placeholder="Keywords..." tabindex="1"><input type="submit" name="gsbtn" id="gsbtn" value=""></div></td>"));

var $grid = $("#data"); 
$("#gs").keypress(function (e) {
    var key = e.charCode || e.keyCode || 0;
    if (key === $.ui.keyCode.ENTER) { // 13
        $("#gsbtn").click();
    }
});
$("#gsbtn").button({
    text: false
}).click(function () {
    var postData = $grid.jqGrid("getGridParam", "postData"),
    colModel = $grid.jqGrid("getGridParam", "colModel"),
    rules = [],
    searchText = $("#gs").val(),
    l = colModel.length,
    i,
    cm;
    for (i = 0; i < l; i++) {
        cm = colModel[i];
        if (cm.search !== false && (cm.stype === undefined || cm.stype === "text")) {
            rules.push({
                field: cm.name,
                op: "cn",
                data: searchText
            });
        }
    }
    postData.filters = JSON.stringify({
        groupOp: "OR",
        rules: rules
    });
    $grid.jqGrid("setGridParam", { search: true });
    $grid.trigger("reloadGrid", [{page: 1, current: true}]);
    return false;
});
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think that one can relatively easy combine two solutions which I suggested before. The resulting demo allows to make global search (search in any searchable column) for multi-word text (multiple values divided by space separator):

enter image description here

or

enter image description here

The full code which I used in the demo is below:

$(function () {
    "use strict";
    var mydata = [
            { id: "1",  invdate: "2007-10-21", name: "test",   note: "3note",   amount: "200.00", tax: "10.00", closed: true,  ship_via: "TN", total: "210.00" },
            { id: "2",  invdate: "2007-10-22", name: "test2",  note: "3note2",  amount: "300.00", tax: "20.00", closed: false, ship_via: "FE", total: "320.00" },
            { id: "3",  invdate: "2007-09-01", name: "test3",  note: "3note3",  amount: "400.00", tax: "30.00", closed: false, ship_via: "FE", total: "430.00" },
            { id: "4",  invdate: "2007-10-14", name: "test4",  note: "3note4",  amount: "200.00", tax: "10.00", closed: true,  ship_via: "TN", total: "210.00" },
            { id: "5",  invdate: "2007-10-31", name: "test5",  note: "3note5",  amount: "300.00", tax: "20.00", closed: false, ship_via: "FE", total: "320.00" },
            { id: "6",  invdate: "2007-09-06", name: "test6",  note: "3note6",  amount: "400.00", tax: "30.00", closed: false, ship_via: "FE", total: "430.00" },
            { id: "7",  invdate: "2007-10-04", name: "test7",  note: "3note7",  amount: "200.00", tax: "10.00", closed: true,  ship_via: "TN", total: "210.00" },
            { id: "8",  invdate: "2007-10-03", name: "test8",  note: "3note8",  amount: "300.00", tax: "20.00", closed: false, ship_via: "FE", total: "320.00" },
            { id: "9",  invdate: "2007-09-22", name: "test9",  note: "3note9",  amount: "400.00", tax: "30.00", closed: false, ship_via: "TN", total: "430.00" },
            { id: "10", invdate: "2007-09-08", name: "test10", note: "3note10", amount: "500.00", tax: "30.00", closed: true,  ship_via: "TN", total: "530.00" },
            { id: "11", invdate: "2007-09-28", name: "test11", note: "3note11", amount: "500.00", tax: "30.00", closed: false, ship_via: "FE", total: "530.00" },
            { id: "12", invdate: "2007-09-10", name: "test12", note: "3note12", amount: "500.00", tax: "30.00", closed: false, ship_via: "FE", total: "530.00" }
        ],
        $grid = $("#list"),
        initDatepicker = function (elem) {
            $(elem).datepicker({
                //dateFormat: "dd-M-yy",
                autoSize: true,
                changeYear: true,
                changeMonth: true,
                showButtonPanel: true,
                showWeek: true
            });
        },
        numberTemplate = {formatter: "number", align: "right", sorttype: "number",
            editrules: {number: true, required: true},
            searchoptions: { sopt: ["eq", "ne", "lt", "le", "gt", "ge", "nu", "nn", "in", "ni"] }},
        highlightFilteredData = function () {
            var $self = $(this), filters, i, l, rules, rule, iCol,
                isFiltered = $self.jqGrid("getGridParam", "search"),
                postData = $self.jqGrid("getGridParam", "postData"),
                colModel = $self.jqGrid("getGridParam", "colModel"),
                colIndexByName = {};

            // validate whether we have input for highlighting
            if (!isFiltered || typeof postData !== "object") {
                return;
            }
            filters = $.parseJSON(postData.filters);
            if (filters == null || filters.rules == null || filters.rules.length <= 0) {
                return;
            }

            // fill colIndexByName which get easy column index by the column name
            for (i = 0, l = colModel.length; i < l; i++) {
                colIndexByName[colModel[i].name] = i;
            }

            rules = filters.rules;
            for (i = 0, l = rules.length; i < l; i++) {
                rule = rules[i];
                iCol = colIndexByName[rule.field];
                if (iCol !== undefined) {
                    $self.find(">tbody>tr.jqgrow>td:nth-child(" + (iCol + 1) + ")").highlight(rule.data);
                }
            }
        };

    $grid.jqGrid({
        datatype: "local",
        data: mydata,
        colNames: ["Client", "Date", "Amount", "Tax", "Total", "Closed", "Shipped via", "Notes"],
        colModel: [
            { name: "name", width: 65, editrules: {required: true} },
            { name: "invdate", width: 80, align: "center", sorttype: "date",
                formatter: "date", //formatoptions: { newformat: "d-M-Y" },
                searchoptions: { sopt: ["eq", "ne", "lt", "le", "gt", "ge"], dataInit: initDatepicker } },
            { name: "amount", width: 75, template: numberTemplate },
            { name: "tax", width: 52, template: numberTemplate },
            { name: "total", width: 60, template: numberTemplate },
            {name: "closed", width: 70, align: "center", formatter: "checkbox",
                edittype: "checkbox", editoptions: {value: "Yes:No", defaultValue: "Yes"},
                stype: "select", searchoptions: { sopt: ["eq", "ne"], value: ":Any;true:Yes;false:No" } },
            {name: "ship_via", width: 105, align: "center", formatter: "select",
                edittype: "select", editoptions: { value: "FE:FedEx;TN:TNT;IN:Intim", defaultValue: "IN" },
                stype: "select", searchoptions: { sopt: ["eq", "ne"], value: ":Any;FE:FedEx;TN:TNT;IN:Intim" } },
            { name: "note", width: 60, sortable: false, search: false, edittype: "textarea" }
        ],
        rowNum: 10,
        rowList: [5, 10, 20],
        toolbar: [true, "top"],
        pager: "#pager",
        gridview: true,
        rownumbers: true,
        autoencode: true,
        ignoreCase: true,
        sortname: "invdate",
        viewrecords: true,
        sortorder: "desc",
        shrinkToFit: false,
        height: "100%",
        caption: "Demonstrate how to implement global multi-word searching (with blank separator)",
        loadComplete: function () {
            highlightFilteredData.call(this);
        }
    }).jqGrid("navGrid", "#pager", {add: false, edit: false, del: false, search: false});

    // fill top toolbar
    $('#t_' + $.jgrid.jqID($grid[0].id))
        .append($("<div><label for="globalSearchText">Global search in grid for:&nbsp;</label><input id="globalSearchText" type="text"></input>&nbsp;<button id="globalSearch" type="button">Search</button></div>"));
    $("#globalSearchText").keypress(function (e) {
        var key = e.charCode || e.keyCode || 0;
        if (key === $.ui.keyCode.ENTER) { // 13
            $("#globalSearch").click();
        }
    });
    $("#globalSearch").button({
        icons: { primary: "ui-icon-search" },
        text: false
    }).click(function () {
        var postData = $grid.jqGrid("getGridParam", "postData"),
            colModel = $grid.jqGrid("getGridParam", "colModel"),
            rules = [],
            searchText = $("#globalSearchText").val(),
            l = colModel.length,
            separator = ' ',
            searchTextParts = $.trim(searchText).split(separator),
            cnParts = searchTextParts.length,
            i,
            iPart,
            cm;
        for (i = 0; i < l; i++) {
            cm = colModel[i];
            if (cm.search !== false && (cm.stype === undefined || cm.stype === "text")) {
                for (iPart = 0; iPart < cnParts; iPart++) {
                    rules.push({
                        field: cm.name,
                        op: "cn",
                        data: searchTextParts[iPart]
                    });
                }
            }
        }
        postData.filters = JSON.stringify({
            groupOp: "OR",
            rules: rules
        });
        $grid.jqGrid("setGridParam", { search: true });
        $grid.trigger("reloadGrid", [{page: 1, current: true}]);
        return false;
    });
});

UPDATED: To allow to use quoted strings with spaces in the global searching string you can use match instead of split. The modified demo allows to use the following

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...