Question

So Im using jquery to clone a div so I can keep an input array dynamic in size. Its working fine but I can't help looking at it and thinking that adding the class before the clone so I can remove the old add more link after the clone with remove after i remove the class from the clone can be done more efficiently. Or perhaps overall more efficient way to do this.

Heres the html:

<div class="reg_heading_description" id="bio_brothers"></div>
                <div class="bio_brother">
                    <div class="clearfix">
                    <label>First Name</label>
                        <div class="input">
                        <input type="text" name="bio_brother_first[]" style="float:left"/>
                    <label>Last Name</label>
                        <input type="text" name="bio_brother_last[]" style="margin-left:20px;"/>                            
                        </div>                          
                    </div>
                    <div class="clearfix">
                    <a href="#" class="more_bio_brother more_relatives" >Add Another</a>
                    </div>
                </div>
            </div>  

and heres the jquery, and yes its in no conflict mode

<script type="text/javascript">
jQuery(document).ready(function () {

    jQuery(".more_bio_brother").click(function () {
        var here = jQuery(this).closest('div').parent();
        var names = jQuery(here).find('input');
        //validate
        var check = 0;
        jQuery.each(names, function () {
            if (jQuery(this).val() == "") {
                check = 1;
            }
        });
        if (check == 1) {
            alert('You must enter a first and last name for this biological brother before you can add another.');
            return false;
        }
        //disable prior 
        jQuery.each(names, function () {
            jQuery(this).attr('readonly', true);
        });
        //add new
        jQuery(here).addClass('old');
        jQuery('#bio_brothers').before(jQuery(here).clone(true));
        jQuery.each(names, function () {
            jQuery(this).attr('readonly', false);
            jQuery(this).val("");
        });
        jQuery(here).removeClass('old');
        jQuery('.old a').remove();
        return false;
    });
});
</script>
Was it helpful?

Solution

Want more than you asked for?

I had a similar situation where I would actually DO stuff, attach events, add data etc. to a group of elements (validation, change events, whatever). I even had a remove button on each "row". Thus I needed to not only clone but clone the data, events, etc, but not always. Sometimes I needed my new stuff before the last row, at the end, etc.

I also wanted to be able to chain my custom row adder.

I also wanted a default number of "blank" rows that would exist.

So, given your structure (slightly modified) I came up with this:http://jsfiddle.net/BGJNP/

EDIT: ADDED a version that has some validation as perscribed: http://jsfiddle.net/BGJNP/1/

OTHER TIPS

There are probably at least a half-dozen perfectly valid ways to accomplish your goal AND make it more efficient. For my two cents, I would:

A) Keep just one "Add New" link on the page, bind an event to it, and never clone and destroy it. Your "Add New" is always going to have just one job: adding a new empty form.

B) On "Add New", I would have a mini-form ready to go, either as an HTML string or as an unattached DOM node. For the former, use the string and append it where it needs to go; for the latter, clone it and attach it where you want it (the original is still unattached and ready for the next time). Heck, if you want to do the latter, when the page first initializes there is an empty form that you can clone as your 'template'.

C) Also on "Add New", I like your idea of disabling the form elements, so I would continue doing this.

Sorry for no code sample, but hopefully this gives you an idea.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top