0

I'm using a jqGrid to display orders in my project with the below code, when I try to refresh using the refresh button on the grid, the formatter for column status i.e. function dropdownFormatter() has the rowObject variable as undefined.

Due to this when I'm trying an auto-reload function, the dropdowns, don't get populated with the proper parameter. This problem is solved if I set the jqGrid property "loadonce" as false.

But if the "loadonce" property is set as false, the dropdown select simply does not filter the grid.

jQuery("#list").jqGrid({
                url:'http://192.168.0.7:8000/orders_get_open',
                datatype: "json",
                colNames:['Id','Order No','Address', 'Pincode', 'Phone Number', "Pickup Date", "Pickup Time", "Delivery Date", "Delivery Time", "Status", "Delivery Boys", "Actions"],
                colModel:[
                    {name: 'order_id', index: 'order_id', hidden: true},
                    {name: 'order_no', index: 'order_no', width: 130},
                    {name: 'user_address',index: 'user_address', width: 400, search: false},
                    {name: 'pincode',index: 'pincode', width: 110, search: false},
                    {name: 'user_phone_number',index: 'user_phone_number', width: 180, search: false},
                    {name: 'pickup_date', index: 'pickup_date'},
                    {name: 'pickup_time', index: 'pickup_time'},
                    {name: 'delivery_date', index: 'delivery_date', width: 170},
                    {name: 'delivery_time', index: 'delivery_time', width: 170},
                    {
                        name: 'status', index: 'status', formatter: statusFormatter, stype: 'select', searchoptions: { 
                            sopt: ['eq'], value: ':All;ordered:Ordered;received:Received;laundry_entry:Laundry Entry;laundry_exit:Laundry Exit;delivered:Delivered'
                        }
                    },
                    {name: 'delivery_boys', index: 'delivery_boys', formatter: dropdownFormatter, search: false},
                    {name: '', index:'', formatter: actionFormatter, search: false}
                ],
                width: "1300",
                height: "auto",
                cache: false,
                rowNum:10,
                rowList:[10,20,30],
                pager: '#pager',
                loadonce: true,
                sortname: 'id',
                viewrecords: true,
                sortable: true,
                sortname: "order_no",
                sortorder: "asc",
                caption:"Order Details",                    
            }).jqGrid('navGrid','#pager', {
                edit:false,add:false,del:false, search: false, refresh: true
            }).jqGrid('filterToolbar', {
                stringResult: true, searchOnEnter: false, defaultSearch: "cn" 
            });

function dropdownFormatter(cellValue, options, rowObject) {
            console.info(cellValue, options, rowObject);
            console.log(rowObject.delivery_boy_id);

            var control = "<select class='form-control'><option value>Select</option>";
            $.each(cellValue, function (idx, obj){
                if (obj.id == rowObject.delivery_boy_id) {
                    control += "<option value='" + obj.id + "' selected='selected'>" + obj.name + "</option>";
                } else {
                    control += "<option value='" + obj.id + "'>" + obj.name + "</option>";                            
                }
            });
            control += "</select>";
            return control;
        }

Sample data: https://api.myjson.com/bins/22vo1

jsfiddle for the code: http://jsfiddle.net/76588Lev/1/

Collins
  • 231
  • 2
  • 14
  • Which version of jqGrid and from which fork ([free jqGrid](), [Guriddo jqGrid JS]() or an old jqGrid in version <=4.7) you use? – Oleg Mar 04 '16 at 15:15
  • This is from the script file: * @license jqGrid 4.6.0 - jQuery Grid * Copyright (c) 2008, Tony Tomov, tony@trirand.com – Collins Mar 04 '16 at 15:17
  • The version 4.6 is dead already. I develop [free jqGrid](https://github.com/free-jqgrid/jqGrid). It's the fork of old jqGrid. I fixed many old bugs in free jqGrid and implemented many errors. If I just replace jqGrid 4.6 to free jqGrid 4.13.0 then the code works: http://jsfiddle.net/OlegKi/76588Lev/2/. You can use free jqGrid from CDN for example (see [the wiki article](https://github.com/free-jqgrid/jqGrid/wiki/Access-free-jqGrid-from-different-CDNs)). By the way free jqGrid set additionally `options.rowData` which hold the input data *always* named format (`options.rowData.delivery_boy_id`) – Oleg Mar 04 '16 at 15:23
  • I would recommend you to set `key: true` property in `order_id` column or **remove** the column `order_id` and use `prmNames: { id: "order_id" }`. You can remove `index` property from all columns and make many other small reduction of the code. By the way free jqGrid supports Bootsrtap. See [the demo](http://www.ok-soft-gmbh.com/jqGrid/OK/formEditOnDoubleClick-bootstrap.htm) included in [the readme](https://github.com/free-jqgrid/jqGrid#main-new-features-and-improvements-implemented-in-the-version-4130) – Oleg Mar 04 '16 at 15:26
  • I just tried the fiddle you modified, I am still not able to filter the grid by status. Am I doing something wrong? – Collins Mar 04 '16 at 15:30
  • See also Oleg's older post on http://stackoverflow.com/questions/24384959/jqgrid-rowobject-value-is-undefined – ralf htp Mar 04 '16 at 15:31
  • @Collins: I verified that http://jsfiddle.net/OlegKi/76588Lev/2/ always initialize correctly both `options.rowData` and `rowObject`. I can see all in console.log too. Do you really have some problems with the demo? Which web browser you used for the test? – Oleg Mar 04 '16 at 15:41
  • @ralfhtp: You are right in general, but the input JSON data are already in `repeatitems: false` format. The described problem should not exist here. Moreover I suggested to use free jqGrid 4.13.0 and `options.rowData` instead of `rowObject`. In the case `options.rowData` will have **always** the same format even with XML input data of if JSON `repeatitems: true` format are used. I implemented the feature specially to solve mixed format of `rowObject`. I placed the fixed information in `options.rowData` only to prevent breaking old code which implemented already for mix format of `rowObject`. – Oleg Mar 04 '16 at 15:46
  • @Oleg: The rowObject is returning proper data on refresh, but if you try to filter the grid using the dropdown filter that doesn't work. With the same code if you just turn loadonce to 'true' the dropdown filter works perfectly, but the rowObject returns undefined. Sorry I seemed to have confused you. – Collins Mar 04 '16 at 15:50
  • @Collins: I can't reproduce any problems. I made some bug fixes which I described above, fixed the name of action column from incorrect `name: ''` to `name: 'act'` and used additional options for Bootstrap style of jqGrid. The resulting demo http://jsfiddle.net/OlegKi/76588Lev/4/ uses `loadonce: true` and filtering works. Additionally one can replace actions buttons and follow the answer http://stackoverflow.com/a/29735149/315935 – Oleg Mar 04 '16 at 16:09
  • @Oleg: If you notice, the dropdownFormatter, which selects the appropriate value for the column 'Delivery Boys' depends on the value for rowObject.delivery_boy_id which is undefined in the update4 of your fiddle, and for some reason it is properly accessible in the update2 of your fiddle. From random testing i figured that this happens on toggling the value of loadonce. – Collins Mar 04 '16 at 16:25
  • @Collins: I see now what you mean. jqGrid read only the properties from `colModel`. To fix the problem you should use another feature of free jqGrid. You need add the list of properties of input items which need be read *additional* using new option: `additionalProperties: ["delivery_boy_id"]`: See http://jsfiddle.net/OlegKi/76588Lev/6/ – Oleg Mar 04 '16 at 16:36
  • Thanks. That solved it, could you answer the question so that this might come in handy for someone else. If you feel the question I asked is misleading, can you suggest edits to that? Once again thanks. – Collins Mar 04 '16 at 16:44

1 Answers1

1

You code contains some small problems with the usage of name: '', which is not allowed, the usage of hidden order_id, which you want to use as the id of your data, but where you don't added key: true property or not used jsonReader: { id: "order_id" }. Nevertheless your main problem have another origin. jqGrid reads and saves locally (because of loadonce: true) only the properties of input data, which are used as columns. You try to use delivery_boy_id property, which are not used in colModel. Thus the values will be in rowObject only during initial loading.

I'd recommend you to upgrade to the latest free jqGrid version: 4.13.0 first of all. Free jqGrid is the fork of jqGrid, which I develop after changing the license agreement in version 4.7.1 (see the post) publishes short after publishing 4.7. The name of the product was renamed to Guriddo jqGrid JS. Guriddo jqGrid JS is the commertial product (see the prices here) with the open source. I used jqGrid 4.7 as the starting point and have implemented a lot of new features described in many the wiki articles and the readme to every version, which was published. Free jqGrid is provided under the same licences (MIT and GPLv2) like old versions of jqGrid (till 4.7).

The new features of free jqGrid, which could be helpful for you are the following:

  • you can inform free jqGrid to read additional properties of input data and save there locally. The properties will be available in custom formatters, cellattr and rowattr callbacks and in the local data later (available using getLocalRow method). For example you can remove unneeded hidden order_id column and add the option additionalProperties: ["order_id", "delivery_boy_id"].
  • additionally I would recommend you to add jsonReader: "order_id" and prmNames: { id: "order_id" } option to inform jqGrid to use the property of input data as the value of rowid (the value of id attribute of <tr> elements of the grid).
  • to add forceClientSorting: true option additionally to loadonce: true. It force local sorting and filtering of data before displaying of the first page of data. The option if very practical if you loads the data from third-party source or from the file, where you can't change the sorting order of the data. In case of usage forceClientSorting: true option you need just add sortname and sortorder it specify the column name or the name of additional property by which the data need be sorted.
  • I'd recommend you to remove unneeded index properties from all colModel items.
  • I see that you use Bootstrap and Font Awesome in the grid. I'd recommend you to use the options iconSet: "fontAwesome" and guiStyle: "bootstrap" to have the same look of free jqGrid. If you want to change some colors of jqGrid elements you will need just add some additional CSS rules. See the demo from the readme of the version 4.13.0.

The resulting demo will be modified to the following: http://jsfiddle.net/OlegKi/76588Lev/6/.

I'd recommend you additionally to consider to replace the column with the custom formatter with action buttons to formatter: "actions" with custom buttons. It's one more option of free jqGrid. You can find more details and the corresponding demo in the answer.

Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798