Multi-step wizard helpers for Alpine.js

Overview

Alpine Wizard

Tests npm version

This package provides an Alpine directive (x-wizard) and a magic helper ($wizard) that allow you to quickly build multi-step wizards using Alpine.js (only 1.1 kB gzipped).

x-wizard-github

Installation

via cdn

<script defer src="https://unpkg.com/@glhd/alpine-wizard@1/dist/wizard.cdn.min.js"></script>
<script defer src="https://unpkg.com/alpinejs@3/dist/cdn.min.js"></script>

via npm

npm install @glhd/alpine-wizard

via yarn

yarn add @glhd/alpine-wizard

Usage

<!-- This is the data our wizard will work with. It's just plain Alpine. -->
<form x-data="{ name: '', age: 0, coppa: false }">
	
	<!-- Add steps with x-wizard:step -->
	<div x-wizard:step>
		Welcome! This step has no requirements, so we can continue
		immediately. This is useful for things like introductions.
	</div>
	
	<!-- Steps can have logic about when they're complete. In this
	     case, you must have entered a value for "name" to continue. -->
	<div x-wizard:step="name.trim() !== ''">
		Your name: <input x-model="name" name="name" />
	</div>
	
	<!-- Here's another step that has logic about when it's complete -->
	<div x-wizard:step="age > 0">
		Your age: <input x-model="age" name="age" />
	</div>
	
	<!-- Steps can also have logic about when they apply. In this
	     case, this step is only shown if the person is under 13. -->
	<div x-wizard:if="age < 13" x-wizard:step="coppa === true">
		<label>
			<input type="checkbox" x-model="coppa" />
			I have my parent or guardian's consent
		</label>
	</div>
	
	<!-- We also expose a $wizard magic that gives lots of helper
	     functionality. Here we have the logic for a continue button -->
	<button
		@click="$wizard.forward()"
		:disabled="$wizard.cannotGoForward()"
		x-show="$wizard.isNotLast()"
	>
		Continue
	</button>
	
	<!-- And here's a "submit" button when they get to the end. -->
	<button
		:disabled="$wizard.isNotComplete()"
		x-show="$wizard.isLast()"
	>
		Submit
	</button>

</form>

Try it out

Validation Rules

The wizard also supports Laravel-style validation rules via the validatorjs package. If you're using the CDN version of the script, be sure to add the Validator package to the page before the wizard plugin (if you're installing via npm or yarn this functionality is available by default):

<script defer src="https://unpkg.com/validatorjs@3/src/validator.js"></script>

This plugin allows you to add a .rules modifier to steps:

<div x-wizard:step.rules="{ age: 'required|numeric|min:1|max:120' }">
    Your age: <input x-model="age" name="age" />
</div>

See the validatorjs documentation for a list of all supported rules and how to configure them.

API

Alpine Directives

x-wizard:step

Use x-wizard:step to define each wizard step. This directive optionally accepts a javascript expression which must return a truthy value before the step is considered complete.

x-wizard:if

Use x-wizard:if to make a step conditional. Any steps that have x-wizard:if will only show if the expression passed to the directive returns a truthy value.

x-wizard:title

Use x-wizard:title to set the step title. This is useful if you want to present the title of the current step elsewhere in your UI. By default, this is just a plain string, but you can generate the title dynamically by using the .dynamic modifier.

Alpine Magics

$wizard

The $wizard magic provides access to the state of your current wizard. It provides a number of useful helper functions:

  • current() — get the current wizard step
  • next() — get the next wizard step (or null if at end)
  • previous() — get the previous wizard step (or null if at beginning)
  • progress() — get current progress, a JS object:
    • current — the current step number (as of 1.2.0)
    • total — the total number of applicable steps
    • complete — the number of completed steps
    • incomplete — the number of steps still to complete
    • percentage — the percent complete, as a string (i.e. "33%")
    • percentage_int — the percent complete, as an integer (i.e. 33) (as of 1.2.0)
    • percentage_float — the percent complete, as an float (i.e. 0.33) (as of 1.2.0)
  • isFirst() — check if we're currently on the first step
  • isNotFirst() — check if we're NOT currently on the first step
  • isLast() — check if we're on the last step
  • isNotLast() — check if we're NOT on the last step
  • isComplete() — check if we're on the last step and all steps are complete
  • isNotComplete()/isIncomplete() — check if we're not on the last step or all steps aren't complete
  • canGoForward() — check if we can move to the next step
  • cannotGoForward() — check if we CANNOT move to the next step
  • forward() — move to the next step if possible
  • canGoBack() — check if we can go to the previous step
  • cannotGoBack() — check if we CANNOT go to the previous step
  • back() — move to the previous step if possible

Each step is a plain javascript object with a few properties:

  • el — the DOM element associated with the step
  • title — the title of the step
  • is_applicable — whether this step applies given the current data
  • is_complete — whether this step is complete
Comments
  • Is there a possibility to create steps dynamically?

    Is there a possibility to create steps dynamically?

    Many thanks for the great project! Is there a possibility to create steps dynamically? I am working on an application where the steps should be loaded dynamically from an API. However, the number and title of the steps is always different.

    opened by FlobeiGM 1
  • How to use with Alpine.plugin()

    How to use with Alpine.plugin()

    Maybe I'm missing something, but I can't get this to run using Alpine.plugin().

    import Alpine from "alpinejs";
    import * as wizard from "@glhd/alpine-wizard";
    
    Alpine.plugin(wizard);
    
    window.Alpine = Alpine;
    Alpine.start();
    

    Doesn't seem to work.

    opened by xtfer 1
  • Possible to create a Request Body or Multipart Requests?

    Possible to create a Request Body or Multipart Requests?

    Hey, awesome project! Is it possible to send data as a request body, instead of all inputs being used as query params?

    I have a scenario where I'm using a textarea input, which could have tens of thousands of words of free text. And in the future, I'd like my form to support file uploads. Possible to do Multipart requests?

    Cheers Ryan

    opened by kartzke 1
  • x-wizard:step not working inside alpine for loop

    x-wizard:step not working inside alpine for loop

    <template x-for="step in configuratorData.steps">
        <div x-wizard:step>
            <span x-text="step.name"></span>
        </div>
    </template>
    
    <div x-wizard:step>
        step outside for loop
    </div>
    

    I want to display steps dynamic based on configurator data. But it makes 3 steps but with all the step data in each step. The step outside the loop works fine. I made a gif to make it more clear. In the screenshot is the html output. Am I doing something wrong.

    image

    wizard

    opened by sanderjongsma 0
  • x-wizard:step.rules does not allow for dots in property name

    x-wizard:step.rules does not allow for dots in property name

    Hey there,

    first off, this is an amazing package, thanks a lot for this. :)

    Now, I am unsure if this is an AlpineJs issue, or if I'm just using it wrong, or if this has something to do with the wizard itself. But I thought I'd ask here.

    I have a form with x-init like so:

    <form 
                x-cloak
                x-data="leadForm()"
                class="border rounded overflow-hidden">
    

    I initialize the leadForm() using alpine.data() in a js file, like so:

    import Alpine from "alpinejs";
    import "./modules/alpine/dynamic-keyword-insertion";
    import wizard from "@glhd/alpine-wizard";
    import data from "./modules/alpine/form-data/index";
    
    window.Alpine = Alpine;
    
    Alpine.plugin(wizard);
    Alpine.data("leadForm", data);
    
    Alpine.start();
    

    ./modules/alpine/form-data/index

    export default () => ({
      step: 1,
      formData: {
        zip: null,
        fname: null,
        lname: null,
        email: null,
        address: null,
        phone: null,
        metaData: {},
      },
      init() {
        // Prepopulate formData from url query string params,
        // to hide wizard steps that have formData set.
        const queryParams = new URLSearchParams(location.search);
    
        // Go over all available options
        Object.keys(this.formData).forEach((key) => {
          // Check if obj has key, otherwise use default option
          this.formData[key] = queryParams.get(key);
        });
    
        console.log(this.formData);
      },
    });
    

    In my form, I'd like to write a custom Validatorjs rule that will make an API call to check if the entered zip code is valid, but I am unable to reference the formData zip code property in the validator directive, like so:

    <div
                  x-wizard:step="formData.zip != null;"
                  x-wizard:if="formData.zip == null"
                  x-wizard:title="Enter Your Zip Code"
                  x-wizard:step.rules="{ formData.zip: 'required|numeric|min:10|max:120' }"
                  class="flex items-center space-x-6">
                  <label for="zip-input">
                    Your Zip:
                  </label>
                  <input
                    x-model="formData.zip"
                    id="zip-input"
                    class="px-2 py-3 border border-gray-300 shadow-sm rounded-md sm:text-sm focus:ring-indigo-500 focus:border-indigo-500"
                  />
    

    results in SyntaxError: Unexpected token '.'. Expected a ':' following the property name 'formData'.

    Also wrapping the property name in quotes/double quotes does not work.

    opened by madsem 2
  • x-if doesnt seem to work on the first element

    x-if doesnt seem to work on the first element

    The following should only show the third step, but always shows the first step. The second step is skipped.

            <div x-data="{ errors: true }">
    
                <div x-wizard:step x-wizard:if="errors == false">
                    First
                    <x-buttons.standard-a @click="$wizard.forward()"
                                          ::disabled="$wizard.cannotGoForward()"
                                          x-show="$wizard.isNotLast()">Confirm & continue...</x-buttons.standard-a>
                </div>
    
                <div x-wizard:step x-wizard:if="errors == false">
                    Second
                    <x-buttons.standard-a @click="$wizard.forward()"
                                          ::disabled="$wizard.cannotGoForward()"
                                          x-show="$wizard.isNotLast()">Confirm & continue...</x-buttons.standard-a>
                </div>
    
                <div x-wizard:step>
                    Third
                </div>
            </div>
    
    opened by xtfer 0
Releases(1.2.0)
Owner
Galahad
Galahad
Full source-code for the step-by-step tutorial on how to use Phaser + Colyseus together.

Phaser: Real-time Multiplayer with Colyseus Full source-code for the step-by-step tutorial on how to use Phaser + Colyseus together. Live Demo See ste

Colyseus 19 Dec 24, 2022
A simple step by step tooltip helper for any site

Tooltip Sequence A minimalistic set of tooltips on your app. What it does So suppose you create a Web Application and you want to take your users or a

Sooraj Sivadasan Nair 299 Dec 21, 2022
A light-weight user's step-by-step guide for your website using Vanilla JS.

WebTour JS A light-weight user's step-by-step guide for your website using Vanilla JS. Features User's walkthrough - can be used to guide user's to yo

JM de Leon 23 Nov 21, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
Easy, lightweight multi-step experiences.

Steppp Steppp is a small library for quickly creating multi-step forms, carousels, and other experiences. It emphasizes a flexible developer experienc

Ramsey Solutions 22 Dec 7, 2022
A demo app showingcasing laravel-livewire-wizard

A demo of spatie/laravel-livewire-wizard This repo contains a Laravel app to showcase the spatie/laravel-livewizard package. Usage Clone the repo Copy

Spatie 52 Dec 29, 2022
Обучающий пример бота Telegram на Node.js с использованием Telegraf. Структура, сцены типа Base, Wizard, работа с api сторонних сервисов

NODE TG BOT TUTORIAL | WEATHER Обучающий пример Telegram bot по определению погоды с меcтоположения человека. Сервис бесплатного API погоды База данны

Владимир Бондаренко 13 Dec 22, 2022
🤝 A set of Persian Helpers for NodeJS to make your life easier

Persian Helpers Persian Helpers is a minimal NodeJS package with a set of helpers/tools specifically for the Persian/Farsi language. If you like the p

Kasra Ghoreyshi 11 Dec 22, 2022
Javascript Library providing form validation helpers

Javascript-Form-Validation Javascript Library providing form validation helpers Table of contents Installation Usage Include Library Use components Co

Benoit Gambier 13 Mar 25, 2022
How to implement Step-up Authentication using Amazon Cognito

How to implement Step-up Authentication using Amazon Cognito This repository contains accompanying source code for the AWS Blog post, How to implement

AWS Samples 15 Dec 15, 2022
AWS Step Functions Workflows Collection

AWS Step Functions Workflows Collection This repo contains Step Functions workflows that shows how to orchestrate multiple services into business-crit

AWS Samples 76 Dec 25, 2022
Hadmean is an internal tool generator. It is language agnostic, schema driven, extremely customizable, featured packed, user-friendly and has just one installation step.

Hadmean Report a Bug · Request a Feature · Ask a Question Table of Contents About Quick Demo Motivation Why you should try Hadmean Getting Started Pre

Hadmean 344 Dec 29, 2022
VSCode Extension - Preview for AWS Step Functions

VS Code - AWS Step Functions Preview This extension lets you see what your state machine looks like in graphical format. This will help you in writing

Piljoong Kim 2 Sep 19, 2022
A refined tool for exploring open-source projects on GitHub with a file tree, rich Markdown and image previews, multi-pane multi-tab layouts and first-class support for Ink syntax highlighting.

Ink codebase browser, "Kin" ?? The Ink codebase browser is a tool to explore open-source code on GitHub, especially my side projects written in the In

Linus Lee 20 Oct 30, 2022
proxy 🦄 yxorp is your Web Proxy as a Service (SAAS) Multi-tenant, Multi-Threaded, with Cache & Article Spinner

proxy ?? yxorp is your Web Proxy as a Service (SAAS) Multi-tenant, Multi-Threaded, with Cache & Article Spinner. Batteries are included, Content Spinning and Caching Engine, all housed within a stunning web GUI. A unique high-performance, plug-and-play, multi-threaded website mirror and article spinner

4D/ҵ.com Dashboards 13 Dec 30, 2022
Add focal point alignment of images to your Alpine 3.x components with a custom directive.

Alpine Focal Add focal point alignment of images to your Alpine 3.x components with a custom directive. This package only supports Alpine v3.x. About

Michael Lefrancois 2 Oct 12, 2021
Animate your Alpine components.

Animate your Alpine components ?? This package provides you with a simple helper to animate your ALpine.js components. Installation The recommended wa

Ralph J. Smit 18 Nov 16, 2022