0

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?

Harlin
  • 1,059
  • 14
  • 18
  • 1
    Why do you not use `alarmValElementList` instead of `alarmValElementList{{...}}` – Mojtaba Kamyabi May 30 '19 at 21:41
  • Good question. If you'll notice, I'm defining a list of elements that will be redefined on each iteration of alarm_list. If I only stick to alarmValElementList alone, I will get errors like alarmValElementList already defined. I think though, your question has helped me at least with refining this a bit by defining alarmValElementList outside the alarm_list for-loop. Thanks for that! – Harlin May 30 '19 at 21:45

1 Answers1

1

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 %}
AMG
  • 1,606
  • 1
  • 14
  • 25
  • Thanks, AMG. That was the first way I thought of but figured that was too many if statements. If it was only one , then that might be a good way. The 2nd part to your answer is actually very good and would work. – Harlin May 31 '19 at 20:00