Support

Account

Home Forums Add-ons Repeater Field Select which repeater field should be visible at start

Solved

Select which repeater field should be visible at start

  • Hi!

    I’m using repeaters for basic tabs where you can choose a tab and it will display that one.

    Now I need to have it so you can choose which tab that will be active from start (Not always the first one). So I was thinking if you can populate a select field with the number of tabs that there is for that specific page.

    So lets say I have the following repeater fields on the page “About us”:

    Repeaters:
    Tab 1
    Tab 2
    Tab 3

    And this is the select field:

    Choose which one should be active from start:
    Tab 1
    Tab 2
    Tab 3

    How do you do that? 🙂

  • I would add a true/false field for “Initially Active” (or something like that) to the repeater. If only one can be initially active I would add some JS so that only one of these fields can be set to true. https://github.com/Hube2/acf-dynamic-ajax-select-example/tree/master/unique-repeater-checkbox

  • What a great idea!

    Ok, so I tried this by putting this code in functions.php

    	// enqueue our JS when ACF envques scripts
    	add_action('acf/input/admin_enqueue_scripts', 'unique_repeater_checkbox_enqueue_script');
    	
    	function unique_repeater_checkbox_enqueue_script() {
    		// enqueue acf extenstion
    		
    		// only enqueue the script on the post page where it needs to run
    		/* *** THIS IS IMPORTANT
    					 ACF uses the same scripts as well as the same field identification
    					 markup (the data-key attribute) if the ACF field group editor
    					 because of this, if you load and run your custom javascript on
    					 the field group editor page it can have unintended side effects
    					 on this page. It is important to alway make sure you're only
    					 loading scripts where you need them.
    		*/
    			
    		// your should change this to check for whatever
    		// admin page(s) you want the script to load on
    		global $post;
    		if (!$post ||
    				!isset($post->ID) || 
    				get_post_type($post->ID) != 'page') {
    			return;
    		}
    			
    		$handle = 'acf-unique-repeater-checkbox';
    		
    		// I'm using this method to set the src because
    		// I don't know where this file will be located
    		// you should alter this to use the correct fundtions
    		// to set the src value to point to the javascript file
    		$version = acf_get_setting('version');
    		if (version_compare($acf_version, '5.7.0', '<')) {
    			$src = get_template_directory_uri() . '/library/js/unique-repeater-checkbox.js';
    		} else {
    			$src = get_template_directory_uri() . '/library/js/unique-repeater-checkbox-acf57.js';
    		}
    		// make this script dependent on acf-input
    		$depends = array('acf-input');
    		
    		wp_enqueue_script($handle, $src, $depends);
    		
    	} // end function unique_repeater_checkbox_enqueue_script

    Where I changed the post type to page since that’s where I load the repeater. And I changed the source so that it will load the JS while editing the specific page.

    It seems to load the “unique-repeater-checkbox.js” NOT the “unique-repeater-checkbox-acf57.js”.

    The JS file looks like this where I edited the data-key to match the true/false field.

    
    	jQuery(document).ready(function($){
    		if (typeof acf == 'undefined') { return; }
    		
    		var unique_repeater_checkbox = acf.ajax.extend({
    			/*
    					why am I extenting the acf.ajax method/property
    					since I'm not using ajax in this example?
    					
    					It's easier. Since most of the time when I'm going to be
    					adding functionality to ACF I'm more than likely going to
    					be adding several actions and one of them is more than likely
    					going to include some kind of ajax. I'm more than likely going
    					to build it all into a single extension for the site and I would
    					put all of my events and functions in a that single extension and
    					call it something like {$client's name}_acf_extension
    			*/
    			
    			events: {
    				// for each field that you want to apply this to add a 'change' event line
    				// and copy the field key for the field and paste it in the "data-key" value
    				'change [data-key="field_5d945ca8ae892"] input': '_update_unique_checkbox',
    			},
    			
    			_update_unique_checkbox: function(e) {
    				var $checked = e.$el.prop('checked');
    				if (!$checked) {
    					// prevent the field from being unchecked and return
    					e.$el.prop('checked', true);
    					return;
    				}
    				// the field is checked, get the currently selected item
    				var $id = e.$el.prop('id');
    				// get the data-key
    				var $key = e.$el.closest('.acf-field').attr('data-key');
    				
    				// get the field from all of the rows in the repeater
    				// exclude hidden fields and the ACF clone row
    				var $list = $('[data-key="'+$key+'"] input').not('[data-key="'+$key+'"] input[type="hidden"]').not('.acf-clone [data-key="'+$key+'"] input');
    				if ($list.length == 1) {
    					// if there is only one row then bail
    					// nothing needs to be done
    					return;
    				}
    				// uncheck all of the other rows except the currently checked one
    				for (i=0; i<$list.length; i++) {
    					var $item_id = $list[i].getAttribute('id');
    					if ($id != $item_id) {
    						// if not the current item then set to false
    						$list[i].checked = false;
    					}
    				}
    			},
    			
    		});
    		
    	});

    But it still doesn’t work. When I have one checkbox checked and check another one it doesn’t uncheck the first one. Regardless of if I “Update” the page or not. Worth mentioning is that I also do not have the Styled UI on for that field. It doesn’t say anything in the console.

    What might be wrong?

    Wordpress version: 5.2.3
    ACF PRO version: 5.8.4

  • The check for acf version is only there for completeness. You can remove the check and just load the JS newer script file since you know you’re using >= 5.7

  • Ok, I did that and this is my code now. It didn’t solve the issue though. Any thoughts?

    	// enqueue our JS when ACF envques scripts
    	add_action('acf/input/admin_enqueue_scripts', 'unique_repeater_checkbox_enqueue_script');
    	
    	function unique_repeater_checkbox_enqueue_script() {
    		// enqueue acf extenstion
    		
    		// only enqueue the script on the post page where it needs to run
    		/* *** THIS IS IMPORTANT
    					 ACF uses the same scripts as well as the same field identification
    					 markup (the data-key attribute) if the ACF field group editor
    					 because of this, if you load and run your custom javascript on
    					 the field group editor page it can have unintended side effects
    					 on this page. It is important to alway make sure you're only
    					 loading scripts where you need them.
    		*/
    			
    		// your should change this to check for whatever
    		// admin page(s) you want the script to load on
    		global $post;
    		if (!$post ||
    				!isset($post->ID) || 
    				get_post_type($post->ID) != 'page') {
    			return;
    		}
    			
    		$handle = 'acf-unique-repeater-checkbox';
    		
    		// I'm using this method to set the src because
    		// I don't know where this file will be located
    		// you should alter this to use the correct fundtions
    		// to set the src value to point to the javascript file
    			$src = get_template_directory_uri() . '/library/js/unique-repeater-checkbox.js';
    		// make this script dependent on acf-input
    		$depends = array('acf-input');
    		
    		wp_enqueue_script($handle, $src, $depends);
    		
    	} // end function unique_repeater_checkbox_enqueue_script
  • Did you change the field key references in the JS file to match your field key?

  • Yes, as you can see in the JS source code I submitted earlier.

    jQuery(document).ready(function($){
    		if (typeof acf == 'undefined') { return; }
    		
    		var unique_repeater_checkbox = acf.ajax.extend({
    			/*
    					why am I extenting the acf.ajax method/property
    					since I'm not using ajax in this example?
    					
    					It's easier. Since most of the time when I'm going to be
    					adding functionality to ACF I'm more than likely going to
    					be adding several actions and one of them is more than likely
    					going to include some kind of ajax. I'm more than likely going
    					to build it all into a single extension for the site and I would
    					put all of my events and functions in a that single extension and
    					call it something like {$client's name}_acf_extension
    			*/
    			
    			events: {
    				// for each field that you want to apply this to add a 'change' event line
    				// and copy the field key for the field and paste it in the "data-key" value
    				'change [data-key="field_5d945ca8ae892"] input': '_update_unique_checkbox',
    			},
    			
    			_update_unique_checkbox: function(e) {
    				var $checked = e.$el.prop('checked');
    				if (!$checked) {
    					// prevent the field from being unchecked and return
    					e.$el.prop('checked', true);
    					return;
    				}
    				// the field is checked, get the currently selected item
    				var $id = e.$el.prop('id');
    				// get the data-key
    				var $key = e.$el.closest('.acf-field').attr('data-key');
    				
    				// get the field from all of the rows in the repeater
    				// exclude hidden fields and the ACF clone row
    				var $list = $('[data-key="'+$key+'"] input').not('[data-key="'+$key+'"] input[type="hidden"]').not('.acf-clone [data-key="'+$key+'"] input');
    				if ($list.length == 1) {
    					// if there is only one row then bail
    					// nothing needs to be done
    					return;
    				}
    				// uncheck all of the other rows except the currently checked one
    				for (i=0; i<$list.length; i++) {
    					var $item_id = $list[i].getAttribute('id');
    					if ($id != $item_id) {
    						// if not the current item then set to false
    						$list[i].checked = false;
    					}
    				}
    			},
    			
    		});
    		
    	});
  • The script you just posted should not be the script you are using. That one is for ACF < 5.7.

  • This is how the markup looks like.

  • Ha! It worked. Thank you John.

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

You must be logged in to reply to this topic.