2

I'm new to JS and I'm trying to update a CSS class of a div, svg and a link using JS. I have the following sidebar made with TailwindCSS in my Django app.

<div class="w-full flex flex-col p-5 border-r border-gray-200">
            <div class="flex py-2 flex-col mt-5">
                <div class="flex flex-row space-x-2 p-4 items-center">
                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
                         stroke="currentColor" class="w-6 h-6 text-gray-500">
                        <path stroke-linecap="round" stroke-linejoin="round"
                              d="M3.75 3v11.25A2.25 2.25 0 006 16.5h2.25M3.75 3h-1.5m1.5 0h16.5m0 0h1.5m-1.5 0v11.25A2.25 2.25 0 0118 16.5h-2.25m-7.5 0h7.5m-7.5 0l-1 3m8.5-3l1 3m0 0l.5 1.5m-.5-1.5h-9.5m0 0l-.5 1.5m.75-9l3-3 2.148 2.148A12.061 12.061 0 0116.5 7.605"/>
                    </svg>
                    <a href="{% url 'tool:testindex' %}"
                       class="font-medium text-sm text-gray-500" onclick="updateClass(this);">{% trans 'Dashboard' %}</a>
                </div>
                <div class="flex flex-row space-x-2 p-4 items-center">
                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
                         stroke="currentColor" class="w-6 h-6 text-gray-500">
                        <path stroke-linecap="round" stroke-linejoin="round"
                              d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25M9 16.5v.75m3-3v3M15 12v5.25m-4.5-15H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z"/>
                    </svg>

                    <a href="{% url 'tool:reports' %}"
                       class="text-gray-500 font-medium text-sm" onclick="updateClass(this);">{% trans 'Invoice control' %}</a>
                </div>
                <div class="flex flex-row space-x-2 p-4  bg-[#68BA9E] rounded-xl items-center">
                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
                         stroke="currentColor" class="w-6 h-6 text-white">
                        <path stroke-linecap="round" stroke-linejoin="round"
                              d="M3 3v1.5M3 21v-6m0 0l2.77-.693a9 9 0 016.208.682l.108.054a9 9 0 006.086.71l3.114-.732a48.524 48.524 0 01-.005-10.499l-3.11.732a9 9 0 01-6.085-.711l-.108-.054a9 9 0 00-6.208-.682L3 4.5M3 15V4.5"/>
                    </svg>

                    <a href="{% url 'tool:sla-compliance' %}"
                       class="text-white font-medium text-sm" onclick="updateClass(this);">{% trans 'SLA Compliance' %}</a>
                </div>
                <div class="flex flex-row space-x-2 p-4 items-center">
                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
                         stroke="currentColor" class="w-6 h-6 text-gray-500">
                        <path stroke-linecap="round" stroke-linejoin="round"
                              d="M8.25 18.75a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m3 0h6m-9 0H3.375a1.125 1.125 0 01-1.125-1.125V14.25m17.25 4.5a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m3 0h1.125c.621 0 1.129-.504 1.09-1.124a17.902 17.902 0 00-3.213-9.193 2.056 2.056 0 00-1.58-.86H14.25M16.5 18.75h-2.25m0-11.177v-.958c0-.568-.422-1.048-.987-1.106a48.554 48.554 0 00-10.026 0 1.106 1.106 0 00-.987 1.106v7.635m12-6.677v6.677m0 4.5v-4.5m0 0h-12"/>
                    </svg>

                    <a href="{% url 'tool:co2-emissions' %}"
                       class="font-medium text-sm text-gray-500" onclick="updateClass(this);">{% trans 'CO2 Emissions' %}</a>
                </div>
                <div class="flex flex-row space-x-2 p-4 items-center">
                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
                         stroke="currentColor" class="w-6 h-6 text-gray-500">
                        <path stroke-linecap="round" stroke-linejoin="round"
                              d="M18 18.72a9.094 9.094 0 003.741-.479 3 3 0 00-4.682-2.72m.94 3.198l.001.031c0 .225-.012.447-.037.666A11.944 11.944 0 0112 21c-2.17 0-4.207-.576-5.963-1.584A6.062 6.062 0 016 18.719m12 0a5.971 5.971 0 00-.941-3.197m0 0A5.995 5.995 0 0012 12.75a5.995 5.995 0 00-5.058 2.772m0 0a3 3 0 00-4.681 2.72 8.986 8.986 0 003.74.477m.94-3.197a5.971 5.971 0 00-.94 3.197M15 6.75a3 3 0 11-6 0 3 3 0 016 0zm6 3a2.25 2.25 0 11-4.5 0 2.25 2.25 0 014.5 0zm-13.5 0a2.25 2.25 0 11-4.5 0 2.25 2.25 0 014.5 0z"/>
                    </svg>

                    <a href="#" class="font-medium text-sm text-gray-500" onclick="updateClass(this);">{% trans 'Claims' %}</a>
                </div>
                {% if request.user.is_superuser %}
                    <div class="flex flex-row space-x-2 p-4 items-center">
                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
                         stroke="currentColor" class="w-6 h-6 text-gray-500">
                        <path stroke-linecap="round" stroke-linejoin="round"
                              d="M16.5 10.5V6.75a4.5 4.5 0 10-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H6.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z"/>
                    </svg>


                    <a href="{% url 'admin:index' %}"
                       class="text-gray-500 font-medium text-sm" onclick="updateClass(this);">{% trans 'Administration' %}</a>
                {% endif %}
                </div>
            </div>
        </div>

I'm trying to update the CSS class when I click on a link inside a div. For every link, the onclick method is linked to the following JS function updateClass:

        <script>

            function updateClass(el) {

                let elem = $(el);
                elem.removeClass('text-gray-500');
                elem.addClass("text-white");

                let svgParent = elem.find('svg');
                svgParent.removeClass('text-gray-500');
                svgParent.addClass("text-white");

                let divParent = elem.closest('div');
                divParent.addClass("bg-[#68BA9E] rounded-xl");
            }

        </script>

This works (except for the svg part, I don't know why). But after the page is reloaded, the css class disappears. How can I keep the changes after reloading the page? I know that I need to alter my function, but I don't understand why I cannot keep the new CSS class.

4
  • You can't do that unless you retain somewhere that your element was clicked, for example you could store a boolean in the local storage, and add your classes on page load if that boolean is true Commented Oct 18, 2022 at 14:09
  • What is the el here to call updateClass function? Commented Oct 18, 2022 at 16:54
  • @Lk77, but I need to update my elements on click, where the boolean would be stored? Commented Oct 18, 2022 at 17:42
  • @EMRANHOSSAIN If I understood your question correctly, the el matches with onclick=updateClass(this); Commented Oct 18, 2022 at 17:43

1 Answer 1

2

As i understand, your user will click, but you want to retain that clicked state accross reload and page changes, i am correct ?

if that's so, i'm also assuming that you have multiple elements that should do that ?

Here is what i would do :

// Have an object to store the state
let clickedState = {};

// Recover the state at the start of the page
if(localStorage.hasItem('clickedState')) {
    try {
        clickedState = JSON.parse(localStorage.getItem('clickedState'))
    } catch (e) {
        // if parsing of json fail we remove the item
        localStorage.removeItem('clickedState')
    }
}    


function updateClass(el) {
    // your function 
}

// the event listener
function onElClick(event) {
    let el = event.target;

    // toggle behaviour
    clickedState[el.id] = clickedState.hasOwnProperty(el.id) ? !clickedState[el.id] : true

    // OR //

    // normal behaviour  
    clickedState[el.id] = true;

    localStorage.setItem('clickedState', JSON.stringify(clickedState))
    
    updateClass(el)
}


// here we redo updateClick for all clicked elements on page load
Object.keys(clickedState).forEach(k => {
    if(clickedState[k]) {
        let el = document.getElementById(k);
        if(el) {
           updateClass(el)
        }
    }   
})

and depending on your needs you might want to implement the reverse action, with a toggle behaviour

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

1 Comment

Hi sorry for delayed answer. Thank you for your answer but I was finally able to do it using the Django attribute request.resolver_match.view_name. If the URL is equal to value returned by the Django attribute, then it updates the class, else the original class is kept.

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.