2013-02-12 49 views
2

我試圖創建一個輸入表,當您在底線的輸入之一中輸入文本時,它會自動添加新行。大多數情況下,它工作正常。不過,我在使用jQuery UI複選框按鈕時遇到了一些麻煩。jQuery UI複選框在克隆時行爲異常

複選框按鈕應單擊時更改其圖標。這適用於原始按鈕,但添加新行時出現的克隆按鈕無法正常工作。

你可以看到它in jsfiddle here。要複製這個問題,請在第三個輸入中輸入一些文字。你會看到第四行出現。如果您按第四個複選框,您會看到第三個複選框是其圖標更改的複選框。錯誤的按鈕也會得到ui-state-focus,但實際上並沒有獲得焦點,這真的讓我感到困惑,雖然正確的按鈕確實獲得了ui狀態激活,並且據我所知,看起來似乎評估爲已被檢查正常。

要清楚,兩個複選框做不是具有相同的ID,並且它們的標籤是正確的複選框 - createNewRow()函數負責。如果你註釋掉將複選框變成jQuery UI複選框的行,你會看到一切正常。如果你在buttonSwitchCheck函數中console.log $(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); 

回答

1

我認爲你正在使用深克隆,也克隆了事件處理程序。在創建新的行函數中,嘗試解除綁定更改事件,然後重新綁定克隆。

+0

我已經嘗試過這樣做;沒有快樂。但是,謝謝。 – flyingGhoti 2013-02-12 18:36:15

+1

啊 - 但我沒有試過的是在按鈕克隆之前銷燬按鈕,然後重新創建按鈕! – flyingGhoti 2013-02-12 18:43:43

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

+0

不幸的是,這並沒有解決問題。不過謝謝!我將不得不更多地關注'.on'方法;它看起來很有用。 – flyingGhoti 2013-02-12 18:38:36

+0

@flyingGhoti我真的認爲會這樣,但是在用你的小提琴進行測試之後,意識到這是'按鈕'小部件的問題。對不起,它沒有解決它,但希望它有助於什麼。我用一些東西更新了我的答案 – Ian 2013-02-12 19:00:04

+0

這確實有一定的優雅。當我接近它時,我可以在整個項目中實施變更。至於jQuery UI不支持克隆......那麼,我只是說這對於知道並保留它是有用的。 – flyingGhoti 2013-02-12 19:07:51