Custom Buttons

Custom Buttons

reidevelopmentreidevelopment Posts: 12Questions: 4Answers: 0

Description of problem: I have a two step editing process. The user can edit rows in the table as they wish. When they have finished editing a row and want to synch that row to the cloud repository, they can click a synch button instead of the regular Save button. I have figured out how to create a custom button and I have the event object when clicked, but I can't seem to identify which row is being edited when the button is pressed.

Would it be better to create a field in the table that they could check when they are ready for the data to be sent to the cloud?

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 21,184Questions: 26Answers: 4,925

    See if this Delegated events example helps. If not please post the code you are trying to use for this so we can see what you are attempting.

    Kevin

  • reidevelopmentreidevelopment Posts: 12Questions: 4Answers: 0

    I tried using the code and couldn't get the data. On my datatable, I have a Edit Pencil button that the user clicks to open a custom form template editing window. I have two buttons, Synch and Update. The Update event works to update the data in the HTML form. I also can get the event from the Synch button click. I have used:

    table.rows({selected}).data() and table.rows(this).data() to get the data and what is returned is a large object named B. If I use the example to assign a variable data to the table.rows(this).data() and then use data[0] or data[1], I get undefined.

  • kthorngrenkthorngren Posts: 21,184Questions: 26Answers: 4,925
    edited November 2022

    I'm guessing the problem is you are trying to use data[0], which is for arrays, but you have objects. So you will want to address the particular objects you want. Again if you need further help please post the code you are trying, along with the Datatables init code. This will help us understand what you have. Better is a link to your page are a test case replicating the issue so we can help debug.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • reidevelopmentreidevelopment Posts: 12Questions: 4Answers: 0

    Here is my GetCatalog() function. It draws the table and editor and creates event handlers:


    function GetCatalog() { console.log('Getting Catalog'); pnp.sp.web.lists .getById(config.ListId) .items.select(FPCATALOGFIELDS.join(',')) .filter('ReviewRequired eq 1') .orderBy('PartNumber', false) .get() .then((d) => { console.log('data: ', d); let editor = new $.fn.dataTable.Editor({ destroy: true, data: d, template: '#customform', table: '#catalog', idSrc: 'Title', fields: [ { name: 'PartNumber', label: 'Part Number', type: 'readonly' }, { name: 'Rev', label: 'Rev', type: 'readonly' }, { name: 'Description', label: 'Description', type: 'readonly' }, { name: 'Group', label: 'Group', type: 'readonly' }, { name: 'HarmonizationCode', label: 'Harmonization Code', render: (d, t, r) => (d == null ? '' : d) }, { name: 'CountryOfOrigin', label: 'Country Of Origin', render: (d, t, r) => (d == null ? '' : d) }, { name: 'Length', label: 'Length' }, { name: 'Width', label: 'Width' }, { name: 'Height', label: 'Height' }, { name: 'PackageTypeLookup', label: 'Package Type', type: 'select', options: config.PackageTypes.map((a) => { return { label: a.Description, value: a.Description }; }) }, { name: 'BulkPackLength', label: 'Length' }, { name: 'BulkPackWidth', label: 'Width' }, { name: 'BulkPackHeight', label: 'Height' }, { name: 'BulkPackPackageTypeLookup', label: 'Package Type', type: 'select', options: config.PackageTypes.map((a) => { return { label: a.Description, value: a.Description }; }) }, { name: 'L2BulkPackLength', label: 'Length' }, { name: 'L2BulkPackWidth', label: 'Width' }, { name: 'L2BulkPackHeight', label: 'Height' }, { name: 'L2BulkPackPackageTypeLookup', label: 'Package Type', type: 'select', options: config.PackageTypes.map((a) => { return { label: a.Description, value: a.Description }; }) }, { name: 'MakeBulkPackLeftOver', label: 'Make Bulk Pack Left Over', type: 'select', options: [ { label: '', value: '' }, { label: 'Yes', value: '1' }, { label: 'No', value: '0' } ] } ] }); const table = $('#catalog').DataTable({ dom: 'Bfrtip', destroy: true, data: d, info: true, paging: true, ordering: true, pageLength: 50, columns: [ { orderable: false, data: null, title: 'Edit', className: 'dt-center pointer editor-edit', defaultContent: '<i class="fa fa-pencil" />' }, { orderable: false, data: null, title: '', className: 'dt-center pointer dt-control', defaultContent: '' }, { data: 'PartNumber' }, { data: 'Rev' }, { data: 'Description' }, { data: 'Group', className: 'dt-center' }, { data: 'HarmonizationCode', className: 'dt-center' }, { data: 'CountryOfOrigin', type: 'string' } ], buttons: [] }); $('#catalog').on('click', 'td.editor-edit', function (e) { e.preventDefault(); const tr = $(this).closest('tr'); const row = table.row(tr); if (row.child.isShown()) { row.child.hide(); tr.removeClass('shown'); } editor.edit($(this).closest('tr'), { title: 'Edit Record', buttons: [ { text: 'Update', action: function (e) { this.submit(); }, tabIndex: 1 }, { text: 'Sync to FreightPop', className: 'sync-to-freightpop', action: function (e) { console.log('Sync to FreightPop'); console.log('e:', e); console.log('table.row(this).data():', table.rows(this).data()); console.log('this:', table.rows({ selected: true }).data()); const data = table.rows(this).data(); console.log('data[0]: ', data[0]); console.log('data[1]:', data[1]); }, tabIndex: 0 } ] }); }); // This is executed when the Update button is pressed. // data is the values of the fields on the form editor.on('edit', function (e, json, data, id) { console.log('edit'); console.log('e:', e); console.log('json:', json); console.log('data:', data); console.log('id:', id); console.log('e.id', e.id); const coo = data.CountryOfOrigin; const itemId = data.ID; const title = data.Title; if (data.PackageTypeLookup == 'Select...') data.PackageTypeLookup = ''; if (data.BulkPackPackageTypeLookup == 'Select...') data.BulkPackPackageTypeLookup = ''; if (data.L2BulkPackPackageTypeLookup == 'Select...') data.L2BulkPackPackageTypeLookup = ''; const d = data; DONOTSAVEFIELDS.forEach((f) => { delete d[f]; }); if (d.PackageTypeLookup == '') { d.PackageType = null; } else { const ptype = config.PackageTypes.find( (p) => p.Description == d.PackageTypeLookup ); d.PackageType = ptype.Value; } if (d.BulkPackPackageTypeLookup == '') { d.BulkPackPackageType = null; } else { const ptype = config.PackageTypes.find( (p) => p.Description == d.BulkPackPackageTypeLookup ); d.BulkPackPackageType = ptype.Value; } if (d.L2BulkPackPackageTypeLookup == '') { d.L2BulkPackPackageType = null; } else { const ptype = config.PackageTypes.find( (p) => p.Description == d.L2BulkPackPackageTypeLookup ); d.L2BulkPackPackageType = ptype.Value; } const keys = Object.keys(d); keys.forEach((i) => (d[i] == '' ? (d[i] = null) : null)); //keys.forEach((i) => delete d[i]); //delete d.__metadata; //d.CountryOfOrigin = 'USA'; //d.HarmonizationCode = '2312.323.3213'; //d.Length = null; console.log('d: ', d); pnp.sp.web.lists .getByTitle('Freight Pop Catalog') .items.getById(itemId) .update(d) .then((results) => console.log('Results of update:', results)); }); editor.on('initSubmit', function (e, action) { console.log('initSubmit'); console.log('e:', e); console.log('action:', action); }); $('#catalog tbody').on('click', 'td.dt-control', function () { const tr = $(this).closest('tr'); const row = table.row(tr); if (row.child.isShown()) { row.child.hide(); tr.removeClass('shown'); } else { row.child(RenderMeasurementsRow(row.data())).show(); tr.addClass('shown'); } }); }); }
  • reidevelopmentreidevelopment Posts: 12Questions: 4Answers: 0

    there is a lot of console.log entries so I can see what is present

  • kthorngrenkthorngren Posts: 21,184Questions: 26Answers: 4,925

    What part if this code is not working as expected? Without no test case its difficult to understand the logic and expectations when a lot of code is posted. Please provide details, line numbers, if wat you are trying to do, what the actual result is and what you are expecting to be different.

    Kevin

  • reidevelopmentreidevelopment Posts: 12Questions: 4Answers: 0

    The part I am having problems with is the code below. I am creating a custom button on the custom form template. When clicked, it executes the action part. I am attempting to get access to the data for the results of the edit.

            editor.edit($(this).closest('tr'), {
              title: 'Edit Record',
              buttons: [
                {
                  text: 'Update',
                  action: function (e) {
                    this.submit();
                  },
                  tabIndex: 1
                },
                {
                  text: 'Sync to FreightPop',
                  className: 'sync-to-freightpop',
                  action: function (e) {
                    console.log('Sync to FreightPop');
                    console.log('e:', e);
                    console.log('table.row(this).data():', table.rows(this).data());
                    console.log('this:', table.rows({ selected: true }).data());
                    const data = table.rows(this).data();
                    console.log('data[0]: ', data[0]);
                    console.log('data[1]:', data[1]);
                  },
                  tabIndex: 0
                }
              ]
            });
    

    When the Update button is selected, I call this.submit() and that then executes the

    editor.on('edit', function (e, json, data, id)
    

    function. That has worked. What the Sync button should do is set a flag so I can execute another method that sends the data to the cloud.

    I don't know how to illustrate that any more than I have.

  • kthorngrenkthorngren Posts: 21,184Questions: 26Answers: 4,925
    edited November 2022 Answer ✓

    I don't know how to illustrate that any more than I have.

    This helps. As you can imagine its difficult, with all the Datatables and Editor options available to dig through over 200 lines of code to try and understand someone else's solution :smile:

    I'm not an Editor expert but my understanding is the action object buttons() API uses this to provide access to the Editor API. Maybe you can use get() to get the row data then send it to the cloud.

    Additionally with the submit() method you might want to keep the form open after the submit. Also you might optionally want to disable the syn button until the edited data has been successfully submitted.

    I built a simple example to demo this with your code example:
    http://live.datatables.net/guwafemu/309/edit

    Just click on the Name column to bring up the form.

    Someone else may post a better way of doing this.

    Kevin

  • reidevelopmentreidevelopment Posts: 12Questions: 4Answers: 0

    the this.get() method actually returned all of the form data. I did not know about that method. Thanks. This gives me all the data I need to send it to the cloud. I appreciate all your help.

Sign In or Register to comment.