克隆时jQuery UI复选框行为不正常

时间:2013-02-12 18:10:06

标签: javascript jquery jquery-ui

我正在尝试创建一个输入表,当您在底线的其中一个输入中输入文本时,该表会自动添加新行。在大多数情况下,它工作正常。但是,我在使用jQuery UI复选框按钮时遇到了一些问题。

复选框按钮应该在单击时更改其图标。这适用于原始按钮,但添加新行时显示的克隆按钮无法正常工作。

你可以看到它in jsfiddle here。要复制该问题,请在第三个输入中放入一些文本。你会看到第四行出现。如果按第四个复选框,您将看到第三个复选框是图标更改的复选框。错误的按钮也会获得ui-state-focus但实际上并没有得到焦点,这真让我感到困惑,尽管正确的按钮确实得到了ui-state-active,据我所知,似乎评估为已经检查过正常。

要清楚,两个复选框具有相同的ID,并且它们的标签用于右侧复选框 - createNewRow()函数负责处理。如果你注释掉将复选框变成jQuery UI复选框的行,你会发现一切正常。如果你在buttonSwitchCheck函数中调用$(this).attr('id')的值,你会看到它也有正确的ID - 如果你点击第四个按钮,它会告诉你$(this)的id是“test4”,但它是“test3”(第三个按钮),它会改变图标。

我生气地盯着这个,我很感激人们可以给予的任何帮助。这是代码:

// Turns on and off an icon as the checkbox changes from checked to unchecked.
function buttonSwitchCheck() {
    if ($(this).prop('checked') === true) {
        $(this).button("option", "icons", {
            primary: "ui-icon-circle-check"
        });
    } else {
        $(this).button("option", "icons", {
            primary: "ui-icon-circle-close"
        });
    }
}

// Add a new row at the bottom once the user starts filling out the bottom blank row.
function createNewRow() {
    // Identify the row and clone it, including the bound events.
    var row = $(this).closest("tr");
    var table = row.closest("table");
    var newRow = row.clone(true);
    // Set all values (except for buttons) to blank for the new row.
    newRow.find('.ssheet').not('.button').val('');
    // Find elements that require an ID (mostly elements with labels like checkboxes) and increment the ID.
    newRow.find('.ssheetRowId').each(function () {
        var idArr = $(this).attr('id').match(/^(.*?)([0-9]*)$/);
        var idNum = idArr[2] - 0 + 1;
        var newId = idArr[1] + idNum;
        $(this).attr('id', newId);
        $(this).siblings('label.ssheetGetRowId').attr('for', newId);
    });
    // Add the row to the table.
    newRow.appendTo(table);
    // Remove the old row's ability to create a new row.
    row.removeClass('ssheetNewRow');
    row.find(".ssheet").unbind('change', createNewRow);
}

$(document).ready(function () {
    // Activate jQuery UI checkboxes.
    $(".checkButton").button().bind('change', buttonSwitchCheck).each(buttonSwitchCheck);

    // When text is entered on the bottom row, add a new row.
    $(".ssheetNewRow").find(".ssheet").not('.checkButton').bind('change', createNewRow);
});

编辑:我能够找到一个解决方案,我将分享这些年龄段。感谢下面的“Funky Dude”,他激励我开始思考正确的方向。

诀窍是在克隆之前销毁原始行中的jQuery UI按钮,然后立即为原始行和副本重新初始化它。您不需要取消绑定并重新绑定更改事件 - 它只是有问题的jQuery UI按钮。在createNewRow函数中:

row.find('.checkButton').button('destroy');
var newRow = row.clone(true);
row.find('.checkButton').add(newRow.find('.checkButton')).button().each(buttonSwitchCheck);

2 个答案:

答案 0 :(得分:2)

尝试使用允许委派的新方法.on,这有助于对DOM进行动态更改:

$(".checkButton").button().each(buttonSwitchCheck);
$("table").on("change", ".checkButton", buttonSwitchCheck);

我不确定,但它可能有助于不必担心将事件绑定到特定元素。

此外,您可以将其用于文本框change事件:

$("table").on("change", ".ssheetNewRow .ssheet:not(.checkButton)", createNewRow);

以下是我改变的小提琴:http://jsfiddle.net/Cugb6/3/

它没有任何不同,但对我来说,它有点清洁。我认为它会修复你的问题,但显然没有,因为button小部件的问题。

有趣的是,它似乎并不“支持”克隆:http://bugs.jqueryui.com/ticket/7959

答案 1 :(得分:1)

我认为你正在使用深度克隆,它也克隆了事件处理程序。在创建新行函数中,尝试解除更改事件的绑定,然后重新绑定克隆。