Support

Account

Home Forums Backend Issues (wp-admin) Dynamically Loading Values From Adjacent Fields

Solved

Dynamically Loading Values From Adjacent Fields

  • I’m creating a questionnaire that has questions that depend on answers from other (multiple choice) questions within the same list, so I’ve got a repeater field of “questions” with sub-fields “question”, “answers” (CSV), “unique ID” (generated automatically) and “dependency”.

    Now I’m trying to dynamically load the list of questions into the dependency field (which is a select) but using any ACF functions seems to break it (eg get_field, has_rows). Is this because the filter runs before they are declared? Is there any way to get this to work?

    Below is an example of some code I’ve been trying.

    function acf_load_field_choices( $field ) {
    
    	if(!isset($_GET['post'])) return array();
    
    	global $post;
    
    	echo (int) have_rows("questions", $post->ID);
    	// also tried $_GET['post'], hard-coded post ID and empty
    
    	print_r(get_field("questions", $post->ID))
    	// also tried $_GET['post'], hard-coded post ID and empty
    
    	return $field;
    }
    
    add_filter('acf/load_field/name=dependency', 'acf_load_field_choices');
  • Is the repeater field on the same post as the select field that you’re trying to load?

    I also don’t understand this if(!isset($_GET['post'])) return array(); The only time this function will be run is when the field dependency is being loaded on the post page, unless you’re using the same field name somewhere else.

  • Hi John,

    Yes, so once the user has saved a questionnaire they’re then able to edit the list of questions to add dependencies between questions.

    I added if(!isset($_GET['post'])) return array(); so that the code wouldn’t try running if the post didn’t have an ID (ie. when it’s a new post – since then there wouldn’t be any custom fields to find, since the post would have never been saved).

    Also, to elaborate on what happens, as soon the edit page gets to the repeater field containing the select the code breaks and no more PHP appears to be processed. There are no errors in the log, however.

  • To be honest, I don’t know why it’s not showing anything as it should be working. try this, possible there’s something in there that’s causing an issue, but I can’t see what it is.

    
    function acf_load_field_choices( $field ) {
      global $post;
      echo '<pre>'; print_r($field); echo '</pre>';
      echo '<pre>'; print_r(get_field('questions', $post->ID); echo '</pre>';
      return $field;
    }
    add_filter('acf/load_field/name=dependency', 'acf_load_field_choices');
    
  • echo '<pre>'; print_r($field); echo '</pre>'; seems to run a bunch of times, out putting the same array, maybe 50+ times, but nothing from echo '<pre>'; print_r(get_field('questions', $post->ID); echo '</pre>';.

    It then doesn’t render anything after (so none of the other sub-fields). This is the array it’s spitting out for $field:

    Array
    (
        [ID] => 15
        [key] => field_56f0735c7223d
        [label] => Dependency
        [name] => dependency
        [type] => select
        [value] => 
        [required] => 0
        [id] => 
        [class] => 
        [conditional_logic] => 0
        [parent] => 6
    )

    It seems like it’s the get_field() function that stops anything further from running.

  • You’re comment about it outputting 50 times indicates a problem. It seems that this function is triggering some type of an infinite loop, which this filter should not be doing on it’s on. what other filters do you have in place on the two fields involved? dependency and questions?

  • There aren’t any other filters set up, just this one. I’ve only just installed WP and ACF Pro so there’s hardly any code in the functions.php file at all.

    Could it be because it’s within a repeater field?

  • I created a separate field “dependency2” that wasn’t within the repeater and it seems to work fine. Something in the repeater side of things must be causing the issue. I guess it doesn’t like me calling to the parent field from a sub-field filter (since “dependency” is a sub-field of “questions”).

    Maybe I’ll just have to store the dependencies as a separate set of fields…

    Thanks for all your help on this by the way! πŸ™‚

  • export your filed group, put it in a .zip file and attach it.

    There’s something odd going on because the filter above should only run once. The fact that it outputs the field more than once means that the field is being loaded multiple tiles which should be happening even with a repeater field.

  • This reply has been marked as private.
  • Your last comment helped clear things up a bit. So basically you each row of the repeater has a dependency field, which I did not understand before. I’ll look at the field group and see if there’s a way to do what you want.

  • Yeah, sorry, I wasn’t that clear – “dependency” is a child of the “questions” repeater.

  • Here is an example of how I’d load values of a field in a row base on other sub fields of a repeater. It’s a little more complicated than a simple function.

    
    <?php 
      
      // use a class so that we can store values rather than 
      // regenerate them for every row of the repeater
      class load_dependency_field {
        
        var $choices = array(); // hold the choices
        
        function __construct() {
          // use the field key when loading a subfield
          add_filter('acf/load_field/key=field_56f0735c7223d', array($this, 'load_choices'));
        } // and function
        
        function load_choices($field) {
          global $post;
          if (get_post_type($post->ID) != 'questionnaire') {
            // only run this when editing the post
            return $field;
          }
          if (!count($this->choices)) {
            // haven't done this before
            $this->get_choices($post->ID);
          }
          $field['choices'] = $this->choices;
          return $field;
        } // end function
        
        function get_choices($post_id) {
          // example of using get_post_meta() instead of get_field for repeater
          // this removes the possiblity of creating infinite loop in ACF
          $repeater = 'questions';
          $subfield = 'question';
          $count = intval(get_post_meta($post_id, $repeater, true));
          for ($i=0; $i<$count; $i++) {
            $question = get_post_meta($post_id, $repeater.'_'.$i.'_'.$subfield);
            $this->choices[$question] = $question;
          }
        } // end function
        
      } // end class
      
      // instantiate the class
      new load_dependency_field();
      
    ?>
    
  • Thanks for that! Looks very promising.

    I’m getting an Illegal offset type error on the line $this->choices[$question] = $question;

  • sorry, the line before that should be

    
    question = get_post_meta($post_id, $repeater.'_'.$i.'_'.$subfield, true);
    

    I missed the , true part which is very important

  • Amazing, thanks. I added in a little extra code as I’m using a unique ID for the questions (in case they change the question text):

    $question = get_post_meta($post_id, $repeater.'_'.$i.'_'.$subfield, true);
    $uid = get_post_meta($post_id, $repeater.'_'.$i.'_'.'uid', true);
    $this->choices[$uid] = $question;

    Thanks again! Really appreciate you taking the time to look at this.

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

You must be logged in to reply to this topic.