Close

Our Bestseller > OneUp - A responsive full-featured WordPress theme + 6 months technical support for just $44 Live Demo

Open Announcement

Pixelentity

Dynamic Forms: jQuery clone() & live()

Download via jsfiddle

Say you want to create a form that lets users insert tags but the tag number is not fixed. Here is a quick method to deal with this scenario.

How we can easily manage a variable number of tags ? Well we can start with a single text field, then provide 2 buttons: The first to add an additional tag and the second to remove a tag. Let’s begin with some simple markup for our dynamic form.

HTML

<form id="multi">
    <div>
        <label>Tag</label><input class="tag" type="text" name="tag" type="text" />
        <a href="#" data-action="add">add</a>
        <a href="#" data-action="delete">delete</a>
    </div>
    <input type="submit" value="save" >
</form>

Now that we have a single but ugly tag input box, lets first solve the uglyness problem by adding some basic css styles.

 

CSS

form {
    font-family: helvetica, arial, sans-serif;
    font-size: 11px;
}

form div{
    margin-bottom:10px;
}

form a {
    font-size: 12px;
    padding: 4px 10px;
    border: 1px solid #444444;
    background: #555555;
    color:#f7f7f7;
    text-decoration:none;
    vertical-align: middle;
}

form a:hover{
    color:#ffffff;
    background:#111111;
}

#multi label {
    margin-left:20px;
    margin-right:5px;
    font-size:12px;
    background:#f7f7f7;
    padding: 4px 10px;
    border:1px solid #cccccc;
    vertical-align: middle;
}

#multi input[type="text"]{
    height:22px;
    padding-left:10px;
    padding-right:10px;
    border:1px solid #cccccc;
    vertical-align: middle;
}

#multi input[type="submit"]{
    margin-left:20px;
    border:none;
    background:#222222;
    outline:none;
    color:#ffffff;
    padding: 4px 10px;
    font-size:12px;
}

Ok, now our forms still actually does nothing, but at least it looks better. So now we need to make this thing work. First thing will be to add an event listener to our “Add” and “Remove” buttons so that we can handle both operations. How do we add another tag to the existing form ? We create a new DOM element as follows:

 

Add DOM Element


var newTag = $('<div><label> ..... other markup here ....</div>');

Next using bind() we add our event listener to this newly created tag, so that the “Add” and “Remove” buttons will work for it also, and than in turn add any new element to the form. However, since the new tag has exactly the same structure as the existing ones, we can instead just use the clone() jQuery method.

 

As the name suggest, this method will clone() a source DOM element hence making a copy that we can insert in our form. But what about the “Add” and “Remove” buttons ? Well, using clone(true) would also copy all event listeners which are bound to the source element, however in this instance we will use another method.

Instead of clone(true), we’ll use the live() method. The live() method works like bind() with the difference being that the event listeners will also be bound to any DOM elements we add after the live() call has been executed. Below is an example of this.

The live() Method


var multiTags = $("#multi");

multiTags.find("a").live("click", handler);

As a result, from now on, each new “a” element added to our form will have “click” events trigger our original “handler” function.
So, our complete code will be as follows:

 

Full Javascript Code

jQuery(function($) {

    var multiTags = $("#multi");

    function handler(e) {
        // get the element who trigged the event
        var jqEl = $(e.currentTarget);
        // get his parent div
        var tag = jqEl.parent();
        // check which action we should perform
        switch (jqEl.attr("data-action")) {
        case "add":
            // clone the tag (div), reset his input text field
            // and place the new tag after the current one
            tag.after(tag.clone().find("input").val("").end());
            break;
        case "delete":
            // remove the element
            tag.remove();
            break;
        }
        return false;
    }

    multiTags.find("a").live("click", handler);
});

To collect entered all tag values, we could bind a simple function to the form submit event.

 

Collect Tag Values

jQuery(function($) {

    // early code here

    function save(e) {
        var tags = multiTags.find("input.tag").map(function() {
            return $(this).val();
        }).get().join(',');
        alert(tags);
        return false;
    }

    multiTags.submit(save).find("a").live("click", handler);
});

And there you have it. Check out the demo below, or demo externally via the “Demo” button at the top of the post.

 

Demo

Tags: ,

Leave a Reply