[Proto-Scripty] Re: Coming from jquery (be gentle)
You should be using event delegation like so: document.observe('click', function(event) { var element = event.findElement('ul.bopCategories li h3'); if (!element) return; element.next('div.bopCategoryDetails').toggle(); element.toggleClassName('expanded'); }); You don't need to wait for the DOM to be loaded to set it up and it's much more efficient (you're using a unique handler for the whole tree instead of one per node).. Best, Tobie On Nov 10, 3:00 pm, Kris Northfield [EMAIL PROTECTED] wrote: Yes, I get the idea. FYI this is what my final code is: $$(ul.bopCategories li h3).each(function (elm) { elm.observe('click', function(evt){ evt.element().next('div.bopCategoryDetails').toggle(); evt.element().toggleClassName('expanded'); }); }); Thanks everyone. On Oct 3, 12:53 pm, T.J. Crowder [EMAIL PROTECTED] wrote: This is a common misunderstanding of `bindAsEventListener` Indeed, it's pretty rare to need to use bindAsEventListener. Finally, invoking `down` without arguments (i.e. when you only need to step one level down) is usually faster than using an expression: It's not down anyway, is it? The div is a sibling of the h3 in the OP's markup... But I'm sure the OP's getting the idea. :-) -- T.J. Crowder tj / crowder software / com On Oct 3, 1:39 pm, kangax [EMAIL PROTECTED] wrote: On Oct 3, 5:38 am, bluezehn [EMAIL PROTECTED] wrote: So get that javascript out of the html and use observers. So the code you have so far is much better in prototype as this: h3Event/h3 div id=divvy2 Test test test test test test test test ets test test test test test /div !-- IN JAVASCRIPT -- document.observe('dom:loaded', function() { $$('h3').each(function(h3) { h3.observe('click', function() { this.down('div').toggle(); }.bindAsEventListener(h3)); This is a common misunderstanding of `bindAsEventListener` : ) Plain `bind` is actually sufficient unless you need to curry (prefill with arguments) an event handler. Also, `h3` (which `bindAsEventListener` uses) seems to be `undefined` here. Finally, invoking `down` without arguments (i.e. when you only need to step one level down) is usually faster than using an expression: $$('h3').invoke('observe', 'click', function() { this.down().toggle(); }); }); }); So I've tried to use a really compact bit of code there not necessarily to do exactly what you want, but to demonstrate loads of cool prototype-ish features. First, 'dom:loaded' is a custom event fired by prototype when the dom has loaded BUT not necessarily all the images, flash files or whatever else you may have on the page. Clearly this is better than onLoad for the body or window. You can see that this event is observed by calling the observe method on an object and specifying a function to run when the event fires. Here the function is defined inline. Moving down the code, $$ returns an array of everything that matches that css definition. So in this case, all 'h3' tags in the dom. The each method can be applied to all enumerables in prototype and is kind of like a foreach language structure. So it's saying apply this function to each h3 element. You'll probably from jquery be familiar with the .down method, it's kind of self explanatory, but then you'll notice as well the bindAsEventListener function at the end there. What that effectively does is make sure that the variable this inside the preceding function refers to the parameter given in bindAsEventListener. Any more qs let us know. -- kangax --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en -~--~~~~--~~--~--~---
[Proto-Scripty] Re: Coming from jquery (be gentle)
Wow this thread should be summarized somewhere as an intro to prototype in 5 minutes page! On Nov 10, 2:16 pm, Tobie Langel [EMAIL PROTECTED] wrote: You should be using event delegation like so: document.observe('click', function(event) { var element = event.findElement('ul.bopCategories li h3'); if (!element) return; element.next('div.bopCategoryDetails').toggle(); element.toggleClassName('expanded'); }); You don't need to wait for the DOM to be loaded to set it up and it's much more efficient (you're using a unique handler for the whole tree instead of one per node).. Best, Tobie On Nov 10, 3:00 pm, Kris Northfield [EMAIL PROTECTED] wrote: Yes, I get the idea. FYI this is what my final code is: $$(ul.bopCategories li h3).each(function (elm) { elm.observe('click', function(evt){ evt.element().next('div.bopCategoryDetails').toggle(); evt.element().toggleClassName('expanded'); }); }); Thanks everyone. On Oct 3, 12:53 pm, T.J. Crowder [EMAIL PROTECTED] wrote: This is a common misunderstanding of `bindAsEventListener` Indeed, it's pretty rare to need to use bindAsEventListener. Finally, invoking `down` without arguments (i.e. when you only need to step one level down) is usually faster than using an expression: It's not down anyway, is it? The div is a sibling of the h3 in the OP's markup... But I'm sure the OP's getting the idea. :-) -- T.J. Crowder tj / crowder software / com On Oct 3, 1:39 pm, kangax [EMAIL PROTECTED] wrote: On Oct 3, 5:38 am, bluezehn [EMAIL PROTECTED] wrote: So get that javascript out of the html and use observers. So the code you have so far is much better in prototype as this: h3Event/h3 div id=divvy2 Test test test test test test test test ets test test test test test /div !-- IN JAVASCRIPT -- document.observe('dom:loaded', function() { $$('h3').each(function(h3) { h3.observe('click', function() { this.down('div').toggle(); }.bindAsEventListener(h3)); This is a common misunderstanding of `bindAsEventListener` : ) Plain `bind` is actually sufficient unless you need to curry (prefill with arguments) an event handler. Also, `h3` (which `bindAsEventListener` uses) seems to be `undefined` here. Finally, invoking `down` without arguments (i.e. when you only need to step one level down) is usually faster than using an expression: $$('h3').invoke('observe', 'click', function() { this.down().toggle(); }); }); }); So I've tried to use a really compact bit of code there not necessarily to do exactly what you want, but to demonstrate loads of cool prototype-ish features. First, 'dom:loaded' is a custom event fired by prototype when the dom has loaded BUT not necessarily all the images, flash files or whatever else you may have on the page. Clearly this is better than onLoad for the body or window. You can see that this event is observed by calling the observe method on an object and specifying a function to run when the event fires. Here the function is defined inline. Moving down the code, $$ returns an array of everything that matches that css definition. So in this case, all 'h3' tags in the dom. The each method can be applied to all enumerables in prototype and is kind of like a foreach language structure. So it's saying apply this function to each h3 element. You'll probably from jquery be familiar with the .down method, it's kind of self explanatory, but then you'll notice as well the bindAsEventListener function at the end there. What that effectively does is make sure that the variable this inside the preceding function refers to the parameter given in bindAsEventListener. Any more qs let us know. -- kangax --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en -~--~~~~--~~--~--~---
[Proto-Scripty] Re: Coming from jquery (be gentle)
Hello Kris, and welcome! When I first started with Prototype, I sat down and read through the API docs from front to back. It took about an hour (and I'm a slow reader), and was hugely useful -- so useful, in fact, that when I started reading this group (well, its predecessor) to gain further knowledge, I was actually able to answer some of people's questions. So as a first step, I would recommend doing that. It'll literally take an hour for the first read-through, and I think you'll find that you'll learn a huge amount from it. I don't know jQuery at all, so I can't translate your jQuery to Prototype reliably, but it would probably look something like this: function toggleContent(evt) { var elm; elm = evt.element(); elm.next('div.bopCategoryDetails').toggle(); elm.toggleClassName('expanded'); } $$(ul.bopCategories li h3).each(function (elm) { elm.observe('click', toggleContent); }); E.g.: 1. Use $$ to select elements by CSS rule http://prototypejs.org/api/utility/dollar-dollar 2. Use Enumerable.each to loop through the resulting array http://prototypejs.org/api/enumerable/each 3. Hook the click event on an element with Event.observe http://prototypejs.org/api/event/observe 4. Find a following sibling according to a CSS rule via Element.next http://prototypejs.org/api/element/next 5. Toggle visibility with Element.toggle http://prototypejs.org/api/element/toggle 6. Toggle classname with Element.toggleClassName http://prototypejs.org/api/element/toggleClassName Although this could be done with nested closures instead of named function, I think a named function is both clearer and more efficient. HTH, -- T.J. Crowder tj / crowder software / com On Oct 3, 10:11 am, Kris Northfield [EMAIL PROTECTED] wrote: Hi all, Trying to get used to prtotype, I've written this code in jquery but need a prototype equivalent. I've trawled the web for ages and read pretty much a whole book (the Manning one with the turk on the front) but I'm still none the wiser. Any help would be much appreciated. I've got this html: ul class=bopCategories li h3 class=expandedHeading One/h3 div class=bopCategoryDetails Lorem ipsum dolor sit amet. /div /li li h3 class=expandedHeading Two/h3 div class=bopCategoryDetails Lorem ipsum dolor sit amet. /div /li /ul which I then toggle the showing/hiding of the divs when the h3s are clicked with this jquery code: $(ul.bopCategories li h3).click(function(){ $(this).siblings(div.bopCategoryDetails).toggle(fast); $(this).toggleClass(expanded); }); How on earth do I do this with Prototype? So far I've only managed to add an onclick event to every h3 and pass the id of the specific div. Like so: h3 onclick=$('divvy2').toggle();Event/h3 div id=divvy2 Test test test test test test test test ets test test test test test /div Obviously this is going to get cumbersome when I have 20 or so list items. Thanks. --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en -~--~~~~--~~--~--~---
[Proto-Scripty] Re: Coming from jquery (be gentle)
Between me and T.J's post you should be able to get something decent working now, plenty of code for you! On Oct 3, 10:38 am, bluezehn [EMAIL PROTECTED] wrote: So get that javascript out of the html and use observers. So the code you have so far is much better in prototype as this: h3Event/h3 div id=divvy2 Test test test test test test test test ets test test test test test /div !-- IN JAVASCRIPT -- document.observe('dom:loaded', function() { $$('h3').each(function(h3) { h3.observe('click', function() { this.down('div').toggle(); }.bindAsEventListener(h3)); }); }); So I've tried to use a really compact bit of code there not necessarily to do exactly what you want, but to demonstrate loads of cool prototype-ish features. First, 'dom:loaded' is a custom event fired by prototype when the dom has loaded BUT not necessarily all the images, flash files or whatever else you may have on the page. Clearly this is better than onLoad for the body or window. You can see that this event is observed by calling the observe method on an object and specifying a function to run when the event fires. Here the function is defined inline. Moving down the code, $$ returns an array of everything that matches that css definition. So in this case, all 'h3' tags in the dom. The each method can be applied to all enumerables in prototype and is kind of like a foreach language structure. So it's saying apply this function to each h3 element. You'll probably from jquery be familiar with the .down method, it's kind of self explanatory, but then you'll notice as well the bindAsEventListener function at the end there. What that effectively does is make sure that the variable this inside the preceding function refers to the parameter given in bindAsEventListener. Any more qs let us know. On Oct 3, 10:11 am, Kris Northfield [EMAIL PROTECTED] wrote: Hi all, Trying to get used to prtotype, I've written this code in jquery but need a prototype equivalent. I've trawled the web for ages and read pretty much a whole book (the Manning one with the turk on the front) but I'm still none the wiser. Any help would be much appreciated. I've got this html: ul class=bopCategories li h3 class=expandedHeading One/h3 div class=bopCategoryDetails Lorem ipsum dolor sit amet. /div /li li h3 class=expandedHeading Two/h3 div class=bopCategoryDetails Lorem ipsum dolor sit amet. /div /li /ul which I then toggle the showing/hiding of the divs when the h3s are clicked with this jquery code: $(ul.bopCategories li h3).click(function(){ $(this).siblings(div.bopCategoryDetails).toggle(fast); $(this).toggleClass(expanded); }); How on earth do I do this with Prototype? So far I've only managed to add an onclick event to every h3 and pass the id of the specific div. Like so: h3 onclick=$('divvy2').toggle();Event/h3 div id=divvy2 Test test test test test test test test ets test test test test test /div Obviously this is going to get cumbersome when I have 20 or so list items. Thanks. --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en -~--~~~~--~~--~--~---
[Proto-Scripty] Re: Coming from jquery (be gentle)
Hi, Brilliant. Both answered a lot of questions and expanded my prototype knowledge ten fold. Thanks very much. Kris. --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en -~--~~~~--~~--~--~---
[Proto-Scripty] Re: Coming from jquery (be gentle)
So get that javascript out of the html and use observers. So the code you have so far is much better in prototype as this: h3Event/h3 div id=divvy2 Test test test test test test test test ets test test test test test /div !-- IN JAVASCRIPT -- document.observe('dom:loaded', function() { $$('h3').each(function(h3) { h3.observe('click', function() { this.down('div').toggle(); }.bindAsEventListener(h3)); }); }); So I've tried to use a really compact bit of code there not necessarily to do exactly what you want, but to demonstrate loads of cool prototype-ish features. First, 'dom:loaded' is a custom event fired by prototype when the dom has loaded BUT not necessarily all the images, flash files or whatever else you may have on the page. Clearly this is better than onLoad for the body or window. You can see that this event is observed by calling the observe method on an object and specifying a function to run when the event fires. Here the function is defined inline. Moving down the code, $$ returns an array of everything that matches that css definition. So in this case, all 'h3' tags in the dom. The each method can be applied to all enumerables in prototype and is kind of like a foreach language structure. So it's saying apply this function to each h3 element. You'll probably from jquery be familiar with the .down method, it's kind of self explanatory, but then you'll notice as well the bindAsEventListener function at the end there. What that effectively does is make sure that the variable this inside the preceding function refers to the parameter given in bindAsEventListener. Any more qs let us know. On Oct 3, 10:11 am, Kris Northfield [EMAIL PROTECTED] wrote: Hi all, Trying to get used to prtotype, I've written this code in jquery but need a prototype equivalent. I've trawled the web for ages and read pretty much a whole book (the Manning one with the turk on the front) but I'm still none the wiser. Any help would be much appreciated. I've got this html: ul class=bopCategories li h3 class=expandedHeading One/h3 div class=bopCategoryDetails Lorem ipsum dolor sit amet. /div /li li h3 class=expandedHeading Two/h3 div class=bopCategoryDetails Lorem ipsum dolor sit amet. /div /li /ul which I then toggle the showing/hiding of the divs when the h3s are clicked with this jquery code: $(ul.bopCategories li h3).click(function(){ $(this).siblings(div.bopCategoryDetails).toggle(fast); $(this).toggleClass(expanded); }); How on earth do I do this with Prototype? So far I've only managed to add an onclick event to every h3 and pass the id of the specific div. Like so: h3 onclick=$('divvy2').toggle();Event/h3 div id=divvy2 Test test test test test test test test ets test test test test test /div Obviously this is going to get cumbersome when I have 20 or so list items. Thanks. --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en -~--~~~~--~~--~--~---
[Proto-Scripty] Re: Coming from jquery (be gentle)
I'll throw in a Low Pro [1] version as well: Event.addBehavior({ 'ul.bopCategories .bopCategoryDetails' : function() { this.hide(); }, 'ul.bopCategories li h3:click' : function(e) { elm = e.element(); elm.next('div.bopCategoryDetails').toggle(); elm.toggleClassName('expanded'); } }); The first function will pre-hide the details. Remove it if it's not something you want to happen. //jarkko [1] http://jlaine.net/2007/8/3/from-rails-ajax-helpers-to-low-pro-part-i On 3.10.2008, at 12.37, T.J. Crowder wrote: Actually, let me revise that: function toggleContent(evt) { var elm; elm = evt.element(); elm.next('div.bopCategoryDetails').toggle(); elm.toggleClassName('expanded'); } function initPage() { $$(ul.bopCategories li h3).each(function (elm) { elm.observe('click', toggleContent); }); } Event.observe(document, 'dom:loaded', initPage); The dom:loaded event is fired when the DOM is ready (before window.onload, usually). -- T.J. Crowder tj / crowder software / com -- Jarkko Laine http://jlaine.net http://dotherightthing.com http://www.railsecommerce.com http://odesign.fi smime.p7s Description: S/MIME cryptographic signature
[Proto-Scripty] Re: Coming from jquery (be gentle)
On Oct 3, 5:38 am, bluezehn [EMAIL PROTECTED] wrote: So get that javascript out of the html and use observers. So the code you have so far is much better in prototype as this: h3Event/h3 div id=divvy2 Test test test test test test test test ets test test test test test /div !-- IN JAVASCRIPT -- document.observe('dom:loaded', function() { $$('h3').each(function(h3) { h3.observe('click', function() { this.down('div').toggle(); }.bindAsEventListener(h3)); This is a common misunderstanding of `bindAsEventListener` : ) Plain `bind` is actually sufficient unless you need to curry (prefill with arguments) an event handler. Also, `h3` (which `bindAsEventListener` uses) seems to be `undefined` here. Finally, invoking `down` without arguments (i.e. when you only need to step one level down) is usually faster than using an expression: $$('h3').invoke('observe', 'click', function() { this.down().toggle(); }); }); }); So I've tried to use a really compact bit of code there not necessarily to do exactly what you want, but to demonstrate loads of cool prototype-ish features. First, 'dom:loaded' is a custom event fired by prototype when the dom has loaded BUT not necessarily all the images, flash files or whatever else you may have on the page. Clearly this is better than onLoad for the body or window. You can see that this event is observed by calling the observe method on an object and specifying a function to run when the event fires. Here the function is defined inline. Moving down the code, $$ returns an array of everything that matches that css definition. So in this case, all 'h3' tags in the dom. The each method can be applied to all enumerables in prototype and is kind of like a foreach language structure. So it's saying apply this function to each h3 element. You'll probably from jquery be familiar with the .down method, it's kind of self explanatory, but then you'll notice as well the bindAsEventListener function at the end there. What that effectively does is make sure that the variable this inside the preceding function refers to the parameter given in bindAsEventListener. Any more qs let us know. -- kangax --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en -~--~~~~--~~--~--~---