views:

210

answers:

2

statement written with jQuery, How whould i write this with prototype

$("#productNav li a").click(function(){
$("#productNav li a").removeClass("selectedProd");
$(this).addClass("selectedProd");
$("#productListCntnr > ul").slideUp(300);
$("#productListCntnr > ul."+this.id).slideDown(300);
});
+1  A: 

I'm not sure about the best way to handle the sliding stuff you're doing but this should do the basic mechanics of the clicking and the adding/removing of the selectedProd CSS class.

Event.observe(window, 'load', function() {
    //When the window loads, iterate over all of the appropriate <a> tags
    $$('#productNav li a').each( function(elem) {

        //Handle the click event on each a tag
        Event.observe(elem, 'click', function(event) {
            //Remove the selectedProd class from all <a> tags
            $$('#productNav li a').each( function(elem) {
                elem.removeClassName('selectedProd');
            });

            //Add the selectedProd class to the <a> tag that was clicked
            this.addClassName('selectedProd');

            //Stop the browser from following the link specified in the href=""
            Event.stop(event);
        });
    });
});
Mark Biek
You could probably shorten this a bit by keeping track of which 'a' tag was previously selected rather than looping over all of them on each click. But I'll leave that as an exercise for you :)
Mark Biek
+1  A: 

While I was thinking about this Mark already answered, but I came up with the following:

$$("#productNav li a").observe('click', function(event){
  $$("#productNav li a").invoke('removeClassName', 'selectedProd'));
  $$("#productListCntnr > ul").invoke('SlideUp',{ duration: 3.0 });
  Event.element(event).invoke('addClassName', 'selectedProd'));
  $$("#productListCntnr > ul#"+Event.element(event).id).invoke('SlideDown',{ duration: 3.0 });
});

The SlideUp and SlideDown methods come from Scriptaculous, not sure if they're directly compatible with the jQuery effect. I also assumed you meant ul# in that last line since you're selecting by ID, in which case, since ID is unique anyway, you could probably do it like this:

Effect.SlideDown(Event.element(event).id, { duration: 3.0 });

--edit

Following Mark's comment I've had a go with the above code in an actual browser, here is a working version:

Event.observe(window, 'load', function() {
    $$("#productNav li a").invoke('observe', 'click', function(event){
        $$("#productNav li a.selectedProd").invoke('removeClassName', 'selectedProd');
        Event.element(event).addClassName('selectedProd');
        Effect.Pulsate(Event.element(event).id, { pulses: 5, duration: 3.0 });
    });
});

I wasn't sure what SlideUp was supposed to be doing, so I took it out, I assume it's not operating on the same list elements as the ones in productNav? SlideDown didn't seem to do anything either, probably because SlideUp was gone, so I swapped it for Pulsate just to confirm it was working. I had to use the alternate syntax I mentioned above as the original didn't work at all (got an error like invoke method doesn't exist on element).

I'm guessing the original code is intended to SlideUp and SlideDown a content area separate from the menu items? In which case this code would have to change, but your original html would also be invalid as it would imply the list items in the menu and the list items in the content area have the same ids. For reference, this is what my HTML looks like:

<ul id="productNav">
    <li><a id="p1" href="#">Product 1</a></li>
    <li><a id="p2" href="#">Product 2</a></li>
    <li><a id="p3" href="#">Product 3</a></li>
    <li><a id="p4" href="#">Product 4</a></li>
    <li><a id="p5" href="#">Product 5</a></li>
    <li><a id="p6" href="#">Product 6</a></li>
</ul>
robertc
I don't think you can use $$() with .observe()
Mark Biek
Or .invoke() for that matter since $$() just returns an array of extended Elements.
Mark Biek
Ah yes. Invoke is OK - it invokes the function on each element of the array (see prototypejs.org/api/enumerable/invoke - it's on the Enumerable object), but yes I expect the observe itself would need to be wrapped up in something like invoke() or each()
robertc
Thanks Much, I really appreciate the answers
adardesign