jqueryjqgridtreegrid

jqGrid TreeGrid not send additional data to server


I have a jqGrid Treegrid defined as below:

$('#MyGrid').jqGrid({
    colNames: ['Id','Nome','Nivel','Combo',''],
    colModel: [
        { hidden: true, name: 'Id' },
        { editable: true, name: 'Nome' },
        { hidden: true, name: 'Nivel' },
        { name: 'Combo', editable: true, edittype: 'select',
            editoptions: {
                buildSelect: createSelectList ,
                dataUrl: '/Home/GetCombo' // <-- to this controller, I want
                    // to send the id of the row edited to load custom items
                    // in select object
            }}, 
        { formatter: 'actions', formatoptions: { keys: true },
            resizable: false, search: false, sortable: false,
            width: 60, viewable: false, name: 'actions' }
    ],
    cellEdit: true,
    url: '...',
    datatype: 'json',
    editurl: '...',
    jsonReader: {
        repeatitems: false,
        id: 'Id',
        subgrid: { repeatitems: false }
    }, 
    mtype: 'POST',
    gridComplete: function() { myOnGridComplete(); },
    ajaxSelectOptions: {
        data: {
            tempid: function () {
                // !!! the next line always returns null
                return $('#MyGrid').jqGrid('getGridParam', 'selrow');
            }
        }
    }, 
    prmNames: { npage: 'npage' }, 
    rowNum: -1,
    ExpandColClick: true,
    ExpandColumn: 'Nome',
    treeGrid: true,
    treeGridModel: 'adjacency',
    width: 700,
    height: '100%'
});

My goal is to send the current row ID to the server, but when I use $('#MyGrid').jqGrid('getGridParam', 'selrow') I always get a null value.

I already read this posts but none of them solve my problem:

Any sugestions?

tks in advance!

Update 1:

The TreeGrid bind is ok. The real problem is when I click the Edit Button in the leaf node. In this event, I want to send additional data to the server.

I tried to accomplish this using the ajaxSelectOptions, but this command always returns null: $('#MyGrid').jqGrid('getGridParam', 'selrow')

Workaround

This is a workaround that I did before Oleg's help:

Step 1: Create a hidden field in the HTML

Step 2: In my myOnGridComplete function, I set a click event to the edit button:

function onGridAjusteDTOComplete()
{
    $('#MyGrid').find('span.ui-icon-pencil').each(function() {
        $(this).click(function(){
            var rowID = $(this).parents('tr').attr('id');
            // !!! the next commented line not work in my case
            // $('#MyGrid').jqGrid('setSelection', therowid );
            $('#myHiddenField').val(rowID); // <-- this works
        });
    });
}

Step 3: Get the rowID from the hidden field in the ajaxSelectOptions:

ajaxSelectOptions: "{type: 'GET', contentType: 'application/json; charset=utf-8',dataType: 'json',cache: false, async:false, data: {id: function () { return $('#myHiddenField').val(); }}}"

Solution

See the solution provided by Oleg below. It's just amazing. Thank you Oleg.


Solution

  • I am not sure that I understand your problem correctly. TreeGrid send automatically the id of parent node during loading of children nodes. See the documentation about nodeid, parentid, n_level parameters which will be send to the server. So I don't understand why you could need to send the id of the currently selected row (selrow) additionally to the server.

    UPDATED: Now I understand the reason of the problem which you describe. It's really interesting problem which could have other people.

    The real solution would be to change the code of jqGrid to support some callback function which could construct the data parameter used in $.ajax call which build <select>. The simplest modification of the original code of jqGrid will be to insert the line

    var rowid = $.jgrid.stripPref($t.p.idPrefix,
            String(options.id).substring(0, String(options.id).length - String(options.name).length - 1));
    

    before the line line of code where $.ajax with dataUrl will be called. Additionally one need to add one more parameter in the $.ajax:

    data: $.isFunction(ajaxso.postData) ?
        ajaxso.postData.call($t, rowid, String(options.name), vl) :
        ajaxso.postData,
    

    After such changes one will be able to use

    ajaxSelectOptions: {
        postData: function (rowid, colName, value) {
            return { id: rowid };
        }
    }
    

    The demo demonstrate that the approach work. You could see in Fiddler, Firebug or in Developer Tools that the option id will be really send to the URL. I'll post the corresponding suggestion to trirand later (I want to make some additional improvements for more common case)

    If you need to implement the solution with the current version of jqGrid you can do the following instead. You can "subclass" the method $.jgrid.createEl which do the $.ajax request. The implementation will also simple enough:

    var originalCreateEl = $.jgrid.createEl,
        createElementOptions;
    
    $.extend($.jgrid, {
        createEl: function (eltype, options, vl, autowidth, ajaxso) {
            if (options.dataUrl) {
                createElementOptions = options;
            }
            return originalCreateEl.call(this,eltype, ptions,vl,autowidth,ajaxso);
        }
    });
    
    $('#MyGrid').jqGrid({
        ...
        ajaxSelectOptions: {
            data: {
                id: function () {
                    var id = createElementOptions.id,
                        colName = createElementOptions.name;
                    if (typeof id !== "string" || typeof colName !== "string") {
                        return null;
                    }
                    return id.substring(0, id.length - colName.length - 1);
                }
            }
        }
    });
    

    The next demo demonstrate the way.

    UPDATED 2: I posted the pull request to make support of postData as property of ` andajaxSelectOptions`. The request is committed now (see here). So the next version of jqGrid (higher as 4.4.1) will have the functionality "out of the box".