Thanks John,
I approached this a different way
I changed the Choices from value : Label to just Choice Value
Part Source:
sh : SECOND HAND
oem : OEM
new : NEW
Part Source:
SH
OEM
NEW
Used Admin Columns Pro 100 products per page, 15 pages – and bulk edited changing the value of the part source to “SH” along with other choice values “OEM” , “NEW”.
Then in my PHP added the conditional on the output.
global $product;
$id = $product->get_id();
$partsource = get_field ('part_source', $id);
if( $partsource == 'SH') {
echo 'SECOND HAND';
} else {
echo esc_attr($partsource);
}
I am having the same issue.
WP: 6.1.1
WOO: 7.3.0
PHP: 7.4.33
ACF: 6.0.7
I have imported all produces via CSV using WP-All-IMPORT
The ACF value are populated and saved in the WooCommerce Product.
This is evident when navigating to EDIT PRODUCT
However the [value] [label] or [array] is not being out on the front end until the post has been [updated]
2000 products – I’m not updating manually.
ACF Button Group
Choices
value : Label
value : Label
value : Label
returning value : (•) Label
I have tried get_field && get_field_object (using array)
value won’t return until the post is updated
John – I can provide access to the site if needed
Hi midwestdev,
Thaks for providing your version of the code.
Any further, and you’d need to add more to the JS and to the PHP to make this cascade into grandchildren, etc.
Can you provide and example of PHP and JS where the cascade has been extended up to 4 levels.
I also noted that after updating the post the values in the select fields only show the parent value.
However when you convert the ACF fields from SELECT back to checkboxes the correct values have been saved.
So I think some additional JS is require on POST EDIT to re-populate the ACF taxonomy.
Did you solve this?
I have solved several issues using the following:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
1 – ACF Field Setup
I have setup fields as FILED TYPE > LAYOUT > GROUP
https://www.advancedcustomfields.com/resources/group/
This allows us to target the fields with a given ACF field group using the field group name.
if( have_rows('group_name')){
while(have_rows('group_name')){
the_row();
if( $subfields = get_row()) {
I am outputting the custom post type, ACF data, to a table using a foreach loop.
The code is then displayed on our post using a [shortcode]
<?php
class CUSTOM_SHORTCODES {
public static function register_shortcodes() {
add_shortcode( 'custom_specs', array( __CLASS__, 'boat_specs' ) );
}
public static function custom_specs($atts) {
$out = '';
$out .= '<div>';
$out .= '<table>';
$out .= '<tbody>';
$subfields = get_row();
$field = get_sub_field_object( $key );
if( have_rows('specifications')){
while(have_rows('specifications')){
the_row();
if( $subfields = get_row()) {
foreach ($subfields as $key => $value) {
if ( !empty($value) ) {
if(is_array($value)) {
$value = @implode(', ', $value);
}
$field = get_sub_field_object($key);
$out .= '<tr class="tb-row"><td class="tb-cell"><span class="acf-label">' . $field['label'] . '</span></td><td class="tb-cell"><span class="acf-value">' . $value . '</span></td></tr>';
}
}
}
}
}
$out .= '</tbody></table></div>';
return $out;
}
}
CUSTOM_SHORTCODES::register_shortcodes();
In this instance, the demo shortcode is [custom_specs]
In our foreach loop, we can check to see if a field has value. If it has no value i.e. null then the field does not show in our for each loop.
if ( !empty($value) ) {
OR
https://www.advancedcustomfields.com/resources/hiding-empty-fields/
If the returned value is an array, we can convert the array to a comma list.
if(is_array($value)) {
$value = @implode(', ', $value);
}
Using this method, we can segment our ACF data into different foreach loop shortcodes for our use case scenario.
Specifications = [custom_specs]
Standard Features = [custom_feat]
Options = [custom_opt]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
2 – Omit / Remove ACF field from the foreach loop.
The ‘price’ is recorded as an ACF field in our field group ‘specifications’.
However, the client does not want to show the ‘price’ field on the table on the front end.
How do we remove the ACF field ‘price’ from our ‘specifications’ foreach loop?
OPTION 1 – “SIMPLE”
Move the ACF field ‘price’ out of the current field group ‘specifications’ so it’s not returned in the shortcode loop [custom_specs].
If OPTION 1 does not fit your requirements, then try this alternative.
OPTION 2 – “ACF continue”
ACF Support has come back with the following. Interestingly, there is no mention of this in the current ACF documentation.
if( have_rows('specifications')){
while(have_rows('specifications')){
the_row();
if( $subfields = get_row()) {
foreach ($subfields as $key => $value) {
// Omit 'price' sub field - enter the field key
if ($key == 'field_123456789') { //skip this!
continue;
}
Using the ACF field key and continue;
we can now remove any ACF field inside our foreach loop.
Fantastic!
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
3 – Removing Conditional Logic Parent > Child ACF fields from our foreach loop.
In this scenario, we have the PARENT FIELD1 and the CHILD FIELD2
The fields can be any ACF field Type: Select, Checkbox, Radio Button, Button Group.
PARENT FIELD1 (*Required? = Yes)
( ) ABC
( ) MNO
( ) XYZ > Show CHILD FIELD2
CHILD FIELD2 (*Required? = Yes + Allow Null? = Yes )
( ) Choice 1
( ) Choice 2
( ) Choice 3
We have conditional logic CHILD FIELD2
Show this field if <PARENT FIELD1> Value is equal to <XYZ>
Great!
If PARENT FIELD1 (•) XYZ is selected, we expect CHILD FIELD2 Choices to show.
If PARENT FIELD1 ( ) XYZ is de-selected, we can expect FIELD2 to hide.
• • • • • • • • • • • • • • • • • • • • • •
Now, this is where it gets tricky.
As part of our strategy, we want to make it easy for the Client to update the data without making things worse.
The Client Selects <PARENT FIELD1>(•) XYZ
CHILD FIELD2 choices are shown.
All choices are null – they are empty.
The Client doesn’t make a selection from CHILD FIELD2 and updates the post.
We get a validation warning – CHILD FIELD2 is set to (*Required) so now we have to make a selection.
The Client selects CHILD FIELD2 (•) Choice 2
We validate, and the post is saved.
CHILD FIELD2 > Choice 2 is saved to the database.
We run our shortcode loop and CHILD FIELD2 is output into our table.
The Client decides, no, actually I didn’t want (•) XYZ, I really wanted ( ) ABC
The Client de-selects ( ) XYZ and selects (•) ABC
CHILD FIELD2 is hidden.
Even though <PARENT FIELD1>( )XYZ is not selected, our foreach loop is still outputting CHILD FIELD2 in the table.
Why ! – you ask?
In the database CHILD FIELD2 still has a saved value = Choice 2.
Our foreach loop condition is “only include fields that have value”.
So CHILD FIELD2 is still showing.
This stems from core ACF functionality – If the field is set to (*Required) ignore the null.
https://github.com/elliotcondon/acf/issues/591
How do we fix this?
• • • • • • • • • • • • • • • • • • • • • •
METHOD 1 – On all CHILD FIELD(s) disable (*Required)
(*Required? = No)
Each CHILD FIELD2 choice can be toggled ON or OFF. Allowing us to de-select our previous selected option. The post can be validated and saved without having a choice selected. The Database value is cleared on Post Update.
But wait – this now requires the Client to understand that the CHILD FIELD2 needs to be un-selected before unselecting the PARENT FIELD1.
LOL
Sometimes the simplest of workflow solutions are the hardest for clients to remember.
• • • • • • • • • • • • • • • • • • • • • •
METHOD 2 – JQuery
Use jQuery to null the CHILD FIELD when the PARENT FIELD is un-selected.
This improves our Method 1 workflow, as the Client doesn’t have to remember to unselect the CHILD FIELD2. Our jQuery Function will handle this.
For this to work, I changed my CHILD FIELD2 field Type to a ‘select’.
When the Field Type ‘select’ is set to (Allow Null? = Yes) a null choice is added to the top of the dropdown select “-Select-“.
https://www.advancedcustomfields.com/resources/select/
I used JQuery to select the first item on the CHILD FIELD2 ‘select’ list
when the Parent is de-selected.
In my WordPress Child theme functions.php
file I am loading a JS file when is_admin()
define( 'CHILD_THEM_URI', get_stylesheet_directory_uri() );
define( 'CHILD_THEM_DIR', get_stylesheet_directory() );
// register scripts for the wp_admin section
add_action( 'admin_head', 'register_admin_scripts' );
function register_admin_scripts() {
if ( is_admin() ) {
wp_enqueue_script( 'admin_js', CHILD_THEM_URI . '/includes/admin.js', array( 'jquery' ) );
}
}
In the JS File I have the following simple click function.
jQuery(document).ready (function ($) {
$('#parent_field_id').on('click',function () {
if ($(this).is(':checked')) {
//alert('You have Checked it');
} else {
//alert('You Un-Checked it');
// Set Conditional Select to null - First Item on the list
$("#child_field_id").prop("selectedIndex", 0);
}
});
});
• • • • • • • • • • • • • • • • • • • • • •
METHOD 3 – delete_field()
We could write a custom function if PARENT FIELD1 is de-selected then dynamically delete the conditional logic CHILD FIELD2 value from the database. Seems heavy to me!
delete_field()
delete_sub_field()
Someone with better PHP skills than me may wish to provide a solution.
I look forward to your responses.
• • • • • • • • • • • • • • • • • • • • • •
METHOD 4 – FUNCTION REQUEST
Have an additional toggle option on the ACF CHILD FIELD next to the (AllowNull? = Yes) to turn ON or OFF the required functionality.
If conditional logic PARENT Field is un-selected – return CHILD FIELD VALUES to the default Null State.
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
I think thats covers everything for now.
Hopefully this helps someone else in the future
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Privacy Policy. If you continue to use this site, you consent to our use of cookies.