This page displays a floor plan, of which there are many. Currently, within each floorplan entry, you add the floors it is on, along with the image of each floor: enter image description here I'm using a for loop to display a big button for each available floor, as you can see on the linked page.

My problem: I want to add disabled buttons for each floor the floorplan isn't on, but I can't figure out how to do it.

The logic should be something like this ("floors" is the name of the matrix field, "floor" is the block type handle):

IF '1' exists in entry.floors.floor.floorNumber
    Show the big selectable '1' button
    Show the disabled '1' button

IF '2' exists in entry.floors.floor.floorNumber
    Show the big selectable '2' button
    Show the disabled '2' button

etc for 3 and 4

It seems like their should be some straightforward solution, but I've had no luck.

Current code for displaying the floor number buttons:

{% for floor in entry.floors.all() %}
{% if floor.type.handle == 'floor' %}
    <li class="tabs-title {% if loop.first %}is-active{% endif %}"><a href="#panel{{ floor.floorNumber }}" {% if loop.first %}aria-selected="true"{% endif %}><img src="{{ siteUrl }}assets/img/{{ floor.floorNumber }}.png" alt="{{ floor.floorNumber }}" /></a></li>
{% endif %}
{% endfor %}

Floor matrix: enter image description here

  • 1
    Could you eventually explain it more in Craft words? I'm sure I'm able to help you but I was not able to figure out the issue. What's your final goal? Do you want to search for a matrix field with or without a certain value? You can check if there is an element with certain criteria via exists() so entry.floors.type('floor').floorNumber(1).exists() will return true or false Jun 29, 2018 at 17:16
  • Yep, that seems to be the selector I'm looking for. For some reason though, using exists() screws up the matrix loop further down the page (the loop will only execute once). This happens even if I render no code, just set a variable. So setting {% set twoExists = entry.floors.type('floor').floorNumber('2').exists() %} at the top of the page causes ONLY the second floor to render in the matrix loop, despite not calling that variable at all. Why is that??
    – Bryce
    Jul 2, 2018 at 22:42
  • The loop being affected: {% for floor in entry.floors.all() %} {% if (floor.type.handle == 'floor') %}*Output floor plate images*{% endif %}{% endfor %}
    – Bryce
    Jul 2, 2018 at 22:47
  • Ok... I was able to fix it using {% for floor in entry.floors.type('floor').floorNumber('').all() %} instead of the above. Is this a bug? Doesn't seem like setting that variable should be affecting a separate loop.
    – Bryce
    Jul 2, 2018 at 22:52

1 Answer 1


You can check if certain elements match for your Query via exists()


returns true or false. However keep in mind entry.floors returns an element of type Query and you'll append the parameters type and floorNumber to the Query. These properties won't reset magically since you call the object by reference and not by value thus you'll either need to reset them

{% do entry.floors.type(null).floorNumber(null) %}

or you don't use the object directly and clone/copy it instead

{% set exists = clone(entry.floors).type('floor').floorNumber(1).exists() %}
  • Thanks for the explanation, this is essentially what I ended up doing. Can you explain the difference between calling by reference vs value? I still don't understand the distinction.
    – Bryce
    Jul 3, 2018 at 16:41
  • Are you on Craft CMS Slack by chance? It's far easier to explain it there Jul 3, 2018 at 17:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.