Dexie.js IndexDB - Array to Datatables

Dexie.js IndexDB - Array to Datatables

TheProphetTheProphet Posts: 4Questions: 1Answers: 0

Link to test case:
https://codepen.io/TheProphet2024/pen/ZEZWMxG
Debugger code (debug.datatables.net):
None
Error messages shown:
None
Description of problem:

Hi guys,

I'm currently trying to use Dexie.js (indexedDB wrapper) with Datatables. I am trying to pass the IndexedDB as an array to Datatables. Unfortunately the procedure fails because no content is rendered and currently no error is displayed.

HTML

<table id="tablec" class="table table-striped display compact">
  <thead>
    <tr>
      <th>Id</th>
      <th>GZ</th>
      <th>Titel</th>
      <th>Editor</th>
      <th>Editor Two</th>
      <th>Art</th>
      <th>Status</th>
      <th>Target Date</th>
      <th>Cover Gap</th>
    </tr>
  </thead>
  <tbody id="table_current">
  </tbody>
  <tfoot>
    <th>#</th>
    <th>GZ</th>
    <th>Titel</th>
    <th>Editor</th>
    <th>Editor Two</th>
    <th>Art</th>
    <th>Status</th>
    <th>Target Date</th>
    <th>Cover Gap</th>
    </tfood>
</table>

JS

var db = new Dexie("Database");
// DB with single table "procedures" with primary key "id"
db.version(1).stores({
  procedures: `
       ++id,
       gz,
       name,
       editor,
       editortwo,
       type,
       status,
       targetdate,
       covergap`
});

// Now add some values.
db.procedures.bulkPut([
  {
    id: 1,
    gz: "9999",
    name: "test",
    editor: "Max Peter",
    editortwo: "Seb Hosh",
    type: "Type 1",
    status: "Created",
    targetdate: "20.05.2024",
    covergap: "01.06.2024"
  },
  {
    id: 2,
    gz: "9998",
    name: "test #2",
    editor: "Max Koch",
    editortwo: "Nora Bidder",
    type: "Type 2",
    status: "Created",
    targetdate: "20.05.2024",
    covergap: "01.06.2024"
  }
]);

async function getAllProcedures() {
  return await db.procedures.toArray();
}
getAllProcedures().then(console.log);

var data = getAllProcedures();

$("#tablec").DataTable({
  data: data,
  columns: [
    { data: "id" },
    { data: "gz" },
    { data: "name" },
    { data: "editor" },
    { data: "editortwo" },
    { data: "type" },
    { data: "status" },
    { data: "targetdate" },
    { data: "covergap" }
  ],
  initComplete: function () {
    var $table = $("#tablec");
    $table
      .DataTable()
      .columns([3, 4, 5, 6])
      .every(function () {
        var column = this;
        var select = $(
          '<select class="form-control form-control-sm"><option value="">Alle</option></select>'
        )
          .appendTo($(column.footer()).empty())
          .on("change", function () {
            var val = $.fn.dataTable.util.escapeRegex($(this).val());
            column.search(val ? "^" + val + "$" : "", true, false).draw();
          });
        column
          .data()
          .unique()
          .sort()
          .each(function (d, j) {
            select.append(
              '<option value="' + d + '">' + d.substr(0, 30) + "</option>"
            );
          });
      });

    $table
      .DataTable()
      .columns([1, 2, 7, 8])
      .every(function () {
        var that = this;
        var input = $(
          '<input type="text" class="form-control form-control-sm" placeholder="Suche..." />'
        )
          .appendTo($(this.footer()).empty())
          .on("keyup change", function () {
            if (that.search() !== this.value) {
              that.search(this.value).draw();
            }
          });
      });
  },
  language: {
    url: "https://cdn.datatables.net/plug-ins/1.13.7/i18n/de-DE.json"
  },
  columnDefs: [
    {
      targets: [7, 8],
      render: DataTable.render.datetime("DD.MM.YYYY")
    }
  ]
});

What is missing here or have I done it wrong?

This question has accepted answers - jump to:

Answers

  • allanallan Posts: 63,514Questions: 1Answers: 10,472 Site admin

    The result from getAllProcedures() is a Promise and data does not accept a Promise - it expects an array of data.

    What you need to do is use rows.add() to add the rows to the table onces the Promise is resolved. e.g.:

    getAllProcedures().then(function (data) {
      table.rows.add(data).draw();
    });
    

    https://codepen.io/DataTables/pen/abxNRJE

    Allan

  • TheProphetTheProphet Posts: 4Questions: 1Answers: 0

    Hi allan,

    thanks for your quick support. The table is filled with content as expected.
    But the " initComplete" functions with filters no longer appear to be working after the change.

  • allanallan Posts: 63,514Questions: 1Answers: 10,472 Site admin

    The problem is still an async one. What is happening (sometimes, but not always!) is that initComplete is triggering before the table's data is loaded, which means that the column().data() method doesn't have any data to populate the select with.

    Its easy to solve the loading aspect - just initialise the DataTable after the data has loaded: https://codepen.io/DataTables/pen/abxNRJE .

    Your key question following that is, do you need to handle data being loaded after the DataTable has been initialised (i.e. based on user data). If so, then you'll need to rebuilt the select elements as needed.

    Allan

  • TheProphetTheProphet Posts: 4Questions: 1Answers: 0

    Hi allan,

    thank´s again for your support. This is exactly the problem i encountered with the debugger. I have tried to initialise the table after loading the data. However, I failed.
    Have you made any adjustments to Codepen.io?

  • kthorngrenkthorngren Posts: 21,337Questions: 26Answers: 4,954
    Answer ✓

    I don't have a codepen account to save changes. Sounds like what you neeed to do is move the initComplete code to build the select lists into a function then call that function after using rows.add(), for example:

    getAllProcedures().then(function (data) {
      table.rows.add(data).draw();
      buildSearchLists();
    });
    

    Kevin

  • allanallan Posts: 63,514Questions: 1Answers: 10,472 Site admin
    Answer ✓

    Apparently I didn't save it... https://codepen.io/DataTables/pen/abxNRJE .

    I've just moved the DataTables initialisation into the getAllProcedures() promise result function and switched back to using data.

    Allan

  • TheProphetTheProphet Posts: 4Questions: 1Answers: 0

    Hey allan and kthorngren,

    thank you for your hints. Works like a charm.

Sign In or Register to comment.