How to change HTML attributes using Flask and Jinja2 templates?

I am using Flask with Jinja2 templates. I have a Jinja2 loop populating a table. I have buttons to collapse/expand a nested table for each row in the outer table.

The way I’ve approached this is to place the hidden table inside of a Jinja2 if statement. However, I have no way to update the variable that the if statement calls. I couldn’t use JavaScript since it is inside a Jinja2 loop.

Is there a way to update a variable on a button click inside a Jinja2 loop? Or a way to change HTML attributes (style visibility and hidden)?

HTML:

{% for row in table %}
<tr>
    <td>
        <button>
            <!—- Click button to toggle row.visible —>
        </button>
    </td>
</tr>
{% if row.visible %}
<tr>
    <td>
        <table>
            <!—- Hidden table -—>
        </table>
    </td>
</tr>
{% endif %}
{% endfor %}

>Solution :

This kind of toggling is better handled in the front-end via JavaScript.

Using Jinja2 template means handling it in the back-end, since the Jinja2 template is only re-rendered when the there is a new request and the view updates. You don’t really want to hit the server just to toggle something on the webpage.

To use JavaScript, the trick is to use JavaScript to modify the css of the table row tags.

For example, using id of the tag to modify visibility:

<script type="text/javascript">
function showHideDiv(id) {
    var e = document.getElementById(id);
    if(e.style.display == null || e.style.display == "none") {
        e.style.display = "table-row";
    } else {
        e.style.display = "none";
    }
}
</script>

{% for row in table %}
<tr>
    <td>
        <button onclick="showHideDiv('hiddable_{{row.id}}')">Show/Hide</button>
    </td>
</tr>
<tr id="hiddable_{{row.id}}">
    <td>
        <table>
            <!—- Hidden table -—>
        </table>
    </td>
</tr>
{% endfor %}

  1. The javascript finds tag by id and toggles the visibility for that tag.
  2. The button calls the javascript function on-click for the corresponding {{row.id}} which is # of iteration in the loop and is populated by the Jinja2 loop.
  3. The table in the same loop uses the same {{row.id}} and is thus controlled by the button in the loop.

Leave a Reply