jqGrid - Toolbar search with auto complete from se

2019-08-28 16:40发布

问题:

After reviewing these 2 questions and Oleg great answers

can jqgrid support dropdowns in the toolbar filter fields

jqGrid toolbar search with autocomplete using json data

I am trying to implement this feature with autocomplete of jQgrid toolbar search with json data coming form the server.

My code:

    myGrid.jqGrid({
    url: './WebService.asmx/ViewNQueryData',
    datatype: 'json',
    mtype: 'POST',
    ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },
    serializeGridData: function (postData) {
        if (postData.filters === undefined) postData.filters = null;
        return JSON.stringify(postData);
    },
    jsonReader: {
        root: function (obj) { return obj.d.rows; },
        page: function (obj) { return obj.d.page; },
        total: function (obj) { return obj.d.total; },
        records: function (obj) { return obj.d.records; }
    },
    colModel: columnModel,
    colNames: columnNames,
    rowNum: 10,
    rowList: [10, 20, 300],
    sortname: 'ID',
    sortorder: "asc",
    sortable: true,
    pager: "#ViewNQueryPager",
    viewrecords: true,
    gridview: true,
    height: 250,
    shrinkToFit: true,//If using frozen coulmns change to false.
    grouping: true,
    groupingView: {
        groupField: ['ID'],
        //groupColumnShow: [false],
        //groupText: ['<b>{0} - {1} Item(s)</b>'],
        groupSummary: [true],
        groupOrder: ['asc'],
        groupDataSorted: true,
        showSummaryOnHide: true
    },
    footerrow: true,
    userDataOnFooter: true,
    gridComplete: function () {
        $('#totalRecordsFound').html(myGrid.jqGrid('getGridParam', 'records') + " Customers");
    },
    loadError: function () {
        alert("Error fetching data");
    }
}).jqGrid('navGrid', '#ViewNQueryPager',
                { edit: false, add: false, del: false, search: true, view: true }, //option
                {}, // use default settings for edit
                {}, // use default settings for add
                {}, // delete instead that del:false we need this
                {multipleSearch: true, multipleGroup: true, showQuery: true, onSearch: function (response) { showQueryDetails(); } },
                { height: 250, jqModal: false, closeOnEscape: true} // view options
                );

myGrid.jqGrid('setColProp', 'FirstName',
        {
            searchoptions: {
                sopt: ['cn'],
                dataInit: function (elem) {
                    $(elem).autocomplete({
                        source: './WebService.asmx/ViewNQueryData',
                        minLength: 1
                    });
                }
            }
        });

myGrid.jqGrid('filterToolbar', { stringResult: true, searchOnEnter: true });

But when i type in the search box the request doesnt get to my webService, and i get on exception in the browser, that he is trying to to this:

http://localhost:50949/WebService.asmx/ViewNQueryData?term=p

but :
Failed to load resource: the server responded with a status of 500 (Internal Server Error)

My web service:

public JqGridData ViewNQueryData(int page, int rows, string sidx, string sord, bool _search, string filters)
{

    if (_search && !String.IsNullOrEmpty(filters))
    {
        JavaScriptSerializer serializer = new JavaScriptSerializer();
        jqGridSearchFilter searchFilter =
            serializer.Deserialize<jqGridSearchFilter>(filters);
        // use the searchFilter here
    }
    List<Person> allGridRows = JsonHelper.GetPersons();
    int recordsCount = allGridRows.Count;

    int startIndex = (page - 1) * rows;
    int endIndex = (startIndex + rows < recordsCount) ?
                   startIndex + rows : recordsCount;

    List<TableRow> gridRowsForResponse = new List<TableRow>(rows);
    for (int i = startIndex; i < endIndex; i++)
    {
        gridRowsForResponse.Add(new TableRow()
        {
            id = i,
            cell = new List<string>(3) {
                allGridRows[i].ID.ToString(),
                allGridRows[i].FirstName,
                allGridRows[i].LastName
        }
        });
    }

    return new JqGridData()
    {
        total = (recordsCount + rows - 1) / rows,
        page = page,
        records = recordsCount,
        rows = gridRowsForResponse
    };
}

What am i doing wrong? missing something? Also what do i need to return from the server? the regular JSON that the grid needs?

回答1:

The error is that you use the same URL './WebService.asmx/ViewNQueryData' for both jQuery UI Autocomplete and the the main grid url.

The main grid url should call web method having (int page, int rows, string sidx, string sord, bool _search, string filters) parameters and return the JSON data in the format

{
    "d": {
        "__type": "JqGridData",
        "total": 3,
        "page": 1,
        "records": 24,
        "rows": [
            {"id": 10, "cell": ["1", "Prabir", "Shrestha"]},
            {"id": 20, "cell": ["2", "Scott", "Gu"]},
            {"id": 43, "cell": ["4", "Bill", "Gates"]}
        ]
    }
}

On the other side the web method for the jQuery UI Autocomplete should has only one input parameter term and return back the data in the format like

["Bill", "Scott"]

or

[
    {
        "label": "Crab-Plover",
        "value": "Crab-Plover"
    },
    {
        "id": "Oenanthe isabellina",
        "label": "Isabelline Wheatear",
        "value": "Isabelline Wheatear"
    }
]

See "Datamodel" part of the jQuery UI Autocomplete documentation.

Because you use ASMX web services which wrap the returned JSON data in d property ({d:{...}}) you have to use some additional modifications to provide the data for jQuery UI Autocomplete in one of supported format. For example you can use source parameter of Autocomplete in callback form instead of the simple URL string. See the answer (or this one) for example.