3

Consider the following table which iterates data from an sqlite database using flask and sqlalchemy.

Assume for this example that the data is a list of invoices and clicking on each row opens a collapsible bootstrap accordion whith further information for the clicked invoice.

<table class="table table-hover" data-toggle="table">  
<thead>
    <tr>
        <th>Date</th>
        <th>Invoice</th>         
    </tr>
</thead>

<tbody>
<tr data-toggle="collapse" data-target="#accordion" class="clickable">
{% for inv in invoices %}
   <td>
      {{ inv.number }}
   </td>
</tr>
<tr>
   <td>
      <div id="accordion" class="collapse">
         {{ inv.data }}
      </div>
   </td>
</tr>
{% endfor %}
</body>
</table>

The problem here is that only the first row is clickable and clicking on it opens all the rows instead of just a single row whereas we would like to be able to click on each row and reveal the data for that specific row exclusively.

I think the problem is do to with the data-target="#accordion" tag which targets the iteration of the collapsed data placeholder instead of the specific placeholder itself.

You can see an example here Twitter Bootstrap Use collapse.js on table cells [Almost Done] and here http://jsfiddle.net/whytheday/2Dj7Y/11/ but again the content is static and not dynamic.

The solution would be to have a "dynamic" data-target tag which matches the target id but I have no idea how to do that.

Alex B
  • 509
  • 7
  • 18

1 Answers1

3

To accomplish this task, you have to insert your tr tag into the jinja loop, then add a dynamic data-target to your tr tag and a dynamic id to all your collapsible bootstrap accordions; So each tr tag will point to the corresponding accordion. Here's what the code should look like:

<tbody>
    {% for inv in invoices %}
        <tr data-toggle="collapse" data-target="#{{inv.number}}"  class="clickable">
            <td>
                {{ inv.number }}
            </td>
        </tr>
        <tr id="{{inv.number}}" class="no-border collapse">
            <td>
                <div>
                    {{ inv.data }}
                </div>
            </td>
        </tr>
    {% endfor %}
</tbody>

The idea here is that, since the invoice number is unique, you will have accordions with unique ids. Thus each attribute data-target of your tr tags (generated dynamically them too), will point to the corresponding accordion.

Extras just in case:

you will notice that I added the class no-border to the second tr block. This is for the case where you would not want to have a border from Bootstrap tables... here is the corresponding css:

<style type="text/css">
    .table>tbody>tr.no-border>td{
        border-top: none;
    }
</style>
Alex B
  • 509
  • 7
  • 18
Tobin
  • 1,481
  • 1
  • 8
  • 16
  • Unfortunately that makes no difference. I tried moving the tag around myself too to see if it would help but it doesn't. I think the problem is do to with the `data-target="#accordion"` tag which targets the iteration of the collapsed data placeholder instead of the specific placeholder itself. The solution would be to have a "dynamic" `data-target` tag which matches the target `id` but I have no idea how to do that. – Alex B Nov 15 '18 at 12:38
  • Adding unique ids is a step in the right direction since only one row collapses now but it immediately closes itself on its own without clicking on it again so doesn't stay open to show the data. – Alex B Nov 15 '18 at 16:38
  • the open close issue was an unrelated issue with some conflicting .js – Alex B Nov 15 '18 at 17:01
  • 1
    I also move the `child` id and class to `` instead of `
    ` so that it applies to the entire row and not just the cell which makes more sense.
    – Alex B Nov 15 '18 at 17:38