Count items in a foreach loop to number elements


#1

I’m having some trouble figuring this out. I’m using a jquery plugin (Scrollit) to scroll to parts of the page but i need to get Kirby to help out a little.

It works by giving elements and id in a data attribute: data-scroll-index="INDEXNUMBER"

Then you can scroll to it by putting a data attribute on an anchor tag: data-scroll-goto="INDEXNUMBER+1"

But this is in a foreach loop with Kirby Builder in it, so i need to get Kirby to automatically populate the INDEXNUMBER for me, and for the link tag it needs to add 1 to it, since this will make scroll on to the next builder panel on the page.

My code looks like this (some of it is slightly fake to illustrate what i need in words).

    <?php foreach($page->builder()->toStructure() as $section): ?>
      <?php $INDEXNUMBER = $theforeachindex  ?>
      <div class="builder-block" data-scroll-index="INDEXNUMBER">
      <?php snippet('builder/' . $section->_fieldset(), array('data' => $section)) ?>
      </div>
      <a data-scroll-goto="INDEXNUMBER+1" target="_blank" class="pagenav"><i class="fa fa-chevron-down" aria-hidden="true"></i></a>
    <?php endforeach ?>

How do i get Kirby to count the number of items in the foreach loop and fill in the numbers, and also how would i get to start from a set number? Some pages already have these numbers hard coded further up the page so i might to start the numbering on the builder panels from an arbitrary number.

Help! Thanks :slight_smile:


#2

You have to set the index variable to the number you’d like before starting the foreach loop, and increment it :

 <?php $index = 0; foreach($page->builder()->toStructure() as $section): $index++; $next = $index + 1;?>
    <div class="builder-block" data-scroll-index="<?php echo $index ?>">
        <?php snippet('builder/' . $section->_fieldset(), array('data' => $section)) ?>
    </div>
    <a data-scroll-goto="<?php echo $next ?>" target="_blank" class="pagenav"><i class="fa fa-chevron-down" aria-hidden="true"></i></a>
<?php endforeach ?>

#3

Use a counter variable with a set value and increase it with every loop.

@sylvainjule beat me to it…

Edit: an alternative to the counter would be using the indexOf() method.

<?php 
$sections = $page->builder()->toStructure()
foreach($sections as $section): 
  $index = $sections->indexOf($section); // add offset if required
  $next = $index + 1;
?>
    <div class="builder-block" data-scroll-index="<?php echo $index ?>">
        <?php snippet('builder/' . $section->_fieldset(), array('data' => $section)) ?>
    </div>
    <a data-scroll-goto="<?php echo $next ?>" target="_blank" class="pagenav"><i class="fa fa-chevron-down" aria-hidden="true"></i></a>
<?php endforeach ?>

#4

Woah two at once! Lol. thanks ill give it a go… :slight_smile:


#5

I’m having a similar problem, and while I found a workaround, I would like to know why I had to find it.

I’m doing a foreach loop, and setting a counting variable at the beginning ($n=0) and adding the (n++); to the line to iterate by one. In the first layout, it should give me a result of “0” for the value, shouldn’t it?

Here’s the code, with my solution to fix it (named $carl, go figure):

<?php 
	$citems = page('carousel')->children()->visible();
	$n = 0;
	$first  = $citems->first();
 ?>
	<div id="myCarousel" class="carousel slide" data-ride="carousel">
		<ol class="carousel-indicators">
				<?php foreach($citems as $citem): $n++; $carl = $n - 1; ?>
		    <li data-target="#myCarousel" data-slide-to="<?php echo $carl ?>" class="<?php if($carl == 0) echo 'active' ?>"></li>
		  		<?php endforeach ?>
		  </ol>

#6

No, you are increasing the number at the beginning; put your $n++ before the endforeach and you don’t need your calculation.

And you might as well use your $first variable to check if the active class should be added instead of the helper (since you have already created it).

Instead of the helper variable, you can also do the following:

<?php 
$citems = page('carousel')->children()->visible();
?>
<div id="myCarousel" class="carousel slide" data-ride="carousel">
  <ol class="carousel-indicators">
    <?php foreach($citems as $citem): ?>
      <li data-target="#myCarousel" data-slide-to="<?= $citems->indexOf($citem); ?>" class="<?php if($citems->indexOf($citem) == 0) echo 'active' ?>"</li>
    <?php endforeach ?>
  </ol>

#7

So it would look like this? (sorry, the syntax is still a mystery to me)

<?php $n++ ?>
<?php endforeach ?>

#8

Yes, or

<?php $n++; endforeach ?>

But see my edit above.


#9

Just saw it, and thank you, that helps immensely. I’m really impressed by Kirby and all it can do. I’m currently building the pieces for the components of Bootstrap 4 as a way to learn the system and to get them all ready for use, too. Cheers!