0

I have multiple groups of dynamic fields I need to add to a form, I used an example to get the main bit working, but I need to setup the javascript to 'target' specific set of

Here is a bootply example

You can see that when the add button is clicked it adds[clones] a new field in the file-controls div. I need to somehow detect the class of the parent [well, 4th predecessor] div when the add button gets clicked.

How is this done?

HTML:

<form id="form" name="form" method="post" class="form" role="form" action="[[~[[*id]]]]" enctype="multipart/form-data">

    <input type="hidden" name="id" value="[[+id]]">


    <div class="row">

      <div class="form-group col-sm-6 [[!+fi.error.expires:notempty=` has-error`]]">
        <label for="expires">Expires</label>
        <select name="expires" class="form-control">
          <option value="24">24 hours</option>
          <option value="48">48 hours</option>
          <option value="72">72 hours</option>
          <option value="96">96 hours</option>
        </select>
      </div>

      <div class="form-group col-sm-6 [[!+fi.error.origin:notempty=` has-error`]]">
          <label for="origin">Origin</label>
          <input name="origin" type="text" id="origin" value="" class="form-control">
      </div>

    </div>

    <div class="row">

      <div class="col-sm-12"><label>Tag numbers: </label></div>

      <div class="tag-controls"> 

        <div class="entry col-sm-4">
          <div class="input-group">
            <input class="form-control" name="fields[]" type="text" placeholder="Type something">
            <div class="input-group-btn">
              <button class="btn btn-success btn-add" type="button"><span class="glyphicon glyphicon-plus"></span></button>
            </div>
          </div>
        </div>

      </div>

    </div>

    <div class="row">

      <div class="col-sm-12"><label>Photos: </label></div>

      <div class="image-controls"> 

        <div class="entry col-sm-4">
          <div class="input-group">
            <input class="form-control" name="fields[]" type="text" placeholder="Type something">
            <div class="input-group-btn">
              <button class="btn btn-success btn-add" type="button"><span class="glyphicon glyphicon-plus"></span></button>
            </div>
          </div>
        </div>

      </div>

    </div>   

    <div class="row">

      <div class="col-sm-12"><label>Files: </label></div>

      <div class="file-controls"> 

        <div class="entry col-sm-4">
          <div class="input-group">
            <input class="form-control" name="fields[]" type="text" placeholder="Type something">
            <div class="input-group-btn">
              <button class="btn btn-success btn-add" type="button"><span class="glyphicon glyphicon-plus"></span></button>
            </div>
          </div>
        </div>

      </div>

    </div>

    <div class="form-group">
        <button type="submit" name="submit" id="submit" value="submit" class="btn button-sm btn-primary">Add Special Offering</button>
    </div>

</form>

Javascript:

// dynamic add form fields
$(function(){

    $(document).on('click', '.btn-add', function(e){

        console.log('button clicked');
        e.preventDefault();

        var controlForm = $('.file-controls'),
        currentEntry = $(this).parents('.entry:first'),
        newEntry = $(currentEntry.clone()).appendTo(controlForm);

        console.log(controlForm);
        console.log(currentEntry);
        console.log(newEntry);

        newEntry.find('input').val('');
        controlForm.find('.entry:not(:last) .btn-add')
        .removeClass('btn-add').addClass('btn-remove')
        .removeClass('btn-success').addClass('btn-info')
        .html('<span class="glyphicon glyphicon-minus"></span>');
        }).on('click', '.btn-remove', function(e)
        {

        $(this).parents('.entry:first').remove();

        e.preventDefault();
        return false;

    });

});
1
  • The 4th Predecessor is .image-controls? change your $(this).parents('.entry:first'); to $(this).parents('.image-controls'); Commented Jul 28, 2014 at 15:54

3 Answers 3

1

The below jquery in your button click event would find the 4 predecessor:

$(this).parent().parent().parent().parent().attr('class');

It might be a better idea to tag these parents with a more unique class then get the collection of $(this).parents(...) using this class name as a selector in the jquery. Below is a snippet of the html change you would need and the jquery

    //jquery

    console.log($(this).parents('.addBtnCntr').attr('class'));

    <!--html-->    
    <div class="tag-controls addBtnCntr">     
        <div class="entry col-sm-4">
          <div class="input-group">
            <input class="form-control" name="fields[]" type="text" placeholder="Type something">
            <div class="input-group-btn">
              <button class="btn btn-success btn-add" type="button"><span class="glyphicon glyphicon-plus"></span></button>
            </div>
          </div>
        </div>

      </div>
Sign up to request clarification or add additional context in comments.

Comments

0

You could give your container DIV ("image-controls" , "tag-controls" ...) another class to identify them as groupcontainer ... Like "myformgroup"

And approach it with $(this).closest(identifier) ...

For example:

<div class="tag-controls myformgroup"> 
            <div class="entry col-sm-4">
                <div class="input-group">
                    <input class="form-control" name="fields[]" type="text" placeholder="Type something">
                    <div class="input-group-btn">
                        <button class="btn btn-success btn-add" type="button"><span class="glyphicon glyphicon-plus">add</span></button>
                    </div>
                </div>
            </div>
        </div>

And in your JS:

            var container = $(this).closest(".myformgroup");
            var classNames = $(container).attr("class");
            var className = classNames.replace("myformgroup", "");
            alert(className.trim());

But now you can only use your controls-name and the "identifier" as class for the control wrapper.

I would recommend the use of "data-target" for your button:

        <div class="row">
        <div class="col-sm-12"><label>Tag numbers: </label></div>

        <div class="tag-controls"> 
            <div class="entry col-sm-4">
                <div class="input-group">
                    <input class="form-control" name="fields[]" type="text" placeholder="Type something">
                    <div class="input-group-btn">
                        <button class="btn btn-success btn-add" data-target="tag-controls" type="button"><span class="glyphicon glyphicon-plus">add</span></button>
                    </div>
                </div>
            </div>
        </div>
    </div>

JS:

alert($(this).data()["target"]);

1 Comment

Thanks, the data target looks the be the most elegant and reusable of the solutions. All I had to do was change the jquery: var controlForm = $("." + $(this).data()["target"]),
0

Easier way would be:

$(".formClass").append("<input id=3 />");

Comments

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.