Big questions about DataTables 2 and a lot of extensions

Big questions about DataTables 2 and a lot of extensions

sloloslolo Posts: 117Questions: 24Answers: 2

Link to test case: https://live.datatables.net/delovaki/1/edit
Debugger code (debug.datatables.net): NA
Error messages shown: NA
Description of problem: Hello,

I created a large test case that covers all the features I'm trying to use with version 2 (v2.3.4 at the time of writing this post) of the DataTables component as well as almost all the extensions.

But first, here are the specifics of my example:
- The DataTable uses the columnControl extension and has two header rows.
- The table rows contain HTML code and controls, as well as SVG-type images.
- Some columns are intentionally hidden to be displayed as child rows (the "Column Visibility" button is for example purposes only).

Here is the list of points I would like to achieve:

1./ Avoid exporting specific columns

As you can see, when I click on the "copy" button, I get the result below:

id  Name    E-mail  Date    SKU Qty Code    Info    Actions
00001   Name 1  email1@domain.com   2025-09-01          123     Delete
00002   Name 2  email2@domain.com   2025-08-05          456     Delete

There shouldn't be the "Info" and "Action" columns and I'm also missing the values ​​for the "SKU" and "Qty" columns.

2./ Avoid being able to move columns by dragging and dropping cells in row 2

What option should I apply to prevent the 2nd row from allowing column movement?

3./ Avoid retrieving the HTML code of the column header

As you can see, I'm creating a child row with the names of the hidden columns as well as the cell contents associated with the column.
But when I retrieve the column name (see code below), I get the entire HTML code, not just the column title.
Is there a way to avoid this?

    lRow.columns(".col-in-row-child").every( function(colIdx) {
      var lCell = oTable.cell(rowIdx, colIdx);
      var lColHeader = oTable.column(colIdx).header();
      if (lCell.data() !== "") {
        lExtraInfo += "<p><strong>" + $(lColHeader).html() + " : </strong>" + lCell.data() + "</p>";
      }
    } );

4./ In the SearchBuilder component, there should not be the 2 columns "Info" and "Action"

I used a class named .no-col-extended-search and set the "columnDefs" property to normally prevent them from being visible, but it didn't change anything.
What did I forget to do?

5./ In the SearchPanes component, the "SKU" and "Qty" columns are missing

What did I miss knowing that they appear well in the SearchPanes component.

6./ Would it be possible to have an option to reset the columnControl component's search field via the ESC keyboard key?

When you enter a filter with the keyboard, it is much faster to reset the field via a keyboard key than having to pick up your mouse again to click on the cross.

7./ Problem when refreshing DataTables when deleting a row

I'm providing a link to a problem I've already encountered so that you don't forget that it exists ;-)

https://datatables.net/forums/discussion/81377/problem-to-delete-a-row-in-datatables-works-in-v1-but-not-in-v2

cf. code below:

  $("body").on('click', 'button.btn[data-action="delete"]', function () {
    // Works well
    //mytable.row($(this).parents('tr')).remove().draw();

    // Does not work well
    deleteRow(this);
  });

  function deleteRow(ele) {
    var objInfo = $(ele).closest("tr");
    //console.log(ele);
    oTable.row($(objInfo)).remove().draw(false);
  }

8./ Problem when SearchPanes or searchBuilder is on the right of the layout

We have already discussed this issue and there is no solution to date. I am just bringing it up again so I don't forget ;-)

  var gDataTablesExtendedSearch = {
    "searchBuilder": {
      // If positionned to the right, searchBuilder is hidden on the right side (change "layout" comment to see the difference with right side)
    "searchPanes": {
      // If positionned to the right, searchPanes is hidden on the right side (change "layout" comment to see the difference with left side)

Thanks in advance for your help and I hope I could implement all these features to my DataTables, it would be just awesome!!!

Lolo.

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 65,162Questions: 1Answers: 10,796 Site admin

    Hi Lolo,

    1./ Avoid exporting specific columns

    Use a column selector for the export buttons. See this example.

    2./ Avoid being able to move columns by dragging and dropping cells in row 2

    That looks like a bug. Thanks for letting me know.

    3./ Avoid retrieving the HTML code of the column header

    Use column().title() to get the title text.

    4./ In the SearchBuilder component, there should not be the 2 columns "Info" and "Action"

    For your selector use: "th:visible:not(.no-col-extended-search)". The problem was that it was selecting on the second row as well. ColumnControl's extra row uses td cells, so a simple th selector resolves the issue here.

    5./ In the SearchPanes component, the "SKU" and "Qty" columns are missing

    The data is too unique and thus they aren't automatically displaying. Use searchPanes.threshold to adjust.

    6./ Would it be possible to have an option to reset the columnControl component's search field via the ESC keyboard key?

    Nice idea. I'll consider that for a future release - thanks.

    7./ Problem when refreshing DataTables when deleting a row

    The fix is in. I'd suggest trying the nightly build to make sure it works for you. It should.

    Allan

  • sloloslolo Posts: 117Questions: 24Answers: 2

    Hi @allan,

    1./ Avoid exporting specific columns

    Use a column selector for the export buttons. See this example.

    That is what I already done but I suspect that DataTables does not recognize the cells content as is HTML data (input type=test" and SVG image)

    Indeed, if I add a simple text in the cell where the input type=text control is located, then it is copied or exported as it should be.

    +++++++++++++++++++++++++++++++++++++++++

    2./ Avoid being able to move columns by dragging and dropping cells in row

    That looks like a bug. Thanks for letting me know.

    I'm used to testing and I enjoy programming, so don't hesitate to let me know if you need a beta tester.
    I'd be happy to participate in any way I can :)

    +++++++++++++++++++++++++++++++++++++++++

    3./ Avoid retrieving the HTML code of the column header

    Use column().title() to get the title text.

    Thanks, it works nice.

    Before:

        lRow.columns(".col-in-row-child").every( function(colIdx) {
          var lCell = oTable.cell(rowIdx, colIdx);
          var lColHeader = oTable.column(colIdx).header();
          if (lCell.data() !== "") {
            lExtraInfo += "<p><strong>" + $(lColHeader).html() + " : </strong>" + lCell.data() + "</p>";
          }
        } );
    

    After:

        lRow.columns(".col-in-row-child").every( function(colIdx) {
          var lCell = oTable.cell(rowIdx, colIdx);
          var lColHeader = oTable.column(colIdx).title();
          if (lCell.data() !== "") {
            lExtraInfo += "<p><strong>" + lColHeader + " : </strong>" + lCell.data() + "</p>";
          }
        } );
    

    +++++++++++++++++++++++++++++++++++++++++

    4./ In the SearchBuilder component, there should not be the 2 columns "Info" and "Action"

    For your selector use: "th:visible:not(.no-col-extended-search)"

    Thanks again, it works nice also.

    +++++++++++++++++++++++++++++++++++++++++

    5./ In the SearchPanes component, the "SKU" and "Qty" columns are missing

    The data is too unique and thus they aren't automatically displaying. Use searchPanes.threshold to adjust.

    Thanks again, it works nice also.

    But I guess it's not really recommended to put 1 for performance reasons, right?

          "config": {
            "buttons": [{
              "extend": "searchPanes",
              "config": {
                "initCollapsed": true,
                "viewTotal": true,
                "columns": "th:visible:not(.no-col-extended-search)",
                "threshold": 1,
              }
            }]
          }
    

    +++++++++++++++++++++++++++++++++++++++++

    6./ Would it be possible to have an option to reset the columnControl component's search field via the ESC keyboard key?

    Nice idea. I'll consider that for a future release - thanks.

    Thanks. let me know if you want more ideas :)

    +++++++++++++++++++++++++++++++++++++++++

    7./ Problem when refreshing DataTables when deleting a row

    The fix is in. I'd suggest trying the nightly build to make sure it works for you. It should.

    I will try it, thanks.

    +++++++++++++++++++++++++++++++++++++++++

    Every time I use this component and delve into the documentation, I discover new things.
    It's truly great work you've done over the years, and I really thank you for that.

    Here is the link to the new, corrected and improved version:

    https://live.datatables.net/qawanune/1/edit

    Only a small correction is missing for point 2 ;)

    2./ Avoid being able to move columns by dragging and dropping cells in row

    Thank you very much for your help and for taking the time to answer me.

    Lolo

  • allanallan Posts: 65,162Questions: 1Answers: 10,796 Site admin

    Hi Lolo,

    Regarding the SVG image, are you looking for that to be in the export data? Buttons will strip HTML by default on export. You can use stripHtml of the exportOptions for the button to stop it doing that if you want the XML of the SVG in the output.

    Buttons does not currently support image export.

    Allan

  • sloloslolo Posts: 117Questions: 24Answers: 2

    Hi @allan,

    1./ Avoid exporting specific columns

    Regarding the SVG image, are you looking for that to be in the export data? Buttons will strip HTML by default on export.

    No, in fact I just want to export the text of the barcode.

    <svg class="barcode" jsbarcode-format="ean13" jsbarcode-value="1122334455666" width="95px" height="39px" x="0px" y="0px" viewBox="0 0 95 39" xmlns="http://www.w3.org/2000/svg" version="1.1" style="transform: translate(0,0)">
        <rect x="0" y="0" width="95" height="39" style="fill:#ffffff;"/>
        <g transform="translate(0, 0)" style="fill:#000000;">
            <rect x="0" y="0" width="1" height="25"/>
            <rect x="2" y="0" width="1" height="25"/>
            ...
            <rect x="92" y="0" width="1" height="25"/>
            <rect x="94" y="0" width="1" height="25"/>
            <text style="font: 12px monospace" text-anchor="middle" x="47.5" y="39">1122334455666</text>
        </g>
    </svg>
    

    In this example, I would like to export only: 1122334455666

    I managed to compensate for the SVG and input type="text" issue by adding an invisible span (see below).

    <span class="invisible">1122334455666</span>

    Do you think this is a good practice, or is there a cleaner way?

    Suggestion: Do you think it might be a good addition to support something like a new data-export property that would be used as data when exporting (like what already exists for data-filter, data-search, ...):

    data-export="1122334455666"

    +++++++++++++++++++++++++++++++++++++++++

    I took the opportunity to correct my export options to exclude certain columns as you explained to me above :)

     "exportOptions": {
            "columns": "th:visible:not(.no-col-exportable, .no-col-printable)",
    

    However, it seems that the copy/export operation doesn't exclude the row with the filters. In fact, there's a blank row between the header row and the first row of the table.

    Is this normal?

    +++++++++++++++++++++++++++++++++++++++++

    You can access to the new test case here:
    https://live.datatables.net/kayovago/1/edit

  • kthorngrenkthorngren Posts: 22,286Questions: 26Answers: 5,125

    In this example, I would like to export only: 1122334455666

    The exported data can be manipulated by using a formatting function. See this example.

    However, it seems that the copy/export operation doesn't exclude the row with the filters. In fact, there's a blank row between the header row and the first row of the table.

    You can control which header rows are exported. See this example.

    Kevin

  • sloloslolo Posts: 117Questions: 24Answers: 2

    Hi @kthorngren,

    You can control which header rows are exported. See this example.

    It works very well, thanks for the tip :)

    +++++++++++++++++++++++++++++++++++++++++

    The exported data can be manipulated by using a formatting function. See this example.

    You are right, but my export is completely broken without setting up a cleanup with "complex" logic based on certain columns.

    Before:

    id  Name    E-mail  Date    SKU Qty Code
    00001   Name 1  email1@domain.com   2025-09-01  1122334455666   1   123
    00002   Name 2  email2@domain.com   2025-08-05  6655443322116   3   456
    

    After:

    id  Name    E-mail  Date    SKU Qty Code
    00001   Name 1  <a href="mailto:#">email1@domain.com</a>    2025-09-01  <svg class="barcode" jsbarcode-format="ean13" jsbarcode-value="1122334455666"></svg>
                      <span class="invisible">1122334455666</span>  <input type="text" value="1" class="form-control form-control-inline form-control-sm numericInput">
                      <span class="invisible">1</span>  <span class="badge badge-primary">123</span>
    00002   Name 2  <a href="mailto:#">email2@domain.com</a>    2025-08-05  <svg class="barcode" jsbarcode-format="ean13" jsbarcode-value="6655443322116"></svg>
                      <span class="invisible">6655443322116</span>  <input type="text" value="3" class="form-control form-control-inline form-control-sm numericInput">
                      <span class="invisible">3</span>  <span class="badge badge-danger">456</span>
    

    As you can see the export contains all the HTML and it is even on several lines potentially.

    So to simplify the life of the user of the DataTables component, why not create a new orthogonal value data-export="xxx" which would simply be the value that we want to export?

    You can access to the new test case here:
    https://live.datatables.net/cibusaxe/1/edit

  • allanallan Posts: 65,162Questions: 1Answers: 10,796 Site admin

    You already can use orthogonal data for export. See this example.

    Allan

  • sloloslolo Posts: 117Questions: 24Answers: 2

    Hi @allan,

    You already can use orthogonal data for export. See this example.

    I thought orthogonal data was data in the form data-search="xxx" or data-filter="yyy", data-...

    In the example you're showing me, I need to know in advance the position of the columns whose export values ​​I want to modify.

    However, in my use case, I have a main function that will initialize ALL my DataTables, and it has no knowledge of the columns (and therefore of the "column": [{ data: 'name' }, ...] object).

    That's why I often use classes to configure my DataTables (hide columns, ...) in conjunction with the "columnDefs" property: [...] because they are already placed on my HTML tables before calling the $("#mytable").Datatable(tableOptions); method.

    As a result, I never use the "columns": [] property, and that would require me to rewrite a lot of code.

    Afterwards, if I have no other choice, I will...

  • kthorngrenkthorngren Posts: 22,286Questions: 26Answers: 5,125
    edited September 27 Answer ✓

    As Allan mentioned use the solution shown in the orthogonal example. Set the orthogonal option to use search or one of the other supported HTML5 data attributes. For example:

        {
          "extend": "copyHtml5",
          "exportOptions": {
            "orthogonal": "search",
            "columns": "th:visible:not(.no-col-exportable, .no-col-printable)",
            "rows": ":visible",
            "format": exportOptionsFormatter,
            "customizeData" : exportCustomizeData,
          }
        },
    

    Results:

    Test
    
    id  Name    E-mail  Date    SKU Qty Code
    00001   Name 1  email1@domain.com   2025-09-01  1122334455666   1   123
    00002   Name 2  email2@domain.com   2025-08-05  6655443322116   3   456
    

    Updated test case:
    https://live.datatables.net/cibusaxe/2/edit

    If all of your exportOptions are the same you could make it a variable so you only need to update it in one place.

    Kevin

  • sloloslolo Posts: 117Questions: 24Answers: 2

    Thank you both so much @allan and @kthorngren

    You've been a tremendous help to me.
    I also hope my example can be useful to others, as it has the advantage of being very comprehensive and covering various DataTables concepts.

    Now, I'll implement this in my code.

    Have a nice day.

    Lolo

Sign In or Register to comment.