Best way to wait for dependent field to load before submitting form?

Best way to wait for dependent field to load before submitting form?

SnacklesSnackles Posts: 33Questions: 8Answers: 0

Hello,

I have some code that exports row(s) of data to a separate database and after updates those row(s) as being "completed" and it works for the most part. To mark these rows as completed, I get the row IDs of the selected rows and open a hidden edit form on them, update the field to be marked as completed, and then submit it.

One of the fields on the form happens to be a dependent cascading type of field, so when a subdepartment is selected a specific list of categories appears. However, I've noticed that the categories field, which is dependent on the subdepartment field, doesn't always load in time before the form is submitted and as a result the row gets updated with an empty categories field.

I've tried a couple things like a setTimeout() function, but that doesn't necessarily wait until the field is loaded; a setInterval() function, which checks if the field is loaded before submitting, but that doesn't seem to work when the form is hidden and if you're using multiSet(); and, I also tried implementing dependent() on the categories field itself with a function that would submit the form, but it ends up messing with some inline editing functionality.

I was wondering what is the most efficient way to have the form wait to submit until the categories field is successfully loaded?

// Filter available categories on subdepartment selection
editorNP.dependent('ProductUpdates.POS_TAB_F04', '/api/Categories');
// Call to the exportItem() function.
exportItem();

// Gather all selected rows.
var rows = table.rows({ selected: true }).indexes();

// If exporting 1 product, use DataTables set method; else, use DataTables multiSet method.
if (rows.length == 1) {

    // Get selected row's id.
    var row = table.row(rows);

    // Open hidden edit form and update fields.
    editorNP.edit(row, false)
        .set('ProductUpdates.completeddate', getDate())
        .set('ProductUpdates.completedby', currentUser)
        .set('ProductUpdates.productstatusID', 4);

    editorNP.submit();

} else {
    // Open hidden edit form and update fields for multiple products.
    editorNP.edit(rows, false);

    // Loop through each product updating fields.
    $.each(rows, function (i, rowIdx) {
        var row = table.row(rowIdx);

        editorNP.field('ProductUpdates.completeddate').multiSet(row.id(), getDate());
        editorNP.field('ProductUpdates.completedby').multiSet(row.id(), currentUser);
        editorNP.field('ProductUpdates.productstatusID').multiSet(row.id(), 4);
    });

    editorNP.submit();
}

This question has an accepted answers - jump to answer

Answers

  • rf1234rf1234 Posts: 2,802Questions: 85Answers: 406

    Something like this might work.

    // Open hidden edit form and update fields for multiple products.
    editorNP.edit(rows, false);
     
    // Loop through each product updating fields.
    var loop = function() {
        $.each(rows, function (i, rowIdx) {
            var row = table.row(rowIdx);
     
            editorNP.field('ProductUpdates.completeddate').multiSet(row.id(), getDate());
            editorNP.field('ProductUpdates.completedby').multiSet(row.id(), currentUser);
            editorNP.field('ProductUpdates.productstatusID').multiSet(row.id(), 4);
        });
    };
    
    
    $.when( loop() ).done(function() {
      editorNP.submit();
    });
    
  • allanallan Posts: 61,635Questions: 1Answers: 10,092 Site admin
    Answer ✓

    I actually thought we had a block for submit while a dependent function was running built into the Editor code. But that doesn't seem to be the case I'm afraid. I've note that to be added.

    I was just looking to see if it is possible to emulate what we'd do internally using the external events, but unfortunately it doesn't appear possible at the moment as there is no callback for when the dependent method ends. What we'd normally do in a case like this is to listen for preSubmit event and if a condition fails (dependent running) cancel the submit and wait until it is finished.

    That is possible at the form level, but not at the field level as the field().processing() option doesn't provide a getter option, and there also isn't a event to indicate the processing state of field (there is processing for the form as a whole though).

    These need to be added before what you are seeing can be addressed - I've marked it for the next release.

    In the meantime there are two options:

    1. Use dependent() with your own functions rather than Editor's built in ones. And you've functions can interact with preSubmit to cancel the submit when needed. This will achieve what you want, but at the code of needing to write more code!
    2. A setTimeout as you say... Sorry.

    Regards,
    Allan

  • SnacklesSnackles Posts: 33Questions: 8Answers: 0

    Thank you rf1234 for the when().done() idea and thank you Allan for looking into it anyway.

    I got something that appears to be working, so I'll go with this for now:

    // Repeating function to check for proper loading of category field before submitting field.
    function checkForCategory(callback, delay, repetitions) {
        var x = 0;
        var intervalID = window.setInterval(function () {
    
            callback();
    
            // If category field is loaded, submit form and clear interval; else, keep looping
            if (editorNP.field('ProductUpdates.OBJ_TAB_F17').val()) {
    
                // Submit form
                editorNP.submit();
    
                // Stop timer
                window.clearInterval(intervalID);
            }
    
            // If function loops repitition times, alert user and cancel function loop
            if (++x === repetitions) {
    
                // Alert user export has failed, because the category didn't load in time.
                alert("Export failed!");
    
                // Close form
                editorNP.close();
    
                // Stop timer
                window.clearInterval(intervalID);
            }
    
        }, delay);
    }
    
    // Gather all selected rows.
    var rows = table.rows({ selected: true }).indexes();
    
    // If exporting 1 product, use DataTables set method; else, use DataTables multiSet method.
    if (rows.length == 1) {
    
        // Get selected row's id.
        var row = table.row(rows);
    
        // Open hidden edit form and update fields.
        editorNP.edit(row, false)
            .set('ProductUpdates.completeddate', getDate())
            .set('ProductUpdates.completedby', currentUser)
            .set('ProductUpdates.productstatusID', 4);
    
        // Function to check if category has loaded every half a second for 30 seconds.
        checkForCategory(function () {}, 500, 60);
    } else {
        // Open hidden edit form and update fields for multiple products.
        editorNP.edit(rows, false);
    
        // Loop through each product updating fields.
        var loop = function () {
            $.each(rows, function (i, rowIdx) {
                var row = table.row(rowIdx);
    
                editorNP.field('ProductUpdates.completeddate').multiSet(row.id(), getDate());
                editorNP.field('ProductUpdates.completedby').multiSet(row.id(), currentUser);
                editorNP.field('ProductUpdates.productstatusID').multiSet(row.id(), 4);
            });
        };
    
        // Loop is complete, submit form.
        $.when(loop()).done(function () {
            editorNP.submit();
        });
    }
    
  • allanallan Posts: 61,635Questions: 1Answers: 10,092 Site admin

    Just to note that the change for this has been committed into Editor now and will be in the upcoming 1.9.5 release.

    Thanks,
    Allan

This discussion has been closed.