1

How can I select all records of a django_tables2 table using a CheckBoxColumn when the table is split into several pages?

I have used this select all rows in django_tables2 code to select all records from one page and this How to get information from Django_tables2 row? to do something with them.

But how can I select all records across pagination limits? And also keep the status of a checkbox when I go back and forth on the pages?

wl_
  • 37
  • 7

2 Answers2

0

I would suggest to add a 'check all' checkbox to your template. Apart from visually checking all rows of the current page (using JavaScript), it being checked should signal the logic in your view that the user intends to check all rows.

Keeping the status of those checkboxes is another story. It can lead to bookkeeping in some very big lists. You could keep them in request.session if they need to be kept for a user in a particular browser session, if they need to be persisted to the database, you can create a model to keep track of the selection of a certain record for a certain user.

Jieter
  • 4,101
  • 1
  • 19
  • 31
  • Thank you for pointing me in the right direction. Could you please share some code, too? How do I catch and transfer the "check all" click event to my view? – wl_ Jan 15 '18 at 09:54
  • Hard to say what exactly the behaviour should be: What if I check select all and then unselect a couple of rows. Do you want this to be persisted for a user? For a session? For every user the same state per record? – Jieter Jan 16 '18 at 15:20
  • I am building a system where researchers can order data for analysis. The variables (data items of interest) shall be picked from a table (mx table length ~1000 rows) and stored permanently. To do that I would need to select (on "select all") the rows that are not currently shown in the HTML page when the table is split into a couple of pages. The selected rows should be stored per user per session (individual users will have different record states). When the user applies filters the selection should be persistent and already selected rows should appear as checked. Do you think it's possible? – wl_ Jan 17 '18 at 07:12
  • Just to make clear, I'm not asking for help with that system in general and database access. I think that's in control. The main question still is how to check rows that are not on the current HTML page and how to preserve the check-status on a user-session-basis and display check information of rows again when filter criteria or HTML pages change. – wl_ Jan 17 '18 at 10:01
0

Ok, now I came up with this JavaScript/jQuery solution. It addresses two aspects. First, to store and display the selected checkboxes when the sort order of the table is changed, the table is filtered or when you naviagte to another page and return the table again. Secondly to check and store all checkboxes on a table page when the "Select All" button on in the table head is clicked. Here I'm stuck with selecting all rows in a table, not only the ones that are displayed on one table page (with pagination on). The selected checkboxes are stored in the session storage of the browser. There is certainly room for improvement in the functions, I don't like the iteration over all rows of the table a lot, but I couldn't find a better solution yet. Still I think it would be nice to have this kind of funtionality available in django-tables2. Maybe in some coming version?

The checkbox column is called "selvars" in my tables.py

class dataset_varsTable(tables.Table):
selvars=tables.CheckBoxColumn(accessor='pk',attrs = { "th__input": {"onclick": "toggle(this)"}}, orderable=False)
... (other table columns)

It's the integer primary key of my model

class vars(models.Model):
    idvar=models.IntegerField('Var.ID', primary_key=True)
    ...

And the JavaScript and jQuery functions in the HTML template with the table

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
var storage_name="checkedvars"; // name of session storage
// function to store/remove checked varids in session storage
function update_checkedvars(varid, check_status){
  var current_checked=[];
  if (sessionStorage.getItem(storage_name)){
    current_checked=sessionStorage.getItem(storage_name).split(",");
  }
  if (isNaN(parseInt(varid))==false && check_status==true){
    current_checked.push(varid);
    // store checked varid in session storage without duplicates
    sessionStorage.setItem(storage_name, Array.from(new Set(current_checked)));
  } else if (isNaN(parseInt(varid))==false && check_status==false){
    // remove unchecked varid from session storage
    sessionStorage.setItem(storage_name, current_checked.filter(e => e !== varid));
  }
}

// toggle button
function toggle(source) {
    checkboxes = document.getElementsByName('selvars');
    for(var i in checkboxes){
        checkboxes[i].checked = source.checked;
        update_checkedvars(checkboxes[i].value, checkboxes[i].checked);
    }
}

$(document).ready( function() {
  // display checkboxes according to selected varids in session storage  
  var current_checked=[];
  if (sessionStorage.getItem(storage_name)){
    current_checked=sessionStorage.getItem(storage_name).split(",");
    checkboxes = document.getElementsByName('selvars');
    for(var i in checkboxes){
      if(current_checked.includes(checkboxes[i].value)){
        checkboxes[i].checked=true;
      }
    }
  }

  // save/remove checked/unchecked varid in session storage  
  $(".selvars").click( function(event) {
    var varid=event.target.value
    var check_status=event.target.checked
    update_checkedvars(varid, check_status);
  });
});
</script>
wl_
  • 37
  • 7