Home > database >  Changing TailwindCSS class using Django and JS
Changing TailwindCSS class using Django and JS

Time:07-22

I have the following code:

                        <nav 
                             aria-label="Transporters">
                            {% if list_transporters_results|length > 0 %}
                                {% for item in list_transporters_results %}
                                    <div>
                                        <div 
                                             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"
                                                    
                                                    id="button-transporter-{{ forloop.counter }}"
                                                    onclick="get_id_transporter(this.id)"
                                            >{{ item.transporter }}</button>
                                            <div >
                                                <svg xmlns="http://www.w3.org/2000/svg" 
                                                     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 >
                                        <p >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?

CodePudding user response:

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.

  • Related