ACF Repeater Load More using AJAX

Have you ever wanted to show a limited amount of items when using an ACF repeater? Maybe you are using this to display images and to save on load time you only want to show a selective amount instead of loading them all. At the end of the day, having to load fewer images is going to speed up your site right?

In this example, we will show you the basics of adding load more functionality for an ACF repeater field. We are going to display a repeater called gallery and load only 9 items if there are more than 9 items we will display a ‘Load more’ button to programmatically load the rest.

So first of all our markup will look as follows:-


<div id="photo-gallery">
	<div class="row">
		<?php
		if( have_rows('media') ): 
			$total = count(get_field('media'));
			$count = 0;
			$number = 8;					
			while ( have_rows('media') ) : the_row(); ?>						
					<div class="col-md-4 col-sm-6">
						<a class="mag-pop" data-img="<?php the_sub_field('image'); ?>" href="<?php the_sub_field('image'); ?>"><img class="img-gallery" alt="BeWILDerwood Gallery" src="<?php the_sub_field('image'); ?>" /></a>
					</div>
				<?php
				if ($count == $number) {
					// we've shown the number, break out of loop
					break;
				} ?>					
			<?php $count++; endwhile;
		else : endif;
		?>
	</div>
	<a id="gallery-load-more" href="javascript: my_repeater_show_more();" <?php if ($total < $count) { ?> style="display: none;"<?php } ?>><h2 id="title-bg"><span>Load more</span></h2></a>
</div>

As you can see, $number defined the number of repeater items we want to initially display. We use the break; clause to prevent further images from loading.

Now moving on to the JavaScript:-


<script type="text/javascript">
	var my_repeater_field_post_id = <?php echo $post->ID; ?>;
	var my_repeater_field_offset = <?php echo $number + 1; ?>;
	var my_repeater_field_nonce = '<?php echo wp_create_nonce('my_repeater_field_nonce'); ?>';
	var my_repeater_ajax_url = '<?php echo admin_url('admin-ajax.php'); ?>';
	var my_repeater_more = true;
	
	function my_repeater_show_more() {
		
		// make ajax request
		jQuery.post(
			my_repeater_ajax_url, {
				// this is the AJAX action we set up in PHP
				'action': 'my_repeater_show_more',
				'post_id': my_repeater_field_post_id,
				'offset': my_repeater_field_offset,
				'nonce': my_repeater_field_nonce
			},
			function (json) {
				// add content to container
				// this ID must match the containter 
				// you want to append content to
				jQuery('#photo-gallery .row').append(json['content']);
				// update offset
				my_repeater_field_offset = json['offset'];
				// see if there is more, if not then hide the more link
				if (!json['more']) {
					// this ID must match the id of the show more link
					jQuery('#gallery-load-more').css('display', 'none');
				}
			},
			'json'
		);
	}
	
</script>

We’ve added comments within the code so you can see what is happening through the process. Now we need to add the code to the functions.php file to load the additional items.


/**
 * ACF Load More Repeater
*/

// add action for logged in users
add_action('wp_ajax_my_repeater_show_more', 'my_repeater_show_more');
// add action for non logged in users
add_action('wp_ajax_nopriv_my_repeater_show_more', 'my_repeater_show_more');

function my_repeater_show_more() {
	// validate the nonce
	if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'my_repeater_field_nonce')) {
		exit;
	}
	// make sure we have the other values
	if (!isset($_POST['post_id']) || !isset($_POST['offset'])) {
		return;
	}
	$show = 9; // how many more to show
	$start = $_POST['offset'];
	$end = $start+$show;
	$post_id = $_POST['post_id'];
	// use an object buffer to capture the html output
	// alternately you could create a varaible like $html
	// and add the content to this string, but I find
	// object buffers make the code easier to work with
	ob_start();
	if (have_rows('media', $post_id)) {
		$total = count(get_field('media', $post_id));
		$count = 0;
		while (have_rows('media', $post_id)) {
			the_row();
			if ($count < $start) {
				// we have not gotten to where
				// we need to start showing
				// increment count and continue
				$count++;
				continue;
			}
			?>
			<div class="col-md-4 col-sm-6">
				<a class="mag-pop" data-img="<?php the_sub_field('image'); ?>" href="<?php the_sub_field('image'); ?>"><img class="img-gallery" alt="BeWILDerwood Gallery" src="<?php the_sub_field('image'); ?>" /></a>
			</div>
			<?php 
			$count++;
			if ($count == $end) {
				// we have shown the number, break out of loop
				break;
			}
		} // end while have rows
	} // end if have rows
	$content = ob_get_clean();
	// check to see if we have shown the last item
	$more = false;
	if ($total > $count) {
		$more = true;
	}
	// output our 3 values as a json encoded array
	echo json_encode(array('content' => $content, 'more' => $more, 'offset' => $end));
	exit;
} // end function my_repeater_show_more

As you can see above, we are going to load an additional 9 images (or repeater values) on click of the load more button. Once all loaded items have appeared, we are hiding the load more button so that is no longer visible.

And that’s pretty much it! If this has helped you, feel free to drop a comment. If you need any help with this, feel free to get in touch and we’ll be happy to assist you! 🙂

Nathan da Silva - Profile

Posted by: Nathan da Silva

Nathan is the Founder of Silva Web Designs. He is passionate about web development, website design and basically anything digital related. His main expertise is with WordPress, Magento, Shopify as well of many other frameworks. Whether you need responsive design, SEO, speed optimisation or anything else in the world of digital then get in touch. If you would like to work with Nathan, simply drop him an email at [email protected]

It’s good to share

3 Tips to Make Your ACF Custom Fields Tidier

Advanced Custom Fields (ACF) is a plugin to organise custom fields. If you are not familiar with it then check out their website.

ACF is very customisable, however, we have a tendency to overuse it. What effect does this have? Well not only does it grow your database unnecessarily, but it also makes the admin panel more complicated than it needs to be.

In this article, we will be providing a few tips on how you can tidy up your ACF fields…

1. One Field For All

Depending on your content, a single WYSIWYG can represent multiple fields.

As an example, let’s say we have the following fields; Title, Description, Button Text and Button URL. Like so:

If you aren’t planning to do a special operation on individual fields, just combine them into a WYSIWYG:

Then what we can do is add a default value indicating the content placement:

Much cleaner and easier right?

2. Galleries as a Pseudo-Repeater

A repeater is an awesome feature, it’s flexible and easy to edit… but did you know that it pollutes your postmeta table?

Let’s say you have a simple Repeater (single image + couple of text fields), you can get away by using the Gallery and the image’s metadata instead.

Shown below is a Meet the Team repeater:

So we converted this to a Gallery:

You can then convert your page template file code to:-


<?php

$team_members = get_field('team');
if( $team_members ): ?>
  <section class="team">
  <?php foreach( $team as $person ): ?>
    <div id="team-wrapper">
      <img src="<?php echo $person['sizes']['medium']; ?>"
           alt="<?php echo $person['title']; ?> Photo" >
      <h3>
        <?php echo $person['title']; ?>
      </h3>
      <?php echo wpautop( $person['caption'] ); ?>
      <p class="job-desc">"<?php echo $person['description']; ?>"></p>
    </div>
  <?php endforeach; ?>
  </section>
<?php endif; ?>

3. Simplify Basic WYSIWYG

When creating a WYSIWYG field, you can change the Toolbar to be ‘Basic’. But it still has too many buttons on it…

The snippets below will control which buttons you want to show:

functions.php


add_action( 'admin_enqueue_scripts', 'my_admin_assets', 100 );

function my_admin_assets() {
  $css_dir = get_stylesheet_directory_uri() . '/css';

  wp_enqueue_style( 'my-admin', $css_dir . '/my-admin.css' );
}

css/my-admin.css


.acf-field-wysiwyg [data-toolbar="basic"] .mce-btn {
  display:none; /* hide all buttons */
}

.acf-field-wysiwyg [data-toolbar="basic"] [aria-label*="Bold"],
.acf-field-wysiwyg [data-toolbar="basic"] [aria-label*="Italic"],
.acf-field-wysiwyg [data-toolbar="basic"] [aria-label*="Bulleted"],
.acf-field-wysiwyg [data-toolbar="basic"] [aria-label*="Numbered"],
.acf-field-wysiwyg [data-toolbar="basic"] [aria-label*="Align center"],
.acf-field-wysiwyg [data-toolbar="basic"] [aria-label*="edit link"] {
  display:inline-block;
}

.acf-field-wysiwyg [data-toolbar="basic"] .mce-edit-area {
  height:150px !important;
}

Our 3 tips to use ACF more efficiently:

  1. Combine multiple fields into WYSIWYG.
  2. Use Gallery as replacement of Repeater (if content is simple).
  3. Simplify the Toolbar in Basic WYSIWYG using CSS.

 

If you have any question or additional tips to share, please leave a comment below. I will definitely reply to you 🙂

Nathan da Silva - Profile

Posted by: Nathan da Silva

Nathan is the Founder of Silva Web Designs. He is passionate about web development, website design and basically anything digital related. His main expertise is with WordPress, Magento, Shopify as well of many other frameworks. Whether you need responsive design, SEO, speed optimisation or anything else in the world of digital then get in touch. If you would like to work with Nathan, simply drop him an email at [email protected]

It’s good to share

Adding ACF Fields as Admin Columns to your CPT

We all know how awesome Advanced Custom Fields (ACF) is right? We pretty much use the Pro version of it on every WordPress website build we do.

Today, we are going to show you how to add fields to your CPT (Custom Post Type) to the backend Admin Columns.

There are a few plugins that can accomplish adding your ACF fields as admin columns to the backend. Admin Columns is one of the best ones that does the trick. The paid version allows your custom post type to connect with ACF Pro.

As programmers, we want to keep the number of plugins we use to a minimum right? well, it’s pretty simple to add these manually!

Okay, so here we go… Let’s say that you have created a post type, ‘hosting’, and two custom meta fields, ‘start_date’ and ‘end_date’. You’d like to add both meta fields to the custom post type list view. First of all, we will need to add the following to the functions.php file:-


/**
 *	ACF Admin Columns
 *
 */

 function add_acf_columns ( $columns ) {
   return array_merge ( $columns, array ( 
     'start_date' => __ ( 'Starts' ),
     'end_date'   => __ ( 'Ends' ) 
   ) );
 }
 add_filter ( 'manage_hosting_posts_columns', 'add_acf_columns' );

This filter adds your additional columns to the list. We have created an array containing two items – one for the start date and one for the end date – and merged it with the existing columns. The filter is hooked to the specific post type, in this case, manage_hosting_posts_columns, based on the format manage_POSTTYPE_posts_columns. You’ll need to edit this filter to match your custom post type slug.

Secondly, add the following code to output the meta field values:-


 /*
 * Add columns to Hosting CPT
 */
 function hosting_custom_column ( $column, $post_id ) {
   switch ( $column ) {
     case 'start_date':
       echo get_post_meta ( $post_id, 'hosting_start_date', true );
       break;
     case 'end_date':
       echo get_post_meta ( $post_id, 'hosting_end_date', true );
       break;
   }
}
add_action ( 'manage_hosting_posts_custom_column', 'hosting_custom_column', 10, 2 );

Again, notice how the action hook is specific to your post type, in this case, manage_hosting_posts_custom_column. The function looks for the name of your custom columns then echoes the metadata.

Awesome, we’ve added the fields now! But wait, do you want to go the extra step and make the fields sortable? Of course, why wouldn’t you! Here’s how we can do that:-


 /*
 * Add Sortable columns
 */

function my_column_register_sortable( $columns ) {
	$columns['start_date'] = 'start_date';
	$columns['end_date'] = 'start_date';
	return $columns;
}
add_filter('manage_edit-hosting_sortable_columns', 'my_column_register_sortable' );

Well, we hope you have found this tutorial usual, be sure to leave a comment if this has helped you or if you require any help!

Nathan da Silva - Profile

Posted by: Nathan da Silva

Nathan is the Founder of Silva Web Designs. He is passionate about web development, website design and basically anything digital related. His main expertise is with WordPress, Magento, Shopify as well of many other frameworks. Whether you need responsive design, SEO, speed optimisation or anything else in the world of digital then get in touch. If you would like to work with Nathan, simply drop him an email at [email protected]

It’s good to share