0

For a project I'm working on, the admin of the system will be assigning questions to some quizes from a huge pool of questions. For better filtering of the questions upon their selection, I had to use Datatables. Then, I noticed that a simple checkbox for each table row wasn't enough to select them when being paginated, so after some research I found the Checkboxes extension for Datatables that would solve $_POST of the selected rows and pagination problems.

Everything worked fine with the transition, but the latest requirement of my project is the ability to re-order questions, so I also utilized jQuery Sortable, to re-order the question rows. But then I noticed that re-ordering the rows, doesn't actually re-order the selected rows returned by Datatables Checkboxes...

The minimal working code I used for a mockup of my project is below:

jQuery(function($) {
  $('#questions-pool tbody').sortable({
    connectWith: '#questions-pool tbody',
    handle: 'td.move-handle',
  });

  var questions = $('#questions-pool').DataTable({
    ordering: false,
    dom: '<"#upper-controls"lf>t<"#lower-controls"ip>',
    lengthMenu: [
      [10, 50, 100, -1],
      [10, 50, 100, 'All']
    ],
    initComplete: function(settings) {
      var api = this.api();
      var selected = [387, 386, 385, 384, 383, 382, 381, 380, 379, 378];

      api.cells(
        api.rows(function(idx, data, node) {
          return (selected.indexOf(Number(data[2])) >= 0) ? true : false;
        }).indexes(),
        3
      ).checkboxes.select();
    },
    columnDefs: [{
      targets: 3,
      checkboxes: {
        selectAllPages: false,
      }
    }],
  });

  $('#get-selected').click(function(event) {
    var form = $('#questions-form');

    $(form).find('.questions-postfields').remove();

    console.log('Deleted previous fields');

    $.each(questions.column(3).checkboxes.selected(), function(index, rowId) {
      $(form).append(
        $('<input>')
        //  .attr('type', 'hidden')
        .attr('name', 'questions[]')
        .attr('class', 'questions-postfields')
        .val(rowId)
      );
    });
  });
});

Also a working fiddle of the code above can be found here. So the fiddle starts with some rows already selected by their respective checkboxes. I also have a button that emulates form submission, where upon the submission I've coded the script to create on-the-fly hidden fields for each selected ID. So upon clicking the button, the previous fields are removed and appended to the form from scratch. However, no matter how you re-order the rows, the selected IDs always appear in the same order.

Do you have any idea why this is happening?

Faye D.
  • 833
  • 1
  • 3
  • 16
  • I would suggest cutting down the scale and what's happening around the problem in the fiddle. For example, just have 5 checkboxes, and just check the first two, than when you re-order it's easy to see that the first two checkboxes stays checked. Preferably remove buttons, input-fields etc. that aren't related to the problem you're trying to solve as well. – MrJalapeno Jun 23 '22 at 08:05
  • What do you have in mind though? Did you have an idea where a smaller dom would prove to be beneficial to spot? I did what you suggested and still can't figure out how to deal with my situation. – Faye D. Jun 23 '22 at 10:23
  • 1
    Could you link to the Fiddle for that one? It's beneficial because it's easier to debug the less stuff that's not directly related to the bug is in the code. Especially for someone coming from outside. See https://stackoverflow.com/help/minimal-reproducible-example – MrJalapeno Jun 23 '22 at 14:01
  • Sure. It's https://jsfiddle.net/princeofabyss/2vrhw69a/1/ – Faye D. Jun 23 '22 at 15:01
  • But I suspect the approach of this Checkboxes approach leads to nowhere.... I'm investigating another approach right now, with normal checkboxes and the jQuery Sortable to help me re-order the rows... – Faye D. Jun 23 '22 at 15:02
  • This approach looks more promising, as it re-orders the returned IDs of the checked rows according to how you re-order them in the table. The only disadvantage I'm facing is that it only returns the rows of the current page... But I found a thread here: https://datatables.net/examples/api/form.html where it's mentioned that using the Datatables API, one can get rows from the rest of the pages also. So I'm currently trying to implement their solution in my case... Anyway, this new approach is here: https://jsfiddle.net/princeofabyss/okaxqc1j/ Feel free to take a look on this too if you want! – Faye D. Jun 23 '22 at 15:06
  • OK, I found it! It was dead easy to be honest! All I had to do was to use the Datatables $() API, instead of normal jQuery DOM traversing to pull the data I wanted even from other pages also. Here is a working fiddle https://jsfiddle.net/princeofabyss/r76shyw9/3/ with re-ordering working, ans also pulling data from all pages!!! – Faye D. Jun 23 '22 at 15:34
  • 3
    jQuery Checkbox relies on jQuery DataTables sort order, but jQuery Sortable changes table rows without letting jQuery DataTables know about changed sort order. – Gyrocode.com Jun 23 '22 at 18:07
  • @Gyrocode.com at least you confirm my suspicion that your extension was not the solution to my problem for allowing me to get the returned selected IDs in a particular order (user-defined by appropriately re-ordering their respective rows), as I spent 2 days trying to make it work. Don't take this the wrong way - your extension is a great solution, when this special requirement of re-ordering isn't involved! But anyway, since I found another solution, I'm happy with that! :D – Faye D. Jun 23 '22 at 18:18

0 Answers0