Skip to content

Commit

Permalink
[PLAY-1510] Loading state for Rails form, resolution of Dialog loading (
Browse files Browse the repository at this point in the history
#3753)

**What does this PR do?** A clear and concise description with your
runway ticket url.
https://runway.powerhrg.com/backlog_items/PLAY-1510

**Screenshots:** Screenshots to visualize your addition/change


**How to test?** Steps to confirm the desired behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See addition/change


#### Checklist:
- [ ] **LABELS** Add a label: `enhancement`, `bug`, `improvement`, `new
kit`, `deprecated`, or `breaking`. See [Changelog &
Labels](https://github.com/powerhome/playbook/wiki/Changelog-&-Labels)
for details.
- [ ] **DEPLOY** I have added the `milano` label to show I'm ready for a
review.
- [ ] **TESTS** I have added test coverage to my code.
  • Loading branch information
skduncan authored Oct 21, 2024
1 parent f9a7d22 commit 693a86c
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 10 deletions.
2 changes: 2 additions & 0 deletions playbook/app/entrypoints/playbook-rails.js
Original file line number Diff line number Diff line change
@@ -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'
Expand Down
2 changes: 2 additions & 0 deletions playbook/app/javascript/plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Original file line number Diff line number Diff line change
@@ -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,
}) %>

<script>
const loadingButton = document.querySelector('[data-disable-with="Loading"]');
if (loadingButton) {
loadingButton.addEventListener("click", function() {
const okayLoadingButton = document.querySelector('[data-disable-with="Loading"]');
const cancelButton = document.querySelector('[data-disable-cancel-with="Loading"]');
let currentClass = okayLoadingButton.className;
let cancelClass = cancelButton ? cancelButton.className : "";

setTimeout(function() {
okayLoadingButton.disabled = false;
okayLoadingButton.className = currentClass.replace("_disabled_loading", "_enabled");

if (cancelButton) {
cancelButton.disabled = false;
cancelButton.className = cancelClass.replace("_disabled", "_enabled");
}
}, 5000);

});
}
</script>
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -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 %>

<script>
const loadingForm = document.querySelector(".pb_form_loading")
if (loadingForm) {
loadingForm.addEventListener("submit", function(event) {
event.preventDefault();

const submitButton = event['submitter'];
const cancelButton = event['target'].querySelector('button[type="reset"]');

if (submitButton) {
let currentClass = submitButton.className;
let newClass = currentClass.replace("_disabled_loading", "_enabled");

let cancelClass = cancelButton ? cancelButton.className : "";
let newCancelClass = cancelClass.replace("_disabled", "_enabled");

setTimeout(function() {
submitButton.disabled = false;
submitButton.className = currentClass;

if (cancelButton) {
cancelButton.disabled = false;
cancelButton.className = cancelClass;
}
}, 5000);
}
});
}
</script>

Original file line number Diff line number Diff line change
@@ -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.
1 change: 1 addition & 0 deletions playbook/app/pb_kits/playbook/pb_form/docs/example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ examples:
rails:
- form_form_with: Default
- form_form_with_validate: Default + Validation
- form_form_with_loading: Default + Loading
2 changes: 2 additions & 0 deletions playbook/app/pb_kits/playbook/pb_form/form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
Expand Down
27 changes: 27 additions & 0 deletions playbook/app/pb_kits/playbook/pb_form/formHelper.js
Original file line number Diff line number Diff line change
@@ -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;
4 changes: 3 additions & 1 deletion playbook/lib/playbook/pb_forms_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)
Expand Down

0 comments on commit 693a86c

Please sign in to comment.