diff --git a/playbook/app/entrypoints/playbook-rails.js b/playbook/app/entrypoints/playbook-rails.js index 6c11e2a8a8..7769cb5fb9 100644 --- a/playbook/app/entrypoints/playbook-rails.js +++ b/playbook/app/entrypoints/playbook-rails.js @@ -1,5 +1,7 @@ // Forms import 'kits/pb_form/pb_form_validation' +import formHelper from 'kits/pb_form/formHelper' +window.formHelper = formHelper // Date Picker import datePickerHelper from 'kits/pb_date_picker/date_picker_helper' diff --git a/playbook/app/javascript/plugins.js b/playbook/app/javascript/plugins.js index d27f3cec4a..0ecdf5e1e6 100644 --- a/playbook/app/javascript/plugins.js +++ b/playbook/app/javascript/plugins.js @@ -6,3 +6,5 @@ export { default as PbTextarea } from '../pb_kits/playbook/pb_textarea' export { default as PbTooltip } from '../pb_kits/playbook/pb_tooltip' export { default as PbTypeahead } from '../pb_kits/playbook/pb_typeahead' export { default as dialogHelper } from '../pb_kits/playbook/pb_dialog/dialogHelper' +export { default as formHelper } from '../pb_kits/playbook/pb_form/formHelper' + diff --git a/playbook/app/pb_kits/playbook/pb_dialog/docs/_dialog_loading.html.erb b/playbook/app/pb_kits/playbook/pb_dialog/docs/_dialog_loading.html.erb index 5d8254f492..764f0d9559 100644 --- a/playbook/app/pb_kits/playbook/pb_dialog/docs/_dialog_loading.html.erb +++ b/playbook/app/pb_kits/playbook/pb_dialog/docs/_dialog_loading.html.erb @@ -1,13 +1,36 @@ <%= pb_rails("button", props: { text: "Open Dialog", data: {"open-dialog": "dialog-loading"} }) %> -<%= pb_rails("dialog", props: { - id:"dialog-loading", - size: "sm", - title: "Loading Exmaple", - text: "Make a loading request?", - cancel_button: "Cancel Button", +<%= pb_rails("dialog", props: { + id:"dialog-loading", + size: "sm", + title: "Loading Example", + text: "Make a loading request?", + cancel_button: "Cancel Button", cancel_button_id: "cancel-button-loading", - confirm_button: "Okay", + confirm_button: "Okay", confirm_button_id: "confirm-button-loading", loading: true, }) %> + + diff --git a/playbook/app/pb_kits/playbook/pb_dialog/docs/_dialog_loading.md b/playbook/app/pb_kits/playbook/pb_dialog/docs/_dialog_loading.md index ad7fbfab33..de0f291d1a 100644 --- a/playbook/app/pb_kits/playbook/pb_dialog/docs/_dialog_loading.md +++ b/playbook/app/pb_kits/playbook/pb_dialog/docs/_dialog_loading.md @@ -1,3 +1 @@ Pressing the "Okay" button will trigger a loading state where the button content is replaced by a spinner icon and both buttons are disabled. - -Currently, the loading state cannot be undone and will require a page refresh to reset the dialog. diff --git a/playbook/app/pb_kits/playbook/pb_form/docs/_form_form_with_loading.html.erb b/playbook/app/pb_kits/playbook/pb_form/docs/_form_form_with_loading.html.erb new file mode 100644 index 0000000000..e0702b1303 --- /dev/null +++ b/playbook/app/pb_kits/playbook/pb_form/docs/_form_form_with_loading.html.erb @@ -0,0 +1,39 @@ +<%= pb_form_with(scope: :example, url: "", method: :get, loading: true) do |form| %> + <%= form.text_field :example_text_field, props: { label: true } %> + + <%= form.actions do |action| %> + <%= action.submit %> + <%= action.button props: { type: "reset", text: "Cancel", variant: "secondary" } %> + <% end %> +<% end %> + + + diff --git a/playbook/app/pb_kits/playbook/pb_form/docs/_form_form_with_loading.md b/playbook/app/pb_kits/playbook/pb_form/docs/_form_form_with_loading.md new file mode 100644 index 0000000000..eef1260771 --- /dev/null +++ b/playbook/app/pb_kits/playbook/pb_form/docs/_form_form_with_loading.md @@ -0,0 +1 @@ +Pressing Submit will trigger a loading state where the button content is replaced by a spinner icon and the submit button will be disabled. diff --git a/playbook/app/pb_kits/playbook/pb_form/docs/example.yml b/playbook/app/pb_kits/playbook/pb_form/docs/example.yml index b04c3fdc51..19f029d494 100644 --- a/playbook/app/pb_kits/playbook/pb_form/docs/example.yml +++ b/playbook/app/pb_kits/playbook/pb_form/docs/example.yml @@ -3,3 +3,4 @@ examples: rails: - form_form_with: Default - form_form_with_validate: Default + Validation + - form_form_with_loading: Default + Loading diff --git a/playbook/app/pb_kits/playbook/pb_form/form.rb b/playbook/app/pb_kits/playbook/pb_form/form.rb index dc7b2574dd..d931173922 100644 --- a/playbook/app/pb_kits/playbook/pb_form/form.rb +++ b/playbook/app/pb_kits/playbook/pb_form/form.rb @@ -7,6 +7,7 @@ class Form < ::Playbook::KitBase type: Playbook::Props::Base prop :form_system_options, deprecated: "Use options instead", type: Playbook::Props::Base + prop :loading, type: Playbook::Props::Boolean, default: false prop :options, type: Playbook::Props::Base prop :validate, type: Playbook::Props::Boolean, default: false @@ -22,6 +23,7 @@ def form_options aria: aria, class: classname, data: data, + loading: loading, validate: validate, }.merge(prop(:options) || prop(:form_system_options) || {}) end diff --git a/playbook/app/pb_kits/playbook/pb_form/formHelper.js b/playbook/app/pb_kits/playbook/pb_form/formHelper.js new file mode 100644 index 0000000000..1c0fdb72d1 --- /dev/null +++ b/playbook/app/pb_kits/playbook/pb_form/formHelper.js @@ -0,0 +1,27 @@ +const formHelper = () => { + const loadingForm = document.querySelector(".pb_form_loading") + if (loadingForm) { + loadingForm.addEventListener("submit", function(event) { + const submitButton = event['submitter']; + const cancelButton = event['target'].querySelector('button[type="reset"]'); + + if (submitButton) { + let currentClass = submitButton.className; + let newClass = currentClass.replace("_enabled", "_disabled_loading"); + + let cancelClass = cancelButton ? cancelButton.className : ""; + let newCancelClass = cancelClass.replace("_enabled", "_disabled"); + + submitButton.disabled = true; + submitButton.className = newClass; + + if (cancelButton) { + cancelButton.disabled = true; + cancelButton.className = newCancelClass; + } + } + }); + } +}; + +export default formHelper; diff --git a/playbook/lib/playbook/pb_forms_helper.rb b/playbook/lib/playbook/pb_forms_helper.rb index c2b4c11d7a..f515b5db13 100755 --- a/playbook/lib/playbook/pb_forms_helper.rb +++ b/playbook/lib/playbook/pb_forms_helper.rb @@ -22,9 +22,10 @@ module PbFormsHelper # @param data [Hash] hash of data attributes # @param validate [Boolean] whether validation should be triggered or not # @see [#form_with] for other options - def pb_form_with(data: {}, validate: false, **kwargs, &block) + def pb_form_with(data: {}, validate: false, loading: false, **kwargs, &block) data = data.merge("pb-form-validation" => validate) classname = ["pb-form", kwargs[:class]].join(" ") + classname += " pb_form_loading" if loading options = kwargs.merge( class: classname, data: data, @@ -33,6 +34,7 @@ def pb_form_with(data: {}, validate: false, **kwargs, &block) content_for(:pb_js, javascript_tag(<<~JS)) window.addEventListener("DOMContentLoaded", function() { PbFormValidation.start() }) + window.addEventListener("DOMContentLoaded", () => formHelper()) JS form_with(**options, &block)