简体   繁体   English

jqGrid-复选框编辑无法编辑所选行

[英]jqGrid - checkbox editing not able to edit selected row

In my jqGrid, I have a checkbox which is also available for editing, ie a user can click on the checkbox and that checkbox's value will be updated in the database. 在我的jqGrid中,我有一个复选框也可用于编辑,即用户可以单击该复选框,并且该复选框的值将在数据库中更新。 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所做的

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 jqGrid版本:最新免费的jqGrid

Data Type: Json being saved to server 数据类型:Json被保存到服务器

Minimal Grid Code : jsFiddle 最小网格代码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. 但是,如果我第一次和第二次在复选框上选择, console.log确实会被每次调用。 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. 但是,只有在我选中该复选框,然后再次单击它时,才会调用saveRow ,以在第一次时取消选中它,之后再也没有。 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. 更新:按照cellattr的建议,我实现了cellattr并在其中调用了一个函数。 In the function I simply pass the rowid and update the checkbox of that rowid on the server. 在函数中,我只是传递了rowid并更新了服务器上该rowid的复选框。

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: 和我的selectThis函数:

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 } . 我认为formatter: "checkbox", formatoptions: { disabled: false }的用法存在误解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. 即使您使用datatype: "local"也不会发生任何事情,甚至在单击时也会更改本地数据。 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. 现在让我们尝试在选择网格的行上开始内联编辑(开始editRow )。 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. 首先,内联编辑使用​​unformatter从行(可编辑列)中获取值,将旧值保存在内部savedRow参数中,然后在可编辑单元格内的旧内容上创建新的编辑控件 Everything is relatively easy in case of using standard disabled checkbox of formatter: "checkbox" . 在使用formatter: "checkbox"标准禁用复选框的情况下,一切都相对容易formatter: "checkbox" jqGrid just creates enabled checkboxs on the place of disabled checkboxs. jqGrid只会在禁用复选框的位置上创建启用的复选框。 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. 用户可以更改复选框的状态或任何其他可编辑列的内容,并通过使用Enter键 保存更改。 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. 您可以监视复选框的状态还(按用途变化editoptions.dataEvents"change"事件为例),并呼吁saveRow不断变化的状态。 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. 如果确实需要使该行保持可编辑状态,则必须在成功保存该行后再次调用editRow 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. 您可以在editRowaftersavefunc回调内调用saveRow ,但是我建议您将editRow的调用包装在setTimeout内,以确保先前保存的处理完成。 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. 另一方面,如果您尝试将formatter: "checkbox" 启用复选框formatter: "checkbox"与内联编辑结合起来,那么处理将更加复杂。 It's important that enabled checkbox can be changed first of all before processing of onclick and onchange event handlers. 重要的是, 处理onclickonchange事件处理程序之前,可以首先更改已启用的复选框。 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. 在不同的Web浏览器中,3个事件的顺序(更改复选框的状态, onclick处理和onchange处理)可以不同。 If the method editRow be executing it uses unformatter of checkbox-formatter to get the current state of the checkbox. 如果正在执行方法editRow则它使用checkbox-formatter的unformatter来获取复选框的当前状态。 Based of the value of the state editRow replace the content of the cell to another content with another enabled checkbox. 根据状态editRow的值,用另一个启用的复选框将单元格的内容替换为另一内容。 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. 可能是复选框的状态已更改,但是editRow会将the changes state解释the changes state类似于复选框the initial state In the same way one can call saveRow only after editRow . 以同样的方式可调用saveRow 后才 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. 因此,您不能只在formatter: "checkbox", formatoptions: { disabled: false }程序的change处理程序内部使用saveRow formatter: "checkbox", formatoptions: { disabled: false } ,因为该行尚未处于编辑模式。

UPDATED: The corresponding implementation (in case of usage formatter: "checkbox", formatoptions: { disabled: false } ) could be the following: 更新:相应的实现(在使用formatter: "checkbox", formatoptions: { disabled: false }情况下formatter: "checkbox", formatoptions: { disabled: false } )可以如下:

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/ 参见jsfiddle演示http://jsfiddle.net/OlegKi/HJema/190/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM