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

strange-forms

v1.1.0

Published

Redux/React toolkit for forms

Downloads

8

Readme

strange-forms

Redux/React toolkit for forms

Build Status Coverage Status

Usage

This is a toolkit for using forms with React and Redux. Specifically, this is meant to help create components containing forms that attempt to update and reflect application state. The special thing about this library is that it assumes the value displayed in a form may deviate from the current value in state, and this library does not rely on any special coordination with actions/reducers as in react-redux-form. When there's a discrepancy between a value in the form and a value in state, it can be recognized an invalid field in the form– this simple fact allows validation to occur solely in the reducer if desired (where it belongs!).

Example

const React = require('react');
const StrangeForms = require('strange-forms');

module.exports = class extends StrangeForms(React.Component) {

    constructor(props) {

        // In this example assume props have shape,
        // { person: { name, age }, occupation: { position, seasonal }}

        // Make sure to pass props to super().
        super(props);

        // This must be called in the constructor
        this.strangeForm({
            // Declare the interesting fields.
            fields: ['name', 'age', 'position', 'seasonal'],
            // Obtain a form field value from props.
            // Can also be a single string, single function, or null (see API docs).
            get: {
                name: (someProps) => someProps.person.firstName,
                age: 'person.age', // Stringified someProps.person.age
                '*': (someProps, field) => someProps.occupation[field] // Catch-all for other fields
            },
            // Also takes per-field format similar to get.
            act: this.act.bind(this),
            // Defaults to (e) => e.target.value.  Also takes per-field format similar to get.
            getFormValue: this.getFormValue.bind(this)
        });
    }

    getFormValue(e) {

        // Just an example of a custom handler that applies a default.
        return e.target.value || '';
    }

    act(field, value) {

        // You'll probably end-up calling an action
        // here to try to update a field with a value.
        // The value comes from getFormValue when the
        // proposeNew()-generated handler is called.
        this.props.updateFieldAction(field, value);
    }

    invalid() {

        return ['name', 'age', 'position', 'seasonal'].some((field) => {

            // By default returns true if the field is invalid.
            return this.fieldError(field);
        });
    }

    render() {

        return <div>

            {this.invalid() && <span>Bad value somewhere!</span>}

            Name:
            <input
                type="text"
                // Reflects in local component state.
                value={this.fieldValue('name')}
                // Updates local component state and calls act, all using getFormValue option.
                onChange={this.proposeNew('name')}
            />

            Age:
            <input
                type="text"
                value={this.fieldValue('age')}
                onChange={this.proposeNew('age')}
            />

            Position:
            <input
                type="text"
                value={this.fieldValue('position')}
                onChange={this.proposeNew('position')}
            />

            Seasonal:
            <input
                type="checkbox"
                checked={this.fieldValue('seasonal')}
                onChange={this.proposeNew('seasonal')}
            />

        </div>;
    }
};

API

StrangeForms(superclass)

Returns a new class extending superclass (which should be an instance of React.Component) endowed with the following methods,

component.strangeForm(options)

This must be called in the component's constructor, and that constructor must have access to component props by calling super(props). These options define the behavior of the component as a strange-form,

  • fields - an array of form field names. Defaults to an empty array.
  • get - defines how fields values are mapped from component properties. Should be specified as either,
    • a function with signature function(props, field) that returns a form field value.
    • a string (e.g. 'user.store') that defines a path into component properties where there's an object mapping field names to values. In this case the result will be stringified.
    • null, which specifies that field values live directly on props. In this case the result will be stringified.
    • an object whose keys are field names and whose values are field-specific functions or strings as defined above. Note, if a string is specified it needs to provide the complete path to the value within component props. A key '*' may be used to define a catch-all.
  • act - defines how application-wide updates are made to state given a field and a new form value for that field. Should be specified as either,
    • a function with signature function(field, value, ...args), where args are additional arguments passed to a component.proposeNew()-generated handler.
    • an object whose keys are field names and whose values are field-specific functions as defined above. A key '*' may be used to define a catch-all.
  • getFormValue - defines a default getFormValue to be used by component.proposeNew(). It should be a function or object specifying functions per field, similar to act and get. Defaults to (e) => e.target.value. See component.proposeNew() for further description of its usage.

component.fieldValue(field)

Returns the field value that should display in the component.

component.fieldError(field, [error])

Returns error if the current value displaying in the component does not match (===) the value found in component props. The error parameter defaults to true. If error is specified as a function function(displayValue, propValue) the result of that function will be returned.

component.proposeNew(field, [getFormValue])

Returns a function function(...anyArgs) that uses the latest form value for field to update local component state and perform act(field, value, ...anyArgs). The latest form value will be determined by getFormValue(...anyArgs), where getFormValue defaults to the value specified in component.strangeForm(options). If getFormValue is an object, it may specify the function to use on a per-field basis, where the key '*' may be used as a catch-all.

When not using the getFormValue argument, the result of this function is cached on a per-field basis. The reason for that is to allow usage of proposeNew() inside a component's render() (similar to the example) without concern about creating new function references.

component.componentWillReceiveProps(nextProps)

This is a lifecycle method used by React, and is not meant to be called manually. Internally strange-forms extends the method in order to update the displayed form values (which live in local component state) when new props are incoming.