Nested dynamically generated forms using jQuery

1.4k views Asked by At

I am creating a survey generator. I want to be able to add multiple choice answers to dynamically generated forms. As seen in the image below.

enter image description here

Currently, adding questions and removing them works perfectly. The problem is that adding and removing answers only works for the first question.

Here is my html partial and scripts:

@extends('app')

@section('content')
    {!! Form::model($survey = new \App\Survey, ['url' => 'surveys']) !!}
    <h1 style="text-align:center">Create a new Survey</h1>

        <div class="form-group">
            {!! Form::label('title', 'Title:') !!}
            {!! Form::text('title', null, ['class' => 'form-control']) !!}
        </div>

    <hr/>

    <div id="input_fields_wrap">
        <div class="form-group">
            {!! Form::label('question', 'Question:') !!}
            <div class="input-group">
                {!! Form::text('questions[]', null, ['class' => 'form-control']) !!}
                <span class="input-group-btn"><button class="btn btn-default btn-info add_answer_button" type="button">Add Answer</button></span>
            </div>
        </div>
        <div class="input_answers_fields_wrap" style="margin-left:40px;">
            {{--Dynamically added answer boxes--}}
        </div>
    </div>
    <div id="add_question_button" class="btn btn-primary" style="margin-bottom:15px" type="text">Add another Question</div>

    <div class="form-group">
        {!! Form::submit('Add Survey', ['class' => 'btn btn-primary form-control']) !!}
    </div>
    {!! Form::close() !!}

@endsection

@section('footer')

    <script>
        // Jquery for adding a question
        $(document).ready(function() {
            var max_fields      = 10; //maximum input boxes allowed
            var wrapper         = $("#input_fields_wrap"); //Fields wrapper
            var add_button      = $("#add_question_button"); //Add button ID

            var x = 1; //initial text box count
            // Add a question
            $(add_button).click(function(e){ //on add input button click
                e.preventDefault();
                if(x < max_fields){ //max input box allowed
                    x++; //text box increment
                    $(wrapper).append('<div class="form-group"><div class="input-group" style="margin-bottom: 15px;">{!! Form::text('questions[]', null, ['class' => 'form-control']) !!}<span class="input-group-btn"><button class="btn btn-default btn-info add_answer_button" type="button">Add Answer</button><button class="btn btn-default btn-danger remove_field" type="button">Remove</button></span></div></div><div class="input_answers_fields_wrap" style="margin-left:40px;"> </div>');
                }
            });

            $(wrapper).on("click",".remove_field", function(e){ //user click on remove text
                e.preventDefault(); $(this).parent().parent('div').remove();
                x--;
            })
        });

        // Jquery for adding an answer to a question
        $(document).ready(function() {
            var max_fields      = 4; //maximum input boxes allowed
            var wrapper         = $(".input_answers_fields_wrap"); //Fields wrapper
            var add_button      = $(".add_answer_button"); //Add button ID

            var x = 1; //initial text box count
            // Add an answer
            $(add_button).click(function(e){ //on add input button click
                e.preventDefault();
                if(x < max_fields){ //max input box allowed
                    x++; //text box increment
                    $(wrapper).append('<div class="input-group" style="margin-bottom: 15px;">{!! Form::text('answers[]', null, ['class' => 'form-control']) !!}<span class="input-group-btn"><button class="btn btn-default remove_field" type="button">Remove</button></span></div>');
                }
            });

            // Remove a field
            $(wrapper).on("click",".remove_field", function(e){
                e.preventDefault(); $(this).parent().parent('div').remove();
                x--;
            })
        });
    </script>

@endsection

1

There are 1 answers

0
wholevinski On

I think this is your issue: the call to $(".input_answers_fields_wrap") only does the query the first time, so your click handler here:

$(wrapper).on("click",".remove_field", function(e){

is only working for that first one that's rendered.

You should use something besides the dynamically added .input_answers_field_wrap and use something higher up in the dom like:

$("body").on("click",".remove_field", function(e){

EDIT: Note that your head was in the right place when using the secondary selector arg, BUT that first .input_answers_fields_wrap is the only one that's been rendered, so it's the only one that it will apply to.