{"id":1386,"date":"2020-04-04T20:48:00","date_gmt":"2020-04-04T13:48:00","guid":{"rendered":"https:\/\/lab.wptips.dev\/?p=1386"},"modified":"2020-10-16T18:32:08","modified_gmt":"2020-10-16T11:32:08","slug":"how-to-create-acf-nested-select-optgroup","status":"publish","type":"post","link":"https:\/\/pixelstudio.id\/blog\/how-to-create-acf-nested-select-optgroup\/","title":{"rendered":"How to Create ACF Nested Select \/ Optgroup"},"content":{"rendered":"\n<blockquote class=\"wp-block-quote\"><p><strong>Update 16 Oct 2020<\/strong>: Code snippet has been updated to support version 5.9.x<\/p><\/blockquote>\n\n\n\n<p>A nested select using <code>&lt;optgroup><\/code> is still a missing basic feature from ACF.<\/p>\n\n\n\n<p>In today&#8217;s tip, we are going to learn how to enable nested options just like shown below:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"383\" height=\"387\" src=\"https:\/\/pixelstudio.id\/blog\/wp-content\/uploads\/2020\/05\/acf-optgroup-result.jpg\" alt=\"\" class=\"wp-image-1389\"\/><figcaption>ACF Select field with nested options<\/figcaption><\/figure><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">The Choices Format<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/pixelstudio.id\/blog\/wp-content\/uploads\/2020\/05\/acf-optgroup-field.jpg\" alt=\"\" class=\"wp-image-1391\" srcset=\"https:\/\/pixelstudio.id\/blog\/wp-content\/uploads\/2020\/05\/acf-optgroup-field.jpg 750w, https:\/\/pixelstudio.id\/blog\/wp-content\/uploads\/2020\/05\/acf-optgroup-field-480x270.jpg 480w\" sizes=\"auto, (max-width: 750px) 100vw, 750px\" \/><figcaption>ACF Select configuration<\/figcaption><\/figure>\n\n\n\n<p>The Choices setting is just a plain textarea (shown above), so we need to determine a format to know which one is the group label.<\/p>\n\n\n\n<p>For this example, the line that begins with <code>#<\/code> will be turned into group label.<\/p>\n\n\n\n<p>Here&#8217;s the setting of our Choices:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">#America\nus : United States\nca : Canada\nmx : Mexico\n#Europe\nuk : United Kingdom\nde : German\nfr : France<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">The Hook<\/h2>\n\n\n\n<p>What we are trying to achieve is to create a nested Array using the group label as it&#8217;s parent. Then pass it to the <code>choices<\/code> argument.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\">\/\/ Don't forget to change the 'name'\nadd_filter('acf\/prepare_field\/name=country', 'acf_allow_optgroup');\n\nfunction acf_allow_optgroup( $field ) {\n  \/\/ Abort if it's native option\n  if( $field['ID'] === 0 ) { return $field; }\n\n  $raw_choices = $field['choices'];\n  $choices = [];\n\n  $current_group = '';\n  foreach( $raw_choices as $value => $label ) {\n\n    \/\/ if first letter is hashtag, turn it into group label\n    if( preg_match( '\/^#(.+)\/', $label, $matches ) ) {\n      $current_group = str_replace( '#', '', $label );\n      $choices[ $current_group ] = [];\n    }\n    \/\/ If group label already defined before this line\n    elseif( !empty( $current_group ) ) {\n      $choices[ $current_group ][ $value ] = $label;\n    }\n    else {\n      $choices[ $value ] = $label;\n    }\n  }\n\n  $field['choices'] = $choices;\n  return $field;\n}<\/code><\/pre>\n\n\n\n<p>That&#8217;s all! <strong>Don&#8217;t forget to change the filter name<\/strong> to fit your field.<\/p>\n\n\n\n<hr class=\"wp-block-separator is-style-dots\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>This is one of those little things that make it easier for my client to edit their own site.<\/p>\n\n\n\n<p>I hope the ACF developer will add a native way to do this. I actually notified him back in 2017 via <a rel=\"noreferrer noopener\" aria-label=\"this Github thread (opens in a new tab)\" href=\"https:\/\/github.com\/elliotcondon\/acf\/issues\/609\" target=\"_blank\">this Github thread<\/a> but I don&#8217;t think he will add it.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>As always, ask any question about ACF Nested Select in the comment below \ud83d\ude42<\/p><\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>A nested select using <optgroup> is still a missing basic feature from ACF. In today&#8217;s tip, we are going to learn how to enable it.<\/p>\n","protected":false},"author":1,"featured_media":1387,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[20,31],"class_list":["post-1386","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-acf","tag-acf","tag-php"],"blocksy_meta":"","_links":{"self":[{"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/posts\/1386","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/comments?post=1386"}],"version-history":[{"count":8,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/posts\/1386\/revisions"}],"predecessor-version":[{"id":1887,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/posts\/1386\/revisions\/1887"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/media\/1387"}],"wp:attachment":[{"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/media?parent=1386"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/categories?post=1386"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/tags?post=1386"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}