Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selecting a set of paragraphs with jQuery

Tags:

jquery

I have an HTML file containing sets of paragraphs, for example:

<p>Page 1</p>
<p>Paragraph 1</p>
<p>Paragraph 2</p>

<p>Page 2</p>
<p>First line.</p>
<p>Some text here.</p>
<p>Some other text here.</p>

<p>Page 3</p>
<p>Paragraph 1</p>
<p>Paragraph 2</p>

I need to select all the paragraphs in a page. The content of the first paragraph in page n is always "Page n", but the number of paragraphs in a page is variable, as is the content of the paragraphs following the page number.

How can I select paragraphs between Page n and Page n+1?

So far I could only figure out how to select the first paragraph in a Page, using jQuery:

var n = 2;
$("p:contains(Page " + n + ")").next("p").css('background-color', 'red');

Thank you in advance.

like image 496
Cristina Fierbinteanu Avatar asked Apr 09 '15 08:04

Cristina Fierbinteanu


2 Answers

If you're stuck with that structure, you're looking for nextUntil, which adds following elements up until (and not including) an element matching the selector you pass it:

var n = 2;
$("p:contains(Page " + n + ")").nextUntil("p:contains(Page " + (n + 1) + ")").css('background-color', 'red');

(Live example below.)

That selects only the paragraphs after the "Page n" paragraph, not the "Page n" paragraph itself. If you also want to include the "Page n" paragraph, use addBack (formerly andSelf, but andSelf was deprecated in favor of addBack in v1.8), like this:

var n = 2;
$("p:contains(Page " + n + ")")
    .nextUntil("p:contains(Page " + (n + 1) + ")")
    .addBack()
    .css('background-color', 'red');

But if you can modify the structure, I'd probably put the contents of each page in a wrapper element, such as section:

<section data-page="1">
    <h1>Page 1</h1>
    <p>Paragraph 1</p>
    <p>Paragraph 2</p>
</section>
<section data-page="2">
    <h1>Page 2</h1>
    <p>First line.</p>
    <p>Some text here.</p>
    <p>Some other text here.</p>
</section>
<section data-page="3">
    <h1>Page 3</h1>
    <p>Paragraph 1</p>
    <p>Paragraph 2</p>
</section>

Note that I also included a data-* attribute identifying the page (also changed the paragraphs containing the page numbers to h1; the spec recommends including an h1-h6 element to identify the section). Then it would be simply:

$("section[data-page=" + n + "] > p").css(/*...*/);

Live example using current structure (without addBack):

var colors = {
  1: "red",
  2: "green",
  3: "blue"
};
var n;
for (n = 1; n <= 3; ++n) {
  $("p:contains(Page " + n + ")").nextUntil("p:contains(Page " + (n + 1) + ")").css('background-color', colors[n]);
}
<p>Page 1</p>
<p>Paragraph 1</p>
<p>Paragraph 2</p>

<p>Page 2</p>
<p>First line.</p>
<p>Some text here.</p>
<p>Some other text here.</p>

<p>Page 3</p>
<p>Paragraph 1</p>
<p>Paragraph 2</p>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
like image 66
T.J. Crowder Avatar answered Nov 02 '22 23:11

T.J. Crowder


If you are able to write "Page 1" --- "Page n", then maybe paragraphs should have a class? Am I right to assume they are dynamically added?

Like so:

<p class="p1">Page 1</p>
<p class="belongs_p1">Paragraph 1</p>
<p class="belongs_p1">Paragraph 2</p>

<p class="p2">Page 2</p>
<p class="belongs_p2">First line.</p>
<p class="belongs_p2">Some text here.</p>
<p class="belongs_p2">Some other text here.</p>

<p class="p3">Page 3</p>
<p class="belongs_p3">Paragraph 1</p>
<p class="belongs_p3">Paragraph 2</p>

That way you can select a paragraph and all paragraphs that belong to it, without the need to calling the content of the paragraph.

like image 36
Alexey Avatar answered Nov 02 '22 23:11

Alexey