Question

Fist, let me say that I only started using js/jquery recently(like, 2 weeks ago)I've been beating my head against a wall in an effort to get all of the following tricks to play nicely together-- any help is greatly appreciated.

I have a form, inside of which the user can register multiple people for a class; inside of each registrant's "block," two radio buttons exist. Selecting one should show one set of class options, selecting the other should show the second set of options:

HTML:

<label for="name" class="label_heading">Registrant Name (first and last)</label>
<input type="text" id="name_1" value="name_1">
<br>
<p class="label_heading">Training Level:</p>
<label for="certification">
    <input type="radio" name="ClassLevel" value="certification" id="select-certification" class="select-certification">Certification

    <select class="copy hidden" name="cert" id="cert1">
        <option value="">Select a Certification Session</option>
        <option value="session1cert">Fort Dodge, IA May 5-9, 2014</option>
        <option value="session2cert">North Platte, NE Sept 22-26, 2014</option>
        <option value="session3cert">Omaha, NE Oct 13-17, 2014</option>
        <option value="session4cert">Waterloo, IA Oct 27-31, 2014</option>
        <option value="session5cert">Grand Island, NE Nov 17-21, 2014</option>
    </select>
</label>
<!--end label for certification-->
<label for="recertification">
    <input type="radio" name="ClassLevel" value="recertification" id="select-recertification" class="select-recertification">Recertification

    <select class="copy hidden" name="recert" id="recert1">
        <option value="">Select a Recertification Session</option>
        <option value="session1recert">Fort Dodge, IA May 8, 2014</option>
        <option value="session2recert">North Platte, NE Sept 25, 2014</option>
        <option value="session3recert">Omaha, NE Oct 16, 2014</option>
        <option value="session4recert">Waterloo, IA Oct 30, 2014</option>
        <option value="session5recert">Grand Island, NE Nov 20, 2014</option>
    </select>
</label>

So, the radio button with the value of "certification" needs to make the select with the name "cert" show up, and selecting "recertification" should make the select "recert" show up. Because I'm repeating this user registration block multiple times on the page, and because each needs to behave the same way, I've chosen to use classes and input["name:"] as selectors in my jQuery, like so:

$(document).ready(function () {
    $(".addReg").click(function (e) {
        $(".tbr_fieldset:hidden").slice($(".tbr_fieldset:hidden").siblings(":first").index(), 1).slideDown();
        e.preventDefault();
    });
});

$(document).ready(function () {
    $("input[name='ClassLevel']").change(function (e) {
        $(this).next(":first").toggle();
        e.preventDefault();
    });
});

This almost works. If you look at it in this http://jsfiddle.net/shark_goatshark/Aktwu/1/ you can see that my "registrant" box multiplies when the + button is clicked, and that the radio buttons do, in fact show the correct/corresponding dropdown. The problem is that they don't re-hide, once clicked. If I click "certification," and make it's dropdown appear, then change my mind and click "recertification," the recertification dropdown appears, but the certification one doesn't disappear.

I know there has to be a more elegant solution, but I'm at a loss. Advanced thanks to any and all input!

Was it helpful?

Solution

Javascript :

$(document).ready(function() {
    $(".hidden").hide();
    $("input[type=radio][name=ClassLevel]").change(function() {
        var parent_id = $(this).closest("fieldset").attr("id");
        var child = $(this).val();

        $("#"+parent_id+" .hidden:visible").toggle();
        $("#"+parent_id+" ."+child).toggle();
    });
});

And the html I used (removed id of each select and added another class that is the same value of the radio button (ie for Certification radio the class of the select associated with it will be certification (added after hidden))

Also, I saw that you will be having multiple pairs on the same page so I've made use of the id of the fieldset (each fieldset must have a unique id in order for this to work properly)

<fieldset id="tbr__15">
<legend>Registrant Information</legend>
<!--<button id="addReg" class="addReg" value="2">+</button>-->
<div id="fieldcontwrapper">
    <!-- Wrapper for Group -->
    <div id="fieldcont">
        <!-- Group your field -->
        <div class="required">
            <label for="name" class="label_heading">Registrant Name (first and last)</label>
            <input type="text" id="name_1" value="name_1">
            <br>
            <p class="label_heading">Training Level:</p>
            <label for="certification">
                <input type="radio" name="ClassLevel" value="certification" id="select-certification" class="select-certification">Certification
                <!-- <label id="cert-available-classes" class="hidden" for="cert">Certification Classes Available</label>    -->
                <select class="copy hidden certification" name="cert">
                    <option value="">Select a Certification Session</option>
                    <option value="session1cert">Fort Dodge, IA May 5-9, 2014</option>
                    <option value="session2cert">North Platte, NE Sept 22-26, 2014</option>
                    <option value="session3cert">Omaha, NE Oct 13-17, 2014</option>
                    <option value="session4cert">Waterloo, IA Oct 27-31, 2014</option>
                    <option value="session5cert">Grand Island, NE Nov 17-21, 2014</option>
                </select>
            </label>
            <!--end label for certification-->
            <label for="recertification">
                <input type="radio" name="ClassLevel" value="recertification" id="select-recertification" class="select-recertification">Recertification
                <!-- <label id="recert-available-classes" class="hidden" for="recert">Recertification Classes Available</label>-->
                <select class="copy hidden recertification" name="recert">
                    <option value="">Select a Recertification Session</option>
                    <option value="session1recert">Fort Dodge, IA May 8, 2014</option>
                    <option value="session2recert">North Platte, NE Sept 25, 2014</option>
                    <option value="session3recert">Omaha, NE Oct 16, 2014</option>
                    <option value="session4recert">Waterloo, IA Oct 30, 2014</option>
                    <option value="session5recert">Grand Island, NE Nov 20, 2014</option>
                </select>
            </label>
            <!--end label for recertification-->
        </div>
    </div>
    <!-- #fieldcont -->
</div>
<!-- #fieldcontwrapper -->
<button id="addReg" class="addReg">+</button>
</fieldset>
<!--fieldset#tbr__16-->
<fieldset id="tbr__16" class="tbr_fieldset">
<legend>Registrant Information</legend>
<!--<button id="addReg" class="addReg" value="2">+</button>-->
<div id="fieldcontwrapper">
    <!-- Wrapper for Group -->
    <div id="fieldcont">
        <!-- Group your field -->
        <div class="required">
            <label for="name" class="label_heading">Registrant Name (first and last)</label>
            <input type="text" id="name_1" value="name_1">
            <br>
            <p class="label_heading">Training Level:</p>
            <label for="certification">
                <input type="radio" name="ClassLevel" value="certification" id="select-certification" class="select-certification">Certification
                <!-- <label id="cert-available-classes" class="hidden" for="cert">Certification Classes Available</label>    -->
                <select class="copy hidden certification" name="cert">
                    <option value="">Select a Certification Session</option>
                    <option value="session1cert">Fort Dodge, IA May 5-9, 2014</option>
                    <option value="session2cert">North Platte, NE Sept 22-26, 2014</option>
                    <option value="session3cert">Omaha, NE Oct 13-17, 2014</option>
                    <option value="session4cert">Waterloo, IA Oct 27-31, 2014</option>
                    <option value="session5cert">Grand Island, NE Nov 17-21, 2014</option>
                </select>
            </label>
            <!--end label for certification-->
            <label for="recertification">
                <input type="radio" name="ClassLevel" value="recertification" id="select-recertification" class="select-recertification">Recertification
                <!-- <label id="recert-available-classes" class="hidden" for="recert">Recertification Classes Available</label>-->
                <select class="copy hidden recertification" name="recert">
                    <option value="">Select a Recertification Session</option>
                    <option value="session1recert">Fort Dodge, IA May 8, 2014</option>
                    <option value="session2recert">North Platte, NE Sept 25, 2014</option>
                    <option value="session3recert">Omaha, NE Oct 16, 2014</option>
                    <option value="session4recert">Waterloo, IA Oct 30, 2014</option>
                    <option value="session5recert">Grand Island, NE Nov 20, 2014</option>
                </select>
            </label>
            <!--end label for recertification-->
        </div>
    </div>
    <!-- #fieldcont -->
</div>
<!-- #Copperfield -->
<button id="addReg" class="addReg">+</button>

OTHER TIPS

Instead of toggle use slideToggle and you only need document.ready at the top one time and all of your code goes between that and the last brackets of that document ready function

Before we start:

$(this).next(":first")

The :first selector here is superfluous. Because $(this) will only ever return one jquery element, and :first returns the first jquery element of the set, it's not required. So what we have is:

$("input[name='ClassLevel']").change(function (e) {
    $(this).next().toggle();
    e.preventDefault();
});

Which would work fine if the change from being selected to unselected triggers a change event. Unfortunately this isn't the case. Only being selected triggers the change event (you can almost think of it as a click event on the input).

Knowing this, this means we need to reset the changes of any previous change event i.e. the showing of your drop-downs. One way you can achieve this is just to simply hide all the dropdowns prior to showing your current dropdown. And so we have:

$("input[name='ClassLevel']").change(function (e) {
    $("input[name='ClassLevel']").next().hide();
    $(this).next().toggle();
    e.preventDefault();
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top