Search code examples
jqueryjqgridfree-jqgrid

Jqgrid Add/update/delete with form modal


I am using free version (latest) of jqgrid with MVC c#. I have set it up with my data and all works fine. I also do have toolbar at the footer with add, edit, delete which when clicked does show the modal form with all the form elements configured. What I am having issues is:

  1. How shall I get the all the form elements of my modal pop up For example I have this in my col model:

    { name: 'name', index: 'name', width: 90, sorttype: "text", editrules: { required: true }}
    

    When the user clicks on the add/edit row I get the name as one of the field in my pop up. So how do I get this field value which the user updated and pass it to my mvc controller.

  2. Second ques is on which method can I grab these values for add/edit/delete? I want to grab these values and use ajax to call my server side method.

  3. Lastly how shall I refresh the grid after add/edit/delete.

Updated: I am using below code:

 <script type="text/javascript">
    $(function () {
        "use strict";
        var $grid = $("#list");             
        $grid.jqGrid({
            url: '@Url.Action("GetData", "Home")',
            datatype: "json",
            mtype: 'Get',
            colNames: ['Id', 'Name', 'Sex', 'Address'],
            loadonce: true,
            height: '100%',
            autowidth: true,
   colModel: [
                { name: 'uid', index: 'uid', editable: true,  editrules: { required: true}},
                { name: 'name', index: 'name', editable: true,  editrules: { required: true}},
                { name: 'sex', index: 'sex', editable: true,  editrules: { required: true}},
                { name: 'address', index: 'address', editable: true,  editrules: { required: true}}
     ],
            cmTemplate: { autoResizable: true, editable: true },
            autoResizing: { compact: true, resetWidthOrg: true },                
            iconSet: "fontAwesome",
            rowNum: 10,
            rowList: [5, 10, 20, "10000:All"],
            viewrecords: true,
            autoencode: true,
            sortable: true,              
            pager: true,
            rownumbers: true,
            sortname: "uid",
            sortorder: "desc",
            pagerRightWidth: 150,
            afterAddRow: function () {

            },
            afterSetRow: function () {

            },
            afterDelRow: function () {

            },
            inlineEditing: {
                keys: true
            },
            formEditing: {
                width: 310,
                closeOnEscape: true,
                closeAfterEdit: true,
                savekey: [true, 13]
            },
            searching: {                    
                loadFilterDefaults: false,
                closeOnEscape: true,
                searchOperators: true,
                searchOnEnter: true
            },

            caption: "MyData"
        }).jqGrid("navGrid")
        .editGridRow("new", properties);              
    });
   </script>

Where above can I use ajax to call my mvc controller as:

    $.ajax({
       url: '/Home/AddNew',
       type: 'POST',
       async: false,
       dataType: 'json',
       processData: false,
       data: {
                //I try to use below code to get value but it returned null
                uid: $('input#uid').val()
             },
        success: function (data) { }
       });  

Solution

  • I think that there are some misunderstanding how editing in jqGrid work. There are exist editurl parameter of jqGrid, which default value is "clientArray" in free jqGrid. It means that changes of data will be done locally without posting any data to the server. If you specify for example editurl: '/Home/Change' then jqGrid will POST the data modifications to the server and Change action should do adding, editing or deleting the data.

    If you want so send additional data together with editing data then you should use additional options/callbacks for that. The options/callbacks depends on the editing mode which you use. You use currently form editing. To be exact you use navGrid method, which adds navigator bar with Add/Edit/Delete buttons. After the user clicks on the buttons, fills the corresponding forms and press Submit button jqGrid (navGrid) executes editGridRow or delGridRow method. One can control the options used by navGrid during the calls of editGridRow or delGridRow method using options of navGrid oder by specifying the options inside of formEditing or formDeleting options of jqGrid. For example you can modify your code to

    cmTemplate: { autoResizable: true, editable: true },
    editurl: "/Home/Change",
    formEditing: {
        width: 310,
        closeOnEscape: true,
        closeAfterEdit: true,
        savekey: [true, 13],
        onclickSubmit: function (options, postData, editOrAdd) {
            return {
                myparam: $("#someInput").val()
            };
        }
    },
    formDeleting: {
        onclickSubmit: function (options, postData, formRowIds) {
            return {
                myDelParam: $("#someInput").val()
            };
        }
    }
    

    The above code will send the default editing parameters to the server and additional parameter myparam or myDelParam. The object returned from onclickSubmit will be combined with the object with other editing data of jqGrid. So send more as one additional parameter you need just return object with more as one property.

    If you don't want to use common URL editurl for all editing operations you can use url option defined inside of formEditing or/and formDeleting. You can use url defined as function if you want. For exymple,

    cmTemplate: { autoResizable: true, editable: true },
    formEditing: {
        url: function (rowid, editOrAdd, postData, options) {
            // editOrAdd is "add" or "edit"
            return editOrAdd === "add" ? "/Home/Add" : "/Home/Edit";
        },
        width: 310,
        closeOnEscape: true,
        closeAfterEdit: true,
        savekey: [true, 13],
        onclickSubmit: function (options, postData, editOrAdd) {
            if (editOrAdd === "add") {
                return {
                    myAddParam: $("#someInput").val()
                };
            } else {
                return {
                    myEditParam: $("#someInput").val()
                };
            }
        }
    },
    formDeleting: {
        url: "/Home/Delete",
        onclickSubmit: function (options, postData, formRowIds) {
            return {
                myDelParam: $("#someInput").val()
            };
        }
    }
    

    UPDATED: to reload the modified data from the server in case of using loadonce: true one can add reloadGridOptions: { fromServer: true } option inside of formEditing, formDeleting and navOptions. Like

    cmTemplate: { autoResizable: true, editable: true },
    formEditing: {
        url: function (rowid, editOrAdd, postData, options) {
            // editOrAdd is "add" or "edit"
            return editOrAdd === "add" ? "/Home/Add" : "/Home/Edit";
        },
        width: 310,
        closeOnEscape: true,
        closeAfterEdit: true,
        savekey: [true, 13],
        reloadGridOptions: { fromServer: true },
        onclickSubmit: function (options, postData, editOrAdd) {
            if (editOrAdd === "add") {
                return {
                    myAddParam: $("#someInput").val()
                };
            } else {
                return {
                    myEditParam: $("#someInput").val()
                };
            }
        }
    },
    formDeleting: {
        url: "/Home/Delete",
        reloadGridOptions: { fromServer: true },
        onclickSubmit: function (options, postData, formRowIds) {
            return {
                myDelParam: $("#someInput").val()
            };
        }
    },
    navOptions: {
        reloadGridOptions: { fromServer: true }
    }
    

    The option fromServer: true will be forwarded to reloadGrid event and the data will be loaded from the server instead of local reloading.