From 008bed03f6f493e24ae31e347ad4cb5ebcbd79ce Mon Sep 17 00:00:00 2001 From: Yun-En Liu Date: Sun, 30 Aug 2020 09:43:39 -0700 Subject: [PATCH 1/3] Adding a setting to not check form validity before submission (primarily used for async delete action) --- .../static/js/jquery.bootstrap.modal.forms.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bootstrap_modal_forms/static/js/jquery.bootstrap.modal.forms.js b/bootstrap_modal_forms/static/js/jquery.bootstrap.modal.forms.js index c7cdd69..b708e6c 100644 --- a/bootstrap_modal_forms/static/js/jquery.bootstrap.modal.forms.js +++ b/bootstrap_modal_forms/static/js/jquery.bootstrap.modal.forms.js @@ -19,7 +19,12 @@ https://github.com/trco/django-bootstrap-modal-forms var addEventHandlers = function (settings) { // submitBtn click handler $(settings.submitBtn).on("click", function (event) { - isFormValid(settings, submitForm); + if (settings.checkValidBeforeSubmit) { + isFormValid(settings, submitForm); + } + else { + submitForm(settings); + } }); // Modal close handler $(settings.modalID).on("hidden.bs.modal", function (event) { @@ -144,6 +149,7 @@ https://github.com/trco/django-bootstrap-modal-forms formURL: null, errorClass: ".invalid", submitBtn: ".submit-btn", + checkValidBeforeSubmit: true, asyncUpdate: false, asyncSettings: { closeOnSubmit: false, From 009143d00ea750116004a2d846119260e77e3fc2 Mon Sep 17 00:00:00 2001 From: Yun-En Liu Date: Sun, 30 Aug 2020 10:48:31 -0700 Subject: [PATCH 2/3] Adding view, url, templates, and js to include async delete buttons on the books example page --- README.rst | 29 ++++++++++++++++++- examples/templates/_books_table.html | 6 +++- .../templates/examples/delete_book_async.html | 22 ++++++++++++++ examples/templates/index.html | 19 ++++++++++++ examples/urls.py | 1 + examples/views.py | 7 +++++ 6 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 examples/templates/examples/delete_book_async.html diff --git a/README.rst b/README.rst index 185a35a..47ca68f 100644 --- a/README.rst +++ b/README.rst @@ -212,7 +212,7 @@ Add script to the template from #5 and bind the ``modalForm`` to the trigger ele }); -Async create/update with or without modal closing on submit +Async create/update/delete with or without modal closing on submit =========================================================== Set ``asyncUpdate`` and ``asyncSettings`` settings to create or update objects without page redirection to ``successUrl`` and define whether a modal should close or stay opened after form submission. See comments in example below and paragraph **modalForm options** for explanation of ``asyncSettings``. @@ -234,6 +234,10 @@ Set ``asyncUpdate`` and ``asyncSettings`` settings to create or update objects w + + ... @@ -278,6 +282,26 @@ Set ``asyncUpdate`` and ``asyncSettings`` settings to create or update objects w }); } updateBookModalForm(); + + //checking for form validity on delete means submitting the delete form twice, causing an error + function deleteBookModalForm() { + $(".delete-book").each(function () { + $(this).modalForm({ + formURL: $(this).data("form-url"), + asyncUpdate: true, + checkValidBeforeSubmit: false, + asyncSettings: { + closeOnSubmit: false, + successMessage: asyncSuccessMessage, + dataUrl: "books/", + dataElementId: "#books-table", + dataKey: "table", + addModalFormFunction: deleteBookModalForm + } + }); + }); + } + deleteBookModalForm(); ... }); @@ -338,6 +362,9 @@ errorClass submitBtn Sets the custom class for the button triggering form submission in modal. ``Default: ".submit-btn"`` +checkValidBeforeSubmit + Sets whether to check form validity before submitting (set to false for async delete). ``Default: true`` + asyncUpdate Sets asynchronous content update after form submission. ``Default: false`` diff --git a/examples/templates/_books_table.html b/examples/templates/_books_table.html index 2cc41b0..62d60fe 100644 --- a/examples/templates/_books_table.html +++ b/examples/templates/_books_table.html @@ -8,7 +8,7 @@ Publication date Pages Price (€) - Read / Update / Delete + Read / Update / Delete / Async Delete @@ -34,6 +34,10 @@ + + {% endfor %} diff --git a/examples/templates/examples/delete_book_async.html b/examples/templates/examples/delete_book_async.html new file mode 100644 index 0000000..552e06f --- /dev/null +++ b/examples/templates/examples/delete_book_async.html @@ -0,0 +1,22 @@ +{% load widget_tweaks %} + +
+ {% csrf_token %} + + + + + + + +
diff --git a/examples/templates/index.html b/examples/templates/index.html index 3f3e62b..e007e81 100644 --- a/examples/templates/index.html +++ b/examples/templates/index.html @@ -114,6 +114,25 @@

} updateBookModalForm(); + function deleteBookModalForm() { + $(".delete-book-async").each(function () { + $(this).modalForm({ + formURL: $(this).data("form-url"), + asyncUpdate: true, + checkValidBeforeSubmit: false, + asyncSettings: { + closeOnSubmit: true, + successMessage: asyncSuccessMessage, + dataUrl: "books/", + dataElementId: "#books-table", + dataKey: "table", + addModalFormFunction: deleteBookModalForm + } + }); + }); + } + deleteBookModalForm(); + // Read and Delete book buttons open modal with id="modal" // The formURL is retrieved from the data of the element $(".bs-modal").each(function () { diff --git a/examples/urls.py b/examples/urls.py index 8baa565..226685a 100644 --- a/examples/urls.py +++ b/examples/urls.py @@ -10,6 +10,7 @@ path('update/', views.BookUpdateView.as_view(), name='update_book'), path('read/', views.BookReadView.as_view(), name='read_book'), path('delete/', views.BookDeleteView.as_view(), name='delete_book'), + path('delete/async/', views.BookDeleteAsyncView.as_view(), name='delete_book_async'), path('books/', views.books, name='books'), path('signup/', views.SignUpView.as_view(), name='signup'), path('login/', views.CustomLoginView.as_view(), name='login'), diff --git a/examples/views.py b/examples/views.py index ed28746..e9f4cf8 100644 --- a/examples/views.py +++ b/examples/views.py @@ -78,6 +78,13 @@ class BookDeleteView(BSModalDeleteView): success_url = reverse_lazy('index') +class BookDeleteAsyncView(BSModalDeleteView): + model = Book + template_name = 'examples/delete_book_async.html' + success_message = 'Success: Book was deleted.' + success_url = reverse_lazy('index') + + class SignUpView(BSModalCreateView): form_class = CustomUserCreationForm template_name = 'examples/signup.html' From 81843e6eaa76e2994c8ba108913dfcad531b228f Mon Sep 17 00:00:00 2001 From: Yun-En Liu Date: Sun, 30 Aug 2020 11:11:51 -0700 Subject: [PATCH 3/3] Adding functional test for async delete button (book delete, leaves empty table behind). Also added gecko autodriver as a requirement and imported into tests since I got an error about not having geckodriver on path when I followed the instructions --- .../templates/examples/delete_book_async.html | 2 +- examples/templates/index.html | 36 +++++++++------- requirements.txt | 5 ++- tests/tests_functional.py | 43 +++++++++++++++++++ 4 files changed, 69 insertions(+), 17 deletions(-) diff --git a/examples/templates/examples/delete_book_async.html b/examples/templates/examples/delete_book_async.html index 552e06f..af7c1a8 100644 --- a/examples/templates/examples/delete_book_async.html +++ b/examples/templates/examples/delete_book_async.html @@ -16,7 +16,7 @@ diff --git a/examples/templates/index.html b/examples/templates/index.html index e007e81..9d7699e 100644 --- a/examples/templates/index.html +++ b/examples/templates/index.html @@ -82,19 +82,23 @@

modalID: "#create-modal" }); - var asyncSuccessMessage = [ - "
", - "Success: Book was updated.", - "", - "
", - "