@nichoth/forms

Stuff for making forms

Usage no npm install needed!

<script type="module">
  import nichothForms from 'https://cdn.skypack.dev/@nichoth/forms';
</script>

README

forms

See a demo

Form components that use preact

The preact components simplify the creation of labels & id attributes, and form validation is done solely through css and html.

install

npm i -S @nichoth/forms

use

css

my-stylesheet.scss:

@use "./node_modules/@nichoth/forms/style/index";
// or individually
@use "./node_modules/@nichoth/forms/style/number-input";
@use "./node_modules/@nichoth/forms/style/text-input";
@use "./node_modules/@nichoth/forms/style/button";

with browserify

var { TextInput, NumberInput } = require('@nichoth/forms/preact')

Or react:

var { TextInput, NumberInput } = require('@nichoth/forms/react')

develop

$ npm start

update the example

$ npm version <major|minor|patch>

example

index.js:

var { TextInput, NumberInput, Button, EditableField, PencilButton } =
    require('@nichoth/forms/preact')
import { render } from 'preact';
import { html } from 'htm/preact';
import { useState } from 'preact/hooks';

function submit (ev) {
    ev.preventDefault()
    console.log('submit')
    console.log('value', ev.target.elements['test-input'].value)
}

function ClickingDemo () {
    var [resolving, setResolving] = useState(false)

    function doSomething (ev) {
        ev.preventDefault()
        setResolving(true)
        // 3 second delay
        setTimeout(() => setResolving(false), 3000)
    }

     return html`<div class="clicking-demo">
        <${Button} type="submit" onClick=${doSomething} isSpinning=${resolving}>
            do something
        </${Button}>
    </div>`
}

function Counter (props) {
    var { min, max } = props
    var [count, setCount] = useState(3)

    function inc () {
        if ((parseInt(count) + 1) > max) return
        if (count < min) return setCount(min)
        setCount(count + 1)
    }

    function dec () {
        if ((parseInt(count) - 1) < min) return
        if (count > max) return setCount(max)
        setCount(count - 1)
    }

    function change (ev) {
        console.log('change', ev.target.value)
        setCount(ev.target.value)
    }

    return html`
        <${NumberInput} min=${2} max=${6} value=${count}
            onIncrease=${inc} onDecrease=${dec} onChange=${change} />
    `
}

function Editing () {
    function save (newValue) {
        console.log('save', newValue)
        // wait 1 second
        // you *must* return a promise here;
        //   it is used by the `EditableField` component to
        //   set the resolving state
        return new Promise(resolve => setTimeout(resolve, 1000))
    }

    return html`
        <${EditableField} value="example" onSave=${save} name="example" />
    `
}

function Demo () {
    return html`<form onsubmit=${submit}>
        <${TextInput} name="test-input" displayName="test input"
            minlength="3" maxlength="6" required=${true}
        />

        <${TextInput} name="something" displayName="something else"
            minlength="3" maxlength="6" required=${false}
        />

        <div class="number">
            <p>min 2, max 6</p>
            <${Counter} min=${2} max=${6} />
        </div>

        <div class="editing">
            <${Editing} />
        </div>

        <div class="btn">
            <${ClickingDemo} />
        </div>

        <div class="button">
            <button type="submit">submit!</button>
        </div>

        <div>
            testing the pencil button
            <${PencilButton} onClick=${ev => {
                ev.preventDefault()
                console.log('click', ev)
            }} />
        </div>
    </form>`
}

render(html`<${Demo} />`, document.getElementById('content'));

read

https://css-tricks.com/form-validation-ux-html-css/

https://daverupert.com/2017/11/happier-html5-forms/

Eventually, I discovered the simplest solution by hooking into the input’s invalid event. Just before the submit event, the browser performs a form.checkValidity() check which checks all the inputs. All inputs with invalid data fire the invalid event to say “Hey, I have invalid data!” It’s here that we can apply the error class we need.

https://css-tricks.com/form-validation-part-1-constraint-validation-html/