2

I'm trying to build a page with a few task lists. For this part, I want to use dynamic input fields. The form is being looped by a foreach, which looks to the number of users.

The problem now is that the tags (add, remove and reset) are not working except at the "first loop". And when I click on the on the first loop value, a field will be added at all the "loops", instead of only the first loop.

My PHP Code:

<?php 
    foreach (glob(/*user as file*/) as $filename) {
        echo '
            <div class="col-md-4 taskblock">
                <img class="taskimage" src="../../../'.$filename.'"/>
                <div class="name">User</div>
                <div class="dynamic-form">

                <a id="add">Add</a> | <a id="remove">Remove</a>  | <a id="reset">Reset</a>  

                    <form>
                    <div class="inputs">
                    <div><input name="dynamic[]" class="field" value="1" type="text"></div>
                    </div>
                    <input name="submit" class="submit" value="Submit" type="button">
                    </form>
                    </div>

                </div>
            ';
    }
?>

And my Script:

$(document).ready(function(){

    var i = $('input').size() + 1;

    $('#add').click(function() {
        $('<div><input type="text" class="field" name="dynamic[]" value="' + i + '" /></div>').appendTo('.inputs');
        i++;
    });

    $('#remove').click(function() {
        if(i > 1) {
            $('.field:last').remove();
            i--;
        }
    });

    $('#reset').click(function() {
        while(i > 2) {
        $('.field:last').remove();
        i--;
        }
    });

    // here's our click function for when the forms submitted

    $('.submit').click(function(){

        var answers = [];
        $.each($('.field'), function() {
            answers.push($(this).val());
        });

        if(answers.length == 0) {
            answers = "none";
        }

        alert(answers);

        return false;

    });

});

1 Answer 1

1

Preamble

Multiple things to fix here.

id vs class

An id property must be unique in a document. This is the reason add, remove and reset only affect the first item. We must change them to class.

<a class="add">Add</a> | <a class="remove">Remove</a>  | <a class="reset">Reset</a>

Counting the fields

Because you are using var i = $('input').size() + 1;, you are actually counting both the text fields and the submit buttons. As such, If you have 3 items and add a text field, it will be populated with the value 7 instead of 4. We must limit the counting to text fields by targeting them with their class .field:

var i = $('input.field').size() + 1;

Targeting the current item only

Because you use appendTo('.inputs');, you add a new text field to all items as they each have that element. You must limit the addition to the current item.

To achieve this, we make use of the this keyword, which will return the add element that triggered the event. From there, we reach the parent element, look for the .inputs element within it, then we inject the new element into it.

$(this).parent().find('.inputs')
    .append('<div><input type="text" class="field" name="dynamic[]" value="' 
    + i + '" /></div>');

That same basic logic must be applied to remove, but for reasons explained in the next part, we will do something slightly different:

var field = $(this).parent().find('.field:gt(0):last')
i -= field.length;
field.remove();

A better reset

Because the variable i is common to all items, its value is always larger than the number of text fields found in any item. Using reset will simply remove all text fields. Instead we must remove all fields except the first from the current item and alter i by subtracting the number of fields we remove.

We select all the fields except the first using the :gt() selector, subtract the number of returned fields from i and then remove the fields.

var fields = $(this).parent().find('.field:gt(0)');
i -= fields.length;
fields.remove();

Epilogue

A demo in available in this JSFiddle.

I'm also not quite sure about the purpose of the variable i and would promptly ditch it, due to its global nature.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your answer, it did the trick! I removed the i variable, it was only for testing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.