Enabling Save button on JQ Grid with InlineEditing and CellEdit
Asked Answered
P

1

0

Hi I have a Grid that is using cell edit and Inline editing. It saves to the ClientArray

$('#list').jqGrid({
    datatype: "local",
    colNames: ["Parameter Id", "Parameter Name", 'Parameter Value'],
    colModel: [
        { name: "Id", index: "Id", align: "left", key: true, editable: false,hidden:true, jmap: 0 },
        { name: "ParameterName", index: "ParameterName", align: "left", editable: false, jmap: 1 },
        { name: "ParameterValue", index: "ParameterValue", align: "left", editable: true, edittype: "text", editoptions: { maxlength: 100 }, editrules: {required: true }, jmap: 2 }
    ],

    pager: "#pager",
    rowNum: 100,
    rowList: [],
    pgbuttons: false,     // disable page control like next, back button
    pgtext: null,         // disable pager text like 'Page 0 of 10'
    viewrecords: true,   // disable current view record text like 'View 1-10 of 100'
    height: '100%',
    scrollOffset: 0,
    sortname: "Name",
    sortorder: "Asc",
    gridview: true,
    caption: 'Parameters',
    autowidth: true,
    hidegrid: false,
    loadonce: true,
    //beforeEditCell: function () {
    //    $("#list_ilsave").removeClass('ui-state-disabled');
    //    return;
    //},
    //afterEditCell: function (rowid, cellname, value, iRow, iCol) {
    //    $('#list').jqGrid('getCell', rowid, iCol).focus();
    //    return;
    //},
    width: totalWidth,
    cellEdit: true,
    cellsubmit: "clientArray"
});

$('#list').jqGrid('inlineNav', '#pager', {
        edit: false,
        add: false,
        del: false,
        save: true,
        savetext: 'Save',
        cancel: false
    });

When I edit a Cell the save button remains disabled. If I manually Enable the button in beforeCellEdit, the editable cell hasn't got focus until you select another cell. This behavior is only happening in IE.

I have tried to fix both these issues individually in my commented out code, and I have found that the loss of focus is caused by the line

$("#list_ilsave").removeClass('ui-state-disabled');

I tried placing this line in beforeEditCell and in afterEditCell and it causes the input field to loose focus.

I was using JQ Grid 4.4.4 and I have tried updating to 4.6.0 after I read there were updates to Inline Editing after 4.4.4

UPDATE I have changed my grid to use onSelectRow

        onSelectRow: function (rowid) {
        var $grid = $('#list');
        var iRow = $("#" + rowid)[0].rowIndex;

        $grid.jqGrid('editRow', rowid, {
            keys: true,
            oneditfunc: function(rowid, response) {
                var $saveButton = $("#list_ilsave");

                if ($saveButton.hasClass('ui-state-disabled')) {
                    $saveButton.removeClass('ui-state-disabled');
                }

                markCellAsDirty(rowid, $grid);
                return true;
            },
            successfunc: function() {
                alert('success');
                return true;
            },
            aftersavefunc: function() {
                alert('after save');
                return true;
            },
            errorfunc: function() {
                alert('error');
                return true;
            }
        });
    },
    cellsubmit: "clientArray"

But I can't get any of the editRow events to fire other than oneditfunc. I also have an issue with getting the changed cells.

This method marks the cells as dirty / edited

function markCellAsDirty(rowid, grid) {
    $(grid.jqGrid("setCell", rowid, "ParameterValue", "", "dirty-cell"));
    $(grid[0].rows.namedItem(rowid)).addClass("edited");
}

I try to get the edited cells as follows

var editedRows = $grid.getChangedCells('dirty');

Before posting editedRows in an AJAX method to my server.

Part answered 19/1, 2016 at 13:58 Comment(8)
Sorry, but I can't follow you. It has no sense to use both cell edit and Inline editing in one grid. Which behavior you want to implement? "Save" button of inline editing can save the row, which will be editing using inline editing. You grid provide no way to start row editing. Thus the "Save" button have no sense.Garvy
The next question why you want to update very old 4.4.4 version to another very old 4.6 version? I'd recommedn you to use free jqGrid 4.12.1. It's the fork which I develop since more as one year. You can download it from GitHub or to use use URLs described here to load directly from CDN.Garvy
Hi Oleg, I'm looking over old code to fix a bug that has been hanging around for a while in my application. I don't think this was my code. The functionality that I want is to that the user can select the row and the editable column will become editable. I don't want to use the edit button. When the user has finished editing the grid I want them to select the save button and then the dirty rows are sent to the server. I am using 4.4.4 because the nuget package I installed jqgrid from for .net hadn't told me of any updates. By the looks of it I have also been following old documentationPart
There are for example NuGet package nuget.org/packages/free-jqGrid which you can use. The NuGet package for 4.4.4 was created by some user who had no direct relation with development of jqGrid. Because of that he had not published any updates more. About your problem. You can start inline editing inside of onSelectRow for example like in the answer. You should remove cellEdit: true of cause to allow inline editing work.Garvy
Hi @Garvy I have changed my code to use onSelectRow as you suggested but I am having issues getting the edited cells. I have updated my question with extra details. Thanks for your help so farPart
Sorry, but I can't follow you. Why you made modification of onSelectRow callback? I suggested you to use free jqGrid 4.12.1 and you included in onSelectRow some code in oneditfunc which i snot needed with free jqGrid. Moreover the main problem which I reported. you can't use cell editing and inline editing together, but UPDATED part contains still cellsubmit: "clientArray" (???). Do you still use cellEdit: true or not? It's better that you prepare small JSFiddle demo which demonstrates the current problem.Garvy
@Garvy I have created the js fiddle jsfiddle.net/byygepy3 to show what I was trying to do. I have also updated the project to use free-jqgrid and I will look at how to use it properlyPart
sorry the external javascript didn't save to the previous link. Pleas use this one instead jsfiddle.net/byygepy3/2Part
G
1

I'm not sure what you want to implement exactly, but I modified your demo to the following https://jsfiddle.net/OlegKi/byygepy3/11/. I include the full JavaScript code of the demo below

$(function () {
    var myData = [
            { id: 10, ParameterName: "Test", ParameterValue: "" },
            { id: 20, ParameterName: "Test 1", ParameterValue: "" },
            { id: 30, ParameterName: "Test 2", ParameterValue: "" }
        ],
        $grid = $("#list");

    // change the text displayed on editrules: {required: true } 
    $.extend(true, $.jgrid.locales["en-US"].edit.msg, {
        required: "No value was entered for this parameter!!!"
    });

    $grid.jqGrid({
        datatype: "local",
        data: myData,
        colNames: ["", "Parameter Name", "Parameter Value"],
        colModel: [
            { name: "act", template: "actions" }, // optional feature
            { name: "ParameterName" },
            { name: "ParameterValue", editable: true,
                editoptions: { maxlength: 100 }, editrules: {required: true } }
        ],
        cmTemplate: { autoResizable: true },
        autoResizing: { compact: true },
        pager: true,
        pgbuttons: false,     // disable page control like next, back button
        pgtext: null,         // disable pager text like 'Page 0 of 10'
        viewrecords: true,    // disable current view record text like 'View 1-10 of 100'
        sortname: "Name",
        iconSet: "fontAwesome",
        caption: 'Parameters',
        autowidth: true,
        hidegrid: false,
        inlineEditing: {
            keys: true
        },
        singleSelectClickMode: "selectonly", // prevent unselect once selected rows
        beforeSelectRow: function (rowid) {
            var $self = $(this), i,
                // savedRows array is not empty if some row is in inline editing mode
                savedRows = $self.jqGrid("getGridParam", "savedRow");
            for (i = 0; i < savedRows.length; i++) {
                if (savedRows[i].id !== rowid) {
                    // save currently editing row
                    // one can replace saveRow to restoreRow in the next line
                    $self.jqGrid("saveRow", savedRows[i].id);
                }
            }
            return savedRows.length === 0; // allow selection if saving successful
        },
        onSelectRow: function (rowid) {
            $(this).jqGrid("editRow", rowid);
        },
        afterSetRow: function (options) {
            var item = $(this).jqGrid("getLocalRow", options.rowid);
            if (item != null) {
                item.dirty = true;
            }
        },
        navOptions: {
            edit: false,
            add: false,
            search: false,
            deltext: "Delete",
            refreshtext: "Refresh"
        },
        inlineNavOptions: {
            save: true,
            savetext: "Save",
            cancel: false,
            restoreAfterSelect: false
        },
        formDeleting: {
            // delete options
            url: window.g_baseUrl + 'MfgTransactions_MVC/COA/Delete?',
            beforeSubmit: function () {
                // get value
                var selRowId = $(this).jqGrid('getGridParam', 'selrow');
                var parametricValue = $(this).jqGrid('getCell', selRowId, 'ParameterValue');

                // check if empty
                if (parametricValue === "") {
                    return [false, "Cannot delete: No value exists for this parameter"];
                }

                return [true, "Successfully deleted"];
            },
            delData: {
                batchId: function () {
                    return $("#BatchId").val();
                }
            },
            closeOnEscape: true,
            closeAfterDelete: true,
            width: 400,
            msg: "Are you sure you want to delete the Parameter?",
            afterComplete: function (response) {
                if (response.responseText) {
                    alert("response.responseText");
                }

                //loadBatchListIntoGrid();
            }
        }
    }).jqGrid('navGrid')
    .jqGrid('inlineNav')
    .jqGrid('navButtonAdd', {
        caption: "Save Changed",
        buttonicon: "fa-floppy-o",
        onClickButton: function () {
            var localData = $(this).jqGrid("getGridParam", "data"),
                dirtyData = $.grep(localData, function (item) {
                    return item.dirty;
                });
            alert(dirtyData.length > 0 ? JSON.stringify(dirtyData) : "no dirty data");
        }
    });

    // make more place for navigator buttons be rwducing the width of the right part
    var pagerIdSelector = $grid.jqGrid("getGridParam", "pager");
    $(pagerIdSelector + "_right").width(100);

    // make the grid responsive
    $(window).bind("resize", function () {
        $grid.jqGrid("setGridWidth", $grid.closest(".container-fluid").width());
    }).triggerHandler("resize");
});

where HTML code is

<div class="container-fluid">
    <div class="row">
        <div id="gridarea" class="col-md-6 col-md-offset-3">
            <table id="list"></table>
        </div>
    </div>
</div>

and CSS code

.ui-th-column>div, .ui-jqgrid-btable .jqgrow>td {
    word-wrap: break-word; /* IE 5.5+ and CSS3 */
    white-space: pre-wrap; /* CSS3 */
    white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
    white-space: -pre-wrap; /* Opera 4-6 */
    white-space: -o-pre-wrap; /* Opera 7 */
    overflow: hidden;
    vertical-align: middle;
}

It demonstrate how one can implement starting inline editing on select row. Additionally I added optional column with template: "actions" which can be alternative implementation. I set property dirty in every item of data inside of afterSetRow callback and I added "Save Changed" button, which uses localData = $(this).jqGrid("getGridParam", "data") and dirtyData = $.grep(localData, function (item) { return item.dirty; }); to get the dirty (modified) data.

Garvy answered 24/1, 2016 at 13:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.