Home > Enterprise >  Conditional classNames & collection_check_boxes
Conditional classNames & collection_check_boxes

Time:07-21

In this example I am displaying all possible Tags on a Post when creating or editing a Post. I want to change the background-color to indicate if an item is checked or not, so I can remove the checkbox. You can see my failed attempt where I conditionally try to change the background-color in the class attribute of tag_item.label.

How can I check if tag_item is checked?

    <div >
        <%= form.collection_check_boxes :tag_ids, Tag.all, :id, :name do |tag_item| %>
            <%= tag_item.label class: "#{tag_item.check_box ? "bg-red-500" : "bg-gray-100"} select-none border2 border-gray-100 flex w-auto p-2 text-sm cursor-pointer text-center" %>
            <%= tag_item.check_box do |tag_item_checkbox| %>
                <p> <%= tag_item_checkbox.inspect %> </p>
            <% end %>
        <% end %>
    </div>

CodePudding user response:

So Im a new Rails developer but solved the problem my way, forgive me that I could not find the "rails way" to this problem. But anyways - it works like a charm.

tag_item.check_box.inspect["checked"] is returning if the tag is applied to the post (in edit view). The toggle(tag_item_id) function is therefore only for setting the background-color client-side as clollection_check_boxes and tag_item.check_box are handling the checked-status and the data when the form get submitted.

...

    <div >
        <%= form.collection_check_boxes :tag_ids, Tag.all, :id, :name do |tag_item| %>
            <div id="post_tag_id_<%= tag_item.object.id %>">
                <%= tag_item.label class: "#{tag_item.check_box.inspect["checked"] ? "bg-red-500" : "bg-gray-100"} select-none border2 border-gray-100 flex w-auto p-2 text-sm cursor-pointer text-center" %>
                <%= tag_item.check_box class: "hidden", onclick: "toggle(#{tag_item.object.id})" %>
            </div>
        <% end %>
    </div>

...

<script>
    function toggle(tag_item_id) {

        const label = document.querySelector("#post_tag_id_"   tag_item_id   " > label");
        const checkbox = document.getElementById("post_tag_ids_"   tag_item_id);

        if (!checkbox.checked) {
            label.classList.remove("bg-red-500");
            label.classList.add("bg-gray-100");

        } else {
            label.classList.remove("bg-gray-100");
            label.classList.add("bg-red-500");
        }
    }
</script>

CodePudding user response:

So, where you're doing the tag_item.check_box ? "bg-red-500" : "bg-gray-100", that tag_item.check_box needs to really be checking whether the tag_item of this iteration is set on the post model.

You might already have a way of referring to the given post (an @post or post local), or you can refer to it in a form context with form.object, so then you need to check whether the current tag_item is in the post's tags, eg:

<%= tag_item.label class: "#{ post.tags.include?(tag_item) ? "bg-red-500" : "bg-gray-100" } other classes" ...etc

Make sense?

  • Related