1

As far as I see, free-jqgrid uses jlinq to filter and search data. I am making my own filters, that are using grids postData in it's well-known format:

{ "groupOp": "AND",
      "groups" : [
        { "groupOp": "OR",
            "rules": [
                { "field": "name", "op": "eq", "data": "England" },
                { "field": "id", "op": "le", "data": "5"}
             ]
        }
      ],
      "rules": [
        { "field": "name", "op": "eq", "data": "Romania" },
        { "field": "id", "op": "le", "data": "1"}
      ]
}

This data converted internally to jlinq query. Are there any public functions to get current query for grid? I also see there is a private possibility to get it in sql-like format.

I want to use as much as possible of default jqGrid functionality, but didn't find anything. Any hints are appreciated.

UPDATE 2:

Here comes fiddle with current implementation. I needed to adopt it, so some ugly parts are there, but you can filter on values, to get the idea. First, play with the grid, cause code is awful (that's why I want to change it, really :))

So, main idea:

  1. We modify filter values to a well-known rules and groups.

  2. We go through all the columns, remove rules and groups for this column name and we filter the data. Here comes my question part: I need to filter the data, but not the grid, just a data to get unique values. Right now I generate a regex from postData and subset grid data by plain javascript. You can see this in getDistinctColumnValues and I want to use some grid filtering possibilities to make it work the same way as all the opts working when we make filtering/searching with postData set.

Also, I've seen some internal function to get filters as a sql-where - this also would be nice for backend prototyping.

freeek
  • 985
  • 7
  • 22

1 Answers1

1

Sorry, but I'm not sure what you need to implement. You can get lastSelectedData parameter to have the array of filtered and sorted data, based on the current filter. The full data are available via lastSelectedData parameter. The filters property of postData parameter gets you the current filter.

You asked "are there any public functions to get current query for grid?". You can use getGridParam method to get current query. I guess, that you want to get access to some internal structures close to jlinq, but it gives really no practical value. You can access the class via $.jgrid.from, but it's not really helpful. Practical one needs only to set new filter in postData.filters parameter, set search parameter to true and call .trigger("reloadGrid") to reload grid with new data.

If you need to filter or to sort some data yourself, then array methods filter and sort will be more effective. If the above information don't help you to solve your problem, please append your question with additional information, which describes the problem more detailed on an example and post me small comment.

Updated: I'm still not sure that I exactly understand what you want to implement. It seems to me that the most functionality of your JSFiddle demo can be removed if you use some free jqGrid options.

Look at https://jsfiddle.net/OlegKi/wqxyo579/25/, which used

colModel: [
    { name: 'name' },
    { name: 'surname' },
    { name: 'age' },
],
cmTemplate: {
    width: 100,
    autoResizable: true,
    stype: 'select',
    searchoptions: {
        generateValue: true,
        noFilterText: "(All)"
    }
},

It sets some default property on every column. Starting with version 4.14.0 free jqGrid supports generateValue: true property of searchoptions for columns having stype: 'select' (see here). Internally it works like another option of colModel: createColumnIndex: true, which generates the map from unique values in all columns having createColumnIndex: true. One can use getUniqueValueFromColumnIndex method to get the index for any column (like var indexName = $("#list").jqGrid("getUniqueValueFromColumnIndex", "name");). If one uses stype: 'select', searchoptions: { generateValue: true }, then filterToolbar build automatically <select> elements using the index. jqGrid uses internally oSv = $("#list")[0].generateValueFromColumnIndex(cmName, sep, delim); (see here). As the result, one can save a lot of customization using the feature.

The only thing, which one should don't forget in case of using createColumnIndex: true or generateValue: true: the index will be build after the data is loaded or reloaded. So one should call filterToolbar after filling the data. If you load the data from the server with respect of loadonce: true option, then you should call filterToolbar better inside of loadCompleted callback (like in the demo). In case of direct loading of local data it's not needed. Just call filterToolbar after filling the data.

Another alternative would be to use <datalist> instead of <select>. It allows to use <input> in the filter toolbar, but have functionality close to select or select2. See https://jsfiddle.net/OlegKi/wqxyo579/24/, where I used createColumnIndex: true, searchoptions: { sopt: [ "cn", "eq", "bw", "ew", "bn", "nc", "en" ], clearSearch: true, generateDatalist: true }. Datalists are implemented in different web browsers in a little different way and they have some disadvantages, but it's native implemented feature and so it works very quickly. One can use it with for example 1000 unique values and 10000 rows in the grid (I'd strictly recommend to use local data paging in the case and to use page size 10-25). Datalists with 1000 elements will still have good performance, much better as select2 for example.

Final remark. I see that you built colModelIndexesByNames to find column by name. The built-in parameter iColByName already exist in free jqGrid and be used internally. If p is reference to parameters of jqGrid (var p = $("#list").jqGrid("getGridParam")), then p.iColByName is the map, which gets column index by column name and p.colModel[p.iColByName.name] will represent the item in colModel, which corresponds "name" column.

Oleg
  • 220,925
  • 34
  • 403
  • 798
  • Yes, I will make you tomorrow a small example with sample data, filters and SQL queries – freeek Sep 02 '19 at 21:52
  • tried to make it as clear as possible, but not too overload with current code. – freeek Sep 03 '19 at 08:59
  • @freeek: Sorry, for late answer. I still can't follow you because of many reasons. 1) all your examples don't contains grid or grid data. It's difficult to understand, which relations has examples with two selects to grid. 2) you use SQL statements, which executed **on the server side**. Filters of jqGrid works **on client side**. Moreover, it does never `SELECT DISTINCT age FROM names WHERE name = "Oleg"` of `SELECT DISTINCT name FROM names;`. jqGrid makes `SELECT id` always with some complex `WHERE`. – Oleg Sep 04 '19 at 20:38
  • @freeek: So it could be reduced to `Array.filter` applied on input `data` with the corresponding callback function, which corresponds the `WHERE`. You wrote that you **want to use some grid filtering possibilities**. I still don't understand why you want to use it (because I see no advantage in usage of `$.jgrid.from` comparing with `Array.filter`. Probably it's because you posted no jqGrid code, which you use. By the way, usage vue, anguler or other is possible and all above still take place. I see you are from St. Petersburg. You can write me email in Russian where you explain the problem. – Oleg Sep 04 '19 at 20:45
  • I just need to know, if I can modify postData's filters and perform a search on grids data, but do not change it, so that the grid stays in a same state. All my examples here are internal calculations and sql here is an example of what I am trying to accomplish on a client side. – freeek Sep 05 '19 at 04:15
  • @freeek: If you set `filters` property of `postData` parameter to new value, set `search` to `true`, optionally set `page` parameter and call `.trigger("reloadGrid")` then jqGrid find ids of rows of the page of filtered and sorted data and display new results. Like in code [here](https://stackoverflow.com/a/50691924/315935), but using `p.postData.filters = JSON.strinfify({...});` and `p.search: true` instead of `p.data = data;`. If you would post the fragment of the code, which you tried, then I could fix it. – Oleg Sep 05 '19 at 06:06
  • This is the problem, I don't want to reload grid, I need to go through `posData` in a loop, modify it, apply and make some calculations with filtered data. Then modify `postData` once more and only then `reloadGrid`. My code is working, as I manually convert `postData` to a regexp to make this in between calculations. – freeek Sep 05 '19 at 07:07
  • @freeek: What you need to modify? The `filters` of `postData` or the `data`, which corresponds the filter? I still don't understand what kind of calculations you mean. If you need to modify `filters` every time **before** applying, then you can use corresponding callbacks of jqGrid. I still suppose that you goes in wrong direction with filters. So I suggest you to explain the problem on an **example** of jqGrid, which you use. Many years before I posted [the answer](https://stackoverflow.com/a/8953934/315935), where I used close scenario, like youth. Later version free jqGrid don't need that. – Oleg Sep 05 '19 at 07:26
  • @freeek: I'd recommend you to take look on `customSortOperations` and `customUnaryOperations` options (see [here](https://stackoverflow.com/a/55424857/315935), [here](https://stackoverflow.com/a/29676941/315935) and other), which allows to define new custom operation, which can be used in `postData.filters` and be visible for user on both filterToolbar and advanced searching dialog like build-in operations. Additionally, I remind, that "in" operation is supported. `inFilterSeparator` option can be used to redefine default `,` separator, used in data for `in` operation, to another one. – Oleg Sep 05 '19 at 07:37
  • Problem is, that current implementation has 500 lines, that need to be adopted to make an example. I replace filters in a toolbar with my own drop-downs. After each filtering operation on a client, depending on a possible combinations, set on another filters, I rebuild them. This is quite a specific thing, my `sql` statements are for getting `filter` values, not grids data. Switching to Russian won't help :) My main aim is to have an ability to get an `array` of filtered grids data, not the data to be displayed, but a possible one, to get all unique fields values on filtered data. – freeek Sep 05 '19 at 08:45
  • Thanks for your patience, @Oleg, I will try to make a full working example, with comments in my code, just to finish this discussion :) I hope, you are right, and I just did it too complex. – freeek Sep 05 '19 at 08:48
  • @freeek: You are welcome! The demo would explains everything. You wrote "My main aim is to have an ability to get an array of filtered grids data, not the data to be displayed". You can get the parameter `lastSelectedData` and compare it with `data`. `lastSelectedData` contains **full** array (not only one page) of data filtered by `postData.filters` and sorted based on `sortname` and `sortorder` parameters. So `lastSelectedData` seems provide what you need (see beginning of my answer). – Oleg Sep 05 '19 at 15:44
  • @freeek: I appended my answer with additional information. – Oleg Sep 08 '19 at 16:48
  • That's what I am talking about: a lot can be simplified! Thank you. Can I put some more comments later here, if I will need some help? – freeek Sep 08 '19 at 21:19
  • @freeek: You are welcome! Of cause you can continue to post comments. I'll try to help you if I could. – Oleg Sep 08 '19 at 21:22