1

I have a problem in dealing with my problem. My problem is I am creating a static navigation. That uses trigger event. Because I am displaying a simple collapsible div. What I did is I include all my id name in an array and I loop it to create an event. But when I click a link i doesn't call my jquery event. Is there a way how can I prevent hard coded of navigation?

Here's my sample code:

var toggleState = true;
var header_name = ["ParentA", "ParentB", "ParentC", "ParentD"];
var child_name = ["ChildA", "ChildB", "ChildC", "ChildD"];

for (var x = 0; x < header_name.length; x++) {
    $("#" + header_name[x]).click(function (e) {
        if (toggleState) {
            $("#" + child_name[x]).show("slide");
        } else {
            $("#" + child_name[x]).hide("slide");
        }
        toggleState = !toggleState;
    });
}
<div id="ParentA">Click A</div>
<div id="ChildA" style="display: none">Child A</div>
<div id="ParentB">Click A</div>
<div id="ChildB" style="display: none">Child B</div>
<div id="ParentC">Click A</div>
<div id="ChildC" style="display: none">Child C</div>

Here's the fiddle: http://jsfiddle.net/rochellecanale/cveze/3/

5
  • 2
    The spaces will give you trouble Replace the spaces in your IDs with underscores. Commented Oct 23, 2013 at 1:42
  • 2
    Arrays should be inside [] not (). Commented Oct 23, 2013 at 1:43
  • Read w3.org/TR/REC-html40/types.html#type-name id must not have spaces Commented Oct 23, 2013 at 1:43
  • ok sorry for my wrong array.. i will edit this Commented Oct 23, 2013 at 1:45
  • will you be able to make some minor changes to the html Commented Oct 23, 2013 at 1:56

3 Answers 3

2

change this:

var header_name = ("Parent A", "Parent B", "Parent C", "Parent D"); 

to this

var header_name = ["Parent A", "Parent B", "Parent C", "Parent D"];

likewise with the next variable

Sign up to request clarification or add additional context in comments.

Comments

2

You need to create a local copy of x for each iteration of the loop. The simplest way to do this is to create a helper function like getClickHandler:

function getClickHandler(x) {
    return function(e){
            if(toggleState){
                $("#" + child_name[x]).show("slide");
            }else{
                $("#" + child_name[x]).hide("slide");
            }
            toggleState = !toggleState;
          };
}

for(var x = 0; x < header_name.length; x++){
    $("#" + header_name[x]).click(getClickHandler(x));
}

The key point here is that the function inside click runs at a later time (asynchronously). Because of how variable scope works in Javascript, your code passes the same reference to x in to each handler, which is why all of them end up getting the last iteration of the array. Doing the above creates a copy of x at the current iteration, and stores it in a local reference (inside the handler function).

1 Comment

Hi again, i did that but it doesn't work. I included my fiddle in the question.
1

If you can make minor changes to the html it should be as simple as

<div id="ParentA" class="click-toggle" data-target="#ChildA">Click A</div>
<div id="ChildA" style="display: none">Child A</div>
<div id="ParentB" class="click-toggle" data-target="#ChildB">Click B</div>
<div id="ChildB" style="display: none">Child B</div>
<div id="ParentC" class="click-toggle" data-target="#ChildC">Click C</div>
<div id="ChildC" style="display: none">Child C</div>

then

$(document).ready(function(){
    $('.click-toggle').click(function () {
        $($(this).data('target')).stop(true, true).slideToggle();
    })
});

Demo: Fiddle

or even

<div id="ParentA" class="click-toggle">Click A</div>
<div id="ChildA" style="display: none">Child A</div>
<div id="ParentB" class="click-toggle">Click B</div>
<div id="ChildB" style="display: none">Child B</div>
<div id="ParentC" class="click-toggle">Click C</div>
<div id="ChildC" style="display: none">Child C</div>

then

$(document).ready(function(){
    $('.click-toggle').click(function () {
        $(this).next().stop(true, true).slideToggle();
    })
});

Demo: Fiddle, if you want to maintain left -> right slide: Fiddle

to make your code work... the main problem is the use of shared closure variable toggleState... each menu item should have its own state variable... the solution is to create a private closure for each one

$(document).ready(function () {
    var header_name = ["ParentA", "ParentB", "ParentC", "ParentD"];
    var child_name = ["ChildA", "ChildB", "ChildC", "ChildD"];
    $.each(header_name, function (idx, id) {
        var toggleState = true;
        $('#' + id).click(function () {
            if (toggleState) {
                $("#" + child_name[idx]).show("slide");
            } else {
                $("#" + child_name[idx]).hide("slide");
            }
            toggleState = !toggleState;
        })
    })
});

Demo: Fiddle

1 Comment

@RochelleCanale which one did you opt for

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.