1

I'm trying to use jqgrid edit form, but I can't understand why jqgrid do not call asmx web method every time I select a row and I click on edit icon (jqgrid call ajax just the first time)

This is the code:

function Grid() {  
   var ret = Array();

   var grid = jQuery("#grid");


var hideLoading = function () {
    $("#lui_" + grid).hide();
    $("#load_" + grid).hide();
}

var strSearch = "";
var strField = "";
var strOper = "";

//
//  handler: si occupa di creare il contenuto del menu a tendina (form jqGrid)
//
var buildOptions = function (dataList) {
    var response = dataList;
    var option = "";

    if (response && response.length) {
        for (var i = 0, l = response.length; i < l; i++) {

        if (response[i]["selectedvalue"] == "on")
            option += '<option role="option" selected="selected" value="' + response[i]["Codice"] + '">' + response[i]["Descrizione"] + '</option>';
        else
            option += '<option role="option" value="' + response[i]["Codice"] + '">' + response[i]["Descrizione"] + '</option>';
        }
    }

    return option;
};

grid.jqGrid({
    // setup custom parameter names to pass to server
    prmNames: {
        search: "isSearch",
        nd: null,
        rows: "numRows",
        page: "page",
        sort: "sortField",
        order: "sortOrder"
    },
    // add by default to avoid webmethod parameter conflicts
    postData: {
        searchString: '',
        searchField: '',
        searchOper: ''
    },
    // setup ajax call to webmethod
    datatype: function (postdata) {
        $.ajax({
        url: '<%# ResolveUrl("~/Service/Domain/ServiceRoom.asmx/GetRoomRateDiscount") %>',
        type: "POST",
        contentType: "application/json; charset=utf-8",
        data: JSON.stringify(postdata),
        dataType: "json",
        success: function (data, st) {
            if (data.d == "KO") {
            grid.GridUnload();

            jAlert("La ricerca non ha restituito alcun risultato", "Book2Guest");

            return false;
            }

            if (st == "success") {
            var grid = $("#grid")[0];
            grid.addJSONData(JSON.parse(data.d));
            ret = JSON.parse(data.d);
            }
        },
        error: function (xhr, textStatus, errorThrown) {
            jAlert("Si è verificato un errore: " + textStatus + " " + errorThrown + " -- " + $.parseJSON(xhr.statusText), "Book2Guest");
        }
        });
    },
    // this is what jqGrid is looking for in json callback
    jsonReader: {
        root: "rows",
        page: "page",
        total: "totalpages",
        records: "totalrecords",
        cell: "cell",
        id: "id",
        userdata: "userdata",
        repeatitems: true
    },
    ajaxSelectOptions: {
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        cache: false,
        data: {
            rowId: function () {
                if (JSON.stringify(grid.jqGrid('getRowData', grid.jqGrid('getGridParam', 'selrow'))['Codice']) == undefined)
                    return "";

                return JSON.stringify(grid.jqGrid('getRowData', grid.jqGrid('getGridParam', 'selrow'))['Codice']);
            }
        }
    },
    colNames: ['ID', 'Rate'],
    colModel: [
        { name: 'ID', index: 'ID', width: 10, align: "center", search: false, sorttype: 'int', searchoptions: { sopt: ['eq', 'ne', 'cn']} },
        {
        name: 'TariffaCodiceOfferta',
        index: 'TariffaCodiceOfferta',
        width: 50,
        hidden: true,
        formatter: 'select',
        editable: true,
        edittype: 'select',
        editrules: { edithidden: true }, //, required: true },
        editoptions: {
            multiselect: true,
            dataUrl: '<%# ResolveUrl("~/Service/Domain/ServiceRoom.asmx/GetRoomRateListByRowId") %>',
            buildSelect: function (data) {
                var response = $.parseJSON(data.d);

                var option = buildOptions(response);
                var s = '<select>';
                s += option;

                return s + "</select>";
            },
            dataInit: function (elem) {
                setTimeout(function () {
                    $(elem).multiselect({ selectedList: 10 });
                }, 50);
            },
            multiple: true
        }
        },
      ],
rowNum: 10,
rowList: [10, 20, 30],
height: 'auto',
pager: '#gridpager',
viewrecords: true,
shrinkToFit: false,
loadComplete: function () {
    hideLoading();
},
loadError: function () {
    hideLoading();
},
editurl: '<%# ResolveUrl("~/Service/Domain/ServiceRoom.asmx/SaveRoomDiscount") %>',
sortname: "ID",
sortorder: "asc",
caption: "Rate list",
onSelectRow: function (id, status) {},
ondblClickRow: function (rowid) {
    grid.jqGrid('editGridRow', rowid,
    {
    width: 450,
    height: 450,
    closeOnEscape: true,
    addCaption: "Add Rate",
    editCaption: "Edit Rate",
    bSubmit: "Salva",
    bCancel: "Annulla",
    bClose: "Chiudi",
    bYes: "Si",
    bNo: "No",
    bExit: "Annulla",
    editData: { 
        "codice": function () {
            var selectedRow = grid.getGridParam("selrow");
            var rowData = grid.getRowData(selectedRow);
            return rowData["Codice"];
        }
    },
    viewPagerButtons: false,
    closeAfterEdit: true,
    reloadAfterSubmit: true,
    beforeShowForm: function (form) {
        var dlgDiv = $("#editmod" + grid[0].id);
        var parentDiv = dlgDiv.parent(); // div#gbox_list
        var dlgWidth = dlgDiv.width();
        var parentWidth = parentDiv.width();
        var dlgHeight = dlgDiv.height();
        var parentHeight = parentDiv.height();

        // Grabbed jQuery for grabbing offsets from here:
        //http://stackoverflow.com/questions/3170902/select-text-and-then-calculate-its-distance-from-top-with-javascript
        var parentTop = parentDiv.offset().top;
        var parentLeft = parentDiv.offset().left;

        dlgDiv[0].style.top = Math.round(parentTop + (parentHeight - dlgHeight) / 2) + "px";
        dlgDiv[0].style.left = Math.round(parentLeft + (parentWidth - dlgWidth) / 2) + "px";
    },
    onClose: function (response, postdata) {
    }
    });

    return;
},
gridComplete: function () {
    if (grid.getGridParam('records') == 0) // are there any records?
    DisplayEmptyText(true);
    else
    DisplayEmptyText(false);
},
emptyDataText: 'There are no records. '
})
grid.setGridWidth(900, true);
grid.jqGrid('navGrid', '#gridpager',
{
    edit: true,
    view: false,
    add: false,
    del: true,
    search: false
},
//prmEdit
{
    width: 450,
    height: 300,
    closeOnEscape: true,
    addCaption: "Aggiungi Offerta",
    editCaption: "Modifica Offerta",
    bSubmit: "Salva",
    bCancel: "Annulla",
    bClose: "Chiudi",
    saveData: "Sono state apportate delle modifiche, sei sicuro di voler continuare?",
    bYes: "Si",
    bNo: "No",
    bExit: "Annulla",
    editData: { 
        "Codice": function () {
            var selectedRow = grid.getGridParam("selrow");
            var rowData = grid.getRowData(selectedRow);
            return rowData["Codice"];
        } 
    },
    viewPagerButtons: false,
    closeAfterEdit: true,
    reloadAfterSubmit: true,
    beforeShowForm: function (form) {
        var dlgDiv = $("#editmod" + grid[0].id);
        var parentDiv = dlgDiv.parent(); // div#gbox_list
        var dlgWidth = dlgDiv.width();
        var parentWidth = parentDiv.width();
        var dlgHeight = dlgDiv.height();
        var parentHeight = parentDiv.height();

        // Grabbed jQuery for grabbing offsets from here:
        //http://stackoverflow.com/questions/3170902/select-text-and-then-calculate-its-distance-from-top-with-javascript
        var parentTop = parentDiv.offset().top;
        var parentLeft = parentDiv.offset().left;

        dlgDiv[0].style.top = Math.round(parentTop + (parentHeight - dlgHeight) / 2) + "px";
        dlgDiv[0].style.left = Math.round(parentLeft + (parentWidth - dlgWidth) / 2) + "px";
    },
    onClose: function (response, postdata) {}
}
//prmSearch, 
//prmView
);
return ret;

}

UPDATE: to solve this issue, you guys have to insert 'recreateForm: true' in the edit section of jqGrid

frabiacca
  • 1,402
  • 2
  • 16
  • 32

1 Answers1

0

You current code don't have 'Codice' column in colModel, but you try to get the data from the column. Even if the original server response has the Codice property, the property will be saved only if you add additional hidden column with the same name.

Sorry, but to tell the trust I would recommend you to rewrite the whole code which you use. The usage of datatype as function is not good. Instead of that you can use jsonReader. The call JSON.parse(data.d) inside of $.ajax having dataType: "json" shows that you did one more important error in the webmethod on the server side. It shows that you make manual conversion of returned object to String instead of returning object from the web method. WebService convert the object to JSON automatically. Because of manual convention to JSON the returned data will be twice converted to JSON. Only because of the error in the server code you have to use JSON.parse(data.d) and can't just use jsonReader like described here for example.

Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • hi oleg, i had to cut colmodel off 'cause it contains a lot of columns (even if 'Codice' one). I'm going to try to modify datatype and jsonreader as you suggest ... – frabiacca Jun 27 '12 at 09:19
  • oleg, i'm working on double json conversion to solve the problem you, correctly, highlighted to me through several answers here. In the meanwhile, could you please explain to me why, on row editing , jqgrid does call ajax method GetRoomRateListByRowId just the first time? – frabiacca Jun 27 '12 at 12:49
  • @frabiacca: the code which you posed will not work because of absent of `'Codice'` column. Another problem with `recreateForm: true` you found yourself. I suggested Tony many times (see [here](http://www.trirand.com/blog/?page_id=393/feature-request/change-default-settings-for-recreatefilter-and-recreateform-to-true/#p21082) for example) to make the setting of `recreateForm: true` and `recreateFilter: true` the default settings of jqGrid. The last time it was before publishing of 4.4.0 version, but he just ignore the suggestion always. – Oleg Jun 27 '12 at 13:27
  • @frabiacca: So I can just repeat to include the lines `$.extend($.jgrid.search, {recreateFilter: true});` (see [here](http://stackoverflow.com/a/10008151/315935), [here](http://stackoverflow.com/a/9726334/315935) or [here](http://stackoverflow.com/a/6884755/315935) for example) and `jQuery.extend(jQuery.jgrid.edit, {recreateForm: true});` (see [here](http://stackoverflow.com/a/6128195/315935)) in **all** of your jqGrid projects. – Oleg Jun 27 '12 at 13:31
  • oleg thx for your answers. as I wrote down before, I know my code does not work (I had to cut down colmodel 'cause of space); i just liked to know that I've to use RecreateForm :D – frabiacca Jun 28 '12 at 09:54
  • @frabiacca: I recommend everybody **always** use `recreateForm: true` and `recreateFilter: true`. If you use at least one dynamic feature in the forms the options are really required. Without the option jqGrid do following by default: instead of closing the form it hide the form only and show it at the next time. In the scenario any for callback will be called *only once* at the first creating of the form. In the most scenarios it follows to problems which are difficult to understand and to debug. – Oleg Jun 28 '12 at 10:08