0

We're using jqGrid to display an interactive list on our site. We have an access layer file for ajax data calls for this list - it receives parameters in a specific format and returns JSON results. This access layer expects url parameters functionName and functionParams (a json collection of parameters).

We're offering inline edit and delete functionality in our grid, but the problem is that you can only set one single URL for both.

So really, we need the edit URL to look something like this:

editurl: 'ListAjaxAccess.cfm?functionName=editMember&functionParams={"id":"341","firstName":"John","lastName":"Smith"}'

And the delete URL to look something like this:

editurl: 'ListAjaxAccess.cfm?functionName=deleteMember&functionParams={"id":"341"}'

However, you can only set one URL for both inline edit and inline delete using editurl, which posts the form to the page along with an "oper" param to differentiate. I can't seem to find a way to access the oper param, or the form values, when defining editurl so that I can build the url dynamically.

The only way around this that I can see is to create another file inlineListProcessing.cfm, set editurl to that instead, and that file will just construct the proper format and invoke ListAjaxAccess. I would prefer not to create an extra in-between file - are there any other options? Is there any way to either call different urls or to build the url string dynamically based on the operation?

froadie
  • 79,995
  • 75
  • 166
  • 235
  • I see many ways to solve your problem. It's important to know **which version of jqGrid you use and which fork?** ([free jqGrid](https://github.com/free-jqgrid/jqGrid) - the fork which I develop, commercial [Guriddo jqGrid JS](http://guriddo.net/?page_id=103334) or some old version of jqGrid in version <=4.7). It's additional important to know **how you use inline editing and delete** (`formatter: "actions"`, `inlineNav` and so on). If you don't use free jqGrid then the implementation will depend on how exactly you use inline editing and delete. – Oleg Oct 23 '15 at 08:26
  • @Oleg - I think we're using free jqGrid, version 4.6 – froadie Oct 23 '15 at 11:18
  • @Oleg I am new to jqGrid (I'm editing a grid someone else put together), so not sure which code you need to see. But this is the last entry in colModel for the actions column: `{ label:'', name: '', search: false,width:60, fixed:true, sortable:false, resize:false, formatter:'actions',formatoptions:{keys:true}}` – froadie Oct 23 '15 at 11:23
  • **Do you need to use HTTP GET or HTTP POST in the requests?** Placing of parameter in URL is typical for HTTP GET requests only, but one use HTTP POST, HTTP PUT or HTTP PATCH typically for edit request and place the parameters inside of **body** of the HTTP request. – Oleg Oct 23 '15 at 14:00
  • @Oleg - need to use a GET. In the URL format detailed in the question – froadie Oct 23 '15 at 14:05
  • I modified my answer and added appended it with additional information. – Oleg Oct 23 '15 at 14:37

1 Answers1

0

It's a little strange that you need to use HTTP POST, but place the parameters in URL. The parameters in URL will be used typically only in HTTP GET requests, but HTTP GET will be typically cached (in it's not prohibited by HTTP headers). In any way everything is possible.

I'll start with Delete. It's important to understand that formatter:'actions' uses form editing delGridRow internally, which options and callbacks are described here. The option url specify the URL used in the Ajax request and mtype option can be used to specify HTTP method. Default is mtype: "POST". To make dynamic URL you can use for example onclickSubmit callback, which first parameter (options) is the reference to internal options of delGridRow. You can modify the url property of options and then jqGrid will use modified URL in the Ajax request which will be send to the server. It's important to understand that the main goal of onclickSubmit is extending the postdata with additional information. One should return empty object {} if no additional data need be send. The second parameter of onclickSubmit is the id or comma-separated list of ids (if you use multiselect: true). I suppose that you don't use multiselect: true option and need delete one row only. The resulting code of onclickSubmit callback will be the following:

onclickSubmit: function (options, rowid) {
    options.url = "ListAjaxAccess.cfm?functionName=deleteMember&functionParams=" +
            JSON.stringify({id: rowid});
}

If you would use free jqGrid than the place where you can set the callback very easy. See the article. You can include jqGrid option formDeleting with the property:

formDeleting: {
    onclickSubmit: function (options, rowid) {
        options.url = "ListAjaxAccess.cfm?functionName=deleteMember&functionParams=" +
                JSON.stringify({id: rowid});
    }
}

Now any call of Delete row method delGridRow will use the callback (inclusive formatter: "actions").

If you have to use old jqGrid 4.6 and you use formatter: "actions", then you should exactly examine the options of formatter: "actions" here. The corresponding changes in your code will be inside of column which defines formatter: "actions". First of all you should never use name: ''. The name of every column should corresponds to rules of id in HTML and the values have to be unique. You can use something like

{
    formatter: "actions",
    formatoptions: {
        delOptions: {
            onclickSubmit: function (options, rowid) {
                options.url = "ListAjaxAccess.cfm?functionName=deleteMember&functionParams=" +
                        JSON.stringify({id: rowid});
            }
        }
    }
}

Now back to the second problem: setting dynamic URL of inline editing. It could be relatively tricky because as I wrote placing of parameters in URL is absolutely untypical for HTTP POST. One can use beforeSaveRow callback to modify the URL dynamically, but the options of the callback don't have the results of modification. So you should confirm that you really require to have the data as parameters of URL and placing the same data in the body of HTTP POST is not an option for you.

UPDATED: If you need to use HTTP GET for inline editing then you should first add the code

$.jgrid = $.jgrid || {};
$.jgrid.inlineEdit = $extend(true, $.jgrid.inlineEdit, {mtype: "GET"});

somewhere at the beginning of your code. It changes the default HTTP method used for inline editing from "POST" to "GET". It's required because formatter: "actions" of old jqGrid 4.6 version have no possibility to specify mtype option of inline editing. In free jqGrid one can use mtype: "GET" inside of formatoptions property of formatter: "actions" or alternatively inside of inlineEditing option of jqGrid: inlineEditing: { mtype: "GET" }.

To make custom formatting of parameters of inline editing one can use serializeRowData callback of jqGrid (see here):

editurl: "ListAjaxAccess.cfm",
serializeRowData: function (postData) {
    return {
        functionName: "editMember",
        functionParams: JSON.stringify(postData)
    }
}

To use HTTP GET for Delete you can add mtype: "GET" option to delOptions described above. Alternatively you can use another form:

{
    formatter: "actions",
    formatoptions: {
        delOptions: {
            mtype: "GET",
            serializeDelData: function (postData) {
                return {
                    functionName: "deleteMember",
                    functionParams: JSON.stringify({id: postData.id});
            }
        }
    }
}

Both Edit and Delete will use editurl: "ListAjaxAccess.cfm", but there will use different URL parameters.

I have to remark that HTTP GET will be cached in web browser by default. To be sure that one don't use caching I recommend you to set Cache-Control: private, max-age=0 HTTP header in the server response on the URL.

Oleg
  • 220,925
  • 34
  • 403
  • 798
  • Wow. Thanks for the long detailed answer. I'm going to play around with these options. – froadie Oct 25 '15 at 07:18
  • @froadie: You are welcome! I hope it will help you to solve the problem. – Oleg Oct 25 '15 at 08:11
  • @Oleg there is no documentation about what to put in the `delOptions` on this page http://www.trirand.com/jqgridwiki/doku.php?id=wiki:predefined_formatter#predefined_format_types . Do you know what options are available ? – singe3 Nov 18 '15 at 08:05
  • @singe3: It's important to distinguish the options of some *methods*, which be called indirectly, from the options of jqGrid. `formatter: "actions"` just creates buttons and some methods like `editRow`, `saveRow`, `editGridRow` and `delGridRow` will be called if the user clicks on the corresponding botton. The `formatoptions.delOptions` allows to specify **any option or callback of `delGridRow` method**, which described [here]((http://www.trirand.com/jqgridwiki/doku.php?id=wiki:form_editing#delgridrow)). – Oleg Nov 18 '15 at 08:13
  • @singe3: Specifing the options of `formatter: "actions"`, `navGrid` or `inlineNav` is difficult to understand. I described the problem and the solution, implemented in [free jqGrid](https://github.com/free-jqgrid/jqGrid), in [the wiki article](https://github.com/free-jqgrid/jqGrid/wiki/New-style-of-usage-options-of-internal-methods). I recommend you to read there together with [the answer](http://stackoverflow.com/a/29735149/315935) and [the demo1](http://www.ok-soft-gmbh.com/jqGrid/OK/CustomActionButton.htm) and [the demo2](http://www.ok-soft-gmbh.com/jqGrid/OK/CustomActionButton1.htm). – Oleg Nov 18 '15 at 08:18