ACF checkbox if statement

What is the proper way to display content if an ACF checkbox is checked? This seems like it should be easy but I am not having luck.

My ACF field is online_ordering_options
Options are:

pick_up : Pick Up
delivery : Delivery
pick_up_delivery : Pick Up & Delivery

Set to return the value.

I’ve tried…

<Loop acf_checkbox=online_ordering_options>
    <If acf_checkbox=online_ordering_options is value="delivery">DELIVERY</If>
</Loop>

then…

<If acf_checkbox=online_ordering_options is value="delivery">DELIVERY</If>

I think your confusion might stem from the fact that you’re assuming the checkbox field could only return one value (or maybe I’m misreading your post, sorry if that’s the case). In reality, the checkbox field allows multiple items to be checked, which is why you can’t simply check a single value and instead need to loop through its multiple potential values and then make your logic work based on the one or many values contained within the field.

The docs mention that this is how to display/render the value(s) of a checkbox field:

<Loop acf_checkbox=field_name>
  <Field />
</Loop>

There doesn’t seem to be any mention in the docs of the If tag supporting an acf_checkbox attribute, so I imagine that’s why the templates you tried weren’t working.

I don’t have an ACF checkbox field nearby to test but the way I imagine I’d achieve this using the syntax that’s documented would be something along these lines:

<Set checkbox_contents>
  <Loop acf_checkbox=online_ordering_options>
    <Field /><If not last>,</If>
  </Loop>
</Set>

<If variable=checkbox_contents any_is value=delivery>DELIVERY</If>

Or a more compact version:

<If check="{Loop acf_checkbox=online_ordering_options}{Field /},{/Loop}" any_is value=delivery>DELIVERY</If>

Or if you’re sure only one of the options is ever going to be selected (in which case I’d recommend probably using an ACF radio field instead), you could try this:

<Loop acf_checkbox=online_ordering_options>
  <If check="{Field}" value=delivery>DELIVERY</If>
</Loop>

Disclaimer: I haven’t tried these myself, but I thought I’d share some ideas about how I’d achieve this based on the syntax that’s written in the documentation. Let me know if these work as-is or if you end up needing to tweak them at all to get them to work.

This seems like it should be easy

I agree, it should be straight-forward to check the value of an ACF checkbox field. If it wasn’t clear from the documentation, or if the template language doesn’t support a simple method, we can improve it.

Looping over the checkbox values, and checking with <If field> works:

<Loop acf_checkbox=online_ordering_options>
    <If field is value="delivery">DELIVERY</If>
</Loop>

Passing a field value to check:

<If check="{Field acf_checkbox=online_ordering_options}" any_is value=delivery>

Surprisingly, this works. The result of Field is a JSON array, but the comparison any_is knows how to handle it.

Then I tried a shortcut with includes.

<If acf_checkbox=online_ordering_options includes value=delivery>

I like this syntax the best, but that didn’t work as expected. Looking in the code, I found that the checkbox field is passed as a List loop with its values, and the comparison includes doesn’t handle that currently. OK, I’ve made a note to improve this in the next version of L&L to support the above syntax.

(Now that I’m thinking, any_is and includes mean pretty much the same thing: “if any item in the list is a value”, and “if the list includes a value”. They should probably be consolidated to use the same logic. EDIT: Nope, on closer view, they’re slightly different. includes will match a value in a piece of text as-is, but any_is will convert the text into a list as comma-separated values. Also, any_is_not and not_includes behave differently too. I wish these could be made more consistent and simpler somehow.)

1 Like

Nice! I was thinking that something along these lines would be the best bet but I wasn’t able to test to confirm that it worked.

@eliot are ACF logic shortcuts like If acf_checkbox=... supposed to work in L&L? I’ve seen a handful of people try that syntax but I’ve generally recommended against it since it’s not documented. Curious to know if that’s something that would make sense to add since it seems a lot of folks expect the language to work that way.

Edit: The tricky part, I imagine, is that the comparisons they can use will depend on the format of the data within the field. For something like a text field, that’s obvious, but in other field types, users might not know the format of the field contents and might get confused. For example, taking the checkbox field, which contains an array like ["field_value"] even if there’s only one value selected, users might think that they could write <If acf_checkbox=checkbox_field is value=field_value> which wouldn’t work. They’d need to use includes or any_is but they wouldn’t know that unless they knew exactly what that field contained. Alright, I think I’ve used your technique of thinking something through as I write it and I’ve convinced myself this wouldn’t be a good feature to add. We should probably simply let people use the syntax <If check="{Field acf_checkbox=checkbox_field}" value=field_value> or even <If field=checkbox_field value=field_value> so that it’s clear that they’re running their logic on the raw field value and they need to know what format of data exists in that field if they want to successfully apply some logic it.

Hey Guys. Thanks for jumping in. This is what I went with:

<Loop acf_checkbox=online_ordering_options>
  <If check="{Field}" value=delivery>DELIVERY</If>
  <If check="{Field}" value=pick_up>PICK UP</If>
  <If check="{Field}" value=pick_up_delivery>PICK UP & DELIVERY</If>
</Loop>

This seems to be the cleanest way for me to show/do more if the boxes are checked. Once I see some simple solutions it helps me understand whats happening.

@eliot thanks for breaking that down further and def helps understand possible use cases.

2 Likes

That’s a smart solution! Quick tip while we’re on the topic, whenever you’ve got multiple If tags, it can sometimes be useful to use Switch and When. Works the same way so not entirely necessary in this case, but it’s a bit more DRY which is always fun :stuck_out_tongue:

<Loop acf_checkbox=online_ordering_options>
  <Switch check="{Field}">
    <When value=delivery />DELIVERY
    <When value=pick_up />PICK UP
    <When value=pick_up_delivery />PICK UP & DELIVERY
  </Switch>
</Loop>
3 Likes

Are ACF logic shortcuts like If acf_checkbox=... supposed to work in L&L?

Yes, the ACF integration adds a logic rule for every field type available, so the If tag has acf_* attributes that support the same common comparisons as the check attribute.

So instead of:

<If check="{Field acf_field=name}">

It can be:

<If acf_field=name>

They need to know what format of data exists in that field if they want to successfully apply some logic

It’s true about the difficulty of handling different kinds of values that a field can contain. Each “comparison operator” like is and includes has its own logic of what value types are expected and accepted/converted.

In this case:

<If acf_checkbox=checkbox_field includes value=field_value>

The includes operator didn’t yet know how to handle a List loop instance that the acf_checkbox field passed to it. This will be supported in the next version of L&L.

1 Like

Did the <If acf_checkbox=checkbox_field includes value=field_value> get added?

I see something about it in the release notes for 3.2.8:

  • Improve comparison “includes” to support a List loop instance, for example: <If acf_checkbox=field_name includes value=some_value>

However it doesn’t seem to work for me. Specifically, in my case, for a custom field called accreditations.

<If check="{Field acf_checkbox=accreditations}" any_is value="ctc">

works as expected, but

<If acf_checkbox=accreditations includes value=ctc>

doesn’t.

Yeah it does look like support for this was added in 3.2.8. I just tested it in the latest version of the plugin and both of those syntaxes work for me with either includes or any_is. Is there something else unique going on in your template that might be causing this? I’m not able to replicate your issue.

Maybe something was broken because when I copied and pasted the second line

it’s now working. Very weird. Must be user error on my part. :frowning: