0

I am using jqGrid with localArray data. I am fetching this array from azure db and binging to grid. After this on manipulation of every single row, I am planning to update it in DB.

I am using inline navigation bar. On clicking of "add row", "save row" & "delete row" button I want to call my custom function and then would like to save/delete data in DB from that function.

First I would like to know whether my design is correct and scalable or not.

At present, I am able to call custom function on click of save button using "aftersavefunc" parameter.

Second, please let me know which parameter I have to set for "delete row" button. I think for "add row", same parameter can work as we have to click "save row" button to save row.

My code is as below for reference :

jQuery("#list4").jqGrid({
    datatype: "local",
    data: myData,
    height: "auto",
    colNames: ['RowNo', 'RouteId', 'Area'],
    colModel: [
        { name: 'id', index: 'id', width: 50, sortable: false },
        { name: 'RouteId', index: 'RouteId', width: 50, sortable: false },
        { name: 'Area', index: 'Area', width: 130, sortable: false, editable: true, editrules: { required: true} },
    ],
    multiselect: false,
    rownumbers: false,
    rowList: [10, 20, 30],
    pager: jQuery('#pager1'),
    viewrecords: true,
    caption: "Bus Schedule Data",
    editurl: "clientArray",
    restoreAfterSelect: false,
    loadonce: true
});
var rowid;
var inlineparams = {
    addParams: { useFormatter: false },
    editParams: {
        aftersavefunc: function (id) {
            var rowData = jQuery('#list4').jqGrid('getRowData', id);
            ScheduleTable.update({ id: 1, Area: rowData.Area.toString() });
        }
    },
    add: true,
    edit: true,
    save: true,
    cancel: true,
    del: true
};

jQuery("#list4").jqGrid('navGrid', "#pager1", { edit: false, save: false, add: false, cancel: false, del: false });
jQuery("#list4").jqGrid('inlineNav', "#pager1", inlineparams);
jQuery("#list4").jqGrid("saveRow", id, {
    keys: false,
    url: "clientArray"
});
Oleg
  • 220,925
  • 34
  • 403
  • 798
Mohit
  • 39
  • 1
  • 2
  • 10

1 Answers1

2

inlineNav method don't have option del which you use (see inlineparams). You have to use remove del: false option of navGrid to have Delete button implemented by form editing (see delGridRow method).

I personally find the usage of inline editing with saving the data in the database inside of aftersavefunc not the best way. You will have problems with implementing of error handling using such approach because the changes in the grid will be first saved locally and then you will try to update the data in the database. If you will have some kind of errors during saving (validation errors, concurrency errors and so on) you will have to restore the previous state of data in the grid. So you have to save the previous state (inside of oneditfunc callback for example) and then restore the old data if required.

So I recommend you from design point of view to change datatype: "local" and editurl: "clientArray" to original Ajax based versions.

If you would use standard way which suggest jqGrid you could communicate with the server per Ajax. In the case the backend could return error description and the user will be able to modify current editing data and try to save there again. What you need is just implementing some server component (ASP.NET Web API service, ASP.NET WCF service, ASP.NET MVC controller, ASMX WebService, ASHX handler etc). All the technologies (even the oldest one like ASMX WebService and ASHX handler) can be used with Windows Azure.

If you do decide to follow your original way you can implement Delete using form editing. I described here originally the way how to implement it in case of editurl: "clientArray". In the answer I posted the way how full set of form editing operations can be used with local data. Another answer contains updated code which work with the current version (4.4.1 and 4.4.4) of jqGrid. I recommend you to use delSettings from the last answer. The onclickSubmit callback of delSettings do all needed for local saving of data.

Small common remarks to your code:

  • I find strange the usage of both id and RouteId in one grid. Probably id is not needed at all and you can add key: true as additional property to RouteId if it is real unique id from the database in your case
  • You can remove index property from all columns becaus the values which you use are the same as the values of name property.
  • You can remove sortable: false (or both width: 50 and sortable: false) from colModel and use instead of that cmTemplate: {sortable: false} (or cmTemplate: {width: 50, sortable: false}). See here for more information.
  • You can remove multiselect: false, rownumbers: false and restoreAfterSelect: false options of jqGrid. The first two have default values (see "Default1" column in the table withe the list of options). The last option (restoreAfterSelect: false) is the option of inlineNav so it should be used, if it's needed, inside of inlineparams.
  • You should replace pager: jQuery('#pager1') to pager: '#pager1'. jqGrid need to have pager as id selector. If you provide input parameter in another form jqGrid detect the error and replace to the #pager1
  • I recommend you use gridview: true options in all your grids to improve performance without any other disadvantages (see the answer for details)
Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • Thanks a lot oleg for putting up such a nice analysis. I would really like to move to Ajax based version instead of local array version. But there is a complexity in my scenario. I have a mobile service hosted on azure and my web site is hosted under azure web services. I am using my mobile service data from my azure web service. Now If I go through Ajax based version, I have to open a service end point on azure web service and that will make a call to data table hosted under azure mobile services. So it will be again an indirect call to database. – Mohit Apr 06 '13 at 14:48
  • With this indirect call, would it be able to provide benefits which you are mentioning? Just brainstorming....let me know if you have some suggestion on this. – Mohit Apr 06 '13 at 14:49
  • @Mohit: You are welcome! All sounds good. If you use some URLs in jqGrid then processing work *asynchronously* so the data in the grid will be loaded/saved/updated after the called web method successfully responds. So I think that you could better use server side processing of editing (see [here](http://stackoverflow.com/a/3918615/315935)). For loading of data you can use `datatype: "json"` together with `loadonce: true`. – Oleg Apr 06 '13 at 14:58
  • I digged down more on azure web service configurations to move my application to ajax based version as you have suggested. I found that azure web services provide Rest end points (http://msdn.microsoft.com/en-us/library/windowsazure/jj710104.aspx) for data access/updates. In this case, I think I do not need to expose explicit Web API service as I am looking for only simple CRUD operations. Please share your thoughts on same. Do you feel I still need to expose Web API endpoints? – Mohit Apr 07 '13 at 15:48
  • @Mohit: Of cause the most databases provide built-in web services mostly as RESTfull, but the problem is frequently that that access is OK only for administrative purpose and not for building user GUI. The first problem is authentication. If you build your own web service it can access to the database with *one* account which has enough right to do all operations. You can have external user account database with application specific permissions. So you can allow uses *modify only specific rows* of one table and filter all other data for the user. – Oleg Apr 07 '13 at 16:10
  • I agree with you here but my scenario is 80% around administrator only. So I am planning to take two step approach for quick delivery of application. I will first make it available for administrators with Rest API's. With this, I will be able to learn to use jqGrid as per needs. After that, I will expose more WCF endpoints for custom needs. – Mohit Apr 07 '13 at 17:35
  • I have one doubt with ajax implementation. I could find that "url" parameter need to be defined as "https://.azure-mobile.net/tables/" to fetch data to populate grid. But I need to add request header "X-ZUMO-APPLICATION". To accomplish this, I think I have to make a httprequest with proper headers in a function and need to set reference of that function in some parameter of jqGrid to load data. Can you point out how is it possible to achieve? – Mohit Apr 07 '13 at 17:45
  • @Mohit: The questions are far from your original question. I think that you should ask *new* question with the description of the problem. Moreover you should describe whether JSON or JSONP need be used. If URL with your HTML page, where jqGrid be used, starts with `https://.azure-mobile.net`? – Oleg Apr 07 '13 at 18:07
  • Sure...I have initiated a new question at "http://stackoverflow.com/questions/15866383/jqgrid-with-ajax-data-json-how-to-call-custom-function-to-load-data-instead". mentioned all details as you have asked – Mohit Apr 07 '13 at 18:50