jqGrid - 复选框编辑无法编辑选定的行 [英] jqGrid - checkbox editing not able to edit selected row

查看:87
本文介绍了jqGrid - 复选框编辑无法编辑选定的行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的jqGrid中,我有一个也可用于编辑的复选框,即用户可以单击复选框,该复选框的值将在数据库中更新。这工作正常。但是当我点击复选框并且我再次尝试点击它时,没有任何反应。该行未保存。从理论上讲,应该保存复选框的未选中值。但这不会发生。



我试过参考Oleg的



在图像中,选择复选框两次后发送请求,而不是每次都发送。



更新:根据@ Oleg的建议,我实现了 cellattr 并在里面调用了一个函数。在函数中,我只是传递rowid并更新服务器上该rowid的复选框。



以下是我使用的代码:

  {
名称:'W3LabelSelected',
索引:'u.W3LabelSelected',
align:'center',
宽度:'170',
可编辑:false,
edittype:'checkbox',
formatter:checkbox,
search:false,
formatoptions:{
disabled:false
},
editoptions: {
值:1:0
},
cellattr:function(rowId,tv,rawObject,cm,rdata){
return'onClick =selectThis('+ rowId +')';
}
},

和我的selectThis函数:

  function selectThis(rowid){
$ .ajax({
type:'POST',
url: myurl,
数据:{
'id':rowid
},
成功:函数(数据){
if(data.success =='success') {
$(#list)。setGridParam({
datatype:'json',
page:1
})。trigger('reloadGrid');
} else {
$(< div title ='Error'class ='ui-state-error ui-corner-all'>+ data.success +< / div>)。对话框({});
}
}
});
}

FIDDLE

解决方案

我认为对<的用法存在误解code> formatter:checkbox,formatoptions:{disabled:false} 。如果您以某种方式在网格列中创建非禁用复选框,则用户只需看到可以单击的复选框,可以更改哪个状态。另一方面,如果用户更改了复选框的状态,则没有任何反应。相反,复选框的初始状态对应于网格的输入数据,但更改后的复选框会使状态发生变化,但不会自动完成任何操作。即使您使用数据类型:local也不会发生任何事情,甚至在点击时也会更改本地数据。如果确实需要根据更改复选框的状态保存更改,则必须实现其他代码。 答案演示了可能的实施方式。您可以在相应的演示上更改某些复选框的状态,然后更改页面并返回第一页。您将看到复选框的状态对应于lates更改。



现在让我们尝试启动内联编辑(启动 editRow )选择网格的行。首先,内联编辑使用​​unformatter从行(可编辑列)中获取值,将旧值保存在内部 savedRow 参数中,然后创建新的编辑控件旧内容所在地的可编辑单元格内部。如果使用格式化程序的标准禁用复选框,则一切都相对容易:复选框。 jqGrid只是在禁用的复选框位置创建启用的复选框。用户可以更改复选框的状态或任何其他可编辑列的内容,并使用 Enter 保存更改。之后,所选行将被保存,并且不会更具可编辑性。您还可以监视复选框状态的更改(使用 editoptions.dataEvents ,使用更改事件示例)并在更改状态时调用 saveRow 。保存后,该行不可编辑,这一点非常重要。如果您确实需要保持行可编辑,则必须在成功保存行之后再次调用 editRow 。您可以在 aftersavefunc 回调 saveRow 中调用 editRow ,但我建议你在 setTimeout 中包装 editRow 的调用,以确保完成上一次保存的处理。这是我推荐你的方式。



另一方面,如果你试图结合格式化程序的启用复选框:checkbox使用内联编辑,您将获得更复杂的处理。重要的是,在 onclick onchange 处理之前,首先可以更改启用的复选框事件处理程序。 3个事件的顺序(更改复选框的状态,处理 onclick 和处理 onchange )可能会有所不同在不同的Web浏览器中。如果方法 editRow 正在执行,则使用checkbox-formatter的格式化来获取复选框的当前状态。根据状态值 editRow 将单元格的内容替换为另一个启用的内容复选框。可能是复选框的状态已经更改,但 editRow 解释更改状态,如复选框的初始状态。以同样的方式,可以在 editRow 之后只调用 saveRow 。所以你不能只在中使用 saveRow 更改格式化程序的处理程序:复选框 ,formatoptions:{disabled:false} ,因为该行还没有处于编辑模式。



更新:相应的实现(如果使用 formatter:复选框,formatoptions:{disabled:false} )可能如下:

  editurl:SomeUrl,
beforeSelectRow:function(rowid,e){
var $ self = $(这个),
$ td = $(e.target).closest(tr.jqgrow> td),
p = $ self.jqGrid(getGridParam),
savedRow = p .savedRow,
cm = $ td.length> 0? p.colModel [$ td [0] .cellIndex]:null,
cmName = cm!= null&& cm.editable? cm.name:数量,
isChecked;
if(savedRow.length> 0&& savedRow [0] .id!== rowid){
$ self.jqGrid(restoreRow,savedRow [0] .id);
}
if(cm!= null&& cm.name ===W3LabelSelected&& $(e.target).is(:checkbox)){
if(savedRow.length> 0){
//某行正在编辑现在
isChecked = $(e.target).is(:checked);
if(savedRow [0] .id === rowid){
$ self.jqGrid(saveRow,rowid,{
extraparam:{
W3LabelSelected:isChecked? 1:0,
},
aftersavefunc:function(response){
$ self.jqGrid(editRow,rowid,{
keys:true,
focusField:cmName
});
}
});
}
}其他{
$ .ajax({
类型:POST,
url:SomeUrl,//可能只是p.editurl
data:$ self.jqGrid(getRowData,rowid)
});
}
}
if(rowid){
$ self.jqGrid(editRow,rowid,{
keys:true,
focusField:cmName
});
}

返回true; //允许选择
}

参见jsfiddle demo http://jsfiddle.net/OlegKi/HJema/190/


In my jqGrid, I have a checkbox which is also available for editing, i.e. a user can click on the checkbox and that checkbox's value will be updated in the database. That is working fine. However when I click on the checkbox and if I try clicking on it again, nothing happens. The row does not get saved. Theoretically the unchecked value of the checkbox should be saved. But this does not happen.

I have tried referring to this answer of Oleg but it does not help.

The weird problem is if I select another row and then try to unselect the checkbox again, I do see a save request going.

I am guessing this is because I am trying to edit a row which is currently selected. But I am not sure what I am doing wrong here.

This is what I am doing in my beforeSelectRow

beforeSelectRow: function (rowid, e) {
    var $target = $(e.target),
        $td = $target.closest("td"),
        iCol = $.jgrid.getCellIndex($td[0]),
        colModel = $(this).jqGrid("getGridParam", "colModel");
    if (iCol >= 0 && $target.is(":checkbox")) {
        if (colModel[iCol].name == "W3LabelSelected") {
            console.log(colModel[iCol].name);
            $(this).setSelection(rowid, true);
            $(this).jqGrid('resetSelection');
            $(this).jqGrid('saveRow', rowid, {
                succesfunc: function (response) {
                    $grid.trigger('reloadGrid');
                    return true;
                }
            });
        }
    }
    return true;
},

Configuration:

jqGrid version: Latest free jqGrid

Data Type: Json being saved to server

Minimal Grid Code: jsFiddle

EDIT: After Oleg's answer this is what I have so far:

beforeSelectRow: function (rowid, e) {
    var $self = $(this),
        iCol = $.jgrid.getCellIndex($(e.target).closest("td")[0]),
        cm = $self.jqGrid("getGridParam", "colModel");
    if (cm[iCol].name === "W3LabelSelected") {
        //console.log($(e.target).is(":checked"));
        $(this).jqGrid('saveRow', rowid, {
            succesfunc: function (response) {
                $grid.trigger('reloadGrid');
                return true;
            }
        });
    }

    return true; // allow selection
}

This is close to what I want. However if I select on the checkbox the first time and the second time, the console.log does get called everytime. However the saveRow gets called only when I check the checkbox and then click on it again to uncheck it the first time and never after that. By default the checkbox can be checked or unchecked based on data sent from server.

In the image, the request is sent after selecting the checkbox two times instead of being sent everytime.

UPDATE: As per @Oleg's suggestion, I have implemented cellattr and called a function inside. In the function I simply pass the rowid and update the checkbox of that rowid on the server.

Here's the code I used:

{
    name: 'W3LabelSelected',
    index: 'u.W3LabelSelected',
    align: 'center',
    width: '170',
    editable: false,
    edittype: 'checkbox',
    formatter: "checkbox",
    search: false,
    formatoptions: {
        disabled: false
    },
    editoptions: {
        value: "1:0"
    },
    cellattr: function (rowId, tv, rawObject, cm, rdata) {
        return ' onClick="selectThis(' + rowId + ')"';
    }
},

and my selectThis function:

function selectThis(rowid) {
    $.ajax({
        type: 'POST',
        url: myurl,
        data: {
            'id': rowid
        },
        success: function (data) {
            if (data.success == 'success') {
                $("#list").setGridParam({
                    datatype: 'json',
                    page: 1
                }).trigger('reloadGrid');
            } else {
                $("<div title='Error' class = 'ui-state-error ui-corner-all'>" + data.success + "</div>").dialog({});
            }
        }
    });
}

FIDDLE

解决方案

I think there is a misunderstanding in the usage of formatter: "checkbox", formatoptions: { disabled: false }. If you creates non-disabled checkboxs in the column of the grid in the way then the user just see the checkbox, which can be clicked and which state can be changed. On the other side nothing happens if the user changes the state of the checkbox. On the contrary the initial state of the checkbox corresponds to input data of the grid, but the changed checkbox makes illusion that the state is changed, but nothing will be done automatically. Even if you use datatype: "local" nothing is happens and even local data will be changed on click. If you do need to save the changes based on the changing the state of the checkbox then you have to implement additional code. The answer demonstrates a possible implementation. You can change the state of some checkboxes on the corresponding demo, then change the page and go back to the first page. You will see that the state of the checkbox corresponds the lates changes.

Now let us we try to start inline editing (start editRow) on select the row of the grid. First of all inline editing get the values from the rows (editable columns) using unformatter, saves the old values in internal savedRow parameter and then it creates new editing controls inside of editable cells on the place of old content. Everything is relatively easy in case of using standard disabled checkbox of formatter: "checkbox". jqGrid just creates enabled checkboxs on the place of disabled checkboxs. The user can change the state of the checkboxs or the content of any other editable columns and saves the changes by usage of Enter for example. After that the selected row will be saved and will be not more editable. You can monitor the changes of the state of the checkbox additionally (by usage editoptions.dataEvents with "change" event for example) and call saveRow on changing the state. It's important that the row will be not editable after the saving. If you do need to hold the row editable you will have to call editRow once more after successful saving of the row. You can call editRow inside of aftersavefunc callback of saveRow, but I recommend you to wrap the call of editRow inside of setTimeout to be sure that processing of previous saving is finished. It's the way which I would recommend you.

On the other side if you try to combine enabled checkboxs of formatter: "checkbox" with inline editing then you will have much more complex processing. It's important that enabled checkbox can be changed first of all before processing of onclick and onchange event handlers. The order of 3 events (changing the state of the checkbox, processing of onclick and processing of onchange) can be different in different web browsers. If the method editRow be executing it uses unformatter of checkbox-formatter to get the current state of the checkbox. Based of the value of the state editRow replace the content of the cell to another content with another enabled checkbox. It can be that the state of the checkbox is already changed, but editRow interprets the changes state like the initial state of the checkbox. In the same way one can call saveRow only after editRow. So you can't just use saveRow inside of change handler of formatter: "checkbox", formatoptions: { disabled: false }, because the line is not yet in editing mode.

UPDATED: The corresponding implementation (in case of usage formatter: "checkbox", formatoptions: { disabled: false }) could be the following:

editurl: "SomeUrl",
beforeSelectRow: function (rowid, e) {
    var $self = $(this),
        $td = $(e.target).closest("tr.jqgrow>td"),
        p = $self.jqGrid("getGridParam"),
        savedRow = p.savedRow,
        cm = $td.length > 0 ? p.colModel[$td[0].cellIndex] : null,
        cmName = cm != null && cm.editable ? cm.name : "Quantity",
        isChecked;
    if (savedRow.length > 0 && savedRow[0].id !== rowid) {
        $self.jqGrid("restoreRow", savedRow[0].id);
    }
    if (cm != null && cm.name === "W3LabelSelected" && $(e.target).is(":checkbox")) {
        if (savedRow.length > 0) {
            // some row is editing now
            isChecked = $(e.target).is(":checked");
            if (savedRow[0].id === rowid) {
                $self.jqGrid("saveRow", rowid, {
                    extraparam: {
                        W3LabelSelected: isChecked ? "1" : "0", 
                    },
                    aftersavefunc: function (response) {
                        $self.jqGrid("editRow", rowid, {
                            keys: true,
                            focusField: cmName
                        });
                    }
                });
            }
        } else {
            $.ajax({
                type: "POST",
                url: "SomeUrl", // probably just p.editurl
                data: $self.jqGrid("getRowData", rowid)
            });
        }
    }
    if (rowid) {
        $self.jqGrid("editRow", rowid, {
            keys: true,
            focusField: cmName
        });
    }

    return true; // allow selection
}

See jsfiddle demo http://jsfiddle.net/OlegKi/HJema/190/

这篇关于jqGrid - 复选框编辑无法编辑选定的行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆