Get the nth-child from toStructure()

I’m looping through an toStructure() object and would like to give certain childs a certain css class.
Is there an way to use nth because I need the second and the last element?

<?php foreach($data->contactItems()->toStructure()->limit(3) as $contact): ?>
	<div class="col-sm-4">
		<div class="row">
			<div class="col-lg-10">
				<div class="h3 light"><?php echo $contact->title()->html() ?></div>

				<?php if($contact->description()->isNotEmpty()): ?>
					<div class="h4"><?php echo $contact->description()->html() ?></div>
				<?php endif ?>

				<?php echo $contact->text()->kt() ?>
			</div>
		</div>
	</div>
<?php endforeach ?>

Why this is not working? :frowning:

<?php $item = $data->contactItems()->toStructure() ?>

<?php foreach ($item as $contact): ?>
	<?php if($item->nth(0)): ?>
		<div class="col-sm-4">
			<div class="row">
				<div class="col-lg-10">
					<div class="h3 light"><?php echo $contact->title()->html() ?></div>

					<?php if($contact->description()->isNotEmpty()): ?>
						<div class="h4"><?php echo $contact->description()->html() ?></div>
					<?php endif ?>

					<?php echo $contact->text()->kt() ?>
				</div>
			</div>
		</div>
	<?php endif ?>
<?php endforeach ?>

You can use indexOf() to achieve what you want:

<?php $item = $data->contactItems()->toStructure() ?>

<?php foreach ($item as $contact): ?>
	<?php if($item->indexOf($contact) == 0): ?>
		<div class="col-sm-4">
			<div class="row">
				<div class="col-lg-10">
					<div class="h3 light"><?php echo $contact->title()->html() ?></div>

					<?php if($contact->description()->isNotEmpty()): ?>
						<div class="h4"><?php echo $contact->description()->html() ?></div>
					<?php endif ?>

					<?php echo $contact->text()->kt() ?>
				</div>
			</div>
		</div>
	<?php endif ?>
<?php endforeach ?>

$item->nth(0) will return true if that item exists, but this will always be true as long as there is a single item, that is, it will be true as long as the loop loops.

2 Likes

Your code produced no output.

I have edited the field name, it should work now.

1 Like

Exactly :slight_smile:

This is a very powerful tool to add things like css classes into the loop!

But is it possible whit nth, too?

This is working:

<div class="col-lg-10<?php if($item->indexOf($contact) == 1): ?> col-lg-offset-1<?php endif ?>"></div>

But I need this:

<div class="col-lg-10<?php if($item->nth(2)($contact) == 1): ?> col-lg-offset-1<?php endif ?>"></div>

Using this is working but it is not perfect:

<div class="col-lg-10<?php if($item->indexOf($contact) == 1 and $item->indexOf($contact) == 4): ?> col-lg-offset-1<?php endif ?><?php if($item->indexOf($contact) == 2 and $item->indexOf($contact) == 5): ?> col-lg-offset-2<?php endif ?>"></div>

Should be or not and.

I have 6 items and would like add a class to every 2nth and a different class to every 3nth element. My code from below is working until I have more than six items. Than I have to manually add more and statements.
It should be working with some kind of nth-child.

	<div class="row">
		<?php $item = $data->contactItems()->toStructure() ?>

		<?php foreach ($item as $contact): ?>

			<div class="col-sm-4">
				<div class="row">
					<div class="col-lg-10<?php if($item->indexOf($contact) == 1 or $item->indexOf($contact) == 4): ?> col-lg-offset-1<?php endif ?><?php if($item->indexOf($contact) == 2 or $item->indexOf($contact) == 5): ?> col-lg-offset-2<?php endif ?>">
						<div class="h3 light"><?php echo $contact->title()->html() ?></div>

						<?php if($contact->description()->isNotEmpty()): ?>
							<div class="h4"><?php echo $contact->description()->html() ?></div>
						<?php endif ?>

						<?php echo $contact->text()->kt() ?>
					</div>
				</div>
			</div>

			<?php if($item->indexOf($contact) == 2): ?>
				</div><div class="row">
			<?php endif ?>

		<?php endforeach ?>
	</div>

@texnixe You are right, it should be or not and

Sorry!

using or like you did is fine but be wary of ors precedence when using it in assignments. :smirk:

// The result of the expression (false || true) is assigned to $e
// Acts like: ($e = (false || true))
$e = false || true;

// The constant false is assigned to $f and then true is ignored
// Acts like: (($f = false) or true)
$f = false or true;

For anyone’s future ref, using indexOf inside an ecco statement to add a class to all items except the first one:

<?php $item = $page->builder()->toStructure()->flip() ?>

<?php foreach($item as $entry): ?>
  <a href="<?= $entry->activity_url()->html() ?>" class="<?php e($item->indexOf($entry) != 0, 'u-padding--t-1') ?> t-border--b-1">
    <?= entry->title()->html() ?>
  </a>
<?php endforeach ?>

Useful when writing functional css.

1 Like

using indexOf is a nice idea for css.

since structure inherits from collection its a quiet powerful field type. the docs have a nice section about that too called Working with a collection.