2

次の jQuery コードは (コード内のコメントごとに) 期待どおりに動作し、本質的には次のようになります。

  1. どのテーブル行がクリックされたかを検出し、
  2. テーブルの行を反復処理し、行に入力があるかどうかを判断します。
  3. 存在する場合は、その行のテキストボックスとテキストエリアの値を取得して保存します
  4. その行の tds から要素を削除します
  5. 入力を保存された値のラベルに置き換えます
  6. 次に、クリックされた行で、ラベルの値が保存され、
  7. ラベルは、保存された値が入力された入力に置き換えられます

関連するjQueryは次のとおりです。

// Detect row clicked and switch that row's labels to populated textboxes for editing
$('#tblBranchCoverage').on('click', 'tr', function () {

// When the following is commented out, the inputs work
//  If this block of code isn't commented, none of the rows inputs are editable
// First set any other rows back to labels if they have textboxes
$(this).parent().children('tr').each(function () {
    if ($(this).find('input').length > 0) {
        // Row has textboxes
        var county = $(this).find('#txtEditCounty').val(),
            state = $(this).find('#txtEditState').val(),
            zips = $(this).find('#txtEditZips').val(),
            $td = $(this).find('td');

        // Clear the cells first
        $td.html('');

        // Put the populated labels back in
        $(this).find('.countyCovered').text(county);
        $(this).find('.stateCovered').text(state);
        $(this).find('.zipsCovered').text(zips);
    }
});

// Only run this if there aren't already textboxes in the current row
if ($(this).find('input').length === 0) {
    // Get the values of the cells before the row is cleared
    var county = $(this).find('td.countyCovered').text(),
        state = $(this).find('td.stateCovered').text(),
        zips = $(this).find('td.zipsCovered').text();

    // Clear the text from the selected row
    $(this).find('.countyCovered, .stateCovered, .zipsCovered').text('');

    // Add textboxes to the cells populated with their respective values
    $(this).find('td.countyCovered').append('<input type="text" id="txtEditCounty" value="' + county + '" style="width: 111px;" /><br />' +
        '<input type="submit" id="btnSubmitCoverageEdits" value="Save Edits" /><br />' +
        '<input type="submit" id="btnCancelCoverageEdits" value="Cancel" />');
    $(this).find('td.stateCovered').append('<input type="text" id="txtEditState" value="' + state + '" max-length="2" style="width: 22px;" />');
    $(this).find('td.zipsCovered').append('<textarea id="txtEditZips" cols="100">' + zips + '</textarea>');

    // Size the textarea to its contents
    $('#txtEditZips').flexible();
}
return false;
});

前述したように、上記の機能は期待どおりに機能しますが、行内の入力の 1 つがクリックされると、編集カーソルがすぐに消えます (フォーカスが入力からすぐに削除されたかのように)。しかし、コードの最初のブロック (コードに記載) をコメントアウトすると、入力は期待どおりに編集可能になります。

このためにjsFiddleをセットアップしました。

4

2 に答える 2

2

これに対する簡単な解決策は、次の行をコードに追加することです。デモはこちら

$('#tblBranchCoverage').on('click', ':input', function (event) {
    event.stopPropagation();
});

この問題は、JavaScript のイベント バブリングが原因で発生しています。入力ボックスをクリックすると、入力をクリックした後、イベントが親要素に渡されます。したがって、すべての入力コントロールでイベントのバブリングを停止する必要があります。 event.stopPropagation();それを行うのに役立ちます。

于 2013-01-23T20:10:02.130 に答える
1

デモ: http://jsfiddle.net/nHgXf/2/

変更された Javascript:

var editting = false;

// Detect row clicked and switch that row's labels to populated textboxes for editing
$('#tblBranchCoverage').on('click', 'tr', function () {
    if(!editting)
    {
        editting = true;
    // When the following is commented out, the inputs work
    //  If this block of code isn't commented, none of the rows inputs are editable
    // First set any other rows back to labels if they have textboxes
$(this).parent().children('tr').each(function () {
        if ($(this).find('input').length > 0) {
            // Row has textboxes
            var county = $(this).find('#txtEditCounty').val(),
                state = $(this).find('#txtEditState').val(),
                zips = $(this).find('#txtEditZips').val(),
                $td = $(this).find('td');

            // Clear the cells first
            $td.html('');

            // Put the populated labels back in
            $(this).find('.countyCovered').text(county);
            $(this).find('.stateCovered').text(state);
            $(this).find('.zipsCovered').text(zips);
        }
    });

    // Only run this if there aren't already textboxes in the current row
    if ($(this).find('input').length === 0) {
        // Get the values of the cells before the row is cleared
        var county = $(this).find('td.countyCovered').text(),
            state = $(this).find('td.stateCovered').text(),
            zips = $(this).find('td.zipsCovered').text();

        // Clear the text from the selected row
        $(this).find('.countyCovered, .stateCovered, .zipsCovered').text('');

        // Add textboxes to the cells populated with their respective values
        $(this).find('td.countyCovered').html('<input type="text" id="txtEditCounty" value="' + county + '" style="width: 111px;" /><br />' +
            '<input type="submit" id="btnSubmitCoverageEdits" value="Save Edits" /><br />' +
            '<input type="submit" id="btnCancelCoverageEdits" value="Cancel" />');
        $(this).find('td.stateCovered').html('<input type="text" id="txtEditState" value="' + state + '" max-length="2" style="width: 22px;" />');
        $(this).find('td.zipsCovered').html('<textarea id="txtEditZips" cols="100">' + zips + '</textarea>');

        // Size the textarea to its contents
        $('#txtEditZips').flexible();
    }
    }
    editting =false;
    return false;
});

基本的に、クリックイベントにバインドしているため、すべてのJavaScriptが継続的に発生し、DOMと選択に問題が発生していました

于 2013-01-23T19:58:04.450 に答える