DubFriend / jquery.repeater

Create a repeatable group of input elements
MIT License
390 stars 193 forks source link

how to add fields validation message ? #60

Open pat-och opened 7 years ago

pat-och commented 7 years ago

i have to add fields validation message in my repeater template. So the message container attribute must be improved at the same time as the corresponding inputs

This is the <span> attribute data-validate-for (very important as it receives the error message with ajax if the field is not correctly filled)

is it possible using repeater library to update this attribute or i need to add jquery developpment somewhere (library hack or out of the box ?)

below the html source code

<div data-repeater-list="group-a">

        <!-- repeater template -->
        <div data-repeater-item style="display:none;">

                        <label for="date">Date</label>
                        <input type="date" name="date" /> 
                        <span class="error_message" data-validate-for="date"></span>

                        <label for="amount">Amount</label>
                        <input type="text" name="amount" />
                        <span class="error_message" data-validate-for="amount"></span>

            <input data-repeater-delete type="button" value="delete" />
        </div>

        <!-- first group displayed -->
        <div data-repeater-item>

                        <label for="date">Date</label>
                        <input type="date" name="date" /> 
                        <span class="error_message" data-validate-for="date"></span>

                        <label for="amount">Amount</label>
                        <input type="text" name="amount" />
                        <span class="error_message" data-validate-for="amount"></span>

            <input data-repeater-delete type="button" value="delete" />
        </div>

</div>

expected values after user adding item

        <!-- first group displayed -->
        <div data-repeater-item>

                        <label for="date">Date</label>
                        <input type="date" name="group[1][date]" /> 
                        <span class="error_message" data-validate-for="group[1][date]"></span>

                        <label for="amount">Amount</label>
                        <input type="text" name="group[1][amount]" />
                        <span class="error_message" data-validate-for="group[1][amount]"></span>

            <input data-repeater-delete type="button" value="Supprimer" />
        </div>

thanks by advance

pat-och commented 7 years ago

i hack the jquery.repeater.js a bit by adding this code (looking for adding by Pat-Och below)

        var setIndexes = function ($items, groupName, repeaters) {

            $items.each(function (index) {

                var $item = $(this);

                $item.data('item-name', groupName + '[' + index + ']');
                $filterNested($item.find('[name]'), repeaters)
                .each(function () {

                    var $input = $(this);

                    // match non empty brackets (ex: "[foo]")
                    var matches = $input.attr('name').match(/\[[^\]]+\]/g);

                    var name = matches ?
                        // strip "[" and "]" characters
                        last(matches).replace(/\[|\]/g, '') :
                        $input.attr('name');

                    var newName = groupName + '[' + index + '][' + name + ']' +
                        ($input.is(':checkbox') || $input.attr('multiple') ? '[]' : '');

                    $input.attr('name', newName);

                    $foreachRepeaterInItem(repeaters, $item, function (nestedFig) {
                        var $repeater = $(this);
                        setIndexes(
                            $filterNested($repeater.find('[data-repeater-item]'), nestedFig.repeaters || []),
                            groupName + '[' + index + ']' +
                                        '[' + $repeater.find('[data-repeater-list]').first().data('repeater-list') + ']',
                            nestedFig.repeaters
                        );
                    });
                });
                //***** adding by Pat-Och
                if (fig.errorMessage) {

                    $filterNested($item.find('.' + fig.errorMessageClass), repeaters)
                        .each(function () {

                            var $span = $(this);

                            // match non empty brackets (ex: "[foo]")
                            var matches = $span.attr('data-validate-for').match(/\[[^\]]+\]/g);

                            var dataValidateFor = matches ?
                                // strip "[" and "]" characters
                                last(matches).replace(/\[|\]/g, '') :
                                $span.attr('data-validate-for');                        

                            var newDataValidateFor = groupName + '[' + index + '][' + dataValidateFor + ']' +
                                ($span.is(':checkbox') || $span.attr('multiple') ? '[]' : '');                        

                            $span.attr('data-validate-for', newDataValidateFor);

                        });
                }
                //***** end adding by Pat-Och
            });

            $list.find('input[name][checked]')
                .removeAttr('checked')
                .prop('checked', true);
        };

in repeater.js

$(document).ready(function () {

    $('.repeater').repeater({
        ....
        // (Optional)
        // manage fields validation message
        // 
        errorMessage: true,
        errorMessageClass: 'error_message',

    })

});
fnicu commented 6 years ago

Hi @pat-och i'm using validation in a repeater, and thanks to you i have the right label on data-validate-for. But I don't really know how can I actually validate the inputs and how to display some message under each input. Thanks.

pat-och commented 6 years ago

if I remember well, as you usually do in your controller (you may need to reprocess your post data to be able to use them correctly in your controller)

fnicu commented 6 years ago

Sorry but not following you. I want to validate an email in eachone of the inputs since is a repeater; so somewhere I have to reprocess the repeater to handle validation?

pat-och commented 6 years ago

you validate your input data as usual, in the controller method which receives the input of your form. display with your debug tool the content of the input and you will see.