Support

Account

Home Forums Search Search Results for 'custom fields not saving'

Search Results for 'custom fields not saving'

reply

  • Hi,
    First of all thanks a ton to Jelmertje & John for all the help and guidance. Anyways. I have finally done it and here I am sharing the solution in the hope it might help others someday in future.

    So, if you are trying to add a custom class to the admin body based on your ACF field data you basically have 2 ways to do that.
    1. Implement it via PHP admin_body_class and in doing so it will work perfectly but as the user makes the changes in the ACF fields the classes won’t be immediately be added to the admin body class and instead the user needs to refresh the page after changing the ACF field data and saving the post/page.
    2. Implement it via JavaScript so that the classes get added immediately as the user make changes to the ACF fields on the admin end.

    Now here I am going to show both the option so that you can decide which one to use.

    Note:
    – Here I am running 2 checks. One is based on Radio Field data and the other is based on the True/False ACF checkbox field data.
    – The PHP script written below is based on PHP 8 syntax
    – The JS script is based on ES6

    THE PHP WAY
    You can do something like these to add custom classes to your admin body based on ACF field data:

    add_filter( 'admin_body_class', function( string $classes ) : string {
      global $post;
    
      // get_current_screen() returns object with current admin screen
      // @link https://codex.wordpress.org/Function_Reference/get_current_screen
      $current_screen = get_current_screen();
    
      if( $current_screen?->base === 'post' ) {
        // Get the RADIO button type data
        $some_acf_field = get_field( 'some_acf_field', $post?->ID ) ?? false;
        
        // Run the received data through the switch statement
        switch( $some_acf_field ) {
          case 'something' :
            $classes .= ' page-has-something';
          break;
    
          case 'foo' :
            $classes .= ' page-has-foo';
          break;
    
          default :
            $classes .= ' page-has-bar';
          break;
        }
    
        // Check based on ACF True/False checkbox field
        if( get_field( 'true_false_ace_field', $post?->ID ) ?? false ) {
    			$classes .= ' has-some-class';
    		}
      }
    
      return $classes;
    } );

    THE JAVASCRIPT WAY
    Now let’s see how to achieve the same using JavaScript.

    Note:
    – Let’s imaging the file name is editor-logic.js and the file has been added to the admin end with the enqueue_block_editor_assets action.

    Now let’s see what’s inside the file.

    /** 
     * Add/Remove Class from the Admin Body tag based on ACF field Data
     * 
     * ACF Fields Being Monitored:
     * 1. Some Radio Field (Name: some_radio_field) [Key: field_61d716c8459d9]
     * 2. Some True False Field (Name some_true_false_field) [Key: field_61d69ffed41ad]
     */
    
    const add_admin_body_class = ( classType = 'something', value  ) => {
    	const adminBodyClassList = document.body.classList
    
    	if( classType === 'something' ) {
    
    		switch( value ) {
    			case 'foo' :
    				if( adminBodyClassList.contains('page-has-bar') ) {
    					adminBodyClassList.remove('page-has-bar')
    				}
    
    				if( adminBodyClassList.contains('page-has-zar') ) {
    					adminBodyClassList.remove('page-has-zar')
    				}
    
    				adminBodyClassList.add('page-has-foo')
    			break;
    
    			case 'bar' :
    				if( adminBodyClassList.contains('page-has-foo') ) {
    					adminBodyClassList.remove('page-has-foo')
    				}
    
    				if( adminBodyClassList.contains('page-has-zar') ) {
    					adminBodyClassList.remove('page-has-zar')
    				}
    
    				adminBodyClassList.add('page-has-foo')
    			break;
    		}
    	}
    
    	// Add Default Page Title Center Alignment Based Classes
    	if( classType === 'another_thing' ) {
    
    		if( value ) {
    			adminBodyClassList.add('page-has-another-thing')
    		} else {
    			adminBodyClassList.remove('page-has-another-thing')
    		}
    	}
    }
    
    ( () => {
    	// Get the Page Container Type
    	const something = acf.getField('field_61d716c8459d9').val() ?? false
    	const anotherThing = acf.getField('field_61d69ffed41ad').val() ?? false
    
    	// Add the admin body classes based on the initial ACF field values
    	add_admin_body_class( 'something', something )
    	add_admin_body_class( 'another_thing', anotherThing )
    
    	// Listen for changes to the something ACF field values
    	const somethingACFField = document.querySelectorAll( '[data-key="field_61d716c3359d9"] input[type="radio"]' )
    	if( somethingACFField.length > 0 ) {
    		somethingACFField.forEach( ( field ) => {
    			field.addEventListener('change', ( e ) => {
    				add_admin_body_class( 'something', e.target.value )
    			} )
    		} )
    	}
    
    	// Listen for changes to the anotherThing ACF field values
    	const anotherThingACFField = document.querySelectorAll( '[data-key="field_61d69ffed41ad"] input[type="checkbox"]' )
    	if( anotherThingACFField.length > 0 ) {
    		anotherThingACFField.forEach( ( field ) => {
    			field.addEventListener('change', ( e ) => {
    				add_admin_body_class( 'another_thing', e.target.checked )
    			} )
    		} )
    	}
    } )();

    Hope this helps others.

  • Hi! Thank you for the quick response 🙂


    @jarvis
    I didn’t know about this! It’s interesting. I tried it and it indeed makes the field group disappear from those available for sync. Problem is that if I save the field group again (which I do all the time), the private value will disappear and they’ll start automatically syncing again. I think it would work if there was a way to check a “private” checkbox directly from the field group edit page, but I’m not sure how to do it.


    @hube2
    What I have is a multisite with a main theme, and every subsite has a child theme. Each subsite has an options page with three subpages (each of them containing one field group). I want to sync only one of those subpages, the other two need to be modified frequently to fit their site’s needs.

    In the main theme’s functions.php, I put two things: a filter to change the saving location of the JSON, and another one to change the loading location, like this:

    
    add_filter('acf/settings/save_json', 'my_acf_json_save_point');
    function my_acf_json_save_point($path) {
        // update path
        $path = get_template_directory() . '/custom-fields';
        
        // return
        return $path;
    }
    
    // changes loading location for custom fields
    add_filter('acf/settings/load_json', 'my_acf_json_load_point');
    function my_acf_json_load_point( $paths ) {
        // remove original path (optional)
        unset($paths[0]);
        
        // append path
        $paths[] = get_template_directory() . '/custom-fields';
        
        // return
        return $paths;
    }

    Hope that’s clear! Again, thank you for your help

  • Hi John,

    Thank you for your quick reply.
    You mention Gutenberg in your 4th reply of the thread on January 29, 2018.
    But it doesn’t matter, I don’t use Gutenberg either, I just mentioned this in case there had been some changes to WordPress since then that makes my problem now irrelevant. Obviously not the case.

    With that number of fields I would defiantly look at a different way to build it.
    I fear this is what I’ll end up doing. Using a repeater is very justified considering what I’m building, but I’ll probably have to separate some functions in different posts types. Not ideal at all, but better than the alternative.

    Before resorting to that solution, I’d like to ask if the solution I thought of could potentially work :

    – Create an additional field in the row (lets call it rowmodified)

    – When there is any change in any field of the row, have a value (for example “1”) added dynamically in the field rowmodified.

    – Add a function that does the following when the post is updated:
    * Start by checking/saving the value of rowmodified in the first row of the repeater.
    * if rowmodified has a value of 1, insert/update the other fields of the row. THEN delete the value of rowmodified.
    * if rowmodified has no value, don’t check/update the other fields of the row (i suppose this is the tricky / impossible part)
    * On to the next row
    * Update the remaining fields out of the repeater.

    As I said I’m not really a developer so i have no idea if it is technically possible, I suppose not, but who knows.

  • Is it possible? Yes. Coding will be required.

    See this topic https://support.advancedcustomfields.com/forums/topic/category-taxonomy-in-repeater-not-saving/

    This is the most recent, but this is a common question.

  • There are plugins that allow saving data to a different DB table, but there is nothing available that will work with repeaters.

    How to use a repeater https://www.advancedcustomfields.com/resources/repeater/

    Importing data requires a plugin that will work with ACF fields. One example is WP All Import Pro.

  • No, there is no limit to the number of field groups or fields. If you are having an issue with saving on pages with a lot of fields it may be because of php max_input_vars

  • The first thing I would do is to not show the field on the front end. For this use an acf/prepare_field filter

    
    your_filter_name($field) {
      if (!is_admin()) {
        return false;
      }
      return $field;
    }
    

    As far as saving the cookie value to the field, there are a couple of way you can do this. I would try using an acf/save_post action with a priority > 10

    I do not have all the details for this function, just an outline.

    
    function your_save_function_name($post_id) {
      // I am not exactly sure what goes in post type check
      // this should be the WC order post type I think
      if (get_post_type($post_id) != 'the right post type') {
        return;
      }
      // check the value of the cookie
      if (!empty($_COOKIE['your-cookie-name')) {
        $value = code_here_to_get_value_to_set(); // depends on how your cookie value is stored
        // use the field key to update the field --- NOT the field name
        update_field('field_XXXXXXXX', $value. $post_id);
      }
    }
    
  • I was looking at this and was coming back to tell you that I didn’t have a lot of luck, but it looks like someone helped you in another thread. The .add() method for repeaters is not documented and I did not find it when looking at the ACF code. I myself will be saving a link to that thread so I can find it in the future.

  • Hi, I couldn’t find an answer to this so I’ll post mine here.
    My repeater is inside of a group field and I’m working outside the loop.
    The post I am saving values to is also one created by wp_insert_post so the custom fields are not actually saved in the database.

    You can get field keys from the edit field group page, click on screen options at the top right.

    $group_key = 'field_5dc936b464376';
    $repeater_key = 'field_5dc937a064379';
    $sub_field_key = 'field_5dc938076437a';
    $sub_field_key2 = 'field_5dc9382b6437b';
    
    update_field( $group_key, [
        $repeater_key => [
            $sub_field_key => 'a',
            $sub_field_key2 => 'b'
        ]
    ], $post_id);
  • Gravity forms is likely saving the checkbox field in the same way that WP would store multiple values for a custom field… that is, multiple entries in the meta table with the same meta_key. ACF stores a checkbox field as a serialized array. If you look in the DB you will likely find multiple values. When editing the post in the admin ACF only gets one value because that is all that it is expecting so it only gets the first one that was saved.

    I do not know anything about GF, but you will need to create some type of filter for GF to make it save correctly for use with ACF. You may need to use different fields for GF than the ACF fields and then create a filter for GF that manually populates the fields in the way that ACF expects the to be populated.

  • https://www.advancedcustomfields.com/resources/acf-fields-relationship-query/

    This could very likely time out the field and stop it from showing results.

    The only way that I can thing to do this (well, the only way without querying the db directly) is to build a filter as suggested by @csaborio and in the filter get all other posts of the same time and look at what’s already been selected.

    
    add_filter('acf/fields/relationship/query/name=related_tracks', 'remove_already_selected', 10, 3);
    function remove_already_selected($args, $field, $post_id) {
      $query = new WP_Query(array(
        'post_type' => 'album', // my assumption
        'post_status' => 'publish',
        'posts_per_page' => -1
      ));
      $selected = array();
      if (count($query->posts)) {
        foreach ($query->posts as $post) {
          $tracks = get_field('related_tracks', $post->ID, false);
          if (!empty($tracks)) {
            foreach ($tracks as $track) {
              $track = intval($track);
              if ($track && !in_array($track, $selected) {
                $selected[] = $track;
              }
            } // end foreach track
          } // end if tracks
        } // end foreach post
      } // end if posts
      if (!empty($selected)) {
        $args['post__not_in'] = $selected ;
      }
      return $args;
    } // end function
    

    As I said, depending on the number of “Album” posts that exist this will eventually time out the AJAX request for the relationship field and would not be very scale-able.

    You could potentially query the post meta table directly to get the acf field value for published posts.

    Another possibility would be to create and acf/save_post. In this filter, when saving an “Album” post you could set an option (get_option()/update_option()) and store a list of selected tracks.

    Yet another option would be to make the relationship bidirectional with a relationship on the Album side and a post object field on the track site. Then you could do something like this.

    
    add_filter('acf/fields/relationship/query/name=related_tracks', 'remove_already_selected', 10, 3);
    function remove_already_selected($args, $field, $post_id) {
      $args['meta_query'] = array(
        'relation' => 'OR'
        array(
          'key' => 'bidirectional_post_object_field_name',
          'value' => ''
        ),
        array(
          'key' => 'bidirectional_post_object_field_name',
          'compare' => 'NOT EXISTS'
        )
      );
      return $args;
    } // end function
    
  • Reading in 10k posts and then looping over them will likely cause other issues with performance due to the data returned in the query and memory.

    The biggest issue to speed is that regex on the date and the number of fields your using to filter.

    If I needed to do something similar to this and knew it before I started I would have a separate field (not in ACF, just your standard WP custom meta field). I would create and acf/save_post filter. In this filter I would get the date field, extract the year and save just the year into this other field. The I could do a simple ‘==’ compare on this field. This would greatly improve the performance of the query.

    But with 10k posts to look at it might still be a little slow. If it was I would likely use WP transients to store the results of the query for a time. This would mean the query would only need to be run once every few days.

    You could also have a taxonomy for the year, as in one of the points you listed, with the right settings you can actually hide this taxonomy. Instead of saving the year in another fields as in my first suggestion the acf/save_post filter would set the correct term in the year taxonomy.

    Post meta can be used for filtering, however, the filtering needs to be limited and the use of things like “LIKE” and “REGEXP” are going to cause performance issues.

    I also have one site, this site has “Products” and there are (no lie) 18 different filters used on this site. Trying to filter by 18 custom fields would simply time out the load of the page. In this case, when a new “Product” is saved a CRON is triggered. This CRON runs through all of the possible values for every filter and stores the results. On the front end of the site I use this information to query the posts.

    Use a WP option, lets call this option “birth_years”. This option would be an array with this architecture.

    
    $birth_years = array (
      // each element of this array is "YEAR" => array()
      "2020" => array (
        // each element of this array is a post ID of a person in this year
        1, 2, 3, 4, 5
      )
    );
    

    Create an acf/save_post filter with a priority of 1 so that it runs before ACF saves the value of the date field. See the doc for this filter. In this filter I would compare the old value with the new value. If it is the same I would do nothing. If it is different I would get the option, remove this person’s post ID from the old year and add it to the new year in my array.

    Then when doing the query for people in the same year I would get the option add this to my query

    
    'post__in' => $birth_year['2020']
    

    completely eliminating the meta query.

    Hope some of this information helps you

  • You cannot query a post type based on data stored for second post type.

    You have a couple of choices.

    1) You do a query on the second post type to get posts filtered by the custom field. You then use the returned post IDs to query and filter the first post type.

    2) When saving post type 1 you copy the data in the meta fields from the related post type 2 to meta field for post type 1. You then can query post type 1 directly using this data.

  • acf/load_field is not the correct thing to use here. This does the work in PHP. It could be done but that would mean making the selection and saving the post to have the other field updated.

    You’d have to use JavaScript, detect a change in the one field and then update the other field using ACF’s JS API https://www.advancedcustomfields.com/resources/javascript-api/

  • I must say +1 to finding a solution to this.

    I rely heavily on flexible content ‘blocks’, in which each page can be customized heavily. Each block has a clone of ‘advanced settings’, which is then loaded for each flexible content block. It very quickly adds to loading and saving times.

    I’d love to make more complex flexible content blocks for my projects, but I feel myself limiting options as to make it more lean. Not for the front-end, I take care of that obviously, but simply for backend loading.

    Any kind of lazyload (setting), or only saving fields that have been edited would be a great addition to ACF, and open up a new range of possibilities for many of us.

  • Same issue here, but with a ‘time-picker’ field.

    I tried changing the field to ‘text’ and I had the same issue – it would not store data. All other fields work OK.

    Additional info:
    I’m on Custom Fields version 5.8.9
    The field that is not saving was the first field I created.
    I can write data direct into the database and see it in my post. But if I edit the data and update the post, the data it disappears.

  • I’m having the same problem. Custom post type not showing up in select list. Tried including taxonomy too per this post https://support.advancedcustomfields.com/forums/topic/post-object-field-no-matches-found/ but that didn’t help. Nothing in debug log. Running Twenty-theme (with only ACF Pro and CPT UI active plugins) as am already trying to debug why Post Object field was showing multiple select fields and then not saving any selection in custom theme. Any suggestions?

  • I have create location rule type, rule values, rule match php code is working when i save the post custom field metabox show that means my custom rule location is working. Conflict is in JS Part for Variation rule only.

    While Editing the post without saving the Metabox show

    But when i choose for variations rule I have to save or update the post. and disable the js by commenting the enqueue input.js

    I want it to be async, just i choose product virtual then the metabox should Show while editing the post

    Conflict is in JS.

    // "Location Rules"
    
    add_filter('acf/location/rule_types', 'wc_product_acf_location_rule_types', 50, 1); 
    add_filter('acf/location/rule_values/woocommerce_product_type', 'wc_product_acf_location_rule_types_woocommerce_product_type', 50, 1);
    add_filter('acf/location/rule_values/woocommerce_variations', 'wc_product_acf_location_rule_types_woocommerce_variations', 50, 1);
    /*--------------------------------------------*/
    
    // Rule Validation
    
    add_filter('acf/location/rule_match/woocommerce_product_type', 'rule_match_woocommerce_product_type', 50, 3); // Rule match tester for when the post edit page is loaded
    add_filter('acf/location/rule_match/woocommerce_variations', 'rule_match_woocommerce_bools', 50, 3);
    
    /*-----------------------------------------------*/
    
    add_filter('acf/location/screen', 'wc_acf_location_parse_types', 1, 1);
    
    // Position Rules
    add_action('acf/create_field', 'wc_product_acf_location_rule_types_create_field', 4, 1);
    
    function wc_acf_location_parse_types( $value ) {
        if(is_array($value) && !empty($value) && isset($value['post_id']) && $value['post_id'] != 0) {
            if(!array_key_exists('woocommerce_product_type', $value) && array_key_exists('post_id', $value) && array_key_exists('post_type', $value) && $value['post_type'] == "product") {
                // Get Product
                $product = wc_get_product($value['post_id']);
    
                // Woocommerce Product Variables
                $value['woocommerce_product_type'] = $product->get_type();
                $value['woocommerce_is_in_stock'] = $product->get_stock_status();
                $value['woocommerce_is_downloadable'] = $product->is_downloadable(); 
                $value['woocommerce_is_virtual'] = $product->is_virtual();
                $value['woocommerce_is_sold_individually'] = $product->is_sold_individually();
            }
        }
    
    function wc_product_acf_location_rule_types($choices) {    
        $choices[__("Woocommerce")] = array(
            'woocommerce_product_type' => __("Product Type", 'acf'),
            'woocommerce_variations' => __("Product Variations", 'acf'),
        );
        return $choices;
    }
    
    function wc_product_acf_location_rule_types_woocommerce_product_type($choices) {
        $choices = wc_get_product_types();
        return $choices;
    }
    
    function wc_product_acf_location_rule_types_woocommerce_variations($choices) {
        $choices = array(
            'is_downloadable'       => 'Downloadable',
            'is_virtual'            => 'Virtual',
        );
    
        return $choices;
    }
    
    function rule_match_woocommerce_product_type($match, $rule, $options) {
        if(isset($options['post_type']))
            $post_type = $options['post_type'];
        else
        {
            if(isset($options['post_id'])) {
                $post_type = get_post_type($options['post_id']);
            }
            return false;
        }
        // Ensure is a product
        if( $post_type != 'product') {
            return false;
        }
        // Ensure Product Type has been set
        if(!array_key_exists('woocommerce_product_type', $options)) {
            return false;
        }
        if($rule['operator'] == "==") {
            $match = ( $options['woocommerce_product_type'] === $rule['value'] );
        }
        elseif($rule['operator'] == "!=") {
            $match = ( $options['woocommerce_product_type'] !== $rule['value'] );
        }
        return $match;
    }
    
    function rule_match_woocommerce_bools($match, $rule, $options) {
        $post_type = $options['post_type'];
        if(!$post_type) {
            if(!$options['post_id']) {
                return false;
            }
            $post_type = get_post_type($options['post_id']);
        }
        // Ensure is a product
        if( $post_type != 'product') {
            return false;
        }
        if(!array_key_exists('woocommerce_is_virtual', $options) && !array_key_exists('value', $rule)) {
            return false;
        }
        $key = 'woocommerce_' . $rule['value'];
        if($rule['operator'] == "==") {
            $match = ( $options[$key] === true);
        }
        elseif($rule['operator'] == "!=") {
            $match = ( $options[$key] !== true );
        } 
        return $match;
    }
    
    function wc_product_acf_location_rule_types_create_field($fields) {
        $fields['choices']['woocommerce_products_general_tab'] = __('Woocommerce Products General Tab', 'acf');
        // if($fields['name'] == 'options[position]') {
        //  _d($fields);
        // }
    
        return $fields;
    }

    The only part which is not working is the JS part but for product type rule it is working suppose my rule is show on grouped product, if i change my product type then the custon field show while editing the post due js part but not working for other rule

    add_action('acf/input/admin_enqueue_scripts', 'acf_wc_input_admin_enqueue_scripts', 10); // Enque JS
    
    function acf_wc_input_admin_enqueue_scripts() {
    
        $settings = array(
            'path' => plugins_url(basename(__DIR__)),
            'dir' => apply_filters('acf/helpers/get_dir', __DIR__),
            'version' => '1.0.3'
        );
        // register acf scripts
        wp_register_script( 'acf-wc-input-product-type-locations', $settings['path'] . '/js/input.js', array('acf-input'), $settings['version'] );
        // scripts
        wp_enqueue_script('acf-wc-input-product-type-locations');
    }

    Here my js part

    
        $(document).ready(function(){
            if (typeof acf == 'undefined') { return; }
        });
    
        $(document).on('change', '#product-type', function(){
            acf.ajax.update('woocommerce_product_type', $(this).val()).fetch();
        });
    
        $(document).on('change', '#_virtual, #_downloadable, function() {
            acf.ajax.update( 'woocommerce_is' + $(this).attr('name'), ($(this).is(':checked'))).fetch();
            $(document).trigger('acf/update_field_groups');
        });
    

    Js part on change for product type is working but for not working for _virtial, _downloadable

    Please anwser the question even some people tried find other solution or upgrade to this code.

  • I am not the developer, just a long time user that has gotten to know the workings of ACF. If you really want to get the developer to weight in then you’ll need to submit a request here https://www.advancedcustomfields.com/contact/

    1) The reason that there is a field key for each field is so that ACF knows how to treat that field value. The issue is that any field name can be repeated. Let’s say that you have a field named “some_field”, this is a simple text field and the data of this field is save for a “Post”. Now let’s say that you create another field with an identical name and you save this field value to “Pages” but is field is a relationship field. The only way that ACF knows how to treat these two fields differently and return the correct value is that each of the fields has a different field key reference.

    Many people are under the mistaken impression that ACF “knows” or “remembers” what fields are used for what post type, taxonomy, user, options page, etc. It does not. When ACF gets or saves a value two pieces of information are required, the post ID (or some other object ID) and the field key. When you are saving a value ACF has this information when the form is submitted. When retrieving a value when you use the field name ACF must look up the correct field key.

    This is the reason that a field key reference is needed. The only way that this would not be the case would be if ACF required a unique field name for every field created.

    2) Fields are stored separately, values in those fields are not always stored as separate values. A selection in a gallery field is not a sub field of the gallery.

    So it might be possible to store the values of a gallery field in multiple entries. This would require deleting all values before updating. Then ACF would need to loop over the values and insert each. This action of deleting and then adding multiple entries could cause a performance issue in the admin. Imagine that you have 20 fields like this and each of these fields has 20 entries. This would do a total of more than 400 queries to insert the values. This is because of the way that WP meta values work.

    Another issue with doing this at this point would be backwards compatibility. Changing the way ACF stores the values now would be difficult.

    There are ways to overcome the issues with doing “LIKE” queries on meta values. You can see how I overcome this by reading the post I created here…. well, it seems that site is now gone….

    Anyway, the idea behind what I wrote is to convert fields that you want to query by to standard ACF field. For example, lets say that I have a checkbox field and the checkbox field has values that I want to query by.

    
    add_filter('acf/update_value/name=my_checkbox_field", "convert_my_ck_to_wp", 20, 3);
    function convert_my_ck_to_wp($values, $post_id, $field) {
      $search_field_name = 'my_checkbox_field_wp';
      delete_post_meta($post_id, $search_field_name);
      if (is_array($values)) {
        foreach ($values as $value) {
          add_post_meta($post_id, $search_field_name, $value, false);
        }
      }
      return $values;
    }
    

    Now a query can be done using the alternate field name. This does create extra data in the database, but this is not nearly as detrimental to queries as doing a “LIKE” query on the ACF value. And since we only do this on fields where we need the values stored this way there is less likelihood of the performance issues we might have if every ACF field was stored in this manner.

  • I’m not seeing any issues saving checkbox fields. I would look for something common to all 3 sites. Another thing to look for is duplicated field names which could cause you issues, duplicate in ACF or field names shared with other custom fields used by anything else on the sites.

  • Yes, this is something that is possible, unfortunately I cannot point you to any examples of doing so except to point out that this is done for the built in radio field and checkbox field. Both of these fields have a toggle for allowing new custom values to be added and when it is toggled on there is another field setting toggle to set saving the custom values as new field choices. I would investigate the JavaScript associated with these field settings to see how it is done for these fields.

  • It’s not necessary to write a custom update_value function, saving multiple values in one field can be done simply by choosing the right input field names.

    Have a look at this thread, where it is explained in detail: https://support.advancedcustomfields.com/forums/topic/need-help-with-creating-new-field-type-with-acf/

  • So, the problem is that when the field is loading after saving the post ID values do not exist on the current site.

    When ACF renders the field it does this

    
    // get posts
    $posts = acf_get_posts(array(
             'post__in' => $field['value'],
             'post_type' => $field['post_type']
    ));
    

    the function acf_get_posts() in api-helpers.php is where you need to look. I’m not sure if you can do anything there. I think that you need to find a way to switch sites before acf renders the field and then switch back after acf renders the field. I would try this hook https://www.advancedcustomfields.com/resources/acf-render_field/, twice, low priority to switch to the main site and high priority to restore the current blog.

    again, I don’t know if it will work.

  • When you are talking about saving the child post, are you using two forms ? Do you have 1 field group containing all your fields and at the saving step you are using the acf/save_post hooks to separate the data into the good post type?

    I have 2 different field groups, I have a custom location rule that shows one field group on top level posts and one field group on child posts. I’m not using 2 post types, I am using one hierarchical post type.

    In the field group for the parent post I have a repeater field that has sub fields, for example “start_date” and “end_date”. There are other fields on the parent post that are also important, for example I have a field that is not in the repeater to allow setting the event as “featured”, things like this also need to be applied to the child posts. The repeater here is the data I need for creation of any child posts.

    Each field I need to copy from the parent or the above repeater has a corresponding field on the child post group. For example if I need “start_date” from the repeater the child post group has a field named “start_date” (not in a repeater)

    When the top level post is saved I have an action on acf/save_post. This action does a comparison between the content in the repeaters (I loop over the repeater) against all existing child posts to see what I need to delete and what I need to add. Then I delete any child posts that are no longer valid and add anything that is new using wp_insert_post() and then I use update_field() using the ID of the newly created post and the value I need from the parent or the repeater on the parent.

    But like I said, you also need to deal with what happens when you delete, trash, untrash, or change the status of the parent post. All of this is done because I need to query the information for individual posts and the data in the repeater is really useless in that form.

    With this setup you could have a list of each client and everything about them with a link to edit each client.

  • This is not a bug, but the intended operation.

    When a field is conditional and it does not appear, that fields value is not changed. It is not changed because the field in not submitted.

    ACF does not look at field 1 to see if the conditions are met when saving field 2. The condition is on field 2. ACF has no idea when a field is save what other fields might be conditional base on the value of the field being saved.

    In your template code you need to do the work something like this.

    
    if (get_field('field#1') == 'A) {
      echo get_field('field#2');
    }
    

    There have been many discussions on these forums about this. Some like this, some do not. With the way it operates, if a user changes the value and saves the post, if they should change their mind later then the value entered into field 2 will not need to be re-entered.

    The only way around this is to create an acf/save_post filter https://www.advancedcustomfields.com/resources/acf-save_post/

    
    add_filter('acf/save_post', 'my_save_post_function_name');
    function my_save_post_function_name($post_id) {
      if (get_field('field#1', $post_id) != 'A') {
        delete_field('field#2', $post_id);
      }
    }
    
Viewing 25 results - 76 through 100 (of 244 total)