Support

Account

Home Forums ACF PRO Echo closing tag after the last row, if rows are not empty

Solved

Echo closing tag after the last row, if rows are not empty

  • Hey,
    I have a table of content which consists the titles (‘step_name’ sub field) of some repeater field. I need to add html tags before and after the list items, only when these sub-fields are not empty.
    I was trying to determine the first and last iteration in the ‘while’ loop, but couldn’t achieve what I wanted. Please help me:

    function itamar_index_for_instructubles() {
    		// check if the instructuble has steps
    		$rows = have_rows('steps');
    		if( $rows ):
    			$i=0;
    			$check=0;
    			$step_num=count($rows);
    			// loop through the steps
    			while ( have_rows('steps') ) : the_row();
    				$i++;
    				$step_title = get_sub_field('step_name');
    				if($step_title!='') :
    					// first iteration
    					if($check==0) :
    						//open tags for the table of content
    						$indexed = '<div class="info-table" id="index"><div class="title">תוכן עניינים<span id="oc-index">-</span></div><div class="body"><ul class="indexed-content">';
    						$check++;
    					endif;
    					$indexed .= '<li>'.$i.'. <a href="#anc'.$i.'">'.$step_title.'</a></li>' ;
    					// last iteration 
    					if($check==$step_num-1) :
    						//closing tags for the table of content
    						$indexed .= '</ul></div><div class="bottom"></div></div>';
    					endif;			
    				endif;
    			endwhile;
    			echo $indexed;
    		endif;
    }
  • Hi @ituk

    You should be able to use the $i variable instead. Could you please try it like the following?

    if($i == 1) :
        //open tags for the table of content
        $indexed = '<div class="info-table" id="index"><div class="title">תוכן עניינים<span id="oc-index">-</span></div><div class="body"><ul class="indexed-content">';
        $check++;
    endif;
    $indexed .= '<li>'.$i.'. <a href="#anc'.$i.'">'.$step_title.'</a></li>' ;
    // last iteration 
    if($i == $step_num) :
        //closing tags for the table of content
        $indexed .= '</ul></div><div class="bottom"></div></div>';
    endif;

    I hope this helps 🙂

  • Hey James and thanks for the reply,
    It seems like there is a problem with $step_num=count($rows);, it returns 1 and therefore the if($i == $step_num) statement occurs on the first iteration and not the last.
    Is there a better way to count the repeater rows?

    EDIT: Solution!
    It’s impossible to count have_rows(), the right way is counting the get_field() itself. so easy 🙂

    function itamar_index_for_instructubles() {
    		// check if the instructuble has steps
    		if( have_rows('שלבים') ):
    			$i=0;
    			$rows = get_field('שלבים');
    			$step_num=count($rows);
    			// loop through the steps
    			while ( have_rows('שלבים') ) : the_row();
    				$i++;
    				$step_title = get_sub_field('שם_השלב');
    				if($step_title!='') :
    					// first iteration
    					if($i == 1) :
    						//open tags for the table of content
    						$indexed = '<div class="info-table" id="index"><div class="title">תוכן עניינים<span id="oc-index">-</span></div><div class="body"><ul class="indexed-content">';
    					endif;
    					$indexed .= '<li>'.$i.'. <a href="#anc'.$i.'">'.$step_title.'</a></li>' ;
    					// last iteration 
    					if($i == $step_num-1) :
    						//closing tags for the table of content
    						$indexed .= '</ul></div><div class="bottom"></div></div>';
    					endif;			
    				endif;
    			endwhile;
    			echo $indexed;
    		endif;
    }

    Thanks!
    Itamar

  • Hey again,
    apparently my function still missed something: it couldn’t handle posts where the first or the last field in the repeater (a step) had an empty sub-field (step title). I figured it out somehow (please see below) but now I have a different problem which I cannot find a solution for – I don’t want the whole loop to happen if all sub-fields are empty. the thing is, it’s impossible to get all sub-fields outside the loop in order to count the empty ones before the loop has started.
    This is what I have now:

    //table of content for instructuble posts
    function itamar_index_for_instructubles() {
    		// check if the instructuble has steps
    		if( have_rows('שלבים') ):
    			$i=0; //counts all iterations, inside the loop
    			$x=0; //counts only iterations with a step title, inside the loop
    			$rows = get_field('שלבים');
    			$total=count($rows); //counts the total number of iterations outside the loop to determine the last one
    			// loop through the steps
    			while ( have_rows('שלבים') ) : the_row();
    				$step_title = get_sub_field('שם_השלב');
    					$i++;
    					// first iteration
    					if($i == 1) :
    						//open tags for the table of content
    						$indexed = '<div class="info-table" id="index"><div class="title">תוכן עניינים<span id="oc-index">-</span></div><div class="body"><ul class="indexed-content">';
    					endif;
    					if($step_title!='' && $i >= 1) :
    					$x++;
    					$indexed .= '<li>'.$x.'. <a href="#anc'.$x.'">'.$step_title.'</a></li>' ;
    					endif;
    					// last iteration 
    					if($i == $total) :
    						//closing tags for the table of content
    						$indexed .= '</ul></div><div class="bottom"></div></div>';
    					endif;			
    			endwhile;
    			echo $indexed;
    		endif;
    }

    And what I would like to do is something like:

    
    /**** before the loop has started ****/
    $total=0;
    $sub_fields = //a function to get all subfields under a given repeater
    foreach($sub_fields as $sub_field){
        if ($sub_field->content != ""){
            $total++;
        }
    }
    /*****/
    /**** inside the loop ****/
    // first iteration
    if($total != 0 && $i == 1) :
    	//open tags for the table of content
    	$indexed = '<div class="info-table" id="index"><div class="title">תוכן עניינים<span id="oc-index">-</span></div><div class="body"><ul class="indexed-content">';
    endif;
    /*****/
    

    Is there a way to get that done?

    Thanks a lot,
    Itamar

    EDIT:
    I found the way:

    //table of content for instructuble posts
    function itamar_index_for_instructubles() {
    		// check if the instructuble has steps
    		if( have_rows('שלבים') ):
    			$rows = get_field('שלבים');
    			$total_steps = count($rows); //counts the total number of steps outside the loop to determine the last one, outside the loop
    			$total_titles = 0; //counts the total number of non-empty step titels, outside the loop
    			if($rows){
    				foreach($rows as $row){
    					if($row['שם_השלב'] != ""){$total_titles++;}
    				}
    			}
    			// loop through the steps
    			if($total_titles != 0) :
    				$i=0; //counts all iterations, inside the loop
    				$x=0; //counts only iterations with a step title, inside the loop
    				while ( have_rows('שלבים') ) : the_row();
    					$step_title = get_sub_field('שם_השלב');
    						$i++;
    						// first iteration
    						if($i == 1) :
    							//open tags for the table of content
    							$indexed .= '<div class="info-table" id="index"><div class="title">תוכן עניינים<span id="oc-index">-</span></div><div class="body"><ul class="indexed-content">';
    						endif;
    						if($step_title!='' && $i >= 1) :
    						$x++;
    						$indexed .= '<li>'.$x.'. <a href="#anc'.$x.'">'.$step_title.'</a></li>' ;
    						endif;
    						// last iteration 
    						if($i == $total_steps) :
    							//closing tags for the table of content
    							$indexed .= '</ul></div><div class="bottom"></div></div>';
    						endif;			
    				endwhile;
    			endif;
    			echo $indexed;
    		endif;
    }
Viewing 4 posts - 1 through 4 (of 4 total)

You must be logged in to reply to this topic.