Prevent multiple form submission on table row actions

This disables any table row actions that do a form submit after an
action is taken and the form is being submitted. It also changes the
cursor to make it clear an action is taking place.

Closes-Bug: #1433849
Change-Id: I004f0ae43e5201eba30ff38a34be680416407fbc
This commit is contained in:
Justin Pomeroy 2015-06-02 09:21:42 -05:00
parent d645696f14
commit ea2f6b35da
2 changed files with 33 additions and 2 deletions

View File

@ -7,10 +7,15 @@ horizon.datatables = {
if ( rows_to_update > 0 ) {
var interval = $rows_to_update.attr('data-update-interval'),
$table = $rows_to_update.closest('table'),
submit_in_progress = $table.closest('form').attr('data-submitted'),
decay_constant = $table.attr('decay_constant');
// Do not update this row if the action column is expanded
if ($rows_to_update.find('.actions_column .btn-group.open').length) {
// Do not update this row if the action column is expanded or the form
// is in the process of being submitted. If we update the row while the
// form is still submitting any disabled action buttons would potentially
// be enabled again, allowing for multiple form submits.
if ($rows_to_update.find('.actions_column .btn-group.open').length ||
submit_in_progress) {
// Wait and try to update again in next interval instead
setTimeout(horizon.datatables.update, interval);
// Remove interval decay, since this will not hit server
@ -170,6 +175,24 @@ horizon.datatables = {
initialize_table_tooltips: function() {
$('div.table_wrapper').tooltip({selector: '[data-toggle="tooltip"]', container: 'body'});
},
disable_actions_on_submit: function($form) {
// This applies changes to the table form when a user takes an action that
// submits the form. It relies on the form being re-rendered after the
// submit is completed to remove these changes.
$form = $form || $(".table_wrapper > form");
$form.on("submit", function () {
// Add the 'submitted' flag to the form so the row update interval knows
// not to update the row and therefore re-enable the actions that we are
// disabling here.
$(this).attr('data-submitted', 'true');
// Disable row action buttons. This prevents multiple form submission.
$(this).find('td.actions_column button[type="submit"]').addClass("disabled");
// Use CSS to update the cursor so it's very clear that an action is
// in progress.
$(this).addClass('wait');
});
}
};
@ -561,6 +584,7 @@ horizon.addInitFunction(horizon.datatables.init = function() {
horizon.datatables.set_table_sorting($('body'));
horizon.datatables.set_table_query_filter($('body'));
horizon.datatables.set_table_fixed_filter($('body'));
horizon.datatables.disable_actions_on_submit();
// Also apply on tables in modal views.
horizon.modals.addModalInitFunction(horizon.datatables.add_table_checkboxes);
@ -568,6 +592,7 @@ horizon.addInitFunction(horizon.datatables.init = function() {
horizon.modals.addModalInitFunction(horizon.datatables.set_table_query_filter);
horizon.modals.addModalInitFunction(horizon.datatables.set_table_fixed_filter);
horizon.modals.addModalInitFunction(horizon.datatables.initialize_table_tooltips);
horizon.modals.addModalInitFunction(horizon.datatables.disable_actions_on_submit);
// Also apply on tables in tabs views for lazy-loaded data.
horizon.tabs.addTabLoadFunction(horizon.datatables.add_table_checkboxes);
@ -578,6 +603,7 @@ horizon.addInitFunction(horizon.datatables.init = function() {
horizon.tabs.addTabLoadFunction(horizon.datatables.initialize_table_tooltips);
horizon.tabs.addTabLoadFunction(function(tab) {
horizon.datatables.validate_button($(tab).find(".table_wrapper > form"));
horizon.datatables.disable_actions_on_submit($(tab).find(".table_wrapper > form"));
});
horizon.datatables.update();

View File

@ -217,6 +217,11 @@ a.current_item:hover h4 {
padding: 0 0 0 1px;
}
.table_wrapper > form.wait,
.table_wrapper > form.wait * {
cursor: wait !important;
}
.table-bordered {
border: none;
}