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

react-bootstrap-formutil

v2.0.1

Published

Happy to build forms with react-formutil in the project based on react-bootstrap ^_^

Downloads

34

Readme

react-bootstrap-formutil

npm peerDependencies definitionTypes gzip download issues license github github github github

react-formutil

Happy to use react-formutil in the project based on react-bootstrap ^_^

react-bootstrap 项目,结合react-formutil 来快速构建表单。

如果你在使用其他 react 组件库,可以查阅:

  1. ant-design react-antd-formutil npm
  2. react-md react-md-formutil npm
  3. Material-UI react-material-formutil npm

安装 Installation

react-bootstrap-formutil

📌📌 该版本适用于 [email protected][email protected]

# npm
npm install react-bootstrap-formutil --save

# yarn
yarn install react-bootstrap-formutil

使用 Usage

react-bootstrap-formutil 整合了 react-formutil 的组件,所以可以直接从react-bootstrap-formutil中导出所需要的 react-formutil 组件。不用单独从 react-formutil 中导出。

本文档适用于 [email protected][email protected] 版本,如果你要查看早期[email protected]的文档,请查看 react-bootstrap-formutil@classic

先看一个使用示例(点击查看在线完整示例 : react-bootstrap-formutil on codesandbox.io):

import React, { Component } from 'react';
import { withForm, FormGroup } from 'react-bootstrap-formutil';
import { FormControl } from 'react-bootstrap'; // 导入react-bootstrap的FormControl组件

@withForm
class MyForm extends Component {
    submit = () => {
        const { $invalid, $getFirstError, $params } = this.props.$formutil;

        if ($invalid) {
            alert($getFistError());
        } else {
            // submit your data
        }
    };

    render() {
        return (
            <form onSubmit={this.onSubmit}>
                <FormGroup name="username" required>
                    <FormControl type="text" />
                </FormGroup>
            </form>
        );
    }
}

FormGroupreact-bootstrap-formuitl 新增加的组件,withFormreact-formutil的组件(没错,你可以直接从react-bootstrap-formutil中导出react-formutil的组件啦)。

只需要将react-bootstrap的交互组件,嵌套在FormGroup下,即可实现自动的表单状态同步。

<FormGroup />

要实现将react-bootstrap的交互组件的值能同步到 react-formutil 的状态中,需要通过 FormGroup 这个组件来实现中间态绑定。

FormGroup提供了与react-bootstrap中同名组件一样的 UI 与状态展示功能,所以你完全可以使用react-bootstrap-formutil中的FormGroup替代react-bootstrap中的该组件。

如果给 FormGroup 传递了多个子节点,可能会出现无法非预期的异常情况。你可以了解如何正确的使用FormGroup嵌套渲染多个节点元素?

FormGroup基于react-formutil中的<EasyField />组件实现,同名属性参数用法可以更多参考<EasyField />

name

设置输入项的 name 值,表单项将会以 name 作为 key 收集到 formutil 的状态中。支持嵌套语法 (同react-formutilField同名参数,可以参考 name

$defaultValue

设置该表单项的默认值 (同react-formutilField同名参数,可以参考$defaultvalue

$validators

设置校验方法 (同react-formutilField同名参数 , 可以参考 $validators

同 react-formutil 的 EasyField,FormControl 也内置了同样的校验规则:

  • required 必填 required
  • maxLength 。最大输入长度,有效输入时才会校验 maxLength="100"
  • minLength 最小输入长度,有效输入时才会校验 minLength="10"
  • max 最大输入数值,仅支持 Number 比较。有效输入时才会校验 max="100"
  • min 最小输入数值,仅支持 Number 比较。有效输入时才会校验 min="10"
  • pattern 正则匹配。有效输入时才会校验 pattern={/^\d+$/}
  • enum 枚举值检测。有效输入时才会校验 enum={[1,2,3]}
  • checker 自定义校验函数。checker={value => value > 10 && value < 100 || ' 输入比如大于 10 小与 100'}

注:校验属性的值为 null 时表示不进行该校验

内置的校验规则无需再次声明,除非规则不符合预期,需要替换,则可以通过$validators 传递同名校验方法即可替换默认的。另外,内置的校验规则,如果校验不通过,会尝试去 validMessage 匹配错误信息。

label

如果表单项需要 label,应该通过该属性设置。你可以传入字符串,或者直接传入Form.Label节点:

<FormGroup name="name" label="Username">
    <Form.Control />
</FormGroup>

//or

<FormGroup name="name" label={<Form.Label>Username</Form.Label>}>
    <Form.Control />
</FormGroup>
helper

如果要设置表单项的 helper,需要通过该字段设置,或者直接传入HelpBlock节点:

<FormGroup name="name" helper="Please type your name">
    <FormControl />
</FormGroup>

//or

<FormGroup name="name" helper={<Form.Text className="text-muted">Please type your name</Form.Text>}>
    <FormControl />
</FormGroup>
labelCol

该属性可用来设置 label 的 栅格 布局:

<FormGroup
    name="agree"
    label="Name"
    wrapperCol={{
        xs: 12,
        md: 10
    }}
    labelCol={{
        xs: 12,
        md: 2
    }}>
    <Control />
</FormGroup>
wrapperCol

该属性可用来搭配labelCol设置水平布局的表单项的 栅格 布局

floatingLabel

指定该属性,启用Floating Labels效果

<FormGroup label="Your Name" floatingLabel={true}>
    <Control placeholder="text here" />
</FormGroup>
addons

该属性可以用来实现InputGroup布局,该属性包含三个字段pre end size,可以分别用来添加前后addons以及设置InputGroup的尺寸大小。

如果pre end的值为字符串,则会自动添加InputGroup.Text组件包装。当然,你也可以自行定义要添加的节点。

<FormGroup
    name="email"
    addons={{
        size: 'lg',
        // 如果是字符串,会自动添加 InputGroup.Text 包装
        pre: 'Email',
        // 也可以直接传递节点
        end: <InputGroup.Text>@apple.com</InputGroup.Text>
    }}>
    <FormControl />
</FormGroup>
extra

该属性用来添加一个额外的节点内容。

<FormGroup name="email" extra={<div>其他内容</div>}>
    <FormControl />
</FormGroup>

// 你可以利用 Fragment 添加多个其他节点内容
<FormGroup
    name="email"
    extra={
        <Fragment>
            <p>...</p>
            <div>...</div>
        </Fragment>
    }>
    <FormControl />
</FormGroup>
$parser

注意: 这里介绍的$parser$formatterreact-formutil@>0.5.0的用法。如果你还在使用0.5.0以前的版本,请参考安装0.5.0版本以上的react-formutil;

当用户在表单中进行输入时(主动更新视图),视图中的值在更新到状态模型中前,会经过 $parser 处理。

// 通过$parser属性来过滤前后输入空格
<FormGroup name="fieldName" $parser={(viewValue, $setViewValue) => viewValue.trim()}>
    //...
</FormGroup>

注意,上述写法不会修改当前视图值,它仅仅影响状态模型中的值。如果希望限制用户的输入(例如禁止用户输入任意空格),可以通过$parser的第二个参数$setViewValue,来在用户每次输入后立即更新视图值。

// 通过$parser属性来过滤前后输入空格
<FormGroup name="fieldName" $parser={(viewValue, $setViewValue) => $setViewValue(viewValue.trim())} />
$formatter

当在表单模型中主动更新模型值时,会通过 $formatter 将模型中的值转换为$viewValue后传递给视图渲染。

// 通过$formatter将模型中的值转换为标准的金额书写格式
<FormGroup name="amount" $formatter={(value, $setModelValue) => priceFormat(value)} />

$formatter同样有一个回调方法$setModelValue,它可以用来在处理模型值时再次对其进行修改。

$validateLazy

可以用来优化表单的校验速度,请参考: $validateLazy

$memo

可以用来优化当前表单项的性能,避免过多的重复渲染。如果你遇到了表单性能问题,可以尝试该属性来改善。

详细解释和使用、注意事项请参考: $memo

checked unchecked

对于 <Form.Check />,其值默认是 checked 属性,为布尔值。可以通过checked unchecked来设置 checked 状态时所要映射的值:

<FormGroup checked="yes" unchecked="no">
    <Form.Check type="checkbox" />
</FormGroup>

该示例中, 当 Switch 为开时,获取的值将为 yes。

validMessage

设置校验结果的错误信息。

<FormGroup
    name="username"
    required
    validMessage={{
        required: '请输入用户名'
    }}>
    <FormControl />
</FormGroup>
feedback

布尔值。设置是否要支持额外的状态,如果设置为true,这表单项正确时将会显示 绿色的valid状态

<FormGroup name="username" feedback>
    <FormControl />
</FormGroup>
valuePropName changePropName focusPropName blurPropName

该四个参数可以用来设置绑定到组件上的值或者值变动、是否聚焦等事件回调。该项一般不需要设置,FormGroup 已经针对 react-bootstrap 中的所有 data-entry 型组件做了兼容处理。

对于一些特殊场景,例如不需要同步 focusblur,则可以通过将该值设为{null}来禁用:

//禁用focus、blur状态同步
<FormGroup focusPropName={null} blurPropName={null} name="username">
    <FormControl />
</FormGroup>
getValueFromEvent

请参考 getValueFromEvent()

controlId as xs sm md lg

这几个属性同react-bootstrapFormGroup 组件的同名属性,事实上任何可以传递给Form.Group的属性都可以传递。

noStyle

该属性从 v1.1.0 起可

noStyle可以用来控制是否输出FormGroup的额外的样式元素。缺省情况下默认值为false

noStyletrue时,将会只渲染字段节点本身,但是其表单状态依然会被处理收集。此时,如果其存在父级嵌套的FormGroup,那么其表达校验状态将会传递给父级的FormGroup来展现。

这对于连续的紧凑型表单元素将非常有用!可以避免校验错误描述信息都堆叠在一起! 但是没有额外的样式显示,包括表单校验状态都无法显示了。此时可以在其外层包裹一层不带nameFormGroup,这些noStyle的表单项就会把他们自身的状态向上进行注册显示了!

但是有以下几点需要注意:

  1. 最外层的FormGroup不能设置name属性,否则将不会被当作子级的校验状态容器
  2. 内层的FormGroup需要添加相应的name值(向表单控制器注册自身)以及noStyle属性(不渲染额外的样式,避免和上层冲突)
// 这里不能设置name
<FormGroup label="姓名">
    <InputGroup>
        {/* 与普通的FormGroup用法一致,只是多了个noStyle */}
        <FormGroup name="demo4.first_name" required validMessage={{ required: 'First name reuqired!' }} noStyle>
            <Form.Control placeholder="姓" />
        </FormGroup>
        <FormGroup name="demo4.last_name" required validMessage={{ required: 'Last name reuqired!' }} noStyle>
            <Form.Control placeholder="名" />
        </FormGroup>
    </InputGroup>
</FormGroup>

以上运行示例请参考 示例 demo4

errorLevel

用来覆盖全局的 errorLevel 设置。参考setErrorLevel(level)

<CheckboxGroup />

该组件用来同步多选组,需要嵌套在FormGroup下配合使用:

每个子项Form.Check组件必须显式设置value属性值

<FormGroup name="group.checkbox" required label="Checkbox group">
    <CheckboxGroup>
        <Form.Check inline type="checkbox" value="1" label="1" />
        <Form.Check inline type="checkbox" value="2" label="2" />
        <Form.Check inline type="checkbox" value="2" label="3" />
    </CheckboxGroup>
</FormGroup>

<RadioGroup />

该组件用来同步单选组,需要嵌套在FormGroup下配合使用:

每个子项Form.Check组件必须显式设置value属性值

<FormGroup name="group.radio" required label="Radio group">
    <RadioGroup>
        <Form.Check inline type="radio" value="1" label="1" />
        <Form.Check inline type="radio" value="2" label="2" />
        <Form.Check inline type="radio" value="2" label="3" />
    </RadioGroup>
</FormGroup>

<SwitchGroup />

该组件用来同步单选组,需要嵌套在FormGroup下配合使用:

每个子项Form.Check组件必须显式设置value属性值

<FormGroup name="group.switch" required label="Switch group">
    <SwitchGroup>
        <Form.Check inline type="switch" value="1" label="1" />
        <Form.Check inline type="switch" value="2" label="2" />
        <Form.Check inline type="switch" value="2" label="3" />
    </SwitchGroup>
</FormGroup>

setErrorLevel(level)

setErrorLevel 该方法可以用来全局设置错误信息何时出现,有三个级别可以设置:

  • 0$dirty $touched invalid 都为 true 时
  • 1$dirty invalid 都为 true 时
  • 2invalid 为 true 时
  • off 关闭错误显示

默认值为 1

注意,该方法影响全局,如果只是希望单独对某个表单项进行设置,可以通过errorLevel属性进行设置:参考errorLevel

import { setErrorLevel } from 'react-bootstrap-formutil';

setErrorLevel(0);

// 当关闭错误显示时,errorLevel='off',你可以手动自行设置错误展示方式:
<FormGroup
    name="errorOff"
    errorLevel="off"
    validationState={$formutil.$errors.errorOff ? 'error' : null}
    helper={$formutil.$errors.errorOff ? <div>出错啦</div> : null}>
    <FormControl />
</FormGroup>;

支持的组件

FormControl Form.Control
<FormGroup name="pwd">
    <FormControl type="password" />
</FormGroup>

<FormGroup name="pwd">
    <FormControl as="select">
        <option value="1">1</option>
        <option value="2">2</option>
    </FormControl>
</FormGroup>
Form.Check FormCheck
<FormGroup name="agree">
    <Form.Check type="checkbox" />
</FormGroup>

<FormGroup name="agree">
    <Form.Check type="radio" />
</FormGroup>

<FormGroup name="agree">
    <Form.Check type="switch" />
</FormGroup>
InputGroup

需要通过 addons 属性调用

<FormGroup name="name" addons={{ pre: '@' }}>
    <FormControl type="text" />
</FormGroup>
ToggleButtonGroup

注意:ToggleButton组件必须指定id属性!! 您可以查看react-boostrap文档详细了解。

<FormGroup name="hobbies">
    <ToggleButtonGroup type="checkbox">
        <ToggleButton value={1} id="t1">option 1</ToggleButton>
        <ToggleButton value={2} id="t2">option 2</ToggleButton>
        <ToggleButton value={3} id="t3">option 3</ToggleButton>
    </ToggleButtonGroup>
</FormGroup>
CheckboxGroup RadioGroup SwitchGroup

注意:这三个组件并不是react-bootstrap提供的组件,而是react-bootstrap-formutil提供的。

import { CheckboxGroup, RadioGroup, SwitchGroup } from 'react-bootstrap-formutil';

动态className

FormGroup会自动给表单节点增加与该表单项校验状态相关的 className:

  • has-error
  • is-invalid
  • is-valid
  • is-touched
  • is-untouched
  • is-focused
  • is-unfocused
  • is-dirty
  • is-pristine

FAQ

给组件设置的 onChange、onFocus 等方法无效、不执行

FormGroup会覆盖掉直接添加到 react-bootstrap 组件上的onFocus onBlur onChange方法,所以如果需要这三个事件方法,需要添加到 FormGroup上:

<FormGroup name="test" onChange={ev => console.log('change', ev)} onFocus={ev => console.log('focus', ev)}>
    <FormControl />
</FormGroup>

在生产环境(NODE_ENV==='production')部分组件调用有异常?

如果在生产环境,发现例如Form.Check ToggleButtonGroup 等组件无法正确捕获用户输入的值,这种情况一般是由于项目中使用了babel-plugin-import插件。

react-bootstrap-formutil中是使用 import { FormControl } from 'react-bootstrap' 这种写法来调用 FormControl 组件的,而babel-plugin-import插件会将项目源代码中的类似语句,替换成import FormControl from 'react-bootstrap/lib/FormControl'。这两种写法获取到的Switch其实并不是严格意义上的相等,前者是对后者的又一层导出封装。

而由于babel-plugin-import一般仅仅会配置成仅仅对项目代码进行处理,所以处于项目node_modules目录中的react-bootstrap-formutil中的语句不会被处理。我们需要通过修改项目 webpack 配置的方式,来使babel-plugin-import插件能处理react-bootstrap-formutil的代码。

可以编辑项目的 webpack 配置(只需要配置生产环境的构建配置即可),在rules模块下添加以下的代码:

{
    test: /\.(js|mjs)$/,
    include: /react-bootstrap-formutil/, // 仅仅处理react-bootstrap-formutil即可
    loader: require.resolve('babel-loader'),
    options: {
        babelrc: false,
        plugins: [[
            "import",
            {
                "libraryName": "react-bootstrap"
            },
            "react-bootstrap"
        ]]
    }
}

如何正确的使用FormGroup嵌套渲染多个节点元素?

你可以通过给给children属性传递render props函数,来自由定义要渲染出的节点。但是请注意,当传递一个render props函数时,需要手动绑定相关绑定事件和 value 属性!

children函数接受一个$fieldHandler的对象,默认情况下其包含value onChange onFocus onBlur四个属性,但是如果你给FormItem传递了valuePropName等属性的话,这个值将会变为你通过valuePropName所定义的名字。

更具体解释可以参考 react-formutil.$fieldHandler

<FormGroup name="username">
    {$fieldHandler => (
        <>
            <FormControl {...$fieldHandler} />
            <div>其它节点内容</div>
        </>
    )}
</FormGroup>