jqGrid - disabling inline dropdown on “edit” but n

2019-08-18 08:57发布

问题:

It looks as if this question has been asked at least once before but was not answered. I have also seen this question answered regarding standard "form" based editing, but not inline.

Code

$(function() {
var lastSel;
var MSVendors = {'9990':'XXXXXX - LEXI','9991':'XXXXXX - RICH','9992':'XXXXXX - BIRM','9993':'XXXXXX - PEMB' };
$('#special_dialog').dialog({
    width:'auto',
    height:'auto',
    resizable:true
});
$.extend($.jgrid.defaults,{
    rowNum:250,
    rowList:[1000,2500,5000],
    viewrecords:true,
    sortorder:'asc',
    height:800,
    autowidth:true,
    deepempty:true,
    altRows: true,
    grouping: true,
    groupingView: {
        groupField: ["vendor"],
        groupColumnShow: [true],
        groupText: ["<b>WAREHOUSE : {0}</b>"],
        groupDataSorted: true,
        groupSummary: [false]
    }
});
var surplusGrid = $('#surplusGrid'),
    editingRowId,
    sEditParam = {
        keys: true,
        oneditfunc: function(id) {
            editingRowId = id;
            $('#surplusGrid_ilsave').removeClass('ui-state-disabled');
            $('#surplusGrid_ilcancel').removeClass('ui-state-disabled');
        },
        afterrestorefunc: function() {
            editingRowId = undefined;
        }
    },
    sAutoCompOpts = {
        source: function(request, response) {
            $.getJSON('/json/json.searchmultiMaterials.php',{term:request.term,type:'m'},function(data) {
                response(data);
            });
        },
        minLength: 3,
        focus: function(e,ui) {
            $('input:text[name="description"]').val(ui.item.description);
            $('input:text[name="vendor"]').val(ui.item.vendor);
            $('input:text[name="mfgr_partno"]').val(ui.item.mfgr_partno);
        },
        select: function(e,ui) {
            $('input:text[name="description"]').val(ui.item.description);
            $('input:text[name="vendor"]').val(ui.item.vendor);
            $('input:text[name="mfgr_partno"]').val(ui.item.mfgr_partno);
        }
    },
    sAddParam = {
        rowID: 'new',
        position:'last'
    };
surplusGrid.jqGrid({
    url: '/json/json.getSurplusStock.php',
    datatype:'json',
    emptyrecords: 'Surplus Stock is currently depleted!',
    colNames: ['ID','Type','Part#','Description','On-Hand','On-Order','On-Hold','Min Stock','Warehouse','Shelf','Bin'],
    colModel: [
        {   name:'id',
            index:'id',
            hidden:true,
            key:false,
            search:false,
            viewable:false
        },
        {   name:'type',
            index:'type',
            width:35,
            sortable:true,
            editable:false,
            align:'center',
            editoptions:{defaultValue:'B'},
            cellattr: function(rowId,val) {
                if (val == 'B') {
                    return 'class="blue_stock"';
                } else {
                    return 'class="gold_stock"';
                }
            }
        },
        {   name:'surplus_partno',
            index:'surplus_partno',
            width:140,
            sortable:false,
            editable:true,
            classes:'ui-ellipsis',
            edittype:'text',
            editoptions:{size:25},
            editrules:{required:true}
        },
        {   name:'description',
            index:'description',
            width:200,
            sortable:false,
            align:'left',
            editable:true,
            classes:'ui-ellipsis',
            edittype:'text',
            editoptions:{size:40},
            editrules:{required:true}
        },
        {   name:'on_hand',
            index:'on_hand',
            width:60,
            sortable:false,
            editable:true,
            align:'center',
            edittype:'text',
            editoptions:{size:6},
            editrules:{required:true,integer:true,minValue:0}
        },
        {   name:'on_order',
            index:'on_order',
            width:60,
            sortable:false,
            editable:true,
            align:'center',
            edittype:'text',
            editoptions:{size:6},
            editrules:{required:false,integer:true,minValue:0}
        },
        {   name:'on_hold',
            index:'on_hold',
            width:60,
            sortable:true,
            editable:true,
            align:'center',
            edittype:'text',
            editoptions:{size:6},
            editrules:{required:true,integer:true}
        },
        {   name:'min_threshold',
            index:'min_threshold',
            width:60,
            sortable:true,
            editable:true,
            align:'center',
            edittype:'text',
            editoptions:{size:6},
            editrules:{required:true,integer:true,minValue:0}
        },
        {   name:'vendor',
            index:'vendor',
            width:120,
            editable:true,
            align:'center',
            editoptions:{value:MSVendors},
            edittype:'select',
            editrules:{required:true,integer:true}
        },
        {   name:'shelf',
            index:'shelf',
            width:40,
            sortable:true,
            editable:true,
            align:'center',
            editoptions:{size:10}
        },
        {   name:'bin',
            index:'bin',
            width:40,
            sortable:true,
            editable:true,
            align:'center',
            editoptions:{size:10}
        }
    ],
    pager:'#surplusFoot',
    sortname:'b.id',
    caption:'Surplus Stock Inventory',
    onSelectRow: function(id) {
        if(id && id !== lastSel) {
            surplusGrid.jqGrid('restoreRow',lastSel);
            var cm = surplusGrid.jqGrid('getColProp','vendor');
            if (id != 'new') { cm.editable = false; }
            lastSel = id;
        }
        surplusGrid.jqGrid('editRow',id,true);
        $('#surplusGrid_ilsave').removeClass('ui-state-disabled');
        $('#surplusGrid_ilcancel').removeClass('ui-state-disabled');
    },
    editurl:'/jqg/jqg.saveSurplusStockEdit.php'
});
surplusGrid.jqGrid('navGrid','#surplusFoot',{
    add:false,
    edit:false,
    del:false
});
surplusGrid.jqGrid('inlineNav','#surplusFoot',{
    add:true,
    edit:true,
    editParams:sEditParam,
    addParams:sAddParam
});
// re-size all grids when dialog box resizes
$('#special_dialog').dialog({
    resizeStop: function(e,ui) {
        surplusGrid.jqGrid('setGridWidth', ui.size.width - 30);
    }
});

});

Works GREAT on inline ADD - dropdown appears and value is passed to the editing URL as expected. On inline EDIT, however, the entire dropdown vanishes, leaving a " " as the cell content rather than the value that was there when the grid initially loaded.

回答1:

The usage of inlineNav is a special case of inline editing, because editRow will be called. Starting with jqGrid 4.5.3 inline editing supports beforeEditRow and beforeAddRow callbacks which was introduced mostly to provide additional customization in case of usage inlineNav. The method beforeEditRow is more interesting, because it will be called in any way of calling editRow.

Before providing an example of usage beforeEditRow I would remark that you have to fix the bug in sAddParam, which you use as the option of addRow. You use unneeded and danger parameter rowID: 'new'. As the result the id of every new row will be the same: "new". In the way you will have id duplicates. The same problem exists in early versions of jqGrid. The current version of jqGrid uses $.jgrid.randId() to generate new unique id for new added row if rowID is null or undefined. The default value of rowID is null. So I strictly recommend you to remove rowID: 'new' option.

The next important thing is the meaning of addParams option of inlineNav. The method addRow calls internally the same editRow method. The addRowParams property of addParams allows to specify the option of editRow called by addRow. So I strictly recommend you to use addParams in the following form

var sEditParam = {
        ... // any options or callbacks
    },
    sAddParam = {
        position: 'last',
        addRowParams: sEditParam
    };

In the way you will be sure that all callbacks and options of inline editing will be applied even in case of usage addRow.

Now back to you main question. I suggest that you use beforeEditRow to change editable property of vendor column. To test whether the current row are just add or not I suggest to test existence of jqgrid-new-row class. The corresponding code could be like the following

var sEditParam = {
    beforeEditRow: function (option, rowid) {
        var tr = $(this).jqGrid("getGridRowById", rowid);

        $(this).jqGrid("setColProp", "vendor", {
            editable: !$(tr).hasClass("jqgrid-new-row")
        });
    }
};
surplusGrid.jqGrid("inlineNav", "#surplusFoot", {
    add: true,
    edit: true,
    editParams: sEditParam,
    addParams: {position: "last", addRowParams: sEditParam}
});