0

I am attempting to create a set of radio buttons that I can easily clone on a button click. I am having difficulty as the underlying HTML requires labels to be attached to specific IDs on the DOM tree. My understanding of how to safely inject new code into the DOM with javascript is that I can't use IDs because they need to all be unique. Is there an accepted method of doing this type of cloning without having to maintain extra javascript variables to hammer together radio button IDs?

Also: I need to be able to delete these buttons sets freely.

A fiddle illustrating the problem and what I'm trying to accomplish can be found at http://jsfiddle.net/MrvYc/3/

D. G.
  • 451
  • 3
  • 11

2 Answers2

1

To link the label with the radio, instead of using a JS variable to maintain, you could generate a unique ID like a GUID, and use it directly.

When deleting the block, no need to have the ID, because you have the close HTMLElement that is inside the block, you can use parent() function and remove() function to do the job.

Here is an example:

/**
 * Generate a guid part
 */
function GuidPart()
{
    return Math.floor(Math.random() * 0x10000).toString(16);
}

/**
 * Generate a new GUID
 */
function getGuid()
{
    return (GuidPart() + GuidPart() + "-" +
            GuidPart() + "-" +
            GuidPart() + "-" +
            GuidPart() + "-" +
            GuidPart() + GuidPart() + GuidPart());
}

/**
 * Build a new block with radio, label and close span
 */
function buildNewRadio(labelText)
{
    // Retrieve a new guid
    var guid = getGuid();

    // Create a span container with the radio and label inside
    // linked together by the guid
    var container = $(document.createElement("span")).append(
        $(document.createElement("input")).attr('id', guid),
        $(document.createElement("label")).attr('for', guid).val(labelText))
        .addClass("container");

    // Finally append the close span (use to remove the entiere block)
    container.append(
        $(document.createElement("span").addClass("close")
            .click(function(mouseEvent) {
                // Retrieve the span container and remove it
                $(this).parent().remove();
            }));

    return container;
}

You can call the buildNewRadio function and attach the result HTMLElement to your DOM container

MatRt
  • 3,494
  • 1
  • 19
  • 14
  • I like how this approach doesn't require me to take up any real-namespace in the DOM. My main concern is in the randomness of Math.random(). [link](http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript) discusses creating GUIDs, and some of the comments point out that there's no good documentation on how well javascript conforms to the entropy requirements to obtain the full 2^122 range of properly formed GUIDs. Have you ever encountered uniqueness problems in using this code before? – D. G. Oct 18 '12 at 17:31
0

I usually just increment the auto generated ID by one each time a new input is added to the DOM:

<input type="button" id="addRadio" value="Add Radio Button" />
            <div id="container">
                <input type="radio" name="myRadio" id="myRadio1" />
                <label for="myRadio1">Radio 1</label>
            </div>

<script type="text/javascript">
            $(document).ready(function() {
                var maxId = 0;
                $('#addRadio').click(function() {
                    var nextId = (!maxId) ? $("input[name='myRadio']").length + 1 : maxId + 1;
                    var wrap = $('<div>').attr('id', 'wrap' + nextId);
                    wrap.append($('<input>').attr({
                        type : 'radio',
                        name : 'myRadio',
                        id : 'myRadio' + nextId
                    }));
                    wrap.append($('<label>').attr({
                        for : 'myRadio' + nextId
                    }).html('Radio' + nextId));
                    wrap.append($('<a>').attr({
                        href : 'javascript:void(0);'
                    })
                    .click(function() {
                        $('#wrap' + nextId).remove();
                    })
                    .html('Delete'));
                    $('#container').append(wrap);

                    maxId = nextId;
                });
});
</script>
marknatividad
  • 630
  • 8
  • 15