<div class="bux-form--field-wrapper">
    <div class="bux-multi-form" id="form-2071953724">
        <h2 class="bux-multi-form__title">Multi-Step Form</h2>
        <div class="bux-multi-form__layout bux-multi-form__layout--horizontal">
            <div class="bux-multi-form__progress">
                <div class="bux-multi-form__progress bux-multi-form__progress-filled"></div>
            </div>
            <div class="bux-multi-form__step-container">
                <div class="bux-multi-form__step">
                    <div class="bux-multi-form__step-icon bux-multi-form__step-icon--current"></div>
                    <div class="bux-multi-form__step-label" aria-current="step">Step 1</div>
                </div>
                <div class="bux-multi-form__step">
                    <div class="bux-multi-form__step-icon"></div>
                    <div class="bux-multi-form__step-label">Step 2</div>
                </div>
                <div class="bux-multi-form__step">
                    <div class="bux-multi-form__step-icon"></div>
                    <div class="bux-multi-form__step-label">Step 3</div>
                </div>
                <div class="bux-multi-form__step">
                    <div class="bux-multi-form__step-icon"></div>
                    <div class="bux-multi-form__step-label">Step 4</div>
                </div>
            </div>
            <div class="bux-multi-form__form-container">
                <form>
                    <div class="bux-multi-form__form">
                        <h3 class="bux-multi-form__form_title">Step 1</h3>
                        <div class="bux-multi-form__form_field">

                            <div class="bux-text-field">

                                <label class="bux-text-field__label" for="bux-text-field__text-field-1519321119">
                                    Text Field
                                </label>

                                <span class="bux-text-field__helper-text" id="bux-text-field__helper-text-1519321119">
                                    Helper Text
                                </span>

                                <input id="bux-text-field__text-field-1519321119" class="bux-text-field__input" name="bux-text-field__text-field-1519321119" aria-describedby="bux-text-field__helper-text-1519321119" placeholder="Placeholder Text (Optional)" />

                            </div>
                        </div>
                        <div class="bux-multi-form__form_field">

                            <div class="bux-text-area">

                                <label class="bux-text-area__label" for="bux-text-area__text-area-394336108">
                                    Text Area
                                </label>

                                <span class="bux-text-area__helper-text" id="bux-text-area__helper-text-394336108">
                                    Helper Text
                                </span>
                                <textarea id="bux-text-area__text-area-394336108" class="bux-text-area__text-area" name="bux-text-area__text-area-394336108" aria-describedby="bux-text-area__helper-text-394336108" placeholder="Placeholder Text (Optional)"></textarea>
                            </div>
                        </div>
                    </div>
                    <div class="bux-multi-form__form">
                        <h3 class="bux-multi-form__form_title">Step 2</h3>
                        <div class="bux-multi-form__form_field">

                            <div class="bux-switch">
                                <fieldset id="bux-switch__switch-1200651285" class="bux-switch__fieldset" aria-describedby="bux-switch__helper-text-1200651285">

                                    <legend class="bux-switch__legend">
                                        Switch
                                    </legend>

                                    <span class="bux-switch__helper-text" id="bux-switch__helper-text-1200651285">
                                        Helper Text
                                    </span>

                                    <div class="bux-switch__input-spacer">

                                        <div class="bux-switch__option ">
                                            <input type="checkbox" id="bux-switch__option-283639681" name="bux-switch__switch-1200651285" role="switch" />
                                            <label for="bux-switch__option-283639681">Item 1</label>
                                        </div>

                                        <div class="bux-switch__option ">
                                            <input type="checkbox" id="bux-switch__option-1607216145" name="bux-switch__switch-1200651285" role="switch" />
                                            <label for="bux-switch__option-1607216145">Item 2</label>
                                        </div>

                                        <div class="bux-switch__option ">
                                            <input type="checkbox" id="bux-switch__option-948268527" name="bux-switch__switch-1200651285" role="switch" />
                                            <label for="bux-switch__option-948268527">Item 3</label>
                                        </div>
                                    </div>
                                </fieldset>
                            </div>
                        </div>
                    </div>
                    <div class="bux-multi-form__form">
                        <h3 class="bux-multi-form__form_title">Step 3</h3>
                        <div class="bux-multi-form__form_field">

                            <div class="bux-radio">
                                <fieldset id="bux-radio__radio-1718515458" class="bux-radio__fieldset" aria-describedby="bux-radio__helper-text-1718515458">

                                    <legend class="bux-radio__legend">
                                        Radio Button
                                    </legend>

                                    <span class="bux-radio__helper-text" id="bux-radio__helper-text-1718515458">
                                        Helper Text
                                    </span>

                                    <div class="bux-radio__input-spacer">

                                        <div class="bux-radio__option">
                                            <input type="radio" id="bux-radio__option-429090702" name="bux-radio__radio-1718515458" />
                                            <label for="bux-radio__option-429090702">Item 1</label>
                                        </div>

                                        <div class="bux-radio__option">
                                            <input type="radio" id="bux-radio__option-402794959" name="bux-radio__radio-1718515458" />
                                            <label for="bux-radio__option-402794959">Item 2</label>
                                        </div>

                                        <div class="bux-radio__option">
                                            <input type="radio" id="bux-radio__option-1975393512" name="bux-radio__radio-1718515458" />
                                            <label for="bux-radio__option-1975393512">Item 3</label>
                                        </div>
                                    </div>
                                </fieldset>
                            </div>
                        </div>
                        <div class="bux-multi-form__form_field">

                            <div class="bux-checkbox">
                                <fieldset id="bux-checkbox__checkbox-648482198" class="bux-checkbox__fieldset" aria-describedby="bux-checkbox__helper-text-648482198">

                                    <legend class="bux-checkbox__legend">
                                        Checkbox
                                    </legend>

                                    <span class="bux-checkbox__helper-text" id="bux-checkbox__helper-text-648482198">
                                        Helper Text
                                    </span>

                                    <div class="bux-checkbox__input-spacer">

                                        <div class="bux-checkbox__option">
                                            <input type="checkbox" id="bux-checkbox__option-385063819" name="bux-checkbox__checkbox-648482198" />
                                            <label for="bux-checkbox__option-385063819">Item 1</label>
                                        </div>

                                        <div class="bux-checkbox__option">
                                            <input type="checkbox" id="bux-checkbox__option-1405713607" name="bux-checkbox__checkbox-648482198" />
                                            <label for="bux-checkbox__option-1405713607">Item 2</label>
                                        </div>

                                        <div class="bux-checkbox__option">
                                            <input type="checkbox" id="bux-checkbox__option-115354247" name="bux-checkbox__checkbox-648482198" />
                                            <label for="bux-checkbox__option-115354247">Item 3</label>
                                        </div>
                                    </div>
                                </fieldset>
                            </div>
                        </div>
                    </div>
                    <div class="bux-multi-form__form">
                        <h3 class="bux-multi-form__form_title">Step 4</h3>
                        <div class="bux-multi-form__form_field">

                            <div class="bux-selection-dropdown">

                                <label class="bux-selection-dropdown__label" for="bux-selection-dropdown__selection-dropdown-2104045904">
                                    Choose One
                                </label>

                                <span class="bux-selection-dropdown__helper-text" id="bux-selection-dropdown__helper-text-2104045904">
                                    Helper Text
                                </span>

                                <div class="bux-selection-dropdown__input">
                                    <select id="bux-selection-dropdown__selection-dropdown-2104045904" name="bux-selection-dropdown__selection-dropdown-2104045904" aria-describedby="bux-selection-dropdown__helper-text-2104045904">
                                        <option>Choose One</option>
                                        <option value="Item 1">Item 1</option>
                                        <option value="Item 2">Item 2</option>
                                        <option value="Item 3">Item 3</option>
                                        <option value="Item 4">Item 4</option>
                                        <option value="Item 5">Item 5</option>
                                    </select>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="bux-multi-form__button-container">
                        <div class="bux-multi-form__back-button">

                            <button class="bux-button bux-button--alt">
                                Back:
                            </button>
                        </div>
                        <div class="bux-multi-form__next-button">

                            <button class="bux-button">
                                Next: Step 2
                            </button>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>
{# 

Multi Step Form

Available variables:

- direction:        Either 'vertical' or 'horizontal'.
- steps:            Array containing a list of steps for the form.
- step.name:        String for the name of the step.
- step.questions:   Array containing a list of forms.
- question.field:   Machine name of the form field.
- question.context: Array of variables for each field item. See each form item's
                    documentation for more details.

#}

<div class="bux-form--field-wrapper">
<div class="bux-multi-form" id="form-{{ random() }}">
    <h2 class="bux-multi-form__title">{{ form_title }}</h2>
    <div class="bux-multi-form__layout bux-multi-form__layout--{{direction}}">
        <div class="bux-multi-form__progress">
            <div class="bux-multi-form__progress bux-multi-form__progress-filled"></div>
        </div>
        <div class="bux-multi-form__step-container">
            {% for step in steps %}
                <div class="bux-multi-form__step">
                    {% if loop.index is same as(1) %}
                        <div class="bux-multi-form__step-icon bux-multi-form__step-icon--current"></div>                   
                        <div class="bux-multi-form__step-label" aria-current="step">{{step.name}}</div>
                    {% else %}
                        <div class="bux-multi-form__step-icon"></div>
                        <div class="bux-multi-form__step-label">{{step.name}}</div>
                    {% endif %}
                </div>
            {% endfor %}
        </div>
        <div class="bux-multi-form__form-container">
            <form>
                {% for step in steps %}
                    <div class="bux-multi-form__form">
                        <h3 class="bux-multi-form__form_title">{{ step.name }}</h3>
                        {% for question in step.questions %}
                            <div class="bux-multi-form__form_field">
                                {% set form_field = '@' ~ question.field|trim %}
                                {% include form_field with (question.context ?? {}) %}
                            </div>
                        {% endfor %}
                    </div>
                {% endfor %}
                <div class="bux-multi-form__button-container">
                    <div class="bux-multi-form__back-button">
                        {% render '@button' with {button_text: 'Back:', modifier: 'alt' } %}
                    </div>
                    <div class="bux-multi-form__next-button">
                        {% render '@button' with {button_text: 'Next: ' ~ steps[1].name} %}
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>
</div>
site_name_prefix: Office of
site_name: Learning Relations Excellence
site_slogan: Additional text or site slogan
address_1: 100 Building Name
address_2: 1 Oval Mall
city: Columbus
state: OH
zip: '43210'
contact_email: email@osu.edu
contact_phone: 614-292-OHIO
contact_tty: 614-688-8605
form_title: Multi-Step Form
direction: vertical
steps:
  - name: Step 1
    questions:
      - field: text-field
        context:
          input_label: Text Field
          helper_text: Helper Text
          placeholder_text: Placeholder Text (Optional)
      - field: text-area
        context:
          input_label: Text Area
          helper_text: Helper Text
          placeholder_text: Placeholder Text (Optional)
  - name: Step 2
    questions:
      - field: switch
        context:
          legend: Switch
          helper_text: Helper Text
          items:
            - text: Item 1
            - text: Item 2
            - text: Item 3
  - name: Step 3
    questions:
      - field: radio-button
        context:
          legend: Radio Button
          helper_text: Helper Text
          items:
            - text: Item 1
            - text: Item 2
            - text: Item 3
      - field: checkbox
        context:
          legend: Checkbox
          helper_text: Helper Text
          items:
            - text: Item 1
              value: item_1
            - text: Item 2
              value: item_2
            - text: Item 3
              value: item_3
  - name: Step 4
    questions:
      - field: selection-dropdown
        context:
          input_label: Selection Dropdown
          dropdown_label: Choose One
          helper_text: Helper Text
          items:
            - text: Item 1
            - text: Item 2
            - text: Item 3
            - text: Item 4
            - text: Item 5
  • Content:
    // BUX Multi Form
    .bux-form--field-wrapper {
      position: relative;
    }
    
    .bux-multi-form {
      position: relative;
    
      &__title,
      &__form-title,
      &__component {
        margin-bottom: $sp-32;
      }
    
      &__layout {
        padding-bottom: $sp-48;
      }
    }
    
    // Progress Bar
    .bux-multi-form__progress {
      background: $gray-light-60;
    
      &-filled {
        background: $scarlet;
        transition: 400ms all ease-in-out;
      }
    }
    
    // Steps
    .bux-multi-form__step {
      &-container {
        display: grid;
      }
    
      &-label {
        margin-top: 2px;
      }
    
      &-icon {
        background-color: #fff;
        margin-right: $sp-8;
        font: inherit;
        color: $gray-dark-80;
        width: 20px;
        height: 20px;
        border: 2px solid $gray-dark-80;
        border-radius: 50%;
        transform: translateY(2.5px);
        display: grid;
        place-content: center;
    
        &::before {
          content: "";
          font-family: "bux-icons";
          transform: scale(0);
        }
    
        &--current {
          border-color: $scarlet;
    
          &::before {
            transform: scale(1);
            transition: 120ms transform ease-in-out;
            width: 10px;
            height: 10px;
            border-radius: 50%;
            background-color: $scarlet;
          }
        }
    
        &--complete {
          &::before {
            content: "\f101";
            font-size: 11px;
            transform: scale(1);
          }
        }
      }
    }
    
    // Forms
    .bux-multi-form__form {
      display: none;
    
      &:first-child {
        display: block;
      }
    }
    
    // Buttons
    .bux-multi-form__button-container {
      position: absolute;
      bottom: 0;
      right: 0;
      display: flex;
      justify-content: flex-end;
      gap: $sp-16;
    }
    
    // Modifiers
    .bux-multi-form__layout--horizontal {
      .bux-multi-form__progress {
        height: $sp-4;
    
        &-filled {
          width: 0;
        }
      }
    
      .bux-multi-form__step-container {
        grid-template-columns: repeat(auto-fit, minmax(25%, 1fr));
        padding: 0 $sp-16 0 $sp-4;
        margin-bottom: $sp-48;
      }
    
      .bux-multi-form__step {
        display: grid;
        grid-template-columns: 18px auto;
        gap: 8px;
        margin-top: $sp-8;
      }
    }
    
    .bux-multi-form__layout--vertical {
      display: flex;
    
      .bux-multi-form__progress {
        width: $sp-4;
        align-self: stretch;
    
        &-filled {
          width: 100%;
          height: 0;
        }
      }
    
      .bux-multi-form__step-container {
        grid-template-rows: repeat(auto-fit, minmax(25%, 1fr));
        padding: $sp-8 $sp-32 0 $sp-4;
      }
    
      .bux-multi-form__step {
        display: flex;
      }
    
      .bux-multi-form__form-container {
        flex-grow: 1;
        padding-top: $sp-8;
      }
    }
    
  • URL: /components/raw/multi-step-form/_multi-step-form.scss
  • Filesystem Path: src/components/forms/multi-step-form/_multi-step-form.scss
  • Size: 2.4 KB
  • Content:
    const SELECTORS = {
        progress: ".bux-multi-form__progress-filled",
        nextButton: ".bux-multi-form__next-button",
        backButton: ".bux-multi-form__back-button",
        stepIcons: ".bux-multi-form__step-icon",
        stepLabels: ".bux-multi-form__step-label",
        stepContainer: ".bux-multi-form__step-container",
        forms: ".bux-multi-form__form",
        iconCurrent: "bux-multi-form__step-icon--current",
        iconComplete: "bux-multi-form__step-icon--complete",
        horizontal: ".bux-multi-form__layout--horizontal",
        vertical: ".bux-multi-form__layout--vertical",
        container: ".bux-multi-form",
    };
    
    class MultiStepForm {
        private progress: HTMLElement;
        private nextButton: HTMLButtonElement;
        private backButton: HTMLButtonElement;
        private stepIcons: NodeListOf<HTMLElement>;
        private stepLabels: NodeListOf<HTMLElement>;
        private readonly forms: NodeListOf<HTMLElement>;
        private readonly isVertical: boolean;
        private currentStep: number;
        private stepContainer: HTMLElement | null | undefined = undefined;
        constructor(private readonly container: HTMLElement) {
            const progress = this.container.querySelector<HTMLElement>(SELECTORS.progress);
            const nextButton = this.container.querySelector(SELECTORS.nextButton)?.querySelector("button");
            const backButton = this.container.querySelector(SELECTORS.backButton)?.querySelector("button");
    
            if (!progress || !nextButton || !backButton) {
                throw new TypeError("Buckeye UX Multi-Step Form is missing required elements.");
            }
    
            this.progress = progress;
            this.nextButton = nextButton;
            this.backButton = backButton;
            this.stepIcons = this.container.querySelectorAll<HTMLElement>(SELECTORS.stepIcons);
            this.stepLabels = this.container.querySelectorAll<HTMLElement>(SELECTORS.stepLabels);
            this.forms = this.container.querySelectorAll<HTMLElement>(SELECTORS.forms);
    
            this.isVertical = this.container.querySelector<HTMLElement>(SELECTORS.vertical) !== null;
            this.currentStep = 0;
    
            this.setInitialFormDisplay();
            this.bindButtonEvents();
        }
    
    
        setInitialFormDisplay() {
            this.setFormsContainerMinHeight();
            this.backButton.style.display = "none";
        }
    
        bindButtonEvents() {
            this.nextButton.addEventListener("click", (event) => this.handleButtonClick(1, event));
            this.backButton.addEventListener("click", (event) => this.handleButtonClick(-1, event));
        }
    
        handleButtonClick(direction: 1 | -1, event: Event) {
            event.preventDefault();
            this.controlForm(direction);
        }
    
        updateProgress() {
            const progressAmount = (100 / this.stepIcons.length) * this.currentStep;
            if (this.isVertical) {
                this.progress.style.height = `${progressAmount}%`;
            } else {
                this.progress.style.width = `${progressAmount}%`;
            }
        }
    
        updateStepIcons(direction: 1 | -1) {
            this.stepIcons[this.currentStep].classList.remove(SELECTORS.iconCurrent);
            if (direction === 1) {
                this.stepIcons[this.currentStep].classList.add(SELECTORS.iconComplete);
            } else if (direction === -1) {
                this.stepIcons[this.currentStep].classList.remove(SELECTORS.iconComplete);
            }
            this.stepIcons[this.currentStep + direction].classList.add(SELECTORS.iconCurrent);
        }
    
        updateStepForm(direction: 1 | -1) {
            this.forms[this.currentStep].style.display = "none";
            this.forms[this.currentStep + direction].style.display = "block";
        }
    
        updateButtons() {
            if (this.currentStep === 0) {
                this.backButton.style.display = "none";
            } else {
                this.backButton.style.display = "block";
                const backButtonLabel = this.getCurrentStepLabel(this.currentStep - 1);
                this.backButton.textContent = `Back: ${backButtonLabel}`;
            }
    
            if (this.currentStep === this.stepIcons.length - 1) {
                this.nextButton.textContent = "Submit";
            } else {
                const nextButtonLabel = this.getCurrentStepLabel(this.currentStep + 1);
                this.nextButton.textContent = `Next: ${nextButtonLabel}`;
            }
        }
    
        controlForm(direction: 1 | -1) {
            if (
                (direction === 1 && this.currentStep < this.stepIcons.length - 1) ||
                (direction === -1 && this.currentStep > 0)
            ) {
                this.updateStepIcons(direction);
                this.updateStepForm(direction);
                this.currentStep += direction;
                this.updateProgress();
                this.updateButtons();
            }
        }
    
        getCurrentStepLabel(index: number) {
            return this.stepLabels[index].textContent;
        }
    
        setFormsContainerMinHeight() {
            this.container.style.visibility = "hidden";
    
            let maxHeight = 0;
            for (const form of this.forms) {
                form.style.display = "block";
                maxHeight = Math.max(maxHeight, this.container.offsetHeight);
                form.style.display = "none";
            }
    
            this.container.style.minHeight = `${maxHeight}px`;
            this.forms[0].style.display = "block";
            this.container.style.visibility = "visible";
    
            if (this.isVertical) {
                this.stepContainer = this.container.querySelector<HTMLElement>(SELECTORS.stepContainer);
                if (this.stepContainer) {
                    this.stepContainer.style.minHeight = `${maxHeight}px`;
                }
            }
        }
    }
    
    export const init = () => {
        const multiFormDivs = document.querySelectorAll(SELECTORS.container);
    
        for (const formDiv of multiFormDivs) {
            const formId = formDiv.id;
            if (formId) {
                const container = document.querySelector<HTMLElement>(`#${formId}`);
                if (!container) {
                    continue;
                }
                new MultiStepForm(container);
            }
        }
    }
    
    if (document.readyState === 'loading') {
        document.addEventListener("DOMContentLoaded", init);
    } else {
        init();
    }
  • URL: /components/raw/multi-step-form/multi-step-form.ts
  • Filesystem Path: src/components/forms/multi-step-form/multi-step-form.ts
  • Size: 6 KB

No notes defined.