[jQuery] Working prototype..thanks again John!
Here is the a prototype of the finished product to show you what I was trying to acheive. http://members.optusnet.com.au/greg.bird/mm/collapse.html * Long page broken up into smaller sections based on H2's * Each scetion is wrapped in a div with a unique ID * All but the first section is hidden * Side navigation created dynamically based on H2's. This toggles the visability of the various sections * Users can see entire page by clicking SHOW ALL I am Considering using an accordian style navigation rather than show/hide. Thanks again John. Your help was invaluable! John Resig wrote: Ok, I did some more digging and you're right. I don't think I ever actually tested nextUntil (oops!) The full implementation can be found here: http://john.jquery.com/jquery/test/nextuntil.html This includes a working version of nextUntil: $.fn.nextUntil = function(expr) { var match = []; // We need to figure out which elements to push onto the array this.each(function(){ // Traverse through the sibling nodes for( var i = this.nextSibling; i; i = i.nextSibling ) { // Make sure that we're only dealing with elements if ( i.nodeType != 1 ) continue; // If we find a match then we need to stop if ( jQuery.filter( expr, [i] ).r.length ) break; // Otherwise, add it on to the stack match.push( i ); } }); return this.pushStack( match, arguments ); }; Additionally, I realized that .wrap() isn't going to do what you need it to. .wrap() wraps each matched element with the same structure. So if you matched 3 paragraphs, you'd have three surrounding divs too. Since you want it to wrap all of the matched elements with a single element, I made a new .wrapAll() plugin: $.fn.wrapAll = function() { // There needs to be at least one matched element for this to work if ( !this.length ) return this; // Find the element that we're wrapping with var b = jQuery.clean(arguments)[0]; // Make sure that its in the right position in the DOM this[0].parentNode.insertBefore( b, this[0] ); // Find its lowest point while ( b.firstChild ) b = b.firstChild; // And add all the elements there return this.appendTo(b); }; So - all of that should help you along now. Let me know if this works for you. --John On 10/18/06, Greg Bird [EMAIL PROTECTED] wrote: Thanks for this Blair.a really interesting approach and one I wouldn't have thought of myself. At the moment, I am having problems with the NextUntil function, but once I have this solved, your suggestion may be a really neat implementation. Cheers, Greg Blair McKenzie-2 wrote: This is just a guess: function BuildNav() { $(#content h2).each(function(){ $(this).before(div class='note newdivmarker'/div).nextUntil(h2).appendTo(.newdivmarker); $( div.newdivmarker).removeClass(newdivmarker); }); } It relies on the assumption that appendTo moves the origonal element list, rather than clones them. Basically: 1. It adds your div before the heading, with a temporary marker so we can find it again 2. Selects all elements until the next heading 3. Moves them to the div 4. Removes the marker from the div Blair On 10/18/06, Greg Bird [EMAIL PROTECTED] wrote: Hi John, thanks again for your help, unfortunately I have deployed your suggestions and am still unable to get it to work. You can view my testpage at: http://members.optusnet.com.au/greg.bird/mm/collapse.html My .js now reads: $(document).ready(function(){ BuildNav(); }); //DEFINE NextUntil FUNCTION $.fn.nextUntil = function(expr) { var match = []; this.each(function(){ var cur = this.nextSibling; while ( cur jQuery.filter( expr, [cur] ).r.length ) { match = jQuery.merge( match, [ cur ] ); cur = cur.nextSibling; } console.log(this,cur,match); }); return this.pushStack( match, arguments ); }; /*BUILD SIDE NAVIGATION*/ function BuildNav() { $(#content h2).each(function(){ $(this).nextUntil(h2).wrap(div class='note'/div); }); } I have logged the script and it appears that the match array is not being populated. I suspect that the Jquery.merge function is not triggering properly Does this function work with JQUERY 1.0.2? In note in the JQUERY doco that the function call is now $.merge. Trialled this without success. My aim here is to put a unique div around each section of the page and then dynamically create an expand/collapse navigation system. Have already achieved a similar result with a sliding navigation system. You can see this at: http://members.optusnet.com.au/greg.bird/mm/index.html This was easier as I didn't need to wrap
Re: [jQuery] Working prototype..thanks again John!
Thanks Brandon, good point. Will implement. Cheers, Greg Brandon Aaron wrote: Looks good. Be sure to return false; in the click event handler. This will keep it from adding the hash to the url and jumping to the top with each click if you are scrolled. -- Brandon Aaron ___ jQuery mailing list discuss@jquery.com http://jquery.com/discuss/ -- View this message in context: http://www.nabble.com/Please-help%21-Dynamically-Wrapping-DIV%27s-around-structural-markup.-tf2464168.html#a6909720 Sent from the JQuery mailing list archive at Nabble.com. ___ jQuery mailing list discuss@jquery.com http://jquery.com/discuss/
Re: [jQuery] Please help (again, sorry)..NextUntil not working
Hi John, thanks again for your help, unfortunately I have deployed your suggestions and am still unable to get it to work. You can view my testpage at: http://members.optusnet.com.au/greg.bird/mm/collapse.html My .js now reads: $(document).ready(function(){ BuildNav(); }); //DEFINE NextUntil FUNCTION $.fn.nextUntil = function(expr) { var match = []; this.each(function(){ var cur = this.nextSibling; while ( cur jQuery.filter( expr, [cur] ).r.length ) { match = jQuery.merge( match, [ cur ] ); cur = cur.nextSibling; } console.log(this,cur,match); }); return this.pushStack( match, arguments ); }; /*BUILD SIDE NAVIGATION*/ function BuildNav() { $(#content h2).each(function(){ $(this).nextUntil(h2).wrap(div class='note'/div); }); } I have logged the script and it appears that the match array is not being populated. I suspect that the Jquery.merge function is not triggering properly Does this function work with JQUERY 1.0.2? In note in the JQUERY doco that the function call is now $.merge. Trialled this without success. My aim here is to put a unique div around each section of the page and then dynamically create an expand/collapse navigation system. Have already achieved a similar result with a sliding navigation system. You can see this at: http://members.optusnet.com.au/greg.bird/mm/index.html This was easier as I didn't need to wrap div's around anything, but simply anchor to the existing H2's Have you got any suggestions? Do you have any test pages so that I can view your implementation? Thanks in advance, Greg John Resig wrote: Hi Greg - I created a plugin a while back that can help with this, called nextUntil: $.fn.nextUntil = function(expr) { var match = []; this.each(function(){ var cur = this.nextSibling; while ( cur jQuery.filter( expr, [cur] ).r.length ) { match = jQuery.merge( match, [ cur ] ); cur = cur.nextSibling; } }); return this.pushStack( match, arguments ); }; Just include that after you include jquery.js then do the following: $(#content h2).each(function(){ $(this).nextUntil(h2).wrap(div class='note'/div); }); Just 3 lines! Not too shabby :) --John On 10/18/06, Greg Bird [EMAIL PROTECTED] wrote: Hi everyone. I am attempting to develop some dynamic in page navigation. I am a big fan of structural markup. Each H2 represents a new section of the current document. I wish to: 1. Find each H2 2. Wrap this in a unique div, up to (but not including) the next H2. This will then be used to further manipulate the page div id=content h2First section/h2 ...[arbitary HTML] h2second section/h2 ...[arbitary HTML] h2third section/h2 . /div Becomes: div id=content div id=1 h2First section/h2 ...[arbitary HTML] /div div id=2 h2second section/h2 ...[arbitary HTML] /div h2third section/h2 . /div Here is the JQuery that I have developed to date: $(document).ready(function(){ BuildNav(); }); /*BUILD SIDE NAVIGATION*/ function BuildNav() { //add back to top links before each H2 $('#content h2').each(function(i){ if(i==0){//FIRST H2 $(this).before('div id='+ i +' class=note')//START A NEW DIV WITH UNIQUE ID } else { $(this).before('/divdiv id='+ i +' class=note');//TERMINATE PREVIOUS DIV, BEGIN NEW ONE } }) $('#content').append('/div');//TERMINATE FINAL DIV } This looks sensible to me but fails. It appears you cannot inject unterminated tags and that JQUERY automatically closes tags on insertion, resulting in: div id=content div id=1/div h2First section/h2 ...[arbitary HTML] div id=2/div h2second section/h2 ...[arbitary HTML] div id=3/div h2third section/h2 . /div Can anyone give me any clues? Thanks in advance, Greg Bird ___ jQuery mailing list discuss@jquery.com http://jquery.com/discuss/ Quoted from: http://www.nabble.com/Please-help%21-Dynamically-Wrapping-DIV%27s-around-structural-markup.-tf2464168.html#a6869443 -- View this message in context: http://www.nabble.com/Please-help%21-Dynamically-Wrapping-DIV%27s-around-structural-markup.-tf2464168.html#a6870422 Sent from the JQuery mailing list archive at Nabble.com. ___ jQuery mailing list discuss@jquery.com http://jquery.com/discuss/
Re: [jQuery] Please help (again, sorry)..NextUntil not working
Thanks for this Blair.a really interesting approach and one I wouldn't have thought of myself. At the moment, I am having problems with the NextUntil function, but once I have this solved, your suggestion may be a really neat implementation. Cheers, Greg Blair McKenzie-2 wrote: This is just a guess: function BuildNav() { $(#content h2).each(function(){ $(this).before(div class='note newdivmarker'/div).nextUntil(h2).appendTo(.newdivmarker); $( div.newdivmarker).removeClass(newdivmarker); }); } It relies on the assumption that appendTo moves the origonal element list, rather than clones them. Basically: 1. It adds your div before the heading, with a temporary marker so we can find it again 2. Selects all elements until the next heading 3. Moves them to the div 4. Removes the marker from the div Blair On 10/18/06, Greg Bird [EMAIL PROTECTED] wrote: Hi John, thanks again for your help, unfortunately I have deployed your suggestions and am still unable to get it to work. You can view my testpage at: http://members.optusnet.com.au/greg.bird/mm/collapse.html My .js now reads: $(document).ready(function(){ BuildNav(); }); //DEFINE NextUntil FUNCTION $.fn.nextUntil = function(expr) { var match = []; this.each(function(){ var cur = this.nextSibling; while ( cur jQuery.filter( expr, [cur] ).r.length ) { match = jQuery.merge( match, [ cur ] ); cur = cur.nextSibling; } console.log(this,cur,match); }); return this.pushStack( match, arguments ); }; /*BUILD SIDE NAVIGATION*/ function BuildNav() { $(#content h2).each(function(){ $(this).nextUntil(h2).wrap(div class='note'/div); }); } I have logged the script and it appears that the match array is not being populated. I suspect that the Jquery.merge function is not triggering properly Does this function work with JQUERY 1.0.2? In note in the JQUERY doco that the function call is now $.merge. Trialled this without success. My aim here is to put a unique div around each section of the page and then dynamically create an expand/collapse navigation system. Have already achieved a similar result with a sliding navigation system. You can see this at: http://members.optusnet.com.au/greg.bird/mm/index.html This was easier as I didn't need to wrap div's around anything, but simply anchor to the existing H2's Have you got any suggestions? Do you have any test pages so that I can view your implementation? Thanks in advance, Greg John Resig wrote: Hi Greg - I created a plugin a while back that can help with this, called nextUntil: $.fn.nextUntil = function(expr) { var match = []; this.each(function(){ var cur = this.nextSibling; while ( cur jQuery.filter( expr, [cur] ).r.length ) { match = jQuery.merge( match, [ cur ] ); cur = cur.nextSibling; } }); return this.pushStack( match, arguments ); }; Just include that after you include jquery.js then do the following: $(#content h2).each(function(){ $(this).nextUntil(h2).wrap(div class='note'/div); }); Just 3 lines! Not too shabby :) --John On 10/18/06, Greg Bird [EMAIL PROTECTED] wrote: Hi everyone. I am attempting to develop some dynamic in page navigation. I am a big fan of structural markup. Each H2 represents a new section of the current document. I wish to: 1. Find each H2 2. Wrap this in a unique div, up to (but not including) the next H2. This will then be used to further manipulate the page div id=content h2First section/h2 ...[arbitary HTML] h2second section/h2 ...[arbitary HTML] h2third section/h2 . /div Becomes: div id=content div id=1 h2First section/h2 ...[arbitary HTML] /div div id=2 h2second section/h2 ...[arbitary HTML] /div h2third section/h2 . /div Here is the JQuery that I have developed to date: $(document).ready(function(){ BuildNav(); }); /*BUILD SIDE NAVIGATION*/ function BuildNav() { //add back to top links before each H2 $('#content h2').each(function(i){ if(i==0){//FIRST H2 $(this).before('div id='+ i +' class=note')//START A NEW DIV WITH UNIQUE ID } else { $(this).before('/divdiv id='+ i +' class=note');//TERMINATE PREVIOUS DIV, BEGIN NEW ONE } }) $('#content').append('/div');//TERMINATE FINAL DIV } This looks sensible to me but fails. It appears you cannot inject unterminated tags and that JQUERY automatically closes tags on insertion, resulting in: div id=content div id=1/div h2First section/h2 ...[arbitary HTML] div id=2/div h2second section/h2 ...[arbitary HTML] div id=3/div h2third section/h2 . /div Can anyone
Re: [jQuery] Please help (again, sorry)..NextUntil not working
Man, you are amazing at this stuff. Really appreciate all the effort you have taken, particularly putting up the test case. I am new to the mailing list and can't get past how prolific you are. You must live and breath this stuff. It is great to find someone so willing to help out!!! I have implemented your code and it works BEAUTIFULLY, straight out of the box. I will now go ahead and construct the dynamic navigation part. Will fire the URL to you when I've finished so you can have a look at where I was headed with this. Thanks again, Cheers, Greg Hat's off, Greg John Resig wrote: Ok, I did some more digging and you're right. I don't think I ever actually tested nextUntil (oops!) The full implementation can be found here: http://john.jquery.com/jquery/test/nextuntil.html This includes a working version of nextUntil: $.fn.nextUntil = function(expr) { var match = []; // We need to figure out which elements to push onto the array this.each(function(){ // Traverse through the sibling nodes for( var i = this.nextSibling; i; i = i.nextSibling ) { // Make sure that we're only dealing with elements if ( i.nodeType != 1 ) continue; // If we find a match then we need to stop if ( jQuery.filter( expr, [i] ).r.length ) break; // Otherwise, add it on to the stack match.push( i ); } }); return this.pushStack( match, arguments ); }; Additionally, I realized that .wrap() isn't going to do what you need it to. .wrap() wraps each matched element with the same structure. So if you matched 3 paragraphs, you'd have three surrounding divs too. Since you want it to wrap all of the matched elements with a single element, I made a new .wrapAll() plugin: $.fn.wrapAll = function() { // There needs to be at least one matched element for this to work if ( !this.length ) return this; // Find the element that we're wrapping with var b = jQuery.clean(arguments)[0]; // Make sure that its in the right position in the DOM this[0].parentNode.insertBefore( b, this[0] ); // Find its lowest point while ( b.firstChild ) b = b.firstChild; // And add all the elements there return this.appendTo(b); }; So - all of that should help you along now. Let me know if this works for you. --John On 10/18/06, Greg Bird [EMAIL PROTECTED] wrote: Thanks for this Blair.a really interesting approach and one I wouldn't have thought of myself. At the moment, I am having problems with the NextUntil function, but once I have this solved, your suggestion may be a really neat implementation. Cheers, Greg Blair McKenzie-2 wrote: This is just a guess: function BuildNav() { $(#content h2).each(function(){ $(this).before(div class='note newdivmarker'/div).nextUntil(h2).appendTo(.newdivmarker); $( div.newdivmarker).removeClass(newdivmarker); }); } It relies on the assumption that appendTo moves the origonal element list, rather than clones them. Basically: 1. It adds your div before the heading, with a temporary marker so we can find it again 2. Selects all elements until the next heading 3. Moves them to the div 4. Removes the marker from the div Blair On 10/18/06, Greg Bird [EMAIL PROTECTED] wrote: Hi John, thanks again for your help, unfortunately I have deployed your suggestions and am still unable to get it to work. You can view my testpage at: http://members.optusnet.com.au/greg.bird/mm/collapse.html My .js now reads: $(document).ready(function(){ BuildNav(); }); //DEFINE NextUntil FUNCTION $.fn.nextUntil = function(expr) { var match = []; this.each(function(){ var cur = this.nextSibling; while ( cur jQuery.filter( expr, [cur] ).r.length ) { match = jQuery.merge( match, [ cur ] ); cur = cur.nextSibling; } console.log(this,cur,match); }); return this.pushStack( match, arguments ); }; /*BUILD SIDE NAVIGATION*/ function BuildNav() { $(#content h2).each(function(){ $(this).nextUntil(h2).wrap(div class='note'/div); }); } I have logged the script and it appears that the match array is not being populated. I suspect that the Jquery.merge function is not triggering properly Does this function work with JQUERY 1.0.2? In note in the JQUERY doco that the function call is now $.merge. Trialled this without success. My aim here is to put a unique div around each section of the page and then dynamically create an expand/collapse navigation system. Have already achieved a similar result with a sliding navigation system. You can see this at: http://members.optusnet.com.au/greg.bird/mm/index.html This was easier as I didn't need to wrap
[jQuery] Request for assistance: Wrapping div's aroiund structural markup
Hi everyone. I am attempting to develop some dynamic in page navigation. I am a big fan of structural markup. Each H2 represents a new section of the current document. I wish to: 1. Find each H2 2. Wrap this in a unique div, up to (but not including) the next H2. This will then be used to further manipulate the page div id=content h2First section/h2 ...[arbitary HTML] h2second section/h2 ...[arbitary HTML] h2third section/h2 . /div Becomes: div id=content div id=1 h2First section/h2 ...[arbitary HTML] /div div id=2 h2second section/h2 ...[arbitary HTML] /div h2third section/h2 . /div Here is the JQuery that I have developed to date: $(document).ready(function(){ BuildNav(); }); /*BUILD SIDE NAVIGATION*/ function BuildNav() { //add back to top links before each H2 $('#content h2').each(function(i){ if(i==0){//FIRST H2 $(this).before('div id='+ i +' class=note')//START A NEW DIV WITH UNIQUE ID } else { $(this).before('/divdiv id='+ i +' class=note');//TERMINATE PREVIOUS DIV, BEGIN NEW ONE } }) $('#content').append('/div');//TERMINATE FINAL DIV } This looks sensible to me but fails. It appears you cannot inject unterminated tags and that JQUERY automatically closes tags on insertion, resulting in: div id=content div id=1/div h2First section/h2 ...[arbitary HTML] div id=2/div h2second section/h2 ...[arbitary HTML] div id=3/div h2third section/h2 . /div Can anyone give me any clues? Thanks in advance, Greg Bird -- View this message in context: http://www.nabble.com/Request-for-assistance%3A--Wrapping-div%27s-aroiund-structural-markup-tf2449875.html#a6828385 Sent from the JQuery mailing list archive at Nabble.com. ___ jQuery mailing list discuss@jquery.com http://jquery.com/discuss/
[jQuery] Please help! Dynamically Wrapping DIV's around structural markup.
Hi everyone. I am attempting to develop some dynamic in page navigation. I am a big fan of structural markup. Each H2 represents a new section of the current document. I wish to: 1. Find each H2 2. Wrap this in a unique div, up to (but not including) the next H2. This will then be used to further manipulate the page div id=content h2First section/h2 ...[arbitary HTML] h2second section/h2 ...[arbitary HTML] h2third section/h2 . /div Becomes: div id=content div id=1 h2First section/h2 ...[arbitary HTML] /div div id=2 h2second section/h2 ...[arbitary HTML] /div h2third section/h2 . /div Here is the JQuery that I have developed to date: $(document).ready(function(){ BuildNav(); }); /*BUILD SIDE NAVIGATION*/ function BuildNav() { //add back to top links before each H2 $('#content h2').each(function(i){ if(i==0){//FIRST H2 $(this).before('div id='+ i +' class=note')//START A NEW DIV WITH UNIQUE ID } else { $(this).before('/divdiv id='+ i +' class=note');//TERMINATE PREVIOUS DIV, BEGIN NEW ONE } }) $('#content').append('/div');//TERMINATE FINAL DIV } This looks sensible to me but fails. It appears you cannot inject unterminated tags and that JQUERY automatically closes tags on insertion, resulting in: div id=content div id=1/div h2First section/h2 ...[arbitary HTML] div id=2/div h2second section/h2 ...[arbitary HTML] div id=3/div h2third section/h2 . /div Can anyone give me any clues? Thanks in advance, Greg Bird -- View this message in context: http://www.nabble.com/Please-help%21-Dynamically-Wrapping-DIV%27s-around-structural-markup.-tf2464168.html#a6869370 Sent from the JQuery mailing list archive at Nabble.com. ___ jQuery mailing list discuss@jquery.com http://jquery.com/discuss/
Re: [jQuery] Please help! Dynamically Wrapping DIV's around structural markup.
Fantastic John Exactly what I was looking for. Thanks for the prompt assistance. I will deploy and test tonight and let you know how I go. I notice how prolific you are on this mailing list...great to see people as switched on as yourself willing to help the intellectually less fortunate Thanks again, Greg John Resig wrote: Hi Greg - I created a plugin a while back that can help with this, called nextUntil: $.fn.nextUntil = function(expr) { var match = []; this.each(function(){ var cur = this.nextSibling; while ( cur jQuery.filter( expr, [cur] ).r.length ) { match = jQuery.merge( match, [ cur ] ); cur = cur.nextSibling; } }); return this.pushStack( match, arguments ); }; Just include that after you include jquery.js then do the following: $(#content h2).each(function(){ $(this).nextUntil(h2).wrap(div class='note'/div); }); Just 3 lines! Not too shabby :) --John On 10/18/06, Greg Bird [EMAIL PROTECTED] wrote: Hi everyone. I am attempting to develop some dynamic in page navigation. I am a big fan of structural markup. Each H2 represents a new section of the current document. I wish to: 1. Find each H2 2. Wrap this in a unique div, up to (but not including) the next H2. This will then be used to further manipulate the page div id=content h2First section/h2 ...[arbitary HTML] h2second section/h2 ...[arbitary HTML] h2third section/h2 . /div Becomes: div id=content div id=1 h2First section/h2 ...[arbitary HTML] /div div id=2 h2second section/h2 ...[arbitary HTML] /div h2third section/h2 . /div Here is the JQuery that I have developed to date: $(document).ready(function(){ BuildNav(); }); /*BUILD SIDE NAVIGATION*/ function BuildNav() { //add back to top links before each H2 $('#content h2').each(function(i){ if(i==0){//FIRST H2 $(this).before('div id='+ i +' class=note')//START A NEW DIV WITH UNIQUE ID } else { $(this).before('/divdiv id='+ i +' class=note');//TERMINATE PREVIOUS DIV, BEGIN NEW ONE } }) $('#content').append('/div');//TERMINATE FINAL DIV } This looks sensible to me but fails. It appears you cannot inject unterminated tags and that JQUERY automatically closes tags on insertion, resulting in: div id=content div id=1/div h2First section/h2 ...[arbitary HTML] div id=2/div h2second section/h2 ...[arbitary HTML] div id=3/div h2third section/h2 . /div Can anyone give me any clues? Thanks in advance, Greg Bird ___ jQuery mailing list discuss@jquery.com http://jquery.com/discuss/ -- View this message in context: http://www.nabble.com/Please-help%21-Dynamically-Wrapping-DIV%27s-around-structural-markup.-tf2464168.html#a6869715 Sent from the JQuery mailing list archive at Nabble.com. ___ jQuery mailing list discuss@jquery.com http://jquery.com/discuss/