Custom button operating on selected rows

Custom button operating on selected rows

alastairjloganalastairjlogan Posts: 3Questions: 1Answers: 0

I'm trying to build a custom button that operates on only the selected rows, which emits some JSON (which should just be some data from two of the columns) to an API so that the server can perform some processing on that.

I believe that my use-case is similar to the example suggested on the custom buttons page, however I can't see a live example for the suggested use-case: "For example, consider a table of pupils in class registration. To mark absent pupils a single button could be used along with the Select extension to firstly select missing pupils and then update a database at a single click."

My issue is that I'm having trouble performing the iteration to pull the relevant data from the table so that the JSON can be built and emitted, can anyone assist here? I've tried using the .every and .each iterator APIs, but without any luck.

My DataTables instance is set up as:

  table = $(table_id).DataTable({
    buttons: [
      {
        text: 'Cancel Execution',
        extend: 'selected',
        action: function(e, dt, node, config) {
          let arr = [];
          dt.rows({selected: true}).every(function(rowIdx, tableLoop, rowLoop) {
            // Extract data from columns 3 and 17 to put in JSON
            let rowData = ???;
            arr.push(rowData);
          });
          // Send data to API, code omitted for brevity...
        },
      },
    ],
    colReorder: true,
    columnDefs: [{
      orderable: false,
      className: 'select-checkbox',
      title: '',
      targets: 0,
    }],
    columns: [
      {'name': 'checkbox_col'},
      {'name': 'col1'},
      {'name': 'col2'},
      {'name': 'col3'},
      {'name': 'col4'},
      {'name': 'col5'},
      {'name': 'col6'},
      {'name': 'col7'},
      {'name': 'col8'},
      {'name': 'col9'},
      {'name': 'col10'},
      {'name': 'col11'},
      {'name': 'col12'},
      {'name': 'col13'},
      {'name': 'col14'},
      {'name': 'col15'},
      {'name': 'col16'},
      {'name': 'col17', 'visible': false},
    ],
    dom: 'Bfrtip',
    fixedColumns: {
      left: 5,
    },
    order: [[1, "desc"]],
    select: {
      style: 'multi',
      selector: 'td:first-child',
    },
  });

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 20,252Questions: 26Answers: 4,761

    The rows().every() docs show using var data = this.data(); to get the row data. You can do something like this:

            dt.rows({selected: true}).every(function(rowIdx, tableLoop, rowLoop) {
              // Extract data from columns 3 and 17 to put in JSON
              var data = this.data()
              let rowData = [ data[3], data[17] ];
              arr.push(rowData);
            });
    

    Kevin

  • alastairjloganalastairjlogan Posts: 3Questions: 1Answers: 0

    Hi Kevin,

    Thank you very much for this, I can't believe I hadn't tried that already!

    One follow-up question, given that I have colReorder: true, I can't always guarantee the order of the columns when the button is clicked is the same as at initialisation, can the column selectors ( e.g. data[3]) be changed to use the column-selector syntax, e.g. something like data['col3:name'] to guarantee the correct column will be selected?

  • kthorngrenkthorngren Posts: 20,252Questions: 26Answers: 4,761
    Answer ✓

    The only way I know of to use something like 'col3:name' is as a column-selector for the column() API. Try using column().index() to get the index for the array. I think something like this should work:

    dt.rows({selected: true}).every(function(rowIdx, tableLoop, rowLoop) {
      // Extract data from columns 3 and 17 to put in JSON
      var data = this.data()
      let rowData = [ data[ dt.column( 'col3:name' ).index() ], data[ dt.column( 'col17:name' ).index() ] );
      arr.push(rowData);
    });
    

    Kevin

  • alastairjloganalastairjlogan Posts: 3Questions: 1Answers: 0

    Ah, I didn't know about the .index() API, this solution is exactly what I've been looking for, and seems robust even when the columns have been reordered!

    Many thanks, Kevin!

Sign In or Register to comment.