Support

Account

Home Forums Add-ons Repeater Field Problem occurs when output as tabs for nested repeater field

Solving

Problem occurs when output as tabs for nested repeater field

  • Problems encountered when trying to format my output as tabs when using nested repeater field. The part where I need to do another while loop to get the content for tab content is not working. I added reset_rows() after searching the forum for answers but it causes an infinite loop of the page. Any help is appreciated.

    Here is my code:

    
    if( have_rows('parent_repeater') ):
      while( have_rows( 'parent_repeater' ) ) : the_row();
    
        if( have_rows( 'parent_flexible_content' ) ):
          while( have_rows( 'parent_flexible_content' ) ) : the_row();
            
            if( get_row_layout() == 'flexible_content_child_one' ):
            // do something
    
            elseif( get_row_layout() == 'flexible_content_child_two' ):
            // do something
            
            elseif( get_row_layout() == 'flexible_content_child_three' ):
              if( have_rows( 'child_repeater' ) ):
              $count = 0;
              // create tab links
              echo '<ul>';
                while( have_rows( 'child_repeater' ) ) : the_row();
    
                $title = get_sub_field( 'title' );
                $tab_id = str_replace(' ', '-', strtolower( $title ) );
    
                echo '<li class="nav';
                if( !$count ) {
                  echo ' active';
                }
                echo '"><a href="#' . $tab_id . '" data-toggle="tab">' . $tab_title . '</a></li>';
    
                $count++
                endwhile; // endof child_repeater
              echo'</ul>';
    
              reset_rows(); // <----- CAUSE INFINITE LOOP
            
              // create tab content ( this part is not working )
              echo 'div class="tab-content">';
                while( have_rows( 'child_repeater' ) ) : the_row();
              
                  $content = get_sub_field( 'content' );
                  echo '<div class="tab-pane fade" id="' . $tab_id . '">' . $content . '</div>'; 
                endwhile; // endof child_repeater
              echo '</div>';
            
              endif; // endof child_repeater
    
            endif; // endof get_row_layout()
    
          // endof parent_flexible_content
          endwhile; 
        endif;
       
      endwhile; // endof parent_repeater
    else:
      Nothing Found!
    endif; // endof parent_repeater
    
    • James

    • September 26, 2016 at 11:41 am

    Hi @delonnkoh

    Please keep in mind that you don’t need to use the reset_rows() function in a nested repeater. This page should give you more idea about it: https://www.advancedcustomfields.com/resources/working-with-nested-repeaters/.

    I hope this helps 🙂

  • Hi @acf-support,

    The problem is I need to loop through twice of the while loop, one for the tab nav links and another for its content.

    • James

    • September 27, 2016 at 12:26 pm

    Hi @delonnkoh

    Have you tried to remove the reset_rows() function? Could you please tell me what happens when you remove it?

    Also, could you please share the JSON export file so I can test it out on my installation?

    If you want, you can also try to put the repeater values in a variable first and then loop through it like this:

    $child_repeater = get_field('child_repeater');
    
    // first loop
    foreach($child_repeater as $item){
        $tab_title = $item['title'];
        $tab_id = str_replace(' ', '-', strtolower( $title ) );
    
        echo '<li class="nav';
        if( !$count ) {
          echo ' active';
        }
        echo '"><a href="#' . $tab_id . '" data-toggle="tab">' . $tab_title . '</a></li>';
    
        $count++
    }
    
    // second loop
    foreach($child_repeater as $item){
        $tab_title = $item['title'];
        $tab_id = str_replace(' ', '-', strtolower( $title ) );
        
        $content = $item['content'];
        echo '<div class="tab-pane fade" id="' . $tab_id . '">' . $content . '</div>'; 
    }

    Thanks 🙂

    • James

    • September 27, 2016 at 12:26 pm

    Hi @delonnkoh

    Have you tried to remove the reset_rows() function? Could you please tell me what happens when you remove it?

    Also, could you please share the JSON export file so I can test it out on my installation?

    If you want, you can also try to put the repeater values in a variable first and then loop through it like this:

    $child_repeater = get_field('child_repeater');
    
    // first loop
    foreach($child_repeater as $item){
        $tab_title = $item['title'];
        $tab_id = str_replace(' ', '-', strtolower( $title ) );
    
        echo '<li class="nav';
        if( !$count ) {
          echo ' active';
        }
        echo '"><a href="#' . $tab_id . '" data-toggle="tab">' . $tab_title . '</a></li>';
    
        $count++
    }
    
    // second loop
    foreach($child_repeater as $item){
        $tab_title = $item['title'];
        $tab_id = str_replace(' ', '-', strtolower( $title ) );
        
        $content = $item['content'];
        echo '<div class="tab-pane fade" id="' . $tab_id . '">' . $content . '</div>'; 
    }

    Thanks 🙂

  • Hi James,

    reset_rows() was added because it was the solution provided for such scenario( when there is a need for more than one while loop of the same repeater field) but it doesn’t work for me as I have pointed out. The only difference is I have a repeater of flexible content which also has a repeater field.

    I managed to solve the problem using good ol’foreach loop to suit my need, just thought that there will be a better way( or good practice) to use reset_rows()

    • mastafu

    • December 15, 2017 at 9:34 pm

    I would like to report it too. Could you guys fix this issue ?
    If you want to create tabs headers and tabs content you need to loop it twice with the same reaptear.

    This creates a problem. In second loop I get 1 row from first loop with empty content. And that breaks tab functionality.

  • Hi James,

    Thanks for your solution. Like mastafu said, this is still an issue and not very well documented. Took some time to find this answer, and seems like an annoying little bugger that should be easy to fix.

    • tynan

    • December 24, 2018 at 10:12 am

    It sounds like mastafu identified an issue but I’m not sure what to do about it. Artificially increment the loop index by 1?

    Here’s my nested tabs, but in Twig:

    {# parent tabs #}
    		<ul class="tabs tabs--parents" data-tabs id="parent-tabs">
    			{% for parent_tab in component.tabs %}
    		  		<li class="tabs-title tabs--parents__title{% if loop.first %} is-active{% endif %}">
    		  			<a data-tabs-target="panel-{{loop.index}}" href="#panel-{{ loop.index }}" {% if loop.first %}aria-selected="true"{% endif %}>{{ parent_tab.tab_title }}</a>
    		  		</li>
    		  	{% endfor %}		
    		</ul>
    		{# end parent tabs #}
    
    		{# parent content panels #}
    		{% for parent_panel in component.tabs %}
    			<div class="tabs-content" data-tabs-content="parent-tabs">
    			  <div class="tabs-panel tabs-panel--parents {% if loop.first %}is-active{% endif %}" id="panel-{{ loop.index }}">
    				
    
    				{# child tabs #}
    				<ul class="tabs tabs--sub-tabs" data-tabs id="sub-tabs">
    					{% for child_tab in parent_panel.sub_tabs %}
    						<li class="tabs-title tabs--sub-tabs__title{% if loop.first %} is-active{% endif %}">
    							<a data-tabs-target="sub-tab-panel-{{loop.index}}" href="#sub-tab-panel-{{ loop.index }}" {% if loop.first %}aria-selected="true"{% endif %}>{{ child_tab.sub_tab_title }}</a>
    						</li>
    					{% endfor %}
    				</ul>
    				{# end child tabs #}
    
    				{# child content panels #}
    				{% for sub_content in parent_panel.sub_tabs %}
    					<div class="tabs-content" data-tabs-content="sub-tabs">
    					  <div class="tabs-panel tabs-panel--sub-tabs {% if loop.first %}is-active{% endif %}" id="sub-tab-panel-{{ loop.index }}">
    					  	{{ sub_content.sub_tab_content }}
    					  </div>
    					</div>
    				{% endfor %}
    				{# end child content panels #}
    
    			  </div>			
    		{% endfor %}
    		{# end parent content panels #}
    

    Same odd behaviour: The parent panels (which each contain a unique set of sub tabs) all work, but curiously only the first sub tab works; subsequent sub tabs add their respective panel content to the page, but don’t switch the panel over. I thought this might be related to the Foundation Tabs, but all the ids, data-tabs-targets and hrefs are looping as expected.

Viewing 9 posts - 1 through 9 (of 9 total)

You must be logged in to reply to this topic.

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 Cookie Policy. If you continue to use this site, you consent to our use of cookies.