Home › Forums › Add-ons › Repeater Field › Getting instance and (sort of) ID of repeater field
Hi there,
I know, some things in the documentation are close to parts of what I want to achieve, but I still feel a bit lost as how to proceed. Let me explain :).
I have a repeater field for my front page. Let’s say it has four subfields. It is exactly three rows big. What I want to have is visible in this little graphic: https://www.canva.com/design/DAAdwd15Pbo/iBbP4QDqmLpeEd6aAMQqPg/view
In a loop at the top I want the first two subfields from each row to appear, so I made a simple loop like
<div class="repeater_loop1">
<?php while(the_repeater_field('repeater_field')): ?>
<div class="subfield">
<h3><?php the_sub_field('subfield1');?></h3>
<p><?php the_sub_field('subfield2'); ?></p>
</div>
<?php endwhile; ?>
</div>
As you can see in the graphic, I want for each instance of my repeater row to have an additional div somewhere below which then contains the remaining two subfields, while I have a link in the loop above (containing the first two subfields) that leads to the corresponding div containing the 3rd and 4th subfield.
Is there a way one could think of how to solve this puzzle? I could think of a sort of ID for a repeater row that can be used to link and identify a certain div, e.g. the link is href=”#repeater_field_row1″ and the corresponding div has an id=”repeater_field_row1″ or alike.
Also, would it be possible to “speak” to a certain row to e.g. place the first row’s second div with subfield3 and subfield4 somewhere else than row2’s and row3’s second divs?
Thanks in advance
physalis.
No idea, anyone? Maybe some kind of hidden field I could attach through the configuration that’s extractable to use for my current case?
Hi @physalis
This can be accomplished quite simply by using a counter variable which you can use to link the top elements, to the bottom elements like so:
<?php if( have_rows('repeater_field') ): $i = 0; ?>
<div class="repeater_loop1">
<?php while( have_rows('repeater_field') ): the_row(); $i++; ?>
<div class="subfield">
<h2>repeater <?php echo $i; ?></h2>
<h3><?php the_sub_field('subfield1');?></h3>
<p><?php the_sub_field('subfield2'); ?></p>
<a href="#block-<?php echo $i; ?>">Continue reading</a>
</div>
<?php endwhile; ?>
</div>
<?php endif; ?>
<?php if( have_rows('repeater_field') ): $i = 0; ?>
<div class="repeater_loop2">
<?php while( have_rows('repeater_field') ): the_row(); $i++; ?>
<div class="content-bluck" id="block-<?php echo $i; ?>">
<h2>#div (repeater <?php echo $i; ?>)</h2>
<h3><?php the_sub_field('subfield3');?></h3>
<p><?php the_sub_field('subfield4'); ?></p>
</div>
<?php endwhile; ?>
</div>
<?php endif; ?>
You will need to use 2 loops and I have taken the liberty of upgrading your code to use the have_rows function which is available in v4.3.0 as ‘the_repeater_field’ is quite old now
Thanks
E
Hey Elliot,
that actually nailed it. Flawlessly. Thank you so much ;).
Best
physalis
Hey Elliot,
I’ve referenced this article quite a few times. This method has been very helpful but a case came up that this didn’t apply. I wanted to share my solution.
Issue:
Outputting the row ID can be problematic when using flexible content fields because a repeater can appear multiple times on the page, resulting in matching row IDs.
Solution:
Use PHPs built in random number generator to create a variable.
Here’s a basic example for use in any project:
<?php
// generate random var for IDs, anchors, etc.
$num = mt_rand ();
$num_var = sprintf ($num);
// echo random var
echo $num_var;
Here’s an example within a repeater field:
<?php if( have_rows('repeater_field') ): ?>
<?php while ( have_rows('repeater_field') ) : the_row(); ?>
<?php
// create random var id for backstretch
$num = mt_rand ();
$num_var = sprintf ($num); ?>
<?php echo $num_var; ?>
<?php endwhile; ?>
<?php endif; ?>
The number range can be altered for info here: http://www.php.net//manual/en/function.mt-rand.php
Hope that helps someone!
UPDATE
I’ve found a few instances where my solutions above didn’t work. When special characters AND similar titles are involved there comes a time to get super specific.
Here’s the combined solution that I’ve come up with from the research I’ve done.
It strips out tags, shortens the output so long title URLs aren’t a problem, and add a row ID for similarly titled links.
// Strip HTML Tags
$anchor_var = strip_tags(get_sub_field('section_title'));
// Clean up things like &
$anchor_var = html_entity_decode($anchor_var);
// Strip out any url-encoded stuff
$anchor_var = urldecode($anchor_var);
// Replace non-AlNum characters with space
$anchor_var = preg_replace('/[^A-Za-z0-9]/', '', $anchor_var);
// Replace Multiple spaces with single space
$anchor_var = preg_replace('/ +/', ' ', $anchor_var);
// Trim the string of leading/trailing space
$anchor_var = trim($anchor_var);
// Trim length of output
$anchor_var_trim = substr($anchor_var,0,15);
Here’s an example within a repeater field:
<?php if( have_rows('repeater_field') ): $i = 0; ?>
<?php while ( have_rows('repeater_field') ) : the_row(); $i++; ?>
<?php echo $anchor_var_trim; ?>-<?php echo $i; ?>
<?php endwhile; ?>
<?php endif; ?>
Hi Elliot –
Could you make a new function to return the current sub_field index? That way we could keep our template code cleaner with something like:
<?php if (sub_field_index() % 2 == 0): ?>
etc etc
<?php endif; ?>
If you need specific identifier, not random ID or index, you can simply hash value of one of repeater fields, which you consider unique enough. It can be used to generate e.g. FAQ item permalink hash, it will be persistent enough, if you will not change question text too often.
<?php if ( have_rows('faqs') ): ?>
<?php while ( have_rows('faqs') ) : the_row(); ?>
<a href="#<?php echo md5( get_sub_field('question') ); ?>">
<?php the_sub_field('question'); ?>
</a>
<?php the_sub_field('answer'); ?>
<?php endwhile; ?>
<?php endif; ?>
Thanks @emaildano
Great solution – just what I needed.
I would prefer a cleaner way though like @kyle is mentioning though. Maybe getting the meta_id for the repeater fields? That number is unique and short.
Forgive my ignorance, I am trying to study and understand more, in the meantime I rely on your help:
I have a sub-field called ‘feedback’ inserted into a ‘day’ repeater. I create several ‘days’ and I would like the end user to enter a comment in the ‘feedback’ field in frontend and press ‘submit’. This comment should be visible on the backend in the ‘feedback’ field.
I managed to do an acf_form with the ‘feedback’ field, the value is written in the db, but I don’t see it in the backend. And above all it is repeated the same for all instances of the repeater. How do I create unique comments for each instance?
thank you so much!
The topic ‘Getting instance and (sort of) ID of repeater field’ is closed to new replies.
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Privacy Policy. If you continue to use this site, you consent to our use of cookies.