0

I have the following code:

                        <nav class="mt-4 flex flex-1 flex-col space-y-2 bg-gray-300 space-y-auto"
                             aria-label="Transporters">
                            {% if list_transporters_results|length > 0 %}
                                {% for item in list_transporters_results %}
                                    <div>
                                        <div class="flex flex-row items-center justify-between p-2"
                                             id="container-button-transporter-{{ forloop.counter }}">
                                            <button type="button"
                                                    hx-get="{% url 'tool:results-transporter' slug=item.slug pk=item.pk %}"
                                                    hx-target="#stats" hx-swap="innerHTML" hx-trigger="click"
                                                    class="cursor-pointer"
                                                    id="button-transporter-{{ forloop.counter }}"
                                                    onclick="get_id_transporter(this.id)"
                                            >{{ item.transporter }}</button>
                                            <div class="bg-[#195266] rounded-full p-2 self-center mr-2">
                                                <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-white"
                                                     fill="none"
                                                     viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                                                    <path stroke-linecap="round" stroke-linejoin="round"
                                                          d="M5 13l4 4L19 7"/>
                                                </svg>
                                            </div>
                                        </div>
                                    </div>
                                {% endfor %}
                            {% else %}
                                <div>
                                    <div class="flex flex-row items-center justify-between">
                                        <p class="text-center">No transporters yet.</p>
                                    </div>
                                </div>

                            {% endif %}

                        </nav>

My objective is to change the class of the div id="container-button-transporter-{{ forloop.counter }}" by clicking on the button button-transporter-{{ forloop.counter }}. Using forloop.counter, I have div such as:

  • container-button-transporter-1
  • container-button-transporter-2
  • etc.

To update the Tailwind class, I have the following JS script:

    <script>

        var transporterId;
        var numberTransporter;
        function get_id_transporter(clickedId){
                transporterId = clickedId;
                numberTransporter = parseInt(transporterId.split("-")[2]);
        }

        const button = document.getElementById(`button-transporter-${numberTransporter}`);

        if(button){
        button.addEventListener('click', function handleClick() {
            document.getElementById(`container-button-transporter-${numberTransporter}`).className = "flex flex-row items-center justify-between p-2 bg-[#195266]";
            document.getElementById(`button-transporter-${numberTransporter}`).className = "text-white";
            });
        }
    </script>

The code above does not work with the variable numberTransporter. However, if I change to button-transporter-${1} and container-button-transporter-${1}, it's working. I don't understand why since the variable is an integer. Could you explain me why?

1 Answer 1

1

You are calling the function get_id_transporter() when you click a button but the rest of the code is only runs once...when the page loads.

With the code above, var transporterId never gets set until a button is clicked. The code that uses transporterId (after if(button) ) has already run

If you change your expression to ${1} it works because button-transporter-1 is an actual ID. If you changed it to ${1+1} and button-transporter-2 was an actual id, it would work also.

There's maybe something a little funky about your logic. I suspect you don't want to add a click event listener after the button is clicked. In any event, you can just call the code that changes the class as part of your get_id_transporter() function eg,

<script>

    function get_id_transporter(clickedId){
            transporterId = clickedId;
            numberTransporter = parseInt(transporterId.split("-")[2]);
            modify_classes(numberTransporter)
    }

    function modify_classes(numberTransporter) {
        document.getElementById(`container-button-transporter-${numberTransporter}`).className = "flex flex-row items-center justify-between p-2 bg-[#195266]";
        document.getElementById(`button-transporter-${numberTransporter}`).className = "text-white";
    }

</script>

Above I separated it out into another function and called it at the end of get_id_transporter, so it doesn't run until it's got something to work with.

Sign up to request clarification or add additional context in comments.

1 Comment

Even though I'm new to Javascript, your explanation was very clear and the solution works like a charm. Thank you very much.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.