Support

Account

Home Forums Add-ons Repeater Field Repeater sorted by Date

Solved

Repeater sorted by Date

  • Can Repeater entries on a page be sorted in code and not through the drage and drop UI? I am specifically wanting to sort by a date field found within the repeater itself and sort entries made into the repeater set by date.

    I saw this tutorial but hoped for some feedback before trying to implement because I was unsure if this sorting would work since it’s by ID?
    http://www.advancedcustomfields.com/resources/how-to/how-to-sorting-a-repeater-field/

    Any advice would be helpful

  • Hi @hungrysquirrel,

    It is possible to sort by date with the above method.

    Let me know if you have any problems 🙂

    Cheers

  • Do you mind giving me any tips on formatting and code structure? I am kinda new to PHP and although this works I am not confident.

    One other question I have is, can you recommend a way to approach a UI that would let a user jump to points on the page that are grouped into the same month? Back story is each repeater will have a name and date and now, since I can sort the list by date I was hoping to make it easier for the user to jump to the content for August.

    <!-- repeater	-->
       <?php
         $repeater = get_field('race_event');
           foreach( $repeater as $key => $row )
             { 
               $column_id[ $key ] = $row['race_date'];
              } 
                array_multisort( $column_id, SORT_ASC, $repeater );
                foreach( $repeater as $row ) :
                  {
                    echo '<li>' . $row['race_name'] . '</li>';
    		$date = DateTime::createFromFormat('Ymd', $row['race_date']); 
    		echo '<li>' . $date->format('m-d-Y') . '</li>';
                   }
             endforeach;
         ?>          
    <!-- /repeater	-->
  • Hi @hungrysquirrel

    Is your above code working? Are you sorting successfully?

    To link to different parts on the page, you can use an anchor tag using a name attribute and #target. Read more here
    http://www.echoecho.com/htmllinks08.htm

    Thanks
    E

  • My code is sorting.

    My question may not have been clear, sorry.

    Is there a way to do grouping within the sorting so all the entries for May are in a group with the “May” heading and all the June dated custom fields are in the “June” grouping?

    If so could you give me some tips on how to implement that with my code above?

  • Hi @hungrysquirrel,

    Something like this?

    $currMonth = "start"
    
    foreach( $repeater as $row ) :
                  {
    		$date = DateTime::createFromFormat('Ymd', $row['race_date']); 
    
    if(currMonth != $date->format('F'))
    echo '<h2>' . $date->format('F') . '</h2><br>';
    $currMonth = $date->format('F');
    
    endif
                    echo '<li>' . $row['race_name'] . '</li>';
    
    		echo '<li>' . $date->format('m-d-Y') . '</li>';
                   }
             endforeach;
    
  • I think this is on the right track but I am getting this error.
    Did I miss something in your example?

    Fatal error: Function name must be a string

    this is my code

    <?php
                 
                 $repeater = get_field('race_event');
                 foreach( $repeater as $key => $row )
                   { 
                     $column_id[ $key ] = $row['race_date'];
                   } 
                   array_multisort( $column_id, SORT_ASC, $repeater );
                   
                   $currMonth = "start";
                   foreach( $repeater as $row ) :
                   {
                     $date = DateTime::createFromFormat('Ymd', $row['race_date']); 
                     $website_url = $row['race_website'];
                     
                     if ($currMonth != $date('F')) :
                       {
                         echo '<h2>' . $date('F') . '</h2><br>';
                         $currMonth = $date('F');
                       }
                     endif;
                     
                     echo '<ul>';
    		               echo '<li><h2>' . $row['race_name'] . '</h2></li>';
    		               echo '<li>Date ' . $date->format('F d, Y') . '</li>';
    		               echo '<li>Distance ' . $row['race_distance'] . '</li>';
    		               echo '<li>Vertical ' . $row['race_vertical'] . '</li>';
    		               echo '<li>URL <a href=' . $website_url . '> ' . $website_url . ' </a></li>';
    		               echo '<li>' . $row['race_description'] . '</li>';
    		             echo '</ul>';
                   }
                   endforeach;
                   ?>
  • Oh wait this might be working…I am new to PHP….
    notice the instances of “$currMonth != $date->format(‘F’)”, I imagine this makes the function return a string, is that right?

    <?php
                 
                 $repeater = get_field('race_event');
                 foreach( $repeater as $key => $row )
                   { 
                     $column_id[ $key ] = $row['race_date'];
                   } 
                   array_multisort( $column_id, SORT_ASC, $repeater );
                   
                   $currMonth = "start";
                   foreach( $repeater as $row ) :
                   {
                     $date = DateTime::createFromFormat('Ymd', $row['race_date']); 
                     $website_url = $row['race_website'];
                     
                     if ($currMonth != $date->format('F')) :
                       {
                         echo '<h2>' . $date->format('F') . '</h2><br>';
                         $currMonth = $date->format('F');
                       }
                     endif;
                     
                     echo '<ul>';
    		               echo '<li><h2>' . $row['race_name'] . '</h2></li>';
    		               echo '<li>Date ' . $date->format('F d, Y') . '</li>';
    		               echo '<li>Distance ' . $row['race_distance'] . '</li>';
    		               echo '<li>Vertical ' . $row['race_vertical'] . '</li>';
    		               echo '<li>URL <a href=' . $website_url . '> ' . $website_url . ' </a></li>';
    		               echo '<li>' . $row['race_description'] . '</li>';
    		             echo '</ul>';
                   }
                   endforeach;
                   ?>
  • Hi @hungrysquirrel,

    Sorry! you’re right, the syntax above was incorrect. I’m glad it got you on the right track though.

    Did you get it working?

    Cheers

  • Si Amigo,

    I got everything working. I am still kinda if’y about the syntax and coding style.

    Thanks again for the help, made all the difference for me.

    Cheers,
    Josh

  • I can’t believe that this thread exists – this is exactly what I was working on and nearly gave up after a few hours of trying to figure it out. So, I have a really stupid basic question on this front, now that I’ve got my race calendar working (seriously, was actually working on a race calendar too):

    When working with an UL / LI structure it injects the month name into the proper sorted location – is this possible with a table structure? I can’t get the month names to insert themselves, they end up creating their own TR elements outside of the sorted elements.

    Thanks for this! Fabulous

  • @mrjpotter I’d have to see your codes to help. I am sort of a PHP hack so no guarantees but I am happy to take a look.

  • I’m getting closer, I think. I’ve gotten the month names to create their own rows and cells within the table in the proper order, but now the code is limiting the results on the table to entries in the current month (February).

    What I’m trying to do is echo month name on its own row before array entries for that month, and if it is not the start of a new month, echo the entries in the array in individual TD elements.

    Any thoughts would be helpful, I think I’m just not good enough with PHP to figure this one out alone.

    
    	<table id="race-calendar">
    	    <thead>
    		<tr>
    		   <th>Date</th>
    		   <th>Race Name</th>
    		   <th>Location</th>
    		   <th>Men's/Women's/Both</th>
    		</tr>
    	    </thead>
    	    <?php
                 
                 $repeater = get_field('races');
                 foreach( $repeater as $key => $row )
                   { 
                     $column_id[ $key ] = $row['race_date'];
                   } 
                   array_multisort( $column_id, SORT_ASC, $repeater );
                   
    	       $currMonth = "start";
    	       foreach( $repeater as $row )
    	       
    		{
    		    $date = DateTime::createFromFormat('Ymd', $row['race_date']);
    			
    			if ($currMonth != $date->format('F')) 
    				    {
    				    echo '<tr><td colspan="2"><h2>' . $date->format('F') . '</h2></td></tr><br>';
    				    $currMonth = $date->format('F');
    				    }
    			else { 
    			echo '<tr class="race">';
    				
    				       echo '<td class="cell">' . $date->format('m/d') . '</td>';
    				       echo '<td class="cell"><h2>' . $row['race_name'] . '</h2></td>';
    				       echo '<td class="cell">' . $row['race_location'] . '</td>';
    				       echo '<td class="cell">' . $row['race_gender'] . '</td>';
    			echo '</tr>';
    			
    			}
    			
    
    		}
                   ?>
    	</table>
    

    Thanks!

  • Looking at some of the code you might need to debug a little but here’s some parts I see that are missing some syntax.

    foreach( $repeater as $row ) needs foreach( $repeater as $row ) :

    You are also missing the end of the foreach loop endforeach; ?>, which leads me to suggest you not render any HTML until you know the logic is working.

    Strip it down and build piece by piece. Then post where you are getting stuck but pay close attn to getting the syntax buttoned up first before adding HTML.

  • Quite right, thanks for having a look at the code for me.

    I modified it to use traditional syntax : rather than {} and added the endforeach but it was still limiting to current month only.

    I modified the loop to output month and one entry, and then kept the else statement the same. It not outputs month name, and all entries in chronological order. I’m not 100% sure this is the best way to achieve this, but it appears to work on the front end and doesn’t throw and php errors on the back end.
    Code:

    	    <?php
                 
                 $repeater = get_field('races');
                 foreach( $repeater as $key => $row ) :
                   
                     $column_id[ $key ] = $row['race_date'];
                   endforeach; 
                   array_multisort( $column_id, SORT_ASC, $repeater );
                   
    	       $currMonth = "start";
    	       foreach( $repeater as $row ) :
    	       
    		
    		    $date = DateTime::createFromFormat('Ymd', $row['race_date']);
    			
    			if ($currMonth != $date->format('F')) 
    				    :
    				    echo '<tr class="month"><td><h2>' . $date->format('F') . '</h2></td></tr><br>';
    				    $currMonth = $date->format('F');
    				    echo '<tr class="race">';
    				
    				       echo '<td class="cell">' . $date->format('m/d') . '</td>';
    				       echo '<td class="cell"><h2>' . $row['race_name'] . '</h2></td>';
    				       echo '<td class="cell">' . $row['race_location'] . '</td>';
    				       echo '<td class="cell">' . $row['race_gender'] . '</td>';
    			echo '</tr>';
    				    
    			else : 
    			
    			echo '<tr class="race">';
    				
    				       echo '<td class="cell">' . $date->format('m/d') . '</td>';
    				       echo '<td class="cell"><h2>' . $row['race_name'] . '</h2></td>';
    				       echo '<td class="cell">' . $row['race_location'] . '</td>';
    				       echo '<td class="cell">' . $row['race_gender'] . '</td>';
    			echo '</tr>';
    			
    			endif;
    			
    
    		endforeach; 
                   ?>
    

    Thanks for starting this thread, super helpful!

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

The topic ‘Repeater sorted by Date’ is closed to new replies.