Giter Site home page Giter Site logo

k1r0s / preact-bind-group Goto Github PK

View Code? Open in Web Editor NEW
26.0 3.0 2.0 47 KB

Preact Component to Group Form fields onChange Events to a single Callback

Home Page: https://npm.im/preact-bind-group

License: MIT License

JavaScript 100.00%
preact preact-components preact-forms

preact-bind-group's Introduction

preact-bind-group

downloads version dependencies dev-dependencies

An event wrapper for preact and react to centralize and simplify events management and state binding.

Edit preact-bind-group example

breaking changes since version 2.*

  • React is now supported. Just import from "preact-bind-group/react"
  • BindGroup component has been renamed to FormGroup

Why

React/Preact forms are a bit cryptic because it leads developer to deal with too many language primitives to tie state with fields, care about events and duplicate this pattern for each field.

How

preact-bind-group exposes a <FormGroup> component that looks for children that contain data-bind attribute which should be assigned to any element or component that emits an onChange event.

Get started

Install it:

npm install preact-bind-group

Import it it in your components and use it:

import { render } from "preact";
import { FormGroup } from "preact-bind-group";

const App = () => (
  <div>
    <h3>FormGroup demo</h3>
    <FormGroup watch={change => console.log(change)}>
      <label>
        Name: <input data-bind="name" />
      </label>
      <br />
      <label>
        Age: <input data-bind="age" />
      </label>
    </FormGroup>
  </div>
);

Watch callback

The watch callback receives an {key: value} object containing the changed property as its parameter.

 {name: "asdas"}

Then you can update your state easily:

  <FormGroup watch={change => this.setState({ ...change })}>

If the input element is of type checkbox or radio, then it'll receive the checked html property as its value.

For convenience, you'll get a second argument with the field key. The callback signature is ({ [key: string]: any }, key: string) => void.

Custom events

You can change the event that FormGroup should listen to:

  <input data-bind="name" data-event="onInput"/>

Note: keep in mind that onInput in Preact === onChange in React, and onChange in Preact === onBlur on React.

Preload form with data

You should use preload attr to fill form fields with default data

<div>
  <h3>FormGroup demo</h3>
  <FormGroup watch={change => console.log(change)} preload={userModel}>
    <div>
      <input data-bind="name"/>
    </div>
    <div>
      <input data-bind="likesPizza" type="checkbox"/>
    </div>
    <div>
      <input data-bind="belovedFood" type="radio" value="potato"/>
      <input data-bind="belovedFood" type="radio" value="banana"/>
      <input data-bind="belovedFood" type="radio" value="peanuts"/>
    </div>
    <div>
      <textarea data-bind="comments"/>
    </div>
  </FormGroup>
</div>

preact-bind-group's People

Contributors

alexjoverm avatar forsakenharmony avatar k1r0s avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

preact-bind-group's Issues

Update fields from state

Right now bindGroup internal state only is updated from outside when component gets mounted.

Would be handy to override bgroup internal state by updating preload bindgroup's attr.

Remove 2nd watch parameter

I think that most of times it won't be needed, and if it is, it can be accessed by Object.keys(obj).

What do you think?

Child.attributes not found when child node is evaluated to null due to conditional rendering with && operator

Hello!

  • using Preact 8 and latest Chrome Version

When rendering conditionally an element inside the BindGroup component with the && operator, when the condition is evaluated to false (hence the element is not rendered), the library crashes at the Child.attributes check performed on the mapChildren function as the child parameter is null (the expression is evaluated to falsy when the rendering condition is not met and is taken by the library as a null node).

Example of crash:

const renderCondition = false;
...

<BindGroup watch={change => {this.handleFormChange(change); } } preload={this.state.form}>
    //Creates a "null" child node which causes the library to crash
    {renderCondition &&  <input  data-bind="username" maxlength="5" />}
</BindGroup>

Crashes on the first if statement:

   static mapChildren (child, cbk, state, setState) {
//child.attributes is not found as child is null!
    if (child.attributes instanceof Object && child.attributes[FormGroup.bindAttrName]) {
      child.attributes = {
        ...child.attributes,
        [child.attributes[FormGroup.bindAttrEvent] || 'onChange']: evt => cbk.apply(null, [...FormGroup.createChangeReport(child, evt, setState), evt]),
        name: child.attributes[FormGroup.bindAttrName],
        ...FormGroup.getFormProps(child, state)
      }
    } else if (child.children instanceof Array && child.children.length) {
      child.children = child.children.map(child => FormGroup.mapChildren(child, cbk, state, setState));
    }
    return child;
  }
}

A possible solution would be to add a null check at the start of the function, e.g

 static mapChildren (child, cbk, state, setState) {
    if(!child) return; //Possible fix
    if (child.attributes instanceof Object && child.attributes[FormGroup.bindAttrName]) {
      child.attributes = {
        ...child.attributes,

WDYT?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.