Leave the editor window open after creating a row and do not reset the form

Leave the editor window open after creating a row and do not reset the form

av-technikav-technik Posts: 6Questions: 2Answers: 0

Hello,

I would like to have the possibility to insert several entries with similar content one after the other.
For this I wanted to replace the "Create" button with two buttons: "Create" and "Create and close".
The "Create" button should create an entry but leave the form open so that I can adjust the contents of the form to create another entry.
However, with my current code there is still the problem that the form is reset after creating. Is there a way that this does not happen?

new $.fn.dataTable.Buttons(table, [
    {
        extend: 'create',
        editor: editor,
        formButtons: [
            {
                text: 'Create and close',
                className: 'btn-primary',
                action: function () {
                    this.submit();
                },
            },
            {
                text: 'Create',
                className: 'btn-secondary',
                action: function () {
                    const that = this;

                    this.submit(function () {
                        that.create();
                    }, null, null, false);
                },
            },
        ],
    },
    { extend: 'edit',   editor: editor },
    { extend: 'remove', editor: editor },
]);

Answers

  • allanallan Posts: 63,523Questions: 1Answers: 10,473 Site admin
    edited June 2023

    create() will clear out the form values and set them to the defined default (or empty if no value defined). This is by design.

    If you want to keep the previous values, you could copy them and then apply them back - e.g.:

    let values = this.val();
    this.submit(
      () => {
        this.create();
        this.val(values);
      },
      null,
      null,
      false
    );
    

    Allan

  • av-technikav-technik Posts: 6Questions: 2Answers: 0

    Unfortunately, this code still resets the form. I also tried to chain the two functions "create" and "val", here unfortunately the same result.
    Also trying to put the val function into a setTimeout didn't work (but I wouldn't prefer that anyway).

  • av-technikav-technik Posts: 6Questions: 2Answers: 0

    @allan Any update on this?

  • Aryan1703Aryan1703 Posts: 77Questions: 20Answers: 1

    Are you inserting same values for every entry?

  • av-technikav-technik Posts: 6Questions: 2Answers: 0

    @Aryan1703
    Almost, I would like to enter all values once and create the entry. Then I want to be able to adjust individual values and save them again.
    The project is a hardware inventory. For example, I would like to add 10 monitors. All data is basically identical, only the inventory number and serial number are different. I would just change these briefly and create the next entry.

  • Aryan1703Aryan1703 Posts: 77Questions: 20Answers: 1

    If you would like to create same entries You can optionally pass the first parameter of .create() as a row count to make it create multiple new rows. So: in my case I wanted to create 15 duplicated entries.

     editor
                        .create(15, false, {
                            title: 'Create Entry',
                            buttons: 'Add',
                            formOptions: {
                                main: {
                                    onSubmit: function (e, action) {
                                        action.submit();
                                    }
                                }
                            }
                        })
    
  • av-technikav-technik Posts: 6Questions: 2Answers: 0

    @Aryan1703
    Good advice, but unfortunately it won't help me.
    I don't want to create the same entry several times, but a slightly different entry each time. There are some fields that are required and unique.

  • rf1234rf1234 Posts: 3,000Questions: 87Answers: 421
    edited May 21

    Here is my duplicate button. That should do the trick. You select a record that you want to duplicate and the form gets populated with the selected record. Then you can modify the data and save the new record. You can repeat that as often as you require. The trick is to start in "edit" mode and then switch to "create" mode.

    The form won't stay open though - as Allan already pointed out. You create a new record, then you will have to select it in order to create the next record and so on. But apart from that this should meet your requirement.

    $.fn.dataTable.ext.buttons.duplicate = {
        extend: "selected",
        text: "Copy & New",
        action: function ( e, dt, node, config ) {
            // Start in edit mode, and then change to create
            editor
                .title($.fn.dataTable.Editor.defaults.i18n.create.title)
                .buttons({
                        label: $.fn.dataTable.Editor.defaults.i18n.create.submit,
                        fn: function () {
                            this.submit();
                        }
                    })
                .edit( dt.rows( {selected: true} ).indexes() )
                .mode( 'create' );
        }
    };
    

    I use it here for example:

    buttons: [
        {   extend: "duplicate", editor: yourEditor  },
    
  • allanallan Posts: 63,523Questions: 1Answers: 10,473 Site admin

    Also, checkout the multi-row editing API which can be used to modify a row's value when creating / editing multiple rows at a time.

    Allan

  • Fr0sTFr0sT Posts: 11Questions: 0Answers: 0

    Hi AV-Technik,

    Did you ever figure out how to do your original question? I want to do the exact same thing.
    User clicks add record,
    pop up the create modal and form
    user fills out the form and submits it
    forms stays filled out and visible and the user makes some tweaks and submits again
    rinse repeat.

    I have it all working but the form won't do anything when the submit button is clicked the 2nd time.
    I got it to let me click submit twice and by putting a editor.create(); in submitComplete but after the 2nd submit it closes the modal form and i can't seem to get it to not do that.

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    @Fr0sT This example from this thread should get you going, it's demonstrating just that.

    Colin

  • Fr0sTFr0sT Posts: 11Questions: 0Answers: 0

    awesome, thank you so much Colin!! I'll check it out.

  • Fr0sTFr0sT Posts: 11Questions: 0Answers: 0

    @colin I looked at your example and tried to apply the correct bits of code to my situation and for some reason after the 2nd submit the window closes and the "new" button no longer opens up the create modal. Any ideas where i might look to troubleshoot that?

    Heres my datatable and editor init sections:

    const editor = new DataTable.Editor({
                    ajax: 'adm_pmv2_ajax',
                    idSrc:  'punchID',
                    fields: [
                        {
                            type: "hidden",
                            name: "punchID"
                        },{
                            label: 'Worker:',
                            name: 'workerID',
                            id: 'Employee_Code',
                            type: 'select2',
                            optionsPair: {
                                label: 'label',
                                value: 'value'
                            },
                            options: [
                                {value: workerID, label: 'workerCode workerFirst workerLast'
                            ]
                        },{
                            label: 'Project:',
                            name: 'pid',
                            id: 'Job_ID',
                            type: 'select2',
                            optionsPair: {
                                label: 'label',
                                value: 'value'
                            },
                            placeholder: 'Select Project',
                            options: [
                                {value: pid, label: 'jobID jobDesc'
                            ]
                        },{
                            label: 'Date:',
                            name: 'date',
                            type: 'datetime',
                            format: 'MM-DD-YYYY'
                        },{
                            label: 'Punch Time:',
                            name: 'punchTime',
                            type: 'datetime',
                            format: 'h:mm:ss A'
                        },{
                            label: 'Event:',
                            name: 'event',
                            type: 'select2',
                            optionsPair: {
                                label: 'title',
                                value: 'value'
                            },
                            placeholder: 'Select Event',
                            options: [
                                {value: '', title: ''},
                                {value: 'Clock-In', title: 'Clock-In'},
                                {value: 'Clock-Out', title: 'Clock-Out'}
                            ]
                        },{
                            label: 'Breaks:',
                            name: 'tookBreaks',
                            type: 'select2',
                            optionsPair: {
                                label: 'title',
                                value: 'value'
                            },
                            options: [
                                {value: '', title: ''},
                                {value: 'Yes', title: 'Yes'},
                                {value: 'No', title: 'No'}
                            ]
                        },{
                            label: 'Lunch:',
                            name: 'tookLunch',
                            type: 'select2',
                            opts: '',
                            optionsPair: {
                                label: 'title',
                                value: 'value'
                            },
                            options: [
                                {value: '', title: ''},
                                {value: 'Yes', title: 'Yes'},
                                {value: 'No', title: 'No'}
                            ]
                        },{
                            label: 'From:',
                            name: 'lunchFrom',
                            type: 'datetime',
                            format: 'h:mm A'
                        },{
                            label: 'To:',
                            name: 'lunchTo',
                            type: 'datetime',
                            format: 'h:mm A'
                        },
                    ],
                    table: '#punches'
                });
    
    
    const table = new DataTable('#punches', {
                        fixedHeader: { header: true, headerOffset: 121 },
                        paging: false,
                        responsive: true,
                        ajax: 'adm_pmv2_ajax',
                        columns: [
                            { data: 'punchID'},
                            { 
                                data: null,
                                render: (data) => data.Employee_Code,
                                editField: ['workerID']
                            },
                            { 
                                data: null,
                                render: (data) => data.Job_ID,
                                editField: ['pid']
                            },
                            { data: 'date', className: 'row-edit dt-center'},
                            { data: 'punchTime', className: 'row-edit dt-center'},
                            { data: 'event', className: 'row-edit dt-center'},
                            { data: 'tookBreaks', className: 'row-edit dt-center'},
                            { data: 'tookLunch', className: 'row-edit dt-center'},
                            { data: 'lunchFrom', className: 'row-edit dt-center'},
                            { data: 'lunchTo', className: 'row-edit dt-center'},
                            { data: null,
                                defaultContent:
                                    '<div class="action-buttons">' +
                                    '<span class="edit"><i class="fa fa-pencil"></i></span> ' +
                                    '</div>',
                                className: 'row-edit dt-center',
                                orderable: false
                            },
                            {
                                data: null,
                                defaultContent:
                                    '<div class="action-buttons">' +
                                    '<span class="remove"><i class="fa fa-trash"></i></span> ' +
                                    '</div>',
                                className: 'noEdit row-remove dt-center',
                                orderable: false
                            }
                        ],
                        layout: {
                            topStart: {
                                buttons: [
                                    {
                                        text: 'Sort',
                                        action: function () {
                                            table.order([[1, 'asc'],[3, 'asc'],[5, 'asc']]).draw();
                                        }
                                    },
                                    { 
                                        extend: 'edit', 
                                        editor: editor ,
                                        formOptions: {
                                            submitTrigger: 10,
                                            submitHtml: '<i class="fa fa-floppy-o"></i>',
                                            onBlur: 'submit',
                                            onComplete: 'none'
                                        },
                                    },
                                    { 
                                        extend: 'create',
                                        editor: editor,
                                        formOptions: {
                                            onComplete: 'none'
                                        },
                                        formButtons: [
                                            { label: 'Create',
                                                fn: function() {
                                                    var that = this;
                                                    this.submit(function() {
                                                        that.create();
                                                    });
                                                }
                                            },
                                            { label: 'Clear',
                                                fn: function() {
                                                    this.set({
                                                        workerID: '',
                                                        date: '',
                                                        punchTime: '',
                                                        event: '',
                                                        tookBreaks: '',
                                                        tookLunch: '',
                                                        lunchFrom: '',
                                                        lunchTo: ''
                                                    });
                                                }
                                            },
                                            { text: 'Cancel', action: function () { this.close(); } }
                                        ],
                                    }
                                ]
                            }
                        },
                        order: [[1, 'asc']]
                    });
    
    
    
    
  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    after the 2nd submit the window closes and the "new" button no longer opens up the create modal

    Do you see any console errors when you submit, either the first or second, that suggests a JavaScript error somewhere.

    If not, that's odd, as that code looks very similar to the code I posted. Maybe as an experiment try removing

                                        formOptions: {
                                            onComplete: 'none'
                                        },
    

    and see if that makes a difference (it wasn't in my code).

    Colin

  • Fr0sTFr0sT Posts: 11Questions: 0Answers: 0
    edited June 5

    Do you see any console errors when you submit, either the first or second, that suggests a JavaScript error somewhere.

    No javascript errors after the first or 2nd submission.

    formOptions: {
        onComplete: 'none'
    },
    

    I removed this but now it only allows for the first submit before it closes the modal. Interestingly, after the modal disappears I can no longer click the NEW button to open it back up.

  • Fr0sTFr0sT Posts: 11Questions: 0Answers: 0
    edited June 5

    The only thing i'm noticing in dev tools is under Issues.

    It is clear until I click NEW and the create modal form opens up. At that point I get an incorrect use of <label for=FORM_ELEMENT>. Pointing at a label tag generated by datatables pointing at a hidden pkid i have setup in the main table.

    Lastly as I interact with each form element on create form i get another issue .

  • allanallan Posts: 63,523Questions: 1Answers: 10,473 Site admin

    Leaving the Editor form open will leave it in a "dead state". It won't do anything since it isn't actually in create or edit mode. The onComplete: 'none' instruction means that when editing (or creation) is complete, just leave the modal in place.

    This can be useful if you then want to immediately start a new edit (or create), which you have to do by calling the approriate API method (e.g. edit() or create()).

    There is an example of this here (note I use the fourth parameter of the submit() method to force the modal not to close, rather than onComplete, but the principle is the same.

    Allan

  • Fr0sTFr0sT Posts: 11Questions: 0Answers: 0

    Thanks @allan, i'll take a look into that and see if i can figure it out. Thanks for all the help guys.

  • rf1234rf1234 Posts: 3,000Questions: 87Answers: 421

    Leaving the Editor form open will leave it in a "dead state". It won't do anything since it isn't actually in create or edit mode.

    For that reason I developed my solution above. I think it is fairly intuitive, too. Maybe you can develop something based on that? For example: After the Editor modal closes you programmatically select the record created and open a new Editor modal. This could be done so fast that it seems the modal stayed open all the time from a user perspective.

    I'd be interested in the result if you give that a try, please :smile:

  • rf1234rf1234 Posts: 3,000Questions: 87Answers: 421

    I made an example where it works:
    https://live.datatables.net/lojihopo/1/edit

    Just save the Editor field values before submission and afterwards repopulate the form with the submitted values.

  • rf1234rf1234 Posts: 3,000Questions: 87Answers: 421
    edited June 7

    @av-technik

    I think this code should do the job:

    new $.fn.dataTable.Buttons(table, [
        {
            extend: 'create',
            editor: editor,
            formButtons: [
                {
                    text: 'Create and close',
                    className: 'btn-primary',
                    action: function () {
                        this.submit();
                    },
                },
                {
                    text: 'Create',
                    className: 'btn-secondary',
                    action: function ( e, dt, button, config ) {
                        const that = this;
     
                        this.submit(function () {
                            var fields = that.displayed();
                            var values = [];
                            $.each(fields, function(key, value) {
                              values.push( that.field(value).val() );
                            })
                            that.create();
                            setTimeout(function() {
                               $.each(fields, function(key, value) {
                                  that.field(value).val(values[key]);
                               }) 
                             }, 300);
                        });
                    },
                },
            ],
        },
        { extend: 'edit',   editor: editor },
        { extend: 'remove', editor: editor },
    ]);
    
  • Fr0sTFr0sT Posts: 11Questions: 0Answers: 0

    @rf1234 Thank you so much for the code example!! I will give this a try and see if i can get it to work.

  • rf1234rf1234 Posts: 3,000Questions: 87Answers: 421

    In this example I extended the timeout to 500ms. That's pretty neat because the submitted values are actually disappearing for a short glimpse and then show up again. I guess that's a somewhat better user experience: The user can see that something was actually "sent" and then copied. Or whatever :smile:

    https://live.datatables.net/lojihopo/2/

  • Fr0sTFr0sT Posts: 11Questions: 0Answers: 0
    edited June 11

    Thanks for all the help!
    I got it working, but as soon as i include
    <script src="/DataTables/Editor-2.3.2/js/editor.bootstrap4.js" type="text/javascript"></script>

    it breaks.

    Editor-2.3.2/js/editor.bootstrap5.js also breaks it.

  • kthorngrenkthorngren Posts: 21,343Questions: 26Answers: 4,954

    I got it working, but as soon as i include it breaks.

    How does it break?

    Do you get errors in the browser's console?

    Kevin

  • Fr0sTFr0sT Posts: 11Questions: 0Answers: 0

    Sorry for my vagueness. by "breaks" I mean it reverts back to the original problem of only allowing one submission. No errors in console. Works great for the first submission then it closes the create form modal and doesn't open it back up when i click the "new' button again.

  • rf1234rf1234 Posts: 3,000Questions: 87Answers: 421
    edited June 12

    This a modified example.
    https://live.datatables.net/pobexeyu/1/

    I included

    src="/DataTables/Editor-2.3.2/js/editor.bootstrap4.js" type="text/javascript">

    and some CSS libraries that I took from this example
    https://editor.datatables.net/examples/styling/bootstrap4

    Works like a charm :smile:

    You need to post a test case highlighting your problem please

  • Fr0sTFr0sT Posts: 11Questions: 0Answers: 0

    Thanks rf1234, its working great now thank you so much!

Sign In or Register to comment.