npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@pelagiccreatures/molamola

v2.0.2

Published

Form Tools

Downloads

28

Readme

@PelagicCreatures/MolaMola

PWA friendly form validation & API payload management

@author Michael Rhodes
@license MIT
Made in Barbados 🇧🇧 Copyright © 2020-2021 Michael Rhodes

MolaMola provides a framework for building forms with validation, captcha, csrf and other plugin capabilities.

Try It

Form Element Layout

<form id="test-form" data-sargasso-class="MolaMola" action="/form-post" method="POST" data-submitter=".submitter" data-status=".status" data-recaptcha="xxx" data-helpers="HelperOne,HelperTwo">
  ....
  <button class="submitter">submit</button>
  <p class="status"></p>
</form>

Attributes:

  • id: the id of the form (required)
  • action: endpoint to transmit data to
  • method: method (POST,GET,PATCH etc)
  • data-helpers: list of MolaMola Helper classes for handling errors and response payload etc.
  • data-submitter: css selector of the form submit button. button will be enabled only when input is valid.
  • data-status: css selector of a container where errors are displayed
  • data-recaptcha: public reCaptchaV3 API key.

If using reCaptchaV3 The recaptcha script must be included with an API id on the page. It will be called on form submit and the token will be added to the payload (g-recaptcha-response) for backend validation and scoring.

<head>
  <script src="https://www.google.com/recaptcha/api.js?render=xxx"></script>
</head>

Input Element Layout

<div class="input-group">
  <input type="text" name="email" placeholder="Email address" data-validate='{"isEmail":true,"notEmpty":true}' data-payload>
  <span class="validation-help"></span>
</div>

Input Attributes:

  • name: payload property (required)
  • data-validate: JSON string detailing applicable Field validators
  • data-validate-message: message to display on validation error (default messages are somewhat cryptic)
  • data-payload: set if the field should be included in form payload

Validation Helper

The built in validation helper marks input errors and displays input error messages

Field validation is implemented by Validator using Sequelize extensions.

Prerequisites for validation behavior:

  • All input elements must be wrapped in an .input-group container
  • All validated inputs must have an .validation-help container inside the .input-group for displaying errors

CSS rules to reveal validation messages on input error

.validation-help { opacity:0; }
.touched .error .validation-help { opacity: 1}

Example validators See Validator for details:

  • data-validate='{"isEmail":true,"notEmpty":true}'
  • data-validate='{"isInt":{"min":1,"max":2}}' data-validate-message='{"isInt":"integer between %s and %s"}'
  • data-validate='{"isLength":{"min":0,"max":10}}'

Note: the format of the attributes must be valid JSON (double quotes required)

Grouping selects, checkboxes and radio buttons

Grouping payloads for multiple and single select, checkboxes and radio buttons

<div class="input-group">
  <input type="text" name="checkbox-group" data-group='[type="checkbox"]' data-validate='{"notEmpty":true}' multiple data-payload>
  <input type="checkbox" value="1" checked> Check 1
  <input type="checkbox" value="2"> Check 2
  <input type="checkbox" value="3" checked> Check 3
  <span class="validation-help"></span>
</div>

<div class="input-group">
  <input type="text" name="radio-group" data-group='[type="radio"]' data-payload>
  <input type="radio" name="radio" value="1" checked> radio 1
  <input type="radio" name="radio" value="2"> radio 2
  <input type="radio" name="radio" value="3"> radio 3
  <span class="validation-help"></span>
</div>

<div class="input-group">
  <select name="select-single" data-validate='{"notEmpty":true}' data-payload>
    <option value="">---</option>
    <option value="1">option 1</option>
    <option value="2" selected>option 2</option>
    <option value="3">option 2</option>
  </select>
  <span class="validation-help"></span>
</div>

<div class="input-group">
  <select name="select-multiple" data-validate='{"notEmpty":true}' multiple data-payload>
    <option value="">---</option>
    <option value="1" selected>option 1</option>
    <option value="2" selected>option 2</option>
    <option value="3">option 2</option>
  </select>
  <span class="validation-help"></span>
</div>

The resulting payload groups multiple and single selects in a consistent manner

{
  "checkbox-group" : [2,3],
  "radio-group": 1,
  "select-single": 2,
  "select-multiple": [1,2]
}

Lookup / unique endpoints

Make an API call on change to validate uniqueness or existence for a field value

TODO: need example

Form Helper

This example hooks up a helper to a form

class ExampleHandler extends MolaMolaModule.MolaMolaHelper {

  // A chance to modify the payload or implement a captcha or something before submit.
  preFlight() {

  }

  // use this method to handle 200 (ok) and 422 (unprocessable entity) responses
  // this example expects a JSON response. The specification of the payload is up to you.
  success(data) {
    alert('submitted')
  }

  // use this method to handle all other http responses
  error(err) {
    alert('error ' + err.message)
  }
}

MolaMolaModule.molaMolaUtils.registerHelperClass('ExampleHandler', ExampleHandler)
<form id="test-form" data-sargasso-class="MolaMola" data-helpers="ExampleHandler" action="/form-post" method="POST" data-submitter=".submitter" data-status=".status">

Endpoint API

Backend API prerequisites for the endpoint:

  • 200 (ok) & 422 (unprocessable entity) are expected to return json. Use 422 for server side validation errors, the response payload is up to implementor and should be handled with a helper success method.

  • Other http errors such as 401 (unauthorized) are handed to the helper error method

You will at least need to receive the payload of the response to take action after the form is submitted and probably show a confirmation page in success or something like that.

Subclass MolaMolaHelper and override the success and error methods to see the response payload and errors. This implementation is up to you. In our example response payload has some sugar to take some actions based on the response.

Serving modules from your project

npm install @pelagiccreatures/sargasso --save-dev
npm install @pelagiccreatures/molamola --save-dev

You can use the .iife.js bundles in the /dist directory of the @PelagicCreatures modules by copying them to a public directory on your server and referencing them in script tags in your html.

node_modules/@pelagiccreatures/sargasso/dist/sargasso.iife.js
node_modules/@pelagiccreatures/molamola/dist/molamola.iife.js

-or-

You can also bundle sargasso modules with your own es6 code using rollup.

npm install npx -g
npm install rollup --save-dev
npm install @rollup/plugin-json --save-dev
npm install @rollup/plugin-commonjs --save-dev
npm install @rollup/plugin-node-resolve --save-dev
npm install rollup-plugin-terser --save-dev

app.js

import { Sargasso, utils, loadPageHandler } from '@pelagiccreatures/sargasso'

import { MolaMola } from '@pelagiccreatures/molamola'

const boot = () => {
  utils.bootSargasso({})
}

export {
  boot
}

html

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <script src="public/dist/js/userapp.iife.js" defer></script>
    <script defer>
      window.onload= () => {
        App.boot()
      }
    </script>
  </body>
</html>

Create a rollup config file

Set input and output ass needed.

rollup.config.js

import commonjs from '@rollup/plugin-commonjs'
import nodeResolve from '@rollup/plugin-node-resolve'
import json from '@rollup/plugin-json'

import {
  terser
}
  from 'rollup-plugin-terser'

export default {
  input: './app.js', // <<< location of your es6 code

  output: {
    format: 'iife',
    file: 'public/dist/js/userapp.iife.js', // <<< where to save the browser bundle
    name: 'App', // <<< global variable where app.js exports are exposed
    sourcemap: true,
    compact: true
  },

  plugins: [
    json(),
    commonjs({}),
    nodeResolve({
      preferBuiltins: false,
      dedupe: (dep) => {
        return dep.match(/^(@pelagiccreatures|lodash|js-cookie)/)
      }
    }),
    terser({
      output: {
        comments: false
      },
      keep_classnames: true,
      keep_fnames: true
    })
  ]
}

Make the bundle

npx rollup --no-treeshake --no-freeze -c rollup.config.js