solerous
solerous

Reputation: 75

show/hide dynamically added divs using jQuery

I have a little combobox allowing a user to select the number of family members they want to register for an event. But if the family members are not U.S. Citizens, I want to show a second set of options for them to enter. I can dynamically add the elements, but I don't know how to show/hide the citizenship fields.

I'm new to jQuery and so I'm probably doing this the wrong way, but here's the function that adds the fields:

function familySize() {
        while (famElements < $("#famNum").val()) { // add fields
                    addFields = '<div class="member"> Name:&nbsp;<input id="name" type="text" placeholder="Name" required> &nbsp;&nbsp;<input id="cit" type="checkbox" onChange="citizenInfo()" >&nbsp;&nbsp;Non U.S. Citizen?<br/></div> <div class="citInfo" style="display:none"> <input id="countryCitizenship" type="text" placeholder="Citizenship" required> </div>';
                    document.getElementById('famItems').innerHTML += addFields;
                    famElements++;
                }
        while (famElements > $("#famNum").val()) { // remove fields
            console.log("remove one");
             $('#famItems div:last').remove();
             famElements--;
        }
    }

<div id="famItems">
            </div>

The style="display:none" on the citInfo div does hide it initially but I just need to figure out how to capture the clicks on the checkboxes to hide/show the citizenship text inputs.

Upvotes: 2

Views: 2064

Answers (3)

solerous
solerous

Reputation: 75

I finally figured it out just through sheer trial and error. If I enclose both the "member" div and the "citInfo" div in another div and then change the checkbox definition to this:

<input class="cit" onChange="citizenInfo(this)" type="checkbox">

then all I need is this function:

function citizenInfo(chkBox) {
 $(chkBox).parent().parent().find('.citInfo').toggle();
}

Upvotes: -1

DarthJDG
DarthJDG

Reputation: 16591

If you're using jQuery, just use a selector instead of getElementById() and use append() to add content to it.

Also, you should never have two items with the same ID. You can sort it out by appending your famElements counter to the IDs of your input fields. As this change ruled out selecting the elements by ID, I also changed your checkboxes to have a class cit, so I can attach the event using an easy selector.

For the click event, you can use .live() or .delegate() so you don't have to keep binding events all the time.

function familySize() {
    while (famElements < $("#famNum").val()) { // add fields
        famElements++;
        addFields = '<div class="member"> Name:&nbsp;<input id="name'+famElements+'" type="text" placeholder="Name" required> &nbsp;&nbsp;<input class="cit" id="cit'+famElements+'" type="checkbox" onChange="citizenInfo()" >&nbsp;&nbsp;Non U.S. Citizen?<br/></div> <div class="citInfo" style="display:none"> <input id="countryCitizenship'+famElements+'" type="text" placeholder="Citizenship" required></div>';
        $('#famItems').append(addFields);
    }
    while (famElements > $("#famNum").val()) { // remove fields
        console.log("remove one");
        $('#famItems div:last').remove();
        famElements--;
    }
}

// Your jQuery ready function
$(function(){
    // Click event on checkboxes
    $('#famItems').delegate('.cit','click',function(){
        var $this = $(this);

            // Show or hide the div
        if($this.is(':checked')){
            $this.parent().find('.citInfo').hide();
        } else {
            $this.parent().find('.citInfo').show();
        }
    });
});

You can build your elements more elegantly with jQuery, but it does what it needs to do. Although you might consider doing that in case you add to your HTML and that big lump of text becomes too much of a mystery.

Upvotes: 1

Mutt
Mutt

Reputation: 935

Use jQuery's live function to handle events of dynamically created items.

$(function(){
    $('#cit').live('change', citizenInfo());
});

Upvotes: 3

Related Questions