Right way to connect Editor instance with Datatable instance in an Vue 3 (typescript) component?

Right way to connect Editor instance with Datatable instance in an Vue 3 (typescript) component?

eugenokeugenok Posts: 15Questions: 3Answers: 0
edited March 2023 in Free community support

Editor version - 2.1.2.

The Datatable's instance is working, Editor's instance is invoked by the "action" action.
But there is no connection between Editor and Datatable instances. An extended button ({ extend: 'create', text: 'New' }) is showing in UI (so that probably means that configuration is like good).

But after I have got the error message:

dataTables.editor.mjs:6354 Uncaught TypeError: Cannot read properties of null (reading 'one')

source code of the error:

var _buttons = $.fn.dataTable.ext.buttons;
$.extend(_buttons, {
    create: {
        action: function (e, dt, node, config) {
            var that = this;
            var editor = config.editor;
            this.processing(true);
            editor 
                .one

so that means that the editor variable is empty.

Also it is impossible to setup editor in the extended button, like usual,
for example { extend: 'create', text: 'New', editor: editorInstance }, because of absence of such a property (editor:).

What is the right way to initialize datatable and its editor? Is it enough to set editor.table property with the table id attribute?

Regards,
Eugene.


Component's code:

<script lang="ts">

import { computed, defineComponent, ref } from 'vue';

import DataTable from 'datatables.net-vue3';
import DataTablesLib from 'datatables.net';
import Editor from 'datatables.net-editor';
import Buttons from 'datatables.net-buttons';

DataTable.use(DataTablesLib);

const table = ref();

export default defineComponent({
  components: {
    DataTable, Editor, Buttons
  },
  setup(props, context) {
    const editor = new Editor({
      table: table.value,
      fields: [{
        label: "email:",
        name: "email"
      }
      ]
    });

    return {
      editor
    }
  },
  data() {
    return {
      columns: [
        {
          data: 'email'
        },
      ],
      data: [{ email: 'test1' }, { email: 'test2' }, { email: 'test3' }]
    };
  },
  mounted() {
    this.editor.table = table.value;
  },
  methods: {
    action() {
      alert(12)
      this.editor
        .title('Add new record')
        .buttons('Save')
        .create();
    }
  }
})

</script>

<template>
  <DataTable id="table" class="display nowrap" 
    :columns="columns" 
    :data="data" 
    :options="{
    dom: 'B',
    buttons: [
      { text: 'test', action: action },
      { extend: 'create', text: 'New' }
    ]
  }" />
</template>

<style>
@import 'datatables.net-buttons-bs5';
@import 'datatables.net-responsive-bs5';
@import 'datatables.net-select-bs5';
@import 'datatables.net-dt';
</style>

Edited by Allan - Syntax highlighting. Details on how to highlight code using markdown can be found in this guide.

Answers

  • kthorngrenkthorngren Posts: 21,328Questions: 26Answers: 4,949

    When creating Editor buttons you need to use the editor option to point to the Editor instance variable. See this example.

    Kevin

  • eugenokeugenok Posts: 15Questions: 3Answers: 0

    Thanks Kevin, but I had already tried that before and there is a type error in that case...
    There is no options for in the "interface ButtonConfig extends ButtonConfigCommon" of inode_modules/datatables.net-buttons/types/types.d.ts, only this is present:
    extend?: string;

  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin

    What versions of Editor and Buttons are you using there? The most recent release should fix that specific issue.

    Allan

  • eugenokeugenok Posts: 15Questions: 3Answers: 0

    Hi, Allan, hope all versions are like the latest one:

    Editor version - 2.1.2.

    Datatables dependencies here:

      "dependencies": {
        "@popperjs/core": "^2.11.6",
        "axios": "^1.2.6",
        "bootstrap": "^5.2.3",
        "datatables.net-autofill-bs5": "^2.5.1",
        "datatables.net-bs5": "^1.13.1",
        "datatables.net-buttons": "^2.3.6",
        "datatables.net-buttons-bs5": "^2.3.3",
        "datatables.net-colreorder-bs5": "^1.6.1",
        "datatables.net-datetime": "^1.2.0",
        "datatables.net-dt": "^1.13.4",
        "datatables.net-editor": "^2.1.0",
        "datatables.net-editor-dt": "^2.0.3",
        "datatables.net-fixedcolumns-bs5": "^4.2.1",
        "datatables.net-fixedheader-bs5": "^3.3.1",
        "datatables.net-keytable-bs5": "^2.8.0",
        "datatables.net-responsive-bs5": "^2.4.0",
        "datatables.net-rowgroup-bs5": "^1.3.0",
        "datatables.net-rowreorder-bs5": "^1.3.1",
        "datatables.net-scroller-bs5": "^2.1.0",
        "datatables.net-searchbuilder-bs5": "^1.4.0",
        "datatables.net-searchpanes-bs5": "^2.1.0",
        "datatables.net-select-bs5": "^1.5.0",
        "datatables.net-select-dt": "^1.5.0",
        "datatables.net-staterestore-bs5": "^1.2.0",
        "datatables.net-vue3": "^2.0.0",
        "focus-visible": "^5.2.0",
        "jquery": "^3.6.4",
        "pinia": "^2.0.28",
        "vue": "^3.2.45",
        "vue-plugin-load-script": "^2.1.1",
        "vue-router": "^4.1.6"
      },
    

    Eugene

  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin

    You might need to update DataTables there. 1.13.4 is the current release.

    Allan

  • eugenokeugenok Posts: 15Questions: 3Answers: 0

    Hi, so I tried again.

    I took this like a start point:
    https://stackblitz.com/edit/datatables-net-vue3-extensions-rpccit?file=src%2FApp.vue

    Have repeated it like the new clean vue 3 project.
    Changing version "datatables.net-dt": "^1.13.1" to "datatables.net-dt": "^1.13.4".
    Datatables works perfect.

    After, had added Editor in the App
    (after "npm i", the license part was installed with install.js script).

    And now I got the error immediately after start (npm run dev):

    ➜ Local: http://localhost:5173/
    ➜ Network: use --host to expose
    ➜ press h to show help
    ✘ [ERROR] Cannot assign to import "$"
    node_modules/datatables.net-editor/js/dataTables.editor.mjs:3220:8:
    3220 │ $ = jq;
    ╵ ^

    Imports are immutable in JavaScript. To modify the value of this import, you must export a setter
    function in the imported file (e.g. "set$") and then import and call that function here instead.


    Eugene

    <script setup lang="ts">
    import { computed, defineComponent, ref } from 'vue';
    import DataTable from 'datatables.net-vue3';
    import DataTablesLib from 'datatables.net';
    import 'datatables.net-select';
    import 'datatables.net-buttons';
    import 'datatables.net-buttons/js/buttons.html5';
    import Editor from 'datatables.net-editor';
    
    DataTable.use(DataTablesLib);
    
    
    
    const columns = [
      { data: 'name' },
      { data: 'position' },
      { data: 'office' },
      { data: 'extn' },
      { data: 'start_date' },
      { data: 'salary' },
    ];
    
    const table = ref();
    
    const editor = new Editor({
          table: '#table',
          // table: table,
          fields: [{
            label: "email:",
            name: "email"
          }
          ]
        });
    
    const options = {
      dom: 'Bftip',
      select: true,
      buttons: [{text: 'test', action: function() {
        editor
        .title( 'Add new record' )
        .buttons( 'Save' )
        .create();
      }}, 
        {extends: 'create', text: 'new', editor: editor}]
    };
    
    </script>
    
    <template>
      <div>
        <h1>DataTables extensions</h1>
        <h2>DataTables + Vue3 example</h2>
        <p>
          This example demonstrates how DataTables' extensions can be used with
          Vue3. The key is to import and then register them with the
          <code>DataTable.use()</code> method. They can then be used as a regular
          DataTable extension. In this example I demonstrate Select and Buttons
          being loaded in.
        </p>
    
        <DataTable
          id="table"
          ref="table"
          :columns="columns"
          :options="options"
    
          ajax="/data.json"
          class="display"
          width="100%"
        >
          <thead>
            <tr>
              <th>Name</th>
              <th>Position</th>
              <th>Office</th>
              <th>Extn.</th>
              <th>Start date</th>
              <th>Salary</th>
            </tr>
          </thead>
          <tfoot>
            <tr>
              <th>Name</th>
              <th>Position</th>
              <th>Office</th>
              <th>Extn.</th>
              <th>Start date</th>
              <th>Salary</th>
            </tr>
          </tfoot>
        </DataTable>
      </div>
    </template>
    
    <style>
    @import 'datatables.net-dt';
    @import 'datatables.net-editor-dt';
    @import 'datatables.net-buttons-dt';
    @import 'datatables.net-select-dt';
    </style>
    
    
  • eugenokeugenok Posts: 15Questions: 3Answers: 0
    edited March 2023

    A little fix:

    const editor = new Editor({
      table: '#table',
      idSrc:  'id',
      fields: [{
        label: "id:",
        name: "id"
      },
      {
        label: "name:",
        name: "name"
      }
      ]
    });
    

    it was wrong field name.

    And after just commented out this line:
    //$ = jq;
    in node_modules/datatables.net-editor/js/dataTables.editor.mjs:3220:8:

    the Test button started to work for creating new records in the table. The New button still do nothing.

  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin

    You are absolutely right about the $ = jq part - that is wrong and I'll get that patched.

    Are you able to give me a link to a page showing the error with the New button not working? The code above looks okay.

    Allan

  • eugenokeugenok Posts: 15Questions: 3Answers: 0

    For now it gives nothing in console output. There are no any messages, there are no any errors...

    Eugene

  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin

    I'd need a link to the page page. If the button is doing nothing it suggests that there is no event handler on it (replaced DOM?) or there is something blocking it.

    Allan

  • eugenokeugenok Posts: 15Questions: 3Answers: 0

    Oh, have no time to give you the link to an external resource... But do you want to say that in your environment extended buttons are working correctly (with this code example)?

    Eugene

  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin

    Hi Eugene,

    Yes. I have bypassed the error you are seeing with $ as well but otherwise it looks okay. If you create a simple button:

    {
      text: 'Test',
      action: function () {
        console.log('Test button pressed');
      }
    }
    

    does that work okay?

    Allan

  • eugenokeugenok Posts: 15Questions: 3Answers: 0

    Yes, Allan, custom actions are working.

    I have even tried to use editor api in it, and it works, I mean create/edit/remove, but only with static json data (serverside: false), and not with ajax request (serverside: true), but probably this is another story...

    Eugene.

  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin

    Hi Eugene,

    If that works, then I'd expect the Editor button to work as well. As I say, I'm afraid that if you'd like a hand with this one, I'd need to be able to access a page that demonstrates the issue so I can debug it.

    Allan

  • eugenokeugenok Posts: 15Questions: 3Answers: 0

    Hi Allan, I have found some workaround, and now I can use custom actions for CRUD with "serverside: true", just added Ajax function in the Editor config, like this:

    let editor = new Editor({
      table: '#table',
      ajax: function (method: any, url: any, data: any, success: any, error: any) {
        DataService.getUserRoleRightList(data).then((d: any) => { success(d.data) });
      },
    

    The Edit button example (where linking is happen explicitly):

    {
      text: 'Edit', action: function () {
        editor
          .title('Edit record')
          .buttons('Save')
          .edit(
            table.value.dt.rows({ selected: true }).indexes()
          );
      }
    },
    

    Extended buttons don't work and as I think it is still looks like there is no connection between the Table and Editor instances.

    Could you please show your working code with the extended buttons?
    Probably it is connected with Vue's component initialization sequence.

Sign In or Register to comment.