18

Is there a way to easily do nextUntil, so that the element matched by the selector is included? I have this, which is only fine if there is a previous sibling:

$("#content").find("h3:first").prev().nextUntil("ul:last").wrapAll("<div id='collapse'></div>");
hippietrail
  • 15,848
  • 18
  • 99
  • 158
jwinn
  • 1,135
  • 3
  • 14
  • 30
  • 1
    Can you update your question with the relevant parts of your HTML markup? This would help us to understand what you're trying to achieve. – Frédéric Hamidi Mar 02 '12 at 21:03

7 Answers7

26

Remove .prev(), replace .nextUntil with .nextAll and use .addBack() at the end of your selector as shown below:

$("#content").find("h3:first").nextAll("ul:last").addBack().wrapAll("<div id='collapse'></div>");

Pre 1.8 should use andSelf instead of addBack

Vadim
  • 1,916
  • 2
  • 19
  • 39
  • 7
    Had never accepted an answer on this old question. FYI, anyone checking this now: "andSelf() - Note: This function has been deprecated and is now an alias for .addBack(), which should be used with jQuery 1.8 and later." – jwinn Oct 02 '13 at 20:58
  • I just discovered this answer today ( 21-07-2017 ) and it helped me on my project , ty – samouray Jul 21 '17 at 11:16
  • Thanks for noticing, @MikhailOrlov. I've fixed this edge case. – Vadim Sep 03 '19 at 18:55
  • The nextUntil() and addBack() having a structure of

    following by whatever you want did the trick for me. Now the

    and the following is wrapped by a div.

    – Daniel Soublett Mar 06 '20 at 20:09
2

The workaround I found was to get the length using nextUntil (or prevUntil), then use slice() with this length + 1 on nextAll():

var inclusiveNextUntil = $(this).nextUntil( '.some-class' ).length;
var inclusiveNextUntil = $(this).nextAll().slice( 0 , inclusiveNextUntil + 1 );

It’s clumsy but it works. HTH

Fwiw in the nextAll docs Biziclop mentions adding + *:

$obj.nextUntil('.last-item-to-include + *')  

but this doesn’t work for me :/

Oli Studholme
  • 2,600
  • 22
  • 16
1

Here's what I do. I think it's a bit cleaner than other suggestions.

var elearr = $('selector1').nextUntil('selector2');
var lastele = elearr[elearr.length-1];
elearr.push($(lastele).next());
BStep
  • 83
  • 5
1
var s = $("li.start").nextUntil("li.stop");
s = s.add(s.last().next()).add(s.first().prev());
//and do whatever you need to with s

The most intuitive, I think. All made with jQuery methods. No need to search twice. Easy to understand and easy to remember.

zhristov
  • 11
  • 2
0

I think correct answer is

$("#content").find("h3:first").nextUntil("ul:last").addSelf().wrapAll("<div id='collapse'></div>");
Hillar Kapsta
  • 135
  • 1
  • 8
0

As answered by others, using .addSelf() is the solution for making the starting element inclusive.

$("#content").find("h3:first").nextUntil("ul:last").addSelf().wrapAll("<div id='collapse'></div>");

And to make the ending element inclusive, using the .nextUntil(".class + *") method solved the issue.

$("#content").find("h3:first").nextUntil("ul:last + *").addSelf().wrapAll("<div id='collapse'></div>");
Justintosh
  • 33
  • 1
  • 4
-1

of course you can, just use jQuery nextAll.

'nextAll' will include the following elements matching that selector.

while 'nextUntil' exclude the matching selector element.

Shlomi Komemi
  • 5,445
  • 3
  • 28
  • 41
  • "next" just gets the single following sibling, whereas I am grabbing all the siblings up until a defined end-point. – jwinn Mar 08 '12 at 16:10
  • -1: from nextAll() ref: Get all **following** siblings of each element in the set of matched elements, optionally filtered by a selector. , so this will **not** include the matched element. –  Feb 27 '14 at 14:51