{% for alarm in " /> {% for alarm in " /> {% for alarm in "/>

Better way to change background color based on element's property

53 views Asked by At

I'm working on a project using Django, some JavaScript and Tachyons. I have the following in a template file:

<tbody class="lh-copy">
    {% for alarm in alarm_list %}
        <tr>
            <td class="pv3 pr3 bb b--black-20 bg-light-green {{ alarm.id }}-td">{{ alarm.agent.name }}</td>
            <td class="pv3 pr3 bb b--black-20 bg-light-green {{ alarm.id }}-td">{{ alarm.profile_name }}</td>
            <td class="pv3 pr3 bb b--black-20 bg-light-green {{ alarm.id }}-td">{{ alarm.is_active }}</td>
            <td class="pv3 pr3 bb b--black-20 bg-light-green {{ alarm.id }}-td">{{ alarm.created }}</td>
            <td class="pv3 pr3 bb b--black-20 bg-light-green {{ alarm.id }}-td">{{ alarm.message }}</td>
            <td class="pv3 pr3 bb b--black-20 bg-light-green {{ alarm.id }}-td">{{ alarm.alrmtype }}</td>
            <td class="pv3 pr3 bb b--black-20 bg-light-green {{ alarm.id }}-td">{{ alarm.acknowledged }}</td>
            <td class="pv3 pr3 bb b--black-20 bg-light-green {{ alarm.id }}-td">{{ alarm.is_hidden }}</td>

            {% if alarm.is_active %}
                <script language="javascript">
                    const alarmValElementList{{ alarm.id }} = document.getElementsByClassName("{{ alarm.id }}-td");
                    for (let i=0; i < alarmValElementList{{ alarm.id }}.length; i ++) {
                        alarmValElementList{{ alarm.id }}[i].classList.remove("bg-light-green");
                        alarmValElementList{{ alarm.id }}[i].classList.add("bg-light-red");
                    };
                </script>
            {% endif %}
         </tr>
     {% endfor %}
 </tbody>

I'm accessing the element alarm from alarm_list and using a template "if" to insert JavaScript code that tells the HTML element to remove the current background color and add another one. I'm not happy to use alarmValeElementList{{ alarm.id }} as a dynamic variable name but I can't think of another way to do this.

Is there a better way to implement this?

ETA:

This looks better I think as it got rid of the dynamic variable name:

<script language="javascript">
    let alarmValElementList = [];
</script>
{% for alarm in alarm_list %}
    <tr>
        <td class="pv3 pr3 bb b--black-20 bg-light-green alarm-val-td">{{ alarm.agent.name }}</td>
        <td class="pv3 pr3 bb b--black-20 bg-light-green alarm-val-td">{{ alarm.profile_name }}</td>
        <td class="pv3 pr3 bb b--black-20 bg-light-green alarm-val-td">{{ alarm.is_active }}</td>
        <td class="pv3 pr3 bb b--black-20 bg-light-green alarm-val-td">{{ alarm.created }}</td>
        <td class="pv3 pr3 bb b--black-20 bg-light-green alarm-val-td">{{ alarm.message }}</td>
        <td class="pv3 pr3 bb b--black-20 bg-light-green alarm-val-td">{{ alarm.alrmtype }}</td>
        <td class="pv3 pr3 bb b--black-20 bg-light-green alarm-val-td">{{ alarm.acknowledged }}</td>
        <td class="pv3 pr3 bb b--black-20 bg-light-green alarm-val-td">{{ alarm.is_hidden }}</td>

        {% if alarm.is_active %}
            <script language="javascript">
                alarmValElementList = document.getElementsByClassName("alarm-val-td");
                for (let i=0; i < alarmValElementList.length; i ++) {
                    alarmValElementList[i].classList.remove("bg-light-green");
                    alarmValElementList[i].classList.add("bg-light-red");
                };
            </script>
        {% endif %}
    </tr>
{% endfor %}

But, I am wondering if there is not a better way to do this possibly?

1

There are 1 answers

1
AMG On

I might be missing something else you are trying to do but would this work?

{% for alarm in alarm_list %}
<tr>
    <td class="pv3 pr3 bb b--black-20 {% if alarm.is_active %}bg-light-red{% else %} bg-light-green{% endif %} alarm-val-td">{{ alarm.agent.name }}</td>
    <td class="pv3 pr3 bb b--black-20 {% if alarm.is_active %}bg-light-red{% else %} bg-light-green{% endif %} alarm-val-td">{{ alarm.profile_name }}</td>
    <td class="pv3 pr3 bb b--black-20 {% if alarm.is_active %}bg-light-red{% else %} bg-light-green{% endif %} alarm-val-td">{{ alarm.is_active }}</td>
    <td class="pv3 pr3 bb b--black-20 {% if alarm.is_active %}bg-light-red{% else %} bg-light-green{% endif %} alarm-val-td">{{ alarm.created }}</td>
    <td class="pv3 pr3 bb b--black-20 {% if alarm.is_active %}bg-light-red{% else %} bg-light-green{% endif %} alarm-val-td">{{ alarm.message }}</td>
    <td class="pv3 pr3 bb b--black-20 {% if alarm.is_active %}bg-light-red{% else %} bg-light-green{% endif %} alarm-val-td">{{ alarm.alrmtype }}</td>
    <td class="pv3 pr3 bb b--black-20 {% if alarm.is_active %}bg-light-red{% else %} bg-light-green{% endif %} alarm-val-td">{{ alarm.acknowledged }}</td>
    <td class="pv3 pr3 bb b--black-20 {% if alarm.is_active %}bg-light-red{% else %} bg-light-green{% endif %} alarm-val-td">{{ alarm.is_hidden }}</td>

</tr>
{% endfor %}

I'd personally probably have a property on the model for alarm which sets the colour class so you could just say:

<td class="pv3 pr3 bb b--black-20 {{ alarm.css_class }} alarm-val-td">{{ alarm.agent.name }}</td>

EDIT if you are concerned with the unsightly visual of too many if's in your template (I'd say it is okay though) you could use the with statement combined with a yesno filter for a cleaner appearance. I haven't tested this but the following might work for your particular case. If you are concerned with performance which I think would be nearly indifferent between the one 'with' or multiple 'if's you should time it out. My bet would be on the multiple if's, however, the 'with' gives an edge on maintainability.

{% with tdalarm_cssclass=alarm.is_active|yesno:"bg-light-red,bg-light-green" %}
    <td class="pv3 pr3 bb b--black-20 {{ tdalarm_cssclass }} alarm-val-td">{{ alarm.agent.name }}</td>
    <td class="pv3 pr3 bb b--black-20 {{ tdalarm_cssclass }} alarm-val-td">{{ alarm.profile_name }}</td>
    <td class="pv3 pr3 bb b--black-20 {{ tdalarm_cssclass }} alarm-val-td">{{ alarm.is_active }}</td>
    <td class="pv3 pr3 bb b--black-20 {{ tdalarm_cssclass }} alarm-val-td">{{ alarm.created }}</td>
    <td class="pv3 pr3 bb b--black-20 {{ tdalarm_cssclass }} alarm-val-td">{{ alarm.message }}</td>
    <td class="pv3 pr3 bb b--black-20 {{ tdalarm_cssclass }} alarm-val-td">{{ alarm.alrmtype }}</td>
    <td class="pv3 pr3 bb b--black-20 {{ tdalarm_cssclass }} alarm-val-td">{{ alarm.acknowledged }}</td>
    <td class="pv3 pr3 bb b--black-20 {{ tdalarm_cssclass }} alarm-val-td">{{ alarm.is_hidden }}</td>
{% endwith %}