Hi, Welcome! You'll find it a bit of an adjustment moving from jQuery to Prototype, but there's a lot of good stuff to get into. I'd recommend having a good, thorough read through the API docs[1] to get started with, just so you know what's available to you. Takes about an hour, but pays you back dramatically in saved time.
One of the biggest things you'll need to get used to is that Prototype does not conflate the concepts of an Element and an Array or list -- they're clear and distinct concepts. jQuery does a lot of that kind of conflation, which some like and others don't. So the methods that are available on Element (like addClassName and removeClassName) are not available on Array, you must explicitly walk through the array -- although Prototype provides a lot of nifty stuff to help you do so. I can't comment on anything specific to Event.addBehavior since I've never used that plug-in (that's not Prototype, it's an add-on -- Low Pro, I think). But there are some errors in the code I can help with that I'm reasonably sure don't relate to that part of things: > <div id="submit-choices'> I'm guessing that you typed in the HTML structure, rather than copy- and-paste? You're opening with " there, but closing with '. > Event.addBehavior({ > '#submit-choices label:click' : function() { > removeClassName($('submit-choices div'), 'active'); > this.addClassNAme('active') > } > } A couple of issues there: 1. You're using removeClassName as an unqualified reference, and so it will be resolved relative to the scope chain. In the code you've quoted, I don't see a containing scope that will have a removeClassName function. You probably want Element.removeClassName, but... 2. ...you're using $() and giving it a selector-like string ("submit- choices div"), although without the # at the beginning. $() is purely for looking up elements by ID[2]. If you want to find elements by selector, you want $$()[3] to do it at the document level, or Element#select[4] to do it within a given element (e.g., searching its descendants). > var divs = document.getElementById('submit- > choices').getElementsByTagName('div'); > if ( divs.hasClassName('active' )) { > divs.removeClassName('active'); > this.addClassNAme('active') > } > } Here's that conflation problem. You're setting 'divs' to a NodeList, then calling a method from Prototype's Element extensions on it. NodeLists aren't Elements, they're NodeLists. You want to operate on each item in the list. In Prototype, if the goal is to remove 'active' from all divs within submit-choices and then add active to the label on which the click occurred (assuming Low Pro hooks up handlers using Element#observe), this would do it: $('submit-choices').select('div').invoke('removeClassName', 'active'); this.addClassName('active'); That uses $()[2] to look up the submit-choices div, then Element#select [4] to get an array of its decendant divs, then Enumerable#invoke[5] to look through that array calling the 'removeClassName' method on each element and passing in 'active' (Element#removeClassName is okay with being called when the class name isn't on the element; it's just a no-op). I'd probably approach the whole problem differently, though. If the goal is that clicking a label will mark its parent div as "active" and clear any other active divs, and that all of this happens within a container called 'submit-choices', I would probably put one single handler on submit-choices rather than using Low Pro to hook up every label within it. Clicks bubble up, so a click on the label will be seen by submit-choices barring someone stopping it. So this would be all that you needed: * * * * document.observe('dom:loaded', function() { $('submit-choices').observe('click', function(event) { var label; var div; label = event.findElement('div > label'); if (label) { div = label.up(); this.select('div.active').invoke( 'removeClassName', 'active'); div.addClassName('active'); event.stop(); } }); }); * * * * (Also on Pastie: http://pastie.org/459429) That one handler, on submit-choices, looks to see if the click was on a label with a div as an immediate parent. If it was, it will remove the "active" class from all "active" divs within the container, then add the "active" class to the parent. Key bits of the above are document.observe's dom:loaded event[6], the fact that Element#observe [7] ensures that "this" within the event handler refers to the element on which the event is hooked (so "this" is submit-choices within th ehandler), and Event#findElement[8]. I think nowadays findElement actually accepts a full CSS selector, but the docs for it still just say "tag name" so I haven't relied on that above; instead I explicitly check the parent's tag name. You can add and remove divs within the submit-choices div, and they'll get picked up by the handler above -- they don't need to get anything hooked on them. The only time you'd have to unhook/rehook a handler would be if you took out submit-choices itself. This is generically called event delegation and can be very powerful when dealing with lists of things, particularly dynamic lists of things. [1] http://prototypejs.org/api [2] http://prototypejs.org/api/utility/dollar [3] http://prototypejs.org/api/utility/dollar-dollar [4] http://prototypejs.org/api/element/select [5] http://prototypejs.org/api/enumerable/invoke [6] http://prototypejs.org/api/document/observe [7] http://prototypejs.org/api/element/observe [8] http://prototypejs.org/api/event/findElement HTH, -- T.J. Crowder tj / crowder software / com Independent Software Engineer, consulting services available On Apr 27, 5:50 am, Jeff <rufus2...@gmail.com> wrote: > i'm new to prototype. i was using jQuery and loved it and am a little > confused coming over to prototype. i am trying to add and remove a > class of active to a labels parent div. does anyone know why i can't > do this? > > i've tried this > > <div id="submit-choices'> > > <div> > <input /><label>my label</label> > </div> > > <div> > <input /><label>my label</label> > </div> > </div><!-- close submit-choices div --> > > Event.addBehavior({ > '#submit-choices label:click' : function() { > removeClassName($('submit-choices div'), 'active'); > this.addClassNAme('active') > } > } > }) > > and also > > Event.addBehavior({ > '#submit-choices label:click' : function() { > var divs = document.getElementById('submit- > choices').getElementsByTagName('div'); > if ( divs.hasClassName('active' )) { > divs.removeClassName('active'); > this.addClassNAme('active') > } > } > }) > > it keeps saying divs.hasClassName is not a function. i mean wtf? --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Prototype & script.aculo.us" group. To post to this group, send email to prototype-scriptaculous@googlegroups.com To unsubscribe from this group, send email to prototype-scriptaculous+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en -~----------~----~----~----~------~----~------~--~---