Search code examples
pythonhtmlcssflaskjinja2

How to change parent style based on child's value using Jinja2/Python?


First off, the :has() combinator achieves what I want to do. For example, I have a table in my HTML where

<table class="table">
    {% for dict_item in data | sort(attribute='name') %}
    <tr class="table__row">
        {% for key, value in dict_item.items() %}
            {% if value == "StandBy" %}
            <td class="table__cell standby">{{ value }}</td>
            {% elif value == "Active" %}
            <td class="table__cell active">{{ value }}</td>
            {% elif value == "Paused" %}
            <td class="table__cell paused">{{ value }}</td>
            {% else %}
            <td class="table__cell">{{ value }}</td>
            {% endif %}
        {% endfor %}
    </tr>
    {% endfor %}
</table>

And the respective css file

.table__row:has(.active) {
    background-color: #5cfb4b;
}

.table__row:has(.standby) {
    background-color: #e5e5e5;
}

.table__row:has(.paused) {
    background-color: #f6FB4B;
}

.table__row:has(.done) {
    background-color: #fe6464;
}

This does what I want it to do which is that it colors the entire row the same color based on one cell's value. However, not all browsers support the :has() combinator and thus, I have to also add the following style rules, but they only color the respective cell, not the entire row.

.standby{
    background-color: #e5e5e5;
}

.active{
    background-color: #5cfb4b;
}

etc...

How would I be able to get rid of all these extra style blocks but also color an entire row the same color. I've tried other sibling combinators such as ~ but they do not work. Would I be able to create an attribute variable in the <tr> element and change it accordingly based on the value of a cell in that row? Then, in the style sheet, can I reference if the attribute is this value, make it this color etc... From similar questions on the stack, most people reference a solution in javascript, but I would like to know if this can be done in Jinja2/Python.

This is a little side project and I am a complete noob in html and css.


Solution

  • ChatGPT for the win! It gave me a nice, detailed, and easy answer!

    To do what I wanted to achieve, just add some Javascript to the HTML file after building the table and add a class to the parent after. This also allow less use of Jinja2 in the for loop of the HTML and we don't need to add classes to the cells now.

    Now, the table can just be

    <table class="table">
        {% for dict_item in data | sort(attribute='name') %}
            <tr class="table__row">
                {% for key, value in dict_item.items() %}
                <td class="table__cell">{{ value }}</td>
                {% endfor %}
            </tr>
        {% endfor %}
    

    Add this Javascript after

    <script>
        var children = document.getElementsByClassName('table__cell');
        for (var i = 0; i < children.length; i++) {
            var child = children[i];
            if (child.innerHTML === 'StandBy') {
                child.parentNode.classList.add('standby');
            }
            else if (child.innerHTML === 'Active') {
                child.parentNode.classList.add('active');
            }
            else if (child.innerHTML === 'Paused') {
                child.parentNode.classList.add('paused');
            }
            else if (child.innerHTML === 'Done') {
                child.parentNode.classList.add('done');
            }
        }
    </script>
    

    And voila, now you can change the background color of the parent row in your css file like so

    .table__row.active {
        background-color: #5cfb4b;
    }
    
    .table__row.standby {
        background-color: #e5e5e5;
    }
    
    .table__row.paused {
        background-color: #f6FB4B;
    }
    
    .table__row.done {
        background-color: #fe6464;
    }