@helios-interactive/reggie

Reggie, your form field butler.

Stats

stars 🌟issues ⚠️updated 🛠created 🐣size 🏋️‍♀️
@helios-interactive/reggie
Minified + gzip package size for @helios-interactive/reggie in KB

Readme

Reggie

A plugin intent on making complex form flows simple, and easily changeable.

Installation

npm install @helios-interactive/reggie --save

Usage

To use Reggie, you need to have a target div on the page, and also need to configure Reggie.

Configuring Reggie

Reggie Accepts a configuration object on instantiation. This object is described here, and broken up by levels of nesting.

Reggie Top Level Options

key type default description required
noSubmit boolean false If set to true, then the reggie generated submit button will be hidden. It will still be present in the DOM to allow for form submission false
targetDiv string The ID of the target div. Reggie will generate the forms within this div. true
initial string The step that Reggie will start on. Should match the name of one of the defined steps true
formClasses string A string of all classes that should be added to the form when it is generated false
steps array The steps provided will determine what content the form collects, and in what order that content should be displayed. Reference the Step Options for details on configuring each of these.

Step Options

key type default description required
name string The name of this step. This must be unique, with no other step names matching it. This name is what you will use later when referencing the step for navigation flow. true
next string The name of the step which should be transitioned to if reggieInstance.next() is called. false
submitButton object If a submit button is provided here, then it will overwrite the default submit button that reggie uses. It will overwrite for this step only. You can pass the class (accepts a string, and can include multiple classes), and the text which will be the text displayed within the button. Ex:{class: 'submit-btn', text: 'Submit'} false
pieces array Pieces defines each field that will be in this step of the form. Reference the Piece Options for details on configuring each of these. true

Piece Options

key type default description required
name string The name of the piece. This should be unique for all pieces. When reggie constructs a model based on the form it will use the piece name to associate the input data with this piece. true
type string 'input' The type of piece to be created. A list of available piece types can be found in the Piece Types section. true
class string A string of all classes that should be added to the piece when it is generated false
containerClass string Every piece has a container div that is created. All classes defined here will be added to the container div. false
placeholder string If the piece type allows for placeholder text, then this text will become the placeholder false
validations array Validations accepts an array of objects. Each object is a validation, and all validations will be run on a validation check. Each object must contain a regex key and a error key. The regex key will be run against the value of the piece, and if it does not get a match, then an error will be triggered. The error key contains the text of the error. Ex: {regex: /\w+/, error: 'Last name is required'} false
options array The options array is used when the piece type needs options (select, and radio). It will define what options are rendered in the piece. sometimes - when type requires it. Reference the Piece-Options Options for details on configuring each of these.
pieces array If the piece type is declared to be 'group' then an additional array of pieces can be nested within the current piece. These pieces accept the same options as the current piece. This is primarily used for grouping elements together on the UI. sometimes - when type requires it.
label string The text of the label that will be associated with the piece in the UI. If no text is present, then no label will be created. Labels also allow for the user to create a named span that can be refereced later, most commonly to treat it as a link. A label with the following { Text content, span-id } syntax will create a span with the content being that which comes before the comma (trimmed), and the id being that which comes after the comma (trimmed). false
labelClass string A string of all classes that should be added to the label when it is generated false
autocomplete boolean true If an input allows autocomplete, then this can be used to toggle that on or off. false

Piece-Options Options

key type default description required
name string The name of the option. In a select piece, this will determine the text shown for the select option. true
label string The text of the label that will be associated with the option in the UI. If no text is present, then no label will be created. If the parent piece is type select, then no label is shown. Labels also allow for the user to create a named span that can be refereced later, most commonly to treat it as a link. A label with the following { Text content, span-id } syntax will create a span with the content being that which comes before the comma (trimmed), and the id being that which comes after the comma (trimmed). false
labelClass string A string of all classes that should be added to the label when it is generated false
value any The value of the piece if this option is choosen. true
class string A string of all classes that should be added to the option when it is generated false

Piece Types

type description requirements
group A group piece allows for other pieces to be grouped within it. It will create a container div within the DOM to place all child pieces inside of. In this way you can break apart each step into sections within the DOM A group type must have child pieces.
radio Creates a radio group with all of the given options as radio buttons A radio type must have options that declare the radio butons.
radio-pill Creates a radio group with all of the given options as radio buttons.In addition, this radio group is styled in a pill shape with each option having a equal section of the pill. A radio type must have options that declare the radio butons.
input This is the default input box
select This will created a styled reggie select element. A select type must have options that declare the select options.
email This will create an imput box of the type email.
checkbox This will create a checkbox input.
tel This will create an input box of the type tel.

Using Reggie

Attributes

Attributes that are available on the reggie instance.

attribute description
model A object defined by the pieces that are sent to reggie. This object is single level, and each key is associated with a piece. Each piece must be unique for the model to work properly. The model will be updated with the latest values from the pieces. The model can be accessed and updated directly using this attribute.
options The options sent to reggie on instantiation
steps The steps array from within the options sent to reggie

Methods

method arguments description example
new options - object. See Configuring Reggie Creates and returns a new reggie instance. new Reggie(reggieOptions)
updateModel form Accepts a form, and will update the model based on the content of the form passed in. reggie.updateModel(document.getElementById('reggie-form'))
validateStep form, updateDOM Accepts a form (or defaults to the reggie form), and a boolean for updateDOM, if true, then validation errors will show in the DOM, if false, then errors will not be placed on the DOM. This method will run all validations for the current step, and return an array with any errors that are present. If no errors are present it will return an empty array. if ( reggie.validateStep(null, false).length > 0 ) { alert('please correct the errors') };
updateDOM Forces a re-render of the reggie DOM. This can be used to incorporate model updates made by your app. reggie.model.firstName = 'foobar'; reggie.updateDOM();
currentStep Returns the current step as an object reggie.currentStep()
currentAttributes Returns an array of attributes that are in the currentStep reggie.currentAttributes()
next Will go to the step defined in the current step's next attribute reggie.next()
previous Will go to the previous step reggie.previous()
goto target, recordTransition Accepts a target (step name), and will render that step to the DOM. The second argument, recordTransition (boolean), will determine if this transition is recorded for use with the previous method. Will go to the given step name. reggie.goto('lastStep')
reset Will reset reggie back to the initial state, and clear out the model to be empty again. reggie.reset()
submitStep Will submit the current step reggie.submitStep()

Events

Each event will provide a details object that contains reggie specific information.

event details description
reggieStepStart {to: 'stepThatIsStarting', from: 'stepThatJustEnded', model: {contains: 'current snapshot of the model'}} Triggers at the beginning of a step, providign an update as to the current state.
reggieStepEnd {to: 'stepThatIsStarting', from: 'stepThatJustEnded', model: {contains: 'current snapshot of the model'}} Triggers at the end of a step, providing an update as to the current state.
reggieStepSubmit {from: 'stepThatJustEnded', model: {contains: 'current snapshot of the model'}} Triggers at the submission of a step, and allows the user to then direct what reggie should do next.

Example Usage


const reggieOptions = {
  noSubmit: false,
  targetDiv: 'reggie-div',
  initial: 'startStep',
  formClasses: 'reggie-form',
  steps: [
      {
      name: "startStep",
      next: "finalStep",
      submitButton: {
        class: 'submit-btn',
        text: 'Custom Submit Button'
      },
      pieces: [
          {
            type: "group",
            class: "input-group",
            pieces: [
              {
                name: "firstName",
                type: "input",
                autocomplete: false,
                placeholder: "First Name",
                class: 'input-box',
                containerClass: 'container-class',
              },
              {
                name: "lastName",
                type: "input",
                autocomplete: false,
                placeholder: "Last Name",
                class: 'input-box'
              }
            ]
          },
          {
            name: "email",
            type: "email",
            placeholder: "Email",
            class: 'input-box',
            containerClass: 'email-container'
          }
        ]
      },
      {
        name: "optionalStep",
        next: "finalStep",
        pieces: [
          {
            name: 'bestNumber',
            type: 'select',
            placeholder: 'Number 1-3',
            label: 'Pick the best number.',
            labelClass: 'reggie-label',
            class: 'reggie-select',
            options: [
              {
                name: '1',
                value: '1'
              },
              {
                name: '2',
                value: '2'
              },
              {
                name: '3',
                value: '3'
              }
            ]
          }
        ]
      }
      {
        name: "finalStep",
        pieces: [
            {
              name: 'gender',
              type: 'radio-pill',
              class: 'reggie-radio-pillbox-custom',
              options: [
                {
                  name: 'male',
                  label: 'MALE',
                  value: 'male'
                },
                {
                  name: 'female',
                  label: 'FEMALE',
                  value: 'female'
                },
                {
                  name: 'unspecified',
                  label: 'UNSPECIFIED',
                  value: 'unspecified'
                }
              ],
              validations: [
                {
                  regex: /\w+/,
                  error: 'Please select a gender'
                }
              ]
            },
            {
              name: 'over18',
              type: 'checkbox',
              containerClass: 'reggie-checkbox-container reggie-form-field',
              class: 'reggie-checkbox',
              label: 'I am at least 18 years old',
              labelClass: 'reggie-label reggie-checkbox-label'
            }
          ]
      }
  ]
}

// Instantiate reggie, and draw the initial step into the DOM
const reggie = new Reggie(reggieOptions);

// Set default values for pieces
reggie.model.gender = 'unspecified';
// Update the DOM. You can do this when setting defaults so that they populate the
// current step. If the defaults pertain to a step that is yet to come, then they will
// automatically populate when that step is rendered.
reggie.updateDOM();

// Handle reggie submission events. You can control the flow of the form here
document.addEventListener('reggieStepSubmit', (event) => {
  // if they are coming from the startStep, and provided an email
  // then make them do the optional step
  // Otherwise just call the step's given next option
  if ( event.detail.from === 'startStep' && reggie.model.email ) {
    reggie.goto("optionalStep");
  } else {
    reggie.next();
  }
})

// Handle reggie step start events.
document.addEventListener('reggieStepSubmit', (event) => {
  // If the user has completed all steps, then behave appropriately
  if ( event.detail.to === 'done' ) {
    let modelKeys = Object.keys(event.detail.model);
    let finalModel = [];
    modelKeys.forEach(key => {
      finalModel.push(`${key}: ${event.detail.model[key]}`);
    });

    alert(`You made it through, here's your data!\n\n${finalModel.join('\n')}`);
  }
}


License

MIT License

Copyright (c) [2017] [Adam McFadden]

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

If you find any bugs or have a feature request, please open an issue on github!

The npm package download data comes from npm's download counts api and package details come from npms.io.