1

I have just moved from jqgrid 3.6.5 to version 4.4.4 of the grid. The problem is that my select lists are not populated with dataUrl option and edittype select. Please see the below figure enter image description here
From the figure you can see that grid has sent two ajax requests to GetManager and GetTerritory but the resultant data is not displayed in select lists. I have added language file, jqgrid.min.js and grid.formedit.js. Below is the code for one of the column models

{ name: 'ManagerId',
                            //sortable: true,
                            index: 'ManagerId',
                            //width: 50,
                            hidden:true,
                            align: 'center',
                            formatter: 'mail',
                            editable: true,
                            edittype: 'select',
                            editoptions: {aysnc:false, dataUrl: '@Url.Action("GetManagers", "Employee")',
                                buildSelect: function (data) {
                                    var response = jQuery.parseJSON(data.responseText);

                                    var s = '<select>';
                                    s += '<option value="0">--No Manager--</option>';
                                    $($.parseJSON(data.responseText)).map(function () {


                                        s += '<option value="' + this.EmployeeId + '">' + this.EmployeeName + '</option>';
                                    });

                                    return s + "</select>";
                                }
                            },
                            editrules: { required: true,edithidden:true },
                            formoptions: { elmsuffix: ' *',label:'Manager' }
                        },

Can anyone suggest what's wrong with it.

Edit 1
server response

[{"EmployeeId":2,"EmployeeName":"Jack"},{"EmployeeId":4,"EmployeeName":"xe"},{"EmployeeId":1001,"EmployeeName":"John"},{"EmployeeId":2000,"EmployeeName":"Jack"},{"EmployeeId":2001,"EmployeeName":"Jill"}]

Response Headers

Cache-Control   private
Connection  Close
Content-Length  203
Content-Type    application/json; charset=utf-8
Date    Thu, 14 Feb 2013 13:20:09 GMT
Server  ASP.NET Development Server/10.0.0.0
X-AspNet-Version    4.0.30319
X-AspNetMvc-Version 3.0

Thanks

Muhammad Adeel Zahid
  • 17,474
  • 14
  • 90
  • 155

1 Answers1

2

First of all I recommend that you examine the type of data parameter inside of buildSelect callback. Depend on some other factors the data could be already object parsed from JSON response. You can just include alert(typeof data.responseText); at the beginning of buildSelect. Alternatively you can use jQuery.isArray to verify whether data parameter is already array of data or one need use jQuery.parseJSON to convert input data to array.

The next problem is that you use jQuery.map instead of jQuery.each. So the code could be about the following

buildSelect: function (response) {
    var data = typeof response === "string" ?
                   $.parseJSON(response.responseText) : response,
        s = "<select>";

    s += '<option value="0">--No Manager--</option>';
    $.each(data, function () {
        s += '<option value="' + this.EmployeeId + '">' + this.EmployeeName +
           '</option>';
    }
    return s + "</select>";
}

You should fix additionally the property aysnc:false of editoptions. Such options is unknown and will be just ignored.

Oleg
  • 220,925
  • 34
  • 403
  • 798
  • Thanks Oleg, you are right the data was actually in `data` instead of `data.responseText`. Is there any batch editing plugin for jqGrid? – Muhammad Adeel Zahid Feb 14 '13 at 17:49
  • @MuhammadAdeelZahid: You are welcome! I don't know what you mean under "batch editing plugin". If you want to edit multiple rows locally and save all changes at once then I would don't recommend you to do this. – Oleg Feb 14 '13 at 17:55
  • by batch editing, I mean user add 4 rows, delete 2, and edit 3. all this happens on client side (in json) and when user clicks the save button, data is persisted to the database only once. – Muhammad Adeel Zahid Feb 14 '13 at 18:01
  • @MuhammadAdeelZahid: I don't recommend to implement such behavior because of possible concurrency errors (modifications of the same data from different computers by different users). Do you have some concurrency control implemented in your current application? I personally use [optimistic concurrency control](http://en.wikipedia.org/wiki/Optimistic_concurrency_control) in all my web applications. – Oleg Feb 14 '13 at 18:10
  • @MuhammadAdeelZahid: See [the answer](http://stackoverflow.com/a/14814507/315935) for example. – Oleg Feb 14 '13 at 18:12
  • I tried to avoid implementing it but it seems to have become the topmost requirement of the client :P – Muhammad Adeel Zahid Feb 14 '13 at 18:12
  • @MuhammadAdeelZahid: Typical client's requirements are performance. quality and user friendly applications. I think that it one develop not one-user application or if the user can edit data which could be accessed or edited at the same time by another user the concurrency control is must to have feature. – Oleg Feb 14 '13 at 18:16
  • ok one more question. how to force select to be loaded from dataUrl each time form is created? – Muhammad Adeel Zahid Feb 14 '13 at 18:22
  • @MuhammadAdeelZahid: You should use `recreateForm: true` option which is default setting in all my productive grids. See [here](http://stackoverflow.com/a/3771744/315935) for example. Additionally you should set correct Cache-Control in the server response from `dataUrl`. – Oleg Feb 14 '13 at 18:26
  • this is true for my popup form as well but the ajax call is sent only once to fetch the select data. for all subsequent CRUD same select is used and no ajax call goes to server – Muhammad Adeel Zahid Feb 14 '13 at 18:27
  • @MuhammadAdeelZahid: I see that HTTP response has `Cache-Control private`. I personally use always "Cache-Control:max-age=0, private". See [the answer](http://stackoverflow.com/a/9269567/315935) if you use ASP.NET. – Oleg Feb 14 '13 at 18:31
  • @MuhammadAdeelZahid: alternatively you can use `ajaxSelectOptions: { cache: false }` (see [the answer](http://stackoverflow.com/a/7422410/315935)), but usage of `Cache-Control: private, max-age=0` is better because it don't increase local cache of web browser. – Oleg Feb 14 '13 at 18:34
  • @MuhammadAdeelZahid: `HttpContext.Current.Response.Cache.SetMaxAge (new TimeSpan (0))` which produce `Cache-Control: private, max-age=0` do perfectly work. I suppose your problem is **previously saved** response with another `Cache-Control`. You should first clear local cache and then reproduce all one more time. – Oleg Feb 14 '13 at 18:37
  • @MuhammadAdeelZahid: Sorry, but the usage of `recreateForm: true` or form editing, setting of HTTP header "Cache-Control:max-age=0, private" and clearing web browser cache from previous experiments is everything what you need to do. I suppose that you made one from the steps incorrect. You should just debug your code and verify that you used all the settings correctly. If you can see that the select don't sent at the second time you should see the reason in the code which you execute: either `$.ajax` will be not executed or the request goes no through network (wrong "Cache-Control"). – Oleg Feb 15 '13 at 09:56
  • Even though I added `ajaxSelectOptions: { cache: false, type: 'POST' }` in grid options but the `buildSelect` is not being called second time the form is created. I have also ensured that `recreateForm` is set to `true`. – Muhammad Adeel Zahid Feb 15 '13 at 10:31
  • @MuhammadAdeelZahid: If you have the demo online I could debug it. Could you include the code which you currently use so that one can see how use set `recreateForm: true` and that you do this before usage of `navGrid`? – Oleg Feb 15 '13 at 10:34
  • after the `jqGrid` definition I am setting recreateform like `}).navGrid('#listPager', { edit: true, add: true, del: true, search: false, refresh: true, recreateForm: true },` – Muhammad Adeel Zahid Feb 15 '13 at 10:35
  • I am doubtful about the location of recreateForm. I think this is the problem – Muhammad Adeel Zahid Feb 15 '13 at 10:36
  • @MuhammadAdeelZahid: You used definitively `recreateForm: true` in the wrong way. It's not options of `navGrid`. It's option of `editGridRow`. I posted you before the reference how it's better to set `recreateForm: true` (see [here](http://stackoverflow.com/a/3771744/315935) one more time. you should use the line *before* `navGrid`). Alternatively you can use `).navGrid('#listPager', { search: false }, {recreateForm: true}, {recreateForm: true});` – Oleg Feb 15 '13 at 10:43
  • Thanks Oleg, it was exactly the problem. Thank you very much :) – Muhammad Adeel Zahid Feb 15 '13 at 10:48