0

jquery を使用して、ユーザーの選択に基づいていくつかの html フィールドを複製しています。しかし、興味深い問題に遭遇しました。一般的に、ユーザーに必要なアプリケーションの数を選択するように求めています。

  1. アプリケーションが 1 つしかない場合: 適用方法を選択する必要があります(簡単にするために、「空中」のみが利用可能です)。b. 「空中」を選択すると、さらに詳しい情報、化学的塗布法 (CAM) を尋ねられます。

  2. 2 つのアプリケーションを選択すると、jquery コードがクローンを作成し、必要な質問の名前を変更します。

私の問題は、2 つのアプリケーションがあることを選択すると、サブ質問「CAM」が表示されないことです。いくつかのトラブルシューティングの後、問題はこの JavaScript にある可能性があることがわかりました: $('.app_method:last').find('select').change(function(). このステートメントは、自動的にループ インデックスを 1 増やします (なぜこれが起こるのか教えてもらえますか?)、これはコードと一致しません。

ここに私のコードのデモがあります:

以下は私のhtmlコードです:

<div class="articles">
        <table align="center">

        <tr><th><label for="id_NOA">Number of applications:</label></th><td><select name="NOA" id="id_NOA">
            <option value="1" selected="selected">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select></td></tr>

        <tr><th><label for="id_Ap_m">Application method 1</label></th><td><select name="Ap_m" id="id_Ap_m">
            <option value="" selected="selected">Select an application method</option>
            <option value="1">Aerial</option>
        </select></td></tr>

        <tr><th><label for="id_CAM_1">Chemical application Method (CAM) 1</label></th><td><select name="CAM_1" id="id_CAM_1">
            <option value="2">2-Interception based on crop canopy</option>
            <option value="9">9-Linear foliar based on crop canop</option>
        </select></td></tr>
        </table>
 </div>

jquery コード:

$(document).ready(function() {

    //this part of code controls inputs when there is only one application
    $('#id_CAM_1').attr('id', 'id_1').closest('tr').addClass('method_options').hide();
    $('#id_Ap_m').change(function() {
        $('tr.method_options').hide();
        if ($(this).val() == "1") {
            $('#id_' + $(this).val()).closest('tr').show();
        }
    });

    i = 1;
    $('.articles').find('table').addClass('table');
    $('#id_Ap_m').closest('tr').addClass('app_method');

    $('#id_NOA').change(function() {
        var total = $(this).val();

        //remove all
        $('.app_method').each(function(index) {
            if (index != 0) $(this).remove()
        });

        //create new ones
        for (var i = 2; i <= total; i++) {
            alert('a=' + i);

            $('.app_method:first').clone().appendTo('.table').find('label').text('Application method ' + i);
            $('.app_method:last').find('select').attr('name', 'Ap_m' + i).attr('id', 'id_Ap_m' + i);
            alert('b=' + i);

            $('<tr class="method_options_1' + i + '" style="display: none;"><th><label for="id_CAM_1">Chemical application Method (CAM)' + i + '</label></th><td><select name="CAM_1_' + i + '" id="id_1_' + i + '"><option value="2">2-Interception based on crop canopy</option><option value="9">9-Linear foliar based on crop canop</option></select></td></tr>').appendTo('.table');
            alert('c=' + i);

//The following statement increase the loop index by one, which causes me problems. Can    
//anyone let me know why this could happen?
            $('.app_method:last').find('select').change(function() {
                alert('d=' + i)
                $('.method_options_1').hide();
                alert('e=' + i);

                if ($(this).val() == "1") {
                    alert('e=' + i);
                    $('.method_options_1' + i).show();
                }
            })
        }
    })
})​

</p>

4

1 に答える 1

2

これはもっと簡単にできると思います:(フィドル: http://jsfiddle.net/QaHWz/ )

<!DOCTYPE html><html><head></head><body>

<table align="center"><tbody>
    <tr><th></th><td><a href="#" id="add_application">Add Application</a></td></tr>
</tbody></table>

<table id="template" style="display:none"><tbody>
    <tr>
        <th><label for="id_Ap_m_{n}">Application method {n}</label></th>
        <td>
            <select class="Ap_m" name="Ap_m_{n}" id="id_Ap_m_{n}" data-application="{n}">
                <option value="" selected="selected">Select an application method</option>
                <option value="1">Aerial</option>
            </select>
        </td></tr>
    <tr style="display:none" class="app_{n} method_1"><th><label for="id_CAM_{n}">Chemical Application Method (CAM) {n}</label></th><td><select name="CAM_{n}" id="id_CAM_{n}">
        <option value="2">2-Interception based on crop canopy</option>
        <option value="9">9-Linear foliar based on crop canopy</option>
    </select></td></tr>
</tbody></table>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
jQuery(function($) {
    var applications = 0;
    $('#add_application').click(function() {
        applications++;
        var last_row = $(this).closest('tr');
        last_row.before(jQuery('#template tbody').html().replace(/{n}/g, applications));
    });
    $(document).delegate('.Ap_m', 'change', function() {
        var app = $(this).data('application');
        $('.app_'+app).hide();
        $('.app_'+app+'.method_'+this.value).show();
    });
});
</script>
</body></html>

編集:あなたが抱えている問題は、関数が実行される前にインクリメントされる変数.change()を使用していることです。の値を別の方法で関数iに取得する必要があります。これを行う方法の 1 つを次に示します。i

$('.app_method:last').find('select').bind('change', { row: i }, function(event) {
    var i = event.data.row;
    alert('d=' + i)
    // ...
});

この{ row: i }ビットにより、jQuery はこのデータを関数に渡されるイベント オブジェクトにアタッチします。次にvar i、外部の影響を受けない関数のスコープ内に作成しi、この値を割り当てます。

于 2012-06-29T23:14:27.807 に答える