简体   繁体   中英

Dynamically add and remove form fields to be validated by Parsley.js

Here is my fiddle: My Fiddle (updated)

In my form (ID: #form), inputs fields are shown or hidden based on the selected option of a select input.

Each Input and its labels a wrapped in a div, which is hidden or shown based on the selected option. The attribute data-children of the select contains the information (in JSON Format) which inputs are to be shown when a certain option is selected.

I use the data-parsley-excluded attribute to remove the fields not visible from the parsley validation ( Parsley Documentation) . Before I execute the parsley method $('#form').destroy(); , at the end $('#form').parsley();

My HTML:

<div class="container">
  <div class="row">
    <div class="col-sm-offset-2 col-sm-8">
         <form id="form" method="post" accept-charset="UTF-8" class="form-horizontal" data-parsley-validate="">
            <div class="form-group">
                <label class="control-label" for="question_01" style="">Question 1</label>
                <select class="form-control" name="question_01" id="question_01" required data-children="{&quot;option_01&quot;:[&quot;input_01&quot;,&quot;input_02&quot;,&quot;input_03&quot;,&quot;input_04&quot;,&quot;input_05&quot;,&quot;input_06&quot;],&quot;option_02&quot;:[&quot;input_01&quot;,&quot;input_06&quot;,&quot;input_07&quot;,&quot;input_08&quot;,&quot;input_09&quot;,&quot;input_10&quot;],&quot;option_03&quot;:[&quot;input_02&quot;,&quot;input_04&quot;,&quot;input_05&quot;,&quot;input_07&quot;,&quot;input_09&quot;,&quot;input_10&quot;,&quot;input_11&quot;]}">
                    <option value="" selected>Bitte auswählen</option>
                    <option value="option_01">Option 01</option>
                    <option value="option_02">Option 02</option>
                    <option value="option_03">Option 03</option>
                </select>
            </div>
            <div id="div_input_01" class="form-group input-div hidden">
                <label for="input_01" style="">Input 01</label>
                <input type="text" class="form-control" name="input_01" id="input_01" required>
            </div>
            <div id="div_input_02" class="form-group input-div hidden">
                <label for="input_02" style="">Input 02</label>
                <input type="text" class="form-control" name="input_02" id="input_02" required>
            </div>
            <div id="div_input_03" class="form-group input-div hidden">
                <label for="input_03" style="">Input 03</label>
                <input type="text" class="form-control" name="input_03" id="input_03" required>
            </div>
            <div id="div_input_04" class="form-group input-div hidden">
                <label for="input_04" style="">Input 04</label>
                <input type="text" class="form-control" name="input_04" id="input_04" required>
            </div>
            <div id="div_input_05" class="form-group input-div hidden">
                <label for="input_05" style="">Input 05</label>
                <input type="text" class="form-control" name="input_05" id="input_05" required>
            </div>
            <div id="div_input_06" class="form-group input-div hidden">
                <label for="input_06" style="">Input 06</label>
                <input type="text" class="form-control" name="input_06" id="input_06" required>
            </div>
            <div id="div_input_07" class="form-group input-div hidden">
                <label for="input_07" style="">Input 07</label>
                <input type="text" class="form-control" name="input_07" id="input_07" required>
            </div>
            <div id="div_input_08" class="form-group input-div hidden">
                <label for="input_08" style="">Input 08</label>
                <input type="text" class="form-control" name="input_08" id="input_08" required>
            </div>
            <div id="div_input_09" class="form-group input-div hidden">
                <label for="input_09" style="">Input 09</label>
                <input type="text" class="form-control" name="input_09" id="input_09" required>
            </div>
            <div id="div_input_10" class="form-group input-div hidden">
                <label for="input_10" style="">Input 10</label>
                <input type="text" class="form-control" name="input_10" id="input_10" required>
            </div>
            <div id="div_input_11" class="form-group input-div hidden">
                <label for="input_11" style="">Input 11</label>
                <input type="text" class="form-control" name="input_11" id="input_11" required>
            </div>
            <button type="button" class="btn btn-info btn-block btn-submit-settings">Submit</button>
        </form>
   </div>
  </div>
</div>

My Javascript:

$(document).ready(function() {
    $('.btn-submit-settings').on('click', function(e) {
        window.Parsley.on('field:error', function()
        {
            console.log('Validation failed for: ', this.$element);
        });
        $('#form').submit();
    });

    $('#form select').change(function() {
        var $this = $(this);
        if ($this.data('children')) {
            $('#form').parsley().destroy();
            // Hide all child elements
            $.each($this.data('children'), function(value_id, input_id_array) {
                $.each(input_id_array, function(key, input_id) {
                    if ($('#div_' + input_id).length ) {
                        $('#' + input_id).val(null);
                        if (!$('#div_' + input_id).hasClass('hidden')) {
                            $('#div_' + input_id).addClass('hidden');
                        }
                    }
                });
            });
            // show the child elements of the selected option
            if ($this.data('children')[$this.val()]) {
                $.each($this.data('children')[$this.val()], function(key, input_id) {
                    if ($('#div_' + input_id).length )
                    {
                        if ($('#div_' + input_id).hasClass('hidden'))
                        {
                            $('#div_' + input_id).removeClass('hidden');
                        }
                    }
                });
            }
            // For all inputs inside hidden div set attribute "data-parsley-excluded" = true 
            $('#form div.input-div.hidden').find(':input').each(function() {
                var attr_data_parsley_excluded = $(this).attr('data-parsley-excluded');
                if (typeof attr_data_parsley_excluded === typeof undefined || attr_data_parsley_excluded === false) {
                    $(this).attr('data-parsley-excluded', 'true');
                }
            });
            // For all inputs inside not hidden div remove attribute "data-parsley-excluded"
            $('#form div.input-div:not(.hidden)').find(':input').each(function() {
                console.log(this.id);
                $(this).removeAttr('data-parsley-excluded');
            });

            $('#form').find(':input').each(function() {
                // Log shows that attribute is set right, seems to be ignored by parsley
                console.log('ID: ' + this.id + ' TYPE: ' + $(this).prop('nodeName') + ': excluded=' + $(this).attr('data-parsley-excluded'));
            });
            $('#form').parsley();
            $('#form').parsley().refresh();
        }
    });
});

I can't get it to work, even though the attributes seem to be set the right way.

The fields once hidden, stay out of the validation.

I guess you should add the attribute data-parsley-required="false" to exclude hidden fields from validation.

I mean, try to change

<input type="text" class="form-control" name="input_01" id="input_01" required>

to this

<input type="text" class="form-control" name="input_01" id="input_01" data-parsley-required="false">

and just change the attribute value if you want to validate it or not

This is more of a personal opinion than a factual answer, but I think you are attempting to solve the problem incorrectly. If I were doing this, I would create 2 parsley groups "shouldValidate" and "shouldNotValidate", and add your fields accordingly based on whether they are displayed or not. Then when you call validate, pass the group name "shouldValidate", and only that set of elements will be validated.

你可能需要调用refresh你的香菜表上修改后excluded

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM