1

システム内に構築されたすべてのフォームで機能する単一の form.js ファイルを使用して、HTML フォームを自動的にアセンブルし、インタラクティブにする動的フォーム システムを構築しています。私はすでにフォームシステムを完成させており、ほとんどの場合、ネストされた div のバグを除いて form.js は完了しています。

少し背景: 必要に応じてテスト中のフォームを投稿しますが、これで私のニーズを説明するのに十分だと思います。質問に回答すると依存関係が表示されるように、質問の依存関係を div に配置するフォームを使用しています。これがどのように機能するかをよりよく理解するために、フォーム システムでは依存関係を無限にネストすることができます。質問 1 に依存関係の質問があり、その依存関係に依存関係があり、質問 2 に依存関係がある場合、次のようになります。

Question 1:
    -> Dependency Question 1-1
         -> Dependency Question 1-1-1
Question 2
    -> Dependency Question 2-1

依存関係の各セクションは、スタイリングと編成のために、独自の div を含みます。

<form>    

    <!-- Other elements (not div) mainly form input, labels, and fieldsets-->

    <div id="dep-1" class="dependency">

        <!-- Other elements (not div) mainly form input, labels, and fieldsets-->

        <div id="dep-1-2" class="dependency">

            <!-- Other elements (not div) mainly form input, labels, and fieldsets-->

            <div id="dep-2-1" class="dependency">

                <!-- Other elements (not div) mainly form input, labels, and fieldsets-->

            </div>

        </div>

    </div>

</form>

ID は単なる表示用であり、フォーム システムによって自動化されています。

私の問題:すべてが思い通りに機能している、またはそう思っていました。すべてのフォームを制御するためのマスター js ファイルで私が抱えている唯一の問題は、ネストされた div です。フォームの読み込み時に、jQuery を使用してすべての依存関係を無効にし、フォームの送信を防ぎます。問題は、それらを再びオンにするときです。私が欲しい機能は、子div内ではなく、そのdivの:inputのみを有効にする依存関係divのためだけです。現在、親 div 内のすべての子 div :input がすべて有効になっています。私は、それが子供のdivに入らないようにするために多くの方法を試し、GoogleとSOに2時間以上費やしました. まだ運がありません...だからここで私はあなたの助けを求めています!

これに使用される form.js コード

function _toggleDependencyContainer(id, result) {
    if (result === true) {
        // Allow only input of parent dependency div, not children dependency divs
        $('#'+id).find(':input').each(function() { // **THIS LINE IS THE ISSUE!!**
            $(this).removeAttr("disabled");
        });
        $('#'+id).slideDown();
    } else {
        // Disable all children input through all child divs
        $('#'+id).slideUp().find(':input').each(function() {
            $(this).attr("disabled", "disabled")
        });
    }   
}
function _toggleElementDependencies(element) {
    if (element.type === undefined) {
        console.log('element.type is undefined');
        return;
    }
    // Get the dependency ID and result then toggle
    switch(element.type.toLowerCase()) {
        case 'select':
        case 'select-one':
        case 'select-multiple':
            $("#"+element.id+" option").each(function () {
                var id = element.id+'-'+this.value+'-dep';
                var result = this.selected;               
                if (id === undefined || id == null) {
                    return;
                }
                _toggleDependencyContainer(id, result);             
            });
            return;
            break;
        case 'radio':
        case 'checkbox':
            var id = element.id+'-dep';
            var result = $(element).is(':checked');
            break;
        case 'file':
        case 'password':
        case 'text':
        case 'textarea':
            var id = element.id+'-dep';
            var result = ( $.trim( $(element).val() ) ) ? true : false;
            break;
        default:
            return;
            break;
    }
    if (id === undefined || id == null) {
        return;
    }
    _toggleDependencyContainer(id, result);
}

$(document).ready(function() {

    $('.dependency').hide(); // hide all dependencies
    //
    // Scan page for forms
    // Loop through each form and process the elements to toggle dependencies
    $('form').each(function(i) {
        // Find all the input elements
        $('#'+this.id).find(':input').not(':disabled').each(function(i) {
            _toggleElementDependencies(this);
        });     
    });

    // Monitor form elements to toggle dependencies
    $(':input').blur(function() {
        _toggleElementDependencies(this);
    });
    $(':radio, :checkbox').click(function() {
        $('input[name="'+this.name+'"]').each(function(i) {
            _toggleElementDependencies(this);
        });
    });
    $('select').change(function() {
        _toggleElementDependencies(this);
    });

});

jQuery のマスターが不足しているスニペットを提供してくれることを期待しています。.not() セレクターを使用してみましたが、子 div に間違った識別子を使用していると思います。私が試してみました:

$('#'+id).not('div>div').find(':input').each(...);
$('#'+id).not('div:first').find(':input').each(...);
$('#'+id).not('div:first-chil').find(':input').each(...);
$('#'+id).not('div').find(':input').each(...);

他にもたくさんありますが、単純なものが欠けていると思います..

EDIT レイアウトを理解するのを助けるために使用しているフォームを追加しています

<form method="post" action="/_projects/newForm/" id="test" name="test">
    <fieldset>
        <legend>One</legend><label for="first-name">First Name&nbsp;<span class="required-icon">*</span></label>
        <input type="text" value="test" class="required" title="First Name" id="first-name" name="first_name">
        <div class="dependency" id="first-name-dep" style="display: block;">
            <label for="first-name2">First Name 2</label>
            <input type="text" title="First Name 2" id="first-name2" name="first_name2">
                <div class="dependency" id="first-name2-dep" style="display: none;">
                    <label for="first-name3">First Name 3</label>
                    <textarea title="First Name 3" id="first-name3" name="first_name3" disabled="disabled"></textarea>
                </div>
        </div>
        <label for="last-name">Last Name</label>
        <input type="text" title="Last Name" id="last-name" name="last_name">
        <label for="last-name2">Last Name2</label>
        <input type="text" title="Last Name2" id="last-name2" name="last_name2">
        <label for="radio-test">Radio Test&nbsp;<span class="required-icon">*</span></label>
        <fieldset class="options-cage" id="options-cage-radio-test">
            <label for="radio-test-1">
                <input type="radio" class="required" title="Yes" value="1" name="radio_test" id="radio-test-1">
                &nbsp;Yes
            </label>
            <label for="radio-test-2">
                <input type="radio" class="required" title="No" checked="checked" value="2" name="radio_test" id="radio-test-2">
                &nbsp;No
            </label>
        </fieldset>
        <div class="dependency" id="radio-test-1-dep" style="display: block;">
            <label for="radio-dep">Radio Dep&nbsp;<span class="required-icon">*</span></label>
            <input type="text" class="required" title="Radio Dep" id="radio-dep" name="radio_dep">
                <div class="dependency" id="radio-dep-dep" style="display: none;">
                    <label for="radio-dep2">Radio Dep 2</label>
                    <input type="text" title="Radio Dep 2" id="radio-dep2" name="radio_dep2" disabled="disabled">
                        <div class="dependency" id="radio-dep2-dep" style="display: none;">
                            <label for="radio-dep3">Radio Dep 3&nbsp;<span class="required-icon">*</span></label>
                            <fieldset class="options-cage" id="options-cage-radio-dep3">
                                <label for="radio-dep3-1">
                                    <input type="radio" class="required" title="Yes" value="1" name="radio_dep3" id="radio-dep3-1" disabled="disabled">&nbsp;Yes</label>
                                <label for="radio-dep3-2">
                                    <input type="radio" class="required" title="No" checked="checked" value="2" name="radio_dep3" id="radio-dep3-2" disabled="disabled">&nbsp;No</label>
                            </fieldset>
                            <div class="dependency" id="radio-dep3-1-dep" style="display: none;">
                                <label for="radio-dep4">Radio Dep 4&nbsp;<span class="required-icon">*</span></label>
                                <input type="text" class="required" title="Radio Dep 4" id="radio-dep4" name="radio_dep4" disabled="disabled">
                                    <div class="dependency" id="radio-dep4-dep" style="display: none;">
                                        <label for="radio-dep5">Radio Dep 5</label>
                                        <input type="text" title="Radio Dep 5" id="radio-dep5" name="radio_dep5" disabled="disabled">
                                            <div class="dependency" id="radio-dep5-dep" style="display: none;">
                                                <label for="radio-dep6">Radio Dep 6&nbsp;<span class="required-icon">*</span></label>
                                                <fieldset class="options-cage" id="options-cage-radio-dep6">
                                                    <label for="radio-dep6-1">
                                                        <input type="checkbox" class="required" title="Yes" value="1" name="radio_dep6" id="radio-dep6-1" disabled="disabled">
                                                        &nbsp;Yes
                                                    </label>
                                                    <label for="radio-dep6-2">
                                                        <input type="checkbox" class="required" title="No" checked="checked" value="2" name="radio_dep6" id="radio-dep6-2" disabled="disabled">
                                                        &nbsp;No
                                                    </label>
                                                </fieldset>
                                            </div>
                                    </div>
                            </div>
                        </div>
                </div>
        </div>
    </fieldset>
    <fieldset>
        <legend>Two</legend><label for="last-name3">Last Name3</label>
        <input type="text" title="Last Name3" id="last-name3" name="last_name3">
            <label for="checkbox-test">Checkbox Test&nbsp;<span class="required-icon">*</span></label>
            <fieldset class="options-cage" id="options-cage-checkbox-test">
                <label for="checkbox-test-10">
                    <input type="checkbox" class="required" title="Yup" value="10" name="checkbox_test[]" id="checkbox-test-10">&nbsp;Yup</label>
                <label for="checkbox-test-12">
                    <input type="checkbox" class="required" title="Nope" checked="checked" value="12" name="checkbox_test[]" id="checkbox-test-12">&nbsp;Nope</label>
            </fieldset>
            <label for="select-test">Select Test&nbsp;<span class="required-icon">*</span></label>
            <select title="Select Test" id="select-test" name="select_test" class="input-select required">
                <option value="">- Please Select</option>
                <option value="1">one</option>
                <option value="2">two</option>
            </select>
    </fieldset>
    <fieldset>
        <input type="hidden" value="test" id="formID" name="formID">
        <input type="hidden" value="dd7c7fae86db8988669231b67ce637138aa6c180" id="csrf" name="csrf">
        <input type="submit" value="Submit">
        <input type="reset" title="Reset the form?" value="Reset">
    </fieldset>
</form>
4

2 に答える 2

2

「私が欲しい機能は、子div内ではなく、そのdivの:inputのみを有効にする依存関係divだけです。」

私がそれをすべて理解したら、あなたはこれを変更するでしょう:

$('#'+id).find(':input').each(function() {

これに:

$('#'+id).children(':input').each(function() {

私の理解では、子入力のみをターゲットにしたいということです。「子」という用語を使用してすべての祖先を参照しているように見えることがありますが、実際には、子はネストの次のレベルのみを意味します。

祖先の比喩を続けると、より深くネストされた要素は孫、ひ孫などになります。

.find()メソッドはすべての祖先を調べますが、メソッド.children()は子のみを調べます。


補足: を明示的にコーディングする必要はありません.each()。あなたはこれを行うことができます:

 $('#'+id).find(':input').removeAttr('disabled');

そして、このメソッドはすべてのマッチに適用されます。


fieldsetDOM の選択はコンテナーのために少し複雑であることが判明したので、次のようにします。

$('#' + id + ' > :input, #' + id + ' > fieldset :input')

これはこれと同等です:

$('#' + id).children(':input').removeAttr('disabled')
$('#' + id).children('fieldset').find(':input').removeAttr('disabled')

最初の ID 選択をキャッシュすることはできますが、私はこれを好む傾向があります。

于 2012-05-12T19:49:35.450 に答える
0

「他の要素 (div ではない) 主に入力、ラベル、およびフィールドセットを形成する」の正確な DOM ツリーが何であるかがわからないため、このコードを使用して、要素内の入力を見つけることができますが、その依存関係divs.

更新版:

$("#" + id + " > :input, #" + id + " :not(div) :input").each(function() {
   // ...
});

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

于 2012-05-12T19:51:49.973 に答える