Search code examples
djangodjango-tables2

how can I summarize checked column with django-tables2


I have a table with some columns. One column is a checkboxcolumn. So, how can I summarize the "quantity" columns that checkboxcolumn is checked? I appreciate if someone can help me.


Solution

  • The django-tables2 docs on CheckBoxColumn mention:

    You might expect that you could select multiple checkboxes in the rendered table and then do something with that. This functionality is not implemented. If you want something to actually happen, you will need to implement that yourself.

    So django-tables2 doesn't have something build in, we have to write something ourselves. That makes this more of a JavaScript/HTML question, but anyway, let's see if we can create a table for this model:

    class Country(models.Model):
        name = models.CharField(max_length=100)
        population = models.PositiveIntegerField()
    

    This is a basic table, adding an empty footer to the table by adding a footer argument to one of the columns. We will use this footer later to put the calculated population sum in.

    class CheckboxTable(tables.Table):
        select = tables.CheckBoxColumn(empty_values=(), footer='')
    
        population = tables.Column(attrs={'cell': {'class': 'population'}})
    
        class Meta:
            model = Country
            template_name = 'django_tables2/bootstrap.html'
            fields = ('select', 'name', 'population')
    

    Now, the template. I used jQuery, to quickly create a function to calculate the sum. This function is executed every time the change event is fired on one of the checkboxes, and on page load.

    {% load django_tables2 %}
    {% render_table table %}
    <script src="//code.jquery.com/jquery.min.js"></script>
    <script>
    $(function () {
    
        // calculate the sum of the population column for the selected rows.
        function update_sum() {
            var sum = 0;
            // loop over each checkbox within <tbody>
            $('tbody input[type=checkbox]').each(function () {
                // if the checkbox is checked
                if ($(this).is(':checked')) {
                    // find the contents of the population column, convert
                    // it to integer and add it to the total.
                    sum += parseInt($(this).parents('tr').find('.population').html());
                }
            });
            // add the sum to the footer cell in the population column.
            $('tfoot .population').html(sum);
        }
    
        // update the sum after each change
        $('tbody input[type=checkbox]').on('change', update_sum);
    
        // update the sum initially.
        update_sum();
    });
    </script>
    

    I added code similar to this to the django-tables2 example application.