组件演示
.demo-basic {
max-width: 652px;
}
import { Button } from 'uxcore';
import { Form } from 'uxcore';
const {
InputFormField: Input,
DateFormField: Date,
TextAreaFormField: TextArea,
OtherFormField: Other,
} = Form;
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
handleSubmit() {
console.log(this.form.getValues());
}
render() {
return (
<div className="demo-basic">
<Form ref={(c) => { this.form = c; }} className="demo-basic-form">
<Input jsxname="theme" jsxlabel="主题" jsxplaceholder="请输入主题" />
<Input jsxname="location" jsxlabel="地点" jsxplaceholder="请输入地点" />
<Date jsxname="date" jsxlabel="时间" jsxtype="cascade" autoMatchWidth />
<TextArea jsxname="content" jsxlabel="内容" inputBoxMaxWidth="large" />
<Other>
<Button style={{ marginLeft: '88px', marginTop: '16px' }} onClick={() => { this.handleSubmit(); }}>确定</Button>
</Other>
</Form>
</div>
);
}
}
ReactDOM.render(<Demo />, document.getElementById('components-form-demo-basic'));
.demo-layout {
max-width: 652px;
}
import { Button } from 'uxcore';
import { Form } from 'uxcore';
const {
Constants,
FormRowTitle,
FormRow: Row,
InputFormField: Input,
SelectFormField: Select,
DateFormField: Date,
TextAreaFormField: TextArea,
ButtonGroupFormField,
OtherFormField: Other,
} = Form;
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {
values: {
layout: 'h',
},
};
}
handleSubmit() {
console.log(this.form.getValues());
}
handleChange(values) {
this.setState({
values,
});
}
render() {
const me = this;
const isV = () => this.state.values.layout === 'v';
return (
<div className="demo-layout">
<Form
ref={(c) => { this.form = c; }}
className="demo-basic-form"
jsxvalues={this.state.values}
jsxonChange={(values) => { this.handleChange(values); }}
verticalAlign={isV()}
>
<Select
jsxname="layout"
jsxlabel="布局"
jsxdata={[
{ value: 'h', text: '横向' },
{ value: 'v', text: '竖向' },
]}
/>
<Input jsxname="location" jsxlabel="地点" jsxplaceholder="请输入地点" />
<Date jsxname="date" jsxlabel="时间" jsxtype="cascade" autoMatchWidth />
<TextArea jsxname="content" jsxlabel="内容" />
<Other>
<Button style={{ marginLeft: isV() ? '0px' : '88px', marginTop: '16px' }} onClick={me.handleSubmit.bind(me)}>确定</Button>
</Other>
</Form>
</div>
);
}
}
ReactDOM.render(<Demo />, document.getElementById('components-form-demo-layout'));
.demo-size {
max-width: 652px;
}
import { Button } from 'uxcore';
import { Form } from 'uxcore';
const {
Constants,
FormRowTitle,
FormRow: Row,
InputFormField: Input,
SelectFormField: Select,
DateFormField: Date,
TextAreaFormField: TextArea,
ButtonGroupFormField,
OtherFormField: Other,
} = Form;
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {
values: {
size: 'large',
},
};
}
handleSubmit() {
console.log(this.form.getValues());
}
handleChange(values) {
this.setState({
values,
});
}
render() {
const me = this;
return (
<div className="demo-size">
<Form
ref={(c) => { this.form = c; }}
className="demo-basic-form"
jsxvalues={this.state.values}
jsxonChange={(values) => { this.handleChange(values); }}
size={this.state.values.size}
>
<Select
jsxname="size"
jsxlabel="尺寸"
jsxdata={[
{ value: 'large', text: '大' },
{ value: 'middle', text: '中' },
{ value: 'small', text: '小' },
]}
/>
<Input jsxname="location" jsxlabel="地点" jsxplaceholder="请输入地点" />
<Date jsxname="date" jsxlabel="时间" jsxtype="cascade" autoMatchWidth />
<TextArea jsxname="content" jsxlabel="内容" />
<Other>
<Button style={{ marginLeft: '88px', marginTop: this.state.values.size === 'small' ? '12px' : '16px' }} onClick={me.handleSubmit.bind(me)}>确定</Button>
</Other>
</Form>
</div>
);
}
}
ReactDOM.render(<Demo />, document.getElementById('components-form-demo-size'));
.demo-validator {
max-width: 652px;
}
import { Button } from 'uxcore';
import { Form } from 'uxcore';
import { Icon } from 'uxcore';
import { Tooltip } from 'uxcore';
const {
InputFormField: Input,
DateFormField: Date,
TextAreaFormField: TextArea,
OtherFormField,
SelectFormField,
Validators,
} = Form;
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {
mode: true,
};
}
handleSubmit() {
console.log(this.form.getValues(true));
}
handleModeChange(values, name) {
console.log(values[name]);
this.setState({
mode: values[name] === 'true',
});
}
render() {
const me = this;
return (
<div className="demo-validator">
<Form className="form-select" jsxvalues={{ mode: 'true' }} jsxonChange={me.handleModeChange.bind(me)}>
<SelectFormField jsxdata={{ true: '实时校验', false: '非实时校验' }} jsxname="mode" jsxlabel="校验模式" showSearch={false} />
</Form>
<Form ref={(c) => { this.form = c; }} className="demo-basic-form" instantValidate={me.state.mode}>
<Input
jsxname="theme"
jsxlabel="主题"
required
jsxtips="这是一个提示"
jsxplaceholder="请输入主题"
jsxrules={[
{ validator: Validators.isNotEmpty, errMsg: '不能为空' },
{ validator(value) { return value.length <= 3; }, errMsg: '不能超过3个字' },
]}
/>
<Input
jsxname="location"
jsxlabel="地点"
required
jsxplaceholder="请输入地点"
jsxrules={[
{ validator: Validators.isNotEmpty, errMsg: '不能为空' },
]}
/>
<Date jsxname="date" jsxlabel="时间" jsxtype="cascade" autoMatchWidth />
<TextArea
jsxname="content"
jsxlabel="内容"
required
jsxrules={[
{ validator: Validators.isNotEmpty, errMsg: '不能为空' },
]}
/>
<OtherFormField>
<Button style={{ marginLeft: '88px', marginTop: '16px' }} onClick={me.handleSubmit.bind(me)}>确定</Button>
</OtherFormField>
</Form>
</div>
);
}
}
ReactDOM.render(<Demo />, document.getElementById('components-form-demo-validator'));
.demo-horizon {
max-width: 652px;
}
import { Button } from 'uxcore';
import { Form } from 'uxcore';
const {
Constants,
FormRowTitle,
FormRow: Row,
InputFormField: Input,
DateFormField: Date,
TextAreaFormField: TextArea,
OtherFormField,
Validators,
} = Form;
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
handleSubmit() {
console.log(this.refs.form.getValues());
}
render() {
const me = this;
return (
<div className="demo-horizon">
<style />
<Form ref="form" className="demo-horizon-form">
<Row>
<Input jsxname="theme" jsxlabel="主题" required jsxplaceholder="请输入主题" jsxrules={[
{ validator: Validators.isNotEmpty, errMsg: '不能为空' },
{ validator(value) { return value.length < 3; }, errMsg: '不能超过3个字' },
]}
/>
<Input jsxname="location" jsxlabel="地点" required jsxplaceholder="请输入地点" jsxrules={[
{ validator: Validators.isNotEmpty, errMsg: '不能为空' },
]}
/>
</Row>
<TextArea jsxname="content" jsxlabel="内容" required jsxrules={[
{ validator: Validators.isNotEmpty, errMsg: '不能为空' },
]}
/>
<OtherFormField>
<Button style={{ marginLeft: '88px', marginTop: '16px' }} onClick={me.handleSubmit.bind(me)}>确定</Button>
</OtherFormField>
</Form>
</div>
);
}
}
ReactDOM.render(<Demo />, document.getElementById('components-form-demo-horizon'));
import { Button } from 'uxcore';
import { Form } from 'uxcore';
const {
InputFormField: Input,
TextAreaFormField: TextArea,
OtherFormField: Other,
} = Form;
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
handleSubmit() {
console.log(this.form.getValues());
}
render() {
return (
<div className="demo-max-width">
<Form ref={(c) => { this.form = c; }} className="demo-basic-form">
<Input jsxname="theme" jsxlabel="主题" jsxplaceholder="请输入主题" inputBoxMaxWidth="middle" />
<Input jsxname="location" jsxlabel="地点" jsxplaceholder="请输入地点" inputBoxMaxWidth="middle" />
<TextArea jsxname="content" jsxlabel="内容" inputBoxMaxWidth="large" />
<Other>
<Button style={{ marginLeft: '88px', marginTop: '16px' }} onClick={() => { this.handleSubmit(); }}>确定</Button>
</Other>
</Form>
</div>
);
}
}
ReactDOM.render(<Demo />, document.getElementById('components-form-demo-max-width'));
.demo-mode {
max-width: 652px;
}
.demo-mode .other {
padding-top: 16px;
}
import { Button } from 'uxcore';
import { Form } from 'uxcore';
const {
Constants,
FormRowTitle,
FormRow: Row,
InputFormField: Input,
DateFormField: Date,
TextAreaFormField: TextArea,
OtherFormField,
SelectFormField,
Validators,
} = Form;
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {
mode: Constants.MODE.EDIT,
};
}
handleSubmit() {
console.log(this.form.getValues());
}
handleChangeMode() {
this.setState({
mode: this.state.mode === Constants.MODE.EDIT ? Constants.MODE.VIEW : Constants.MODE.EDIT,
});
}
render() {
const me = this;
return (
<div className="demo-mode">
<Form
ref={(c) => { this.form = c; }}
className="demo-basic-form"
jsxvalues={{
theme: 'Form 展示',
location: 'Uxcore 站点',
date: ['2015-10-15', '2015-11-15'],
content: '这是一个 Form 的模式转换页面。',
}}
jsxmode={me.state.mode}
>
<Input jsxname="theme" jsxlabel="主题" required jsxplaceholder="请输入主题" />
<Input
jsxname="location"
jsxlabel="地点"
required
jsxplaceholder="请输入地点"
jsxrules={[
{ validator: Validators.isNotEmpty, errMsg: '不能为空' },
]}
/>
<Date jsxname="date" jsxlabel="时间" jsxtype="cascade" autoMatchWidth />
<TextArea
jsxname="content"
jsxlabel="内容"
required
jsxrules={[
{ validator: Validators.isNotEmpty, errMsg: '不能为空' },
]}
/>
<OtherFormField className="other">
<Button style={{ marginLeft: '88px', marginRight: '8px' }} onClick={me.handleSubmit.bind(me)}>确定</Button>
<Button style={{ marginRight: '8px' }} type="secondary" onClick={me.handleChangeMode.bind(me)}>转换模式</Button>
</OtherFormField>
</Form>
</div>
);
}
}
ReactDOM.render(<Demo />, document.getElementById('components-form-demo-mode'));
.demo-search {
max-width: 652px;
}
import classnames from 'classnames';;
import assign from 'object-assign';;
import { Form } from 'uxcore';
const {
Constants,
FormRowTitle,
FormRow,
SearchFormField,
} = Form;
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
const me = this;
const searchOptions = {
jsxname: 'search',
dataType: 'jsonp',
placeholder: '搜索商品',
jsxfetchUrl: 'http://suggest.taobao.com/sug',
classOptions: [
{
value: '1',
text: '类别一',
},
{
value: '2',
text: '类别二',
},
],
classConfig: {
placeholder: '类别',
},
afterFetch: (obj) => {
const data = {};
obj.result.forEach((item, index) => {
data[item[1]] = item[0];
});
return data;
},
onIconClick: (e) => {
console.log(me.refs.form.getValues());
},
};
const tidyVer = assign({}, searchOptions, {
jsxname: 'tidy',
tidy: true,
advancedOptions: [],
classOptions: [],
});
return (
<div className="demo-search">
<Form ref="form">
<FormRowTitle jsxtitle="标准搜索" />
<SearchFormField {...searchOptions} />
<FormRowTitle jsxtitle="精简搜索" />
<SearchFormField {...tidyVer} />
</Form>
</div>
);
}
}
ReactDOM.render(<Demo />, document.getElementById('components-form-demo-search'));
目前 Form 已经提供了12种通用表单域,满足各种场景的需求。 Form 中所有表单域的默认值由 jsxvalues 统一管理。 通用表单域不满足业务需求?点此查看如何自定义表单域
.demo-comp .other {
padding-top: 16px;
}
import classnames from 'classnames';;
import { Button } from 'uxcore';
import { Form } from 'uxcore';
import { PickableFormField } from 'uxcore';
const {
Constants,
FormRowTitle,
FormRow,
FormField,
InputFormField,
Validators,
RadioGroupFormField,
SelectFormField,
TextAreaFormField,
NumberInputFormField,
DateFormField,
CheckboxGroupFormField,
CascadeSelectFormField,
OtherFormFieconstld,
ButtonGroupFormField,
EditorFormField,
SwitchFormField,
OtherFormField,
} = Form;
const CheckboxItem = CheckboxGroupFormField.Item;
const RadioItem = RadioGroupFormField.Item;
const { Count, LeftAddon, RightAddon } = InputFormField;
const Option = SelectFormField.Option;
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {
showPass: false,
jsxvalues: {
test1: '我是测试',
fruit: 'apple',
number: 1,
city: 'nj',
option: '1',
// textArea: "我是多行文本",
// date: "2015-09-01",
goods2: ['a', 'b'],
checkbox: ['sea'],
dicts: {
datas: [
{
city: 'hz',
email: '333',
name: '33',
},
],
},
cascade: ['a', 'ab'],
},
jsxdata: {
bj: '北京',
nj: '南京南京南京南京南京南京南京南京南京南京南京南京南京南京',
dj: '东京',
xj: '西京',
},
mode: Constants.MODE.EDIT,
};
}
handleClick() {
const me = this;
console.log(JSON.stringify(me.form.getValues(true)));
}
handleSetValues() {
const me = this;
me.form.setValues({
test1: '我不是测试',
});
}
handleShowPassChange() {
const me = this;
me.setState({
showPass: !me.state.showPass,
});
}
handleFormClick(data) {
this.form.setState({
mode: Constants.MODE.VIEW,
});
}
update() {
console.log('work');
this.forceUpdate();
}
handleChange(value, name, pass) {
console.log(value, name, pass);
const me = this;
// if (name == 'number') {
// me.form.setValues({
// number: 1
// })
// }
}
handleReset() {
this.form.resetValues();
}
handleKeyDown(e) {
if (e.keyCode == Form.KeyCode.Enter) {
console.log('enter');
}
}
handleTextAreaBlur(e, pass) {
console.log(e, pass);
}
changeMode() {
this.setState({
mode: this.state.mode == Constants.MODE.EDIT ? Constants.MODE.VIEW : Constants.MODE.EDIT,
});
}
handleValueChange() {
const me = this;
me.setState({
jsxvalues: {
test1: '我是测试22',
fruit: 'apple',
city: [],
textArea: '我是多行文本',
date: '2015-09-01',
checkbox: ['sea'],
// cascade: ["a", "ab"]
},
jsxdata: {
bj: '北',
nj: '南',
dj: '东',
xj: '西',
},
});
}
render() {
const me = this;
const data = {
test1: '我是测试',
fruit: 'apple',
city: 'nj',
textArea: '我是多行文本',
date: '2015-09-01',
checkbox: ['sea'],
// cascade: ["a", "ab"]
};
const casData = {
length: 3,
contents: [
{
value: 'a',
text: 'A',
contents: [
{
value: 'ab',
text: 'AB',
contents: [
{
value: 'abc',
text: 'ABC',
},
{
value: 'abd',
text: 'ABD',
},
],
},
{
value: 'ac',
text: 'AC',
contents: [
{
value: 'acb',
text: 'ACB',
},
{
value: 'acd',
text: 'ACD',
},
],
},
],
},
{
value: 'b',
text: 'B',
contents: [
{
value: 'ba',
text: 'BA',
contents: [
{
value: 'bab',
text: 'BAB',
},
{
value: 'bad',
text: 'BAD',
},
],
},
{
value: 'bc',
text: 'BC',
contents: [
{
value: 'bca',
text: 'BCA',
},
{
value: 'bcd',
text: 'BCD',
},
],
},
],
},
],
};
const columns = [
{ dataKey: 'city',
title: '城市',
width: 180,
type: 'select',
options: {
hz: '杭州',
bj: '北京',
sh: '上海',
ah: '安徽',
} },
{ dataKey: 'name', title: '姓名', width: 200, type: 'text' },
{ dataKey: 'email', title: 'Email', width: 200, type: 'text' },
{ dataKey: 'action1',
title: '操作1',
width: 100,
type: 'action',
actions: {
增加(rowData) {
me.refs.grid.addEmptyRow();
},
删除(rowData) {
me.refs.grid.delRow(rowData);
},
},
},
];
const renderProps = {
jsxcolumns: columns,
};
const itemsData = [{
text: '条件一',
value: 1,
num: 15,
}, {
text: '条件二',
value: 2,
num: 20,
}, {
text: '条件三',
value: 3,
disable: true,
}];
return (
<div className="demo-comp">
<Form
ref={(c) => { this.form = c; }}
instantValidate
jsxmode={me.state.mode}
jsxvalues={me.state.jsxvalues}
jsxonChange={me.handleChange.bind(me)}
>
<FormRowTitle jsxtitle="我是行标题" />
<FormRow>
<InputFormField
labelMatchInputHeight
required
jsxname="test1"
jsxdisabled={false}
autoTrim={false}
jsxlabel="普通输入框普通输入框"
jsxtips="请输入数字"
validateOnBlur={false}
onKeyDown={me.handleKeyDown.bind(me)}
jsxrules={{ validator: Validators.isNotEmpty, errMsg: '不能为空' }}
>
<LeftAddon>
<i className="kuma-icon kuma-icon-phone" />
</LeftAddon>
<RightAddon>
<span style={{ lineHeight: '24px' }}>元</span>
</RightAddon>
<Count total={20} />
</InputFormField>
<NumberInputFormField
jsxname="number"
jsxlabel="数字输入框"
jsxtype="money"
delimiter=","
fixedNum={4}
jsxplaceholder="输入数字"
jsxtips="数字和一般的输入框不同"
jsxrules={[
{ validator: Validators.isNotEmpty, errMsg: '不能为空' },
{ validator: Validators.isNum, errMsg: '请输入数字' },
]}
/>
<ButtonGroupFormField jsxshow={false}>
<Button size="medium" type="primary" action="submit" onClick={me.handleFormClick.bind(me)}>提交</Button>
<Button size="medium" type="secondary" action="reset">取消</Button>
</ButtonGroupFormField>
</FormRow>
<FormRow>
<RadioGroupFormField jsxname="fruit" jsxlabel="Radio" jsxflex={1}>
<RadioItem value="apple" text="Apple" />
<RadioItem value="orange" text="Orange" />
<RadioItem value="watermelon" text="Watermelon" />
</RadioGroupFormField>
<CheckboxGroupFormField jsxname="checkbox" jsxlabel="复选框">
<CheckboxItem value="air" text="天空" />
<CheckboxItem value="sea" text="大海" />
</CheckboxGroupFormField>
</FormRow>
<InputFormField jsxname="pass" jsxlabel="请输入密码" inputType={me.state.showPass ? 'text' : 'password'}>
<RightAddon>
<i className={classnames({
'kuma-icon': true,
'kuma-icon-privacy': !me.state.showPass,
'kuma-icon-public': me.state.showPass,
})} onClick={me.handleShowPassChange.bind(me)}
/>
</RightAddon>
</InputFormField>
<FormRow>
<SwitchFormField jsxname="switch" jsxlabel="开关" checkedChildren="显示" unCheckedChildren="隐藏" />
<PickableFormField
jsxlabel="test:"
jsxname="test"
multiple
type="hook"
>
{itemsData.map((data, index) => (
<PickableFormField.Item key={index} value={data.value} number={data.num} disabled={data.disable}>{data.text}</PickableFormField.Item>
))}
</PickableFormField>
</FormRow>
<TextAreaFormField jsxname="textArea"
jsxlabel="多行文本框"
jsxrules={{ validator: Validators.isNotEmpty, errMsg: '不能为空' }}
jsxplaceholder="测试"
validateOnBlur={false}
onBlur={me.handleTextAreaBlur.bind(me)}
/>
<FormRowTitle jsxtitle="我是行标题2" />
<FormRow>
<SelectFormField
jsxlabel="单选"
jsxname="city"
allowClear
jsxrules={{ validator: Validators.isNotEmpty, errMsg: '不能为空' }}
disabled={false}
jsxdata={me.state.jsxdata}
/>
<DateFormField format="yyyy-MM-dd HH:mm:ss" jsxname="date" jsxlabel="日期" jsxto={'2016-05-24'} locale="zh-cn" />
</FormRow>
<FormRow>
<SelectFormField
jsxlabel="单选 combo 模式"
disabled={false}
jsxname="goods"
jsxfetchUrl="http://suggest.taobao.com/sug"
dataType="jsonp"
combobox
afterFetch={(obj) => {
const data = {};
obj.result.forEach((item, index) => {
data[item[1]] = item[0];
});
return data;
}}
/>
<SelectFormField
jsxlabel="多选模式"
jsxname="goods2"
multiple
jsxfetchUrl="http://suggest.taobao.com/sug"
jsxdata={{
a: 'A',
b: 'B',
}}
beforeFetch={function (data) {
console.log(data);
if (data.q == undefined) {
data.q = 'a';
}
return data;
}}
dataType="jsonp"
afterFetch={(obj) => {
const newData = {};
obj.result.forEach((item) => {
newData[item[1]] = item[0];
});
return newData;
}}
/>
</FormRow>
<SelectFormField
jsxname="option"
jsxlabel="传 option"
>
<Option value="1">第一个选项</Option>
<Option value="2">第二个选项</Option>
<Option value="3">第三个选项</Option>
</SelectFormField>
<FormRowTitle jsxtitle="级联类" />
<DateFormField showTime jsxtype="cascade" jsxname="casDate" jsxlabel="级联日期" format="yyyy/MM/dd" />
<CascadeSelectFormField
jsxdata={casData}
allowClear
jsxplaceholder={['选项一', '选项二', '选项三']}
jsxname="cascade"
jsxlabel="级联选择"
/>
<EditorFormField
jsxname="editor"
jsxlabel="富文本编辑器"
placeholder="测试"
/>
<OtherFormField className="other">
<Button style={{ marginLeft: '88px', marginRight: '8px' }} onClick={me.handleClick.bind(me)}>提交</Button>
<Button style={{ marginRight: '8px' }} type="secondary" onClick={me.handleReset.bind(me)}>重置</Button>
<Button style={{ marginRight: '8px' }} type="secondary" onClick={me.handleSetValues.bind(me)}>手动setValues</Button>
<Button style={{ marginRight: '8px' }} type="secondary" onClick={me.handleValueChange.bind(me)}>修改 props</Button>
<Button style={{ marginRight: '8px' }} type="secondary" onClick={me.changeMode.bind(me)}>转变模式</Button>
<Button style={{ marginRight: '8px' }} type="secondary" onClick={me.update.bind(me)}>强制刷新</Button>
</OtherFormField>
</Form>
</div>
);
}
}
ReactDOM.render(<Demo />, document.getElementById('components-form-demo-comp'));
更多使用场景,请参考 场景 -> 表单相关 部分。
API
Form
getValues(force) 获取目前的 values 和 pass(是否通过检测)。 参数:
- force
Boolean
: 强制校验或不校验,undefined 时则忽略此配置。
- force
resetValues() 重置所有的 FormField,如果有默认值则重置为默认值。
setValues(data) 手动设置各个 FormField 的值,在表单联动时可能会用得到。 参数:
- data
Object
: 和 jsxvalues 的格式相同。
- data
isDirty() 获取目前的表单是否没有通过检测,返回 true 或 false。
doValidate(force, always) 获取目前的表单是否通过检测,返回 true 或者 false。
- force:是否强制校验,无视不校验的规则。
- always:强制校验通过或者失败,通常可以用于清空出错状态。
doValidateAndScroll(force, always) 获取目前的表单是否通过检测并滚动至第一个出错的 field,参数同上。
Form.createFormField(options)
Name | Type | Require | Default | Since Ver. | Note |
---|---|---|---|---|---|
options.component | React Element | yes | input | 1.8.12 | 被包裹的组件,需要提供 value 和 onChange,或相同功能的 API |
options.valuePropName | string | No | value | 1.8.12 | 与 value 对应的 prop 名字 |
options.changePropName | string | No | onChange | 1.8.12 | 与 onChange 对应的 prop 名字 |
options.processValue | func(value, ...other) | No | - | 1.8.12 | 针对 value(editKey 对应字段)的处理函数 |
options.renderView | func(value) | No | val => JSON.stringify(val) |
1.8.12 | 定制化渲染 view 状态 |
props
Form
配置项 | 类型 | 必填 | 默认值 | 功能/备注 |
---|---|---|---|---|
className | string | optional | "" | 加入额外的类名,在使用 kuma 的基础上进行适当的定制时会用得到 |
jsxprefixCls | string | optional | "kuma-form" | 默认类名,用户可以通过修改此项来完成样式的定制 |
jsxmode | string | optional | "EDIT" | Form 编辑和只读模式,传值方式见 demo |
jsxvalues | object | optional | - | 传入表单的初始值,格式见 Usage,每一个 key 与 formField 中的 jsxname 相对应,注意是初始值,不要把 onChange 中的变化同步到这里 |
jsxonChange | function(values, name, pass) | optional | noop | 当表单中值有变化时触发,传回 values,格式同 jsxvalues,同时传回发生变化的表单域的 name,以及该表单域是否通过校验 |
instantValidate | boolean | optional | true | 是否开启即时校验 |
asyncValidate | boolean | optional | false | 是否开启异步校验模式,目前仅支持全局配置 |
verticalAlign | boolean | optional | false | 表单域是否竖排 |
size | string | optional | large | 尺寸,支持 large、middle、small |
jsxvalues 的格式
{
jsxname1: value1,
jsxname2: value2
}
FormRow
配置项 | 类型 | 必填 | 默认值 | 功能/备注 |
---|---|---|---|---|
className | string | optional | "" | 加入额外的类名,在使用 kuma 的基础上进行适当的定制时会用得到 |
jsxprefixCls | string | optional | "kuma-form-row" | 默认类名,用户可以通过修改此项来完成样式的定制 |
FormField 通用配置
配置项 | 类型 | 必填 | 默认值 | 功能/备注 |
---|---|---|---|---|
className | string | optional | "" | 加入额外的类名,在使用 kuma 的基础上进行适当的定制时会用得到 |
jsxshow | bool | optional | true | 是否显示该表单域,不显示的表单域将不占宽度 |
jsxmode | string | optional | "EDIT" | FormField 的编辑和只读模式,优先级高于 Form,传值方式见 demo |
jsxshowLabel | bool | optional | true | 是否显示 label |
jsxname | string | required | - | 表单字段,返回值时该字段将作为 key |
jsxlabel | string | required | - | 左侧的说明文字,不写即为留白 |
jsxprefixCls | string | optional | "kuma-form-field" | 默认类名,用户可以通过修改此项来完成样式的定制 |
jsxflex | number | optional | 1 | 占 FormRow 宽的比例,类似于 css3 中的 flex-box |
jsxtips | string | optional | "" | 说明文字 |
jsxrules | object/array | optional | - | validators,具体用法和格式见 Usage,Form 已经提供了一些现成的 validator 供使用。也可以自己编写 |
instantValidate | boolean | optional | true | 是否开启即时校验 |
verticalAlign | boolean | optional | false | 表单域是否竖排 |
inputBoxMaxWidth | string | optional | - | 泛指的输入框的最大宽度,通常用于较宽页面 |
Validators
Form 提供了一些通用的 validator,通过 Form.Validators 来引入。用法还是见 Usage 和
demo/formDemo.js
包括: 所有的 validator 返回 true,表示通过。 validator 也可以自己定义,会传入相应的表单值,根据判断,返回 true,表示通过。
- isNotEmpty
- isNum
- isInt: 是否是整数
- isDecimal: 是否是小数
- isArray
- isRegExp
- isObject
- isFunc
- isEmail
- isUrl
- isHex
- isIdCard: 是否是中国身份证。
- isCNMobile: 是否是中国手机号。
FormField 专属配置
所有的 FormField 都共享通用配置,所有的专属配置在
demo/formDemo.js
,均有体现。
InputFormField
配置项 | 类型 | 必填 | 默认值 | 功能/备注 | 版本 |
---|---|---|---|---|---|
jsxplaceholder | string | optional | "" | 占位符 | - |
jsxdisabled | boolean | optional | false | disable 状态 | - |
validateOnBlur | boolean | optional | false | 验证是否是在 blur 的时候出发,默认情况是在 change 时触发,此项为 true 后,onChange 的 pass 永远为 true,相对应的 onBlur 的 pass 会随之变化 | 1.2.10 |
onKeyDown | function(e) | optional | noop | 监听键盘事件 | |
onBlur | function(e, pass) | optional | noop | 输入框 blur 时触发,第二个参数为验证是否通过,若 validateOnBlur 为 false,则 pass 永远为 true | 1.2.10 |
onFocus | function(e) | optional | noop | 输入框获取焦点时触发 | 1.2.10 |
renderView | function(value) | optional | noop | 自定义渲染 view 状态,参数是默认渲染的值 | 1.6.0 |
autoTrim | boolean | optional | - | 自动去除值两端的空格 | 1.2.12 |
inputType | string | optional | 'text' | input 的 type,目前支持 "text" 和 "password" | 1.2.23 |
插件:
- Count,通过 InputFormField.Count 取得,一个内置的计数器,用法如下:
<InputFormField> <Count total="20"> </InputFormField>
- LeftAddon/RightAddon,通过 InputFormField.LeftAddon/InputFormField.RightAddon 取得,给 input 左侧加入自定义的图标或文字,用法如下:
<InputFormField> <LeftAddon> <i className="kuma-icon kuma-icon-phone"></i> </LeftAddon> <RightAddon> <span>元</span> </RightAddon> </InputFormField>
TextAreaFormField
配置项 | 类型 | 必填 | 默认值 | 功能/备注 | |
---|---|---|---|---|---|
jsxplaceholder | string | optional | "" | 占位符 | |
validateOnBlur | boolean | optional | false | 验证是否是在 blur 的时候出发,默认情况是在 change 时触发,此项为 true 后,onChange 的 pass 永远为 true,相对应的 onBlur 的 pass 会随之变化 | 1.2.11 |
onKeyDown | function(e) | optional | noop | 监听键盘事件 | |
onBlur | function(e, pass) | optional | noop | 输入框 blur 时触发,第二个参数为验证是否通过,若 validateOnBlur 为 false,则 pass 永远为 true | 1.2.11 |
onFocus | function(e) | optional | noop | 输入框获取焦点时触发 | 1.2.11 |
autoTrim | boolean | optional | - | 自动去除值两端的空格 | 1.2.12 |
autosize | boolean | optional | true | 根据内容自动撑开(IE8 下无效) | 1.3.10 |
配置 autosize 的同时,还可以通过样式指定 min-height 和 max-height
插件:
- Count,通过 TextAreaFormField.TextAreaCount 取得,一个内置的计数器,用法如下:
<TextAreaFormField> <TextAreaCount total={100}> </TextAreaFormField>
RadioGroupFormField
配置项 | 类型 | 必填 | 默认值 | 功能/备注 |
---|---|---|---|---|
jsxdisabled | boolean | optional | false | disable 状态 |
- Item:通过 RadioGroupFormField.Item 取得,有两个 props
- value
- text:显示的值
- 使用方式:
<RadioGroupFormField>
<Item value="1" text="a">
<Item value="2" text="b">
<Item value="3" text="c">
</RadioGroupFormField>
SelectFormField
配置项 | 类型 | 必填 | 默认值 | 功能/备注 |
---|---|---|---|---|
jsxdata | object | optional | - | 传入用于生成列表的数据,格式为{value: text} |
jsxfetchUrl | string | optional | - | 如果 Select 是通过搜索异步获取选项,则需要填入此项 |
jsxstyle | obj | optional | - | 与 react 传入 style 的方式相同,修改选择框的样式 |
beforeFetch | func | optional | - | 会传入 {q: value}, value 为搜索框中变化的值,在发出 ajax 请求之前,将数据处理为应该发送的格式,并需返回该数据。 |
afterFetch | func | optional | - | 会传入返回的数据, 将其处理为 jsxdata 的格式并返回 |
dataType | string | optional | 'json' | 发送 ajax 请求的类型 |
jsxdata 的格式
jsxdata 目前支持两种格式
// Object
{
a: "A",
b: "B"
}
// Array
[
{
value: 'a',
text: 'A'
}
]
配置 jsxfetchUrl 后,会在组件渲染后立刻以空搜索值发起一次请求,我们强烈建议服务端完善空值搜索的请求处理逻辑,返回热点数据和用户关联数据,以提供更好的选择体验。
此外,SelectFormField 还支持 uxcore-select2 除 onSelect/onDeselect 外的全部属性。
SearchFormField
配置项 | 类型 | 必填 | 默认值 | 功能/备注 |
---|---|---|---|---|
advancedOptions | array | optional | - | 右侧高级选项的选择项:格式为[{value: xxx, text: xxx}] |
advancedConfig | object | optional | - | 右侧高级选项的配置,同 uxcore-select2 |
classOptions | array | optional | - | 左侧类别选项的选择项:格式为[{value: xxx, text: xxx}] |
classConfig | object | optional | - | 左侧类别选项的配置,同 uxcore-select2 |
tidy | bool | optional | - | 精简模式 |
onIconClick | function(e) | optional | - | 点击搜索图标触发回调 |
该组件继承自 SelectFormField,支持 SelectFormField 的全部 props。
CheckboxGroupFormField
配置项 | 类型 | 必填 | 默认值 | 功能/备注 |
---|---|---|---|---|
jsxdisabled | boolean | optional | false | disable 状态 |
- Item:通过 CheckboxGroupFormField.Item 取的,有两个 props
- value
- text:显示的值
- disabled:该 Item 的 disable 状态。
- addon: 额外指定的信息,例如tips
- 使用方式:
<CheckboxGroupFormField>
<Item value="1" text="a" disabled={true} />
<Item value="2" text="b" />
<Item value="3" text="c"
addon={
<Tooltip overlay={<div>提示</div>}>
<i className='kuma-icon kuma-icon-caution' style={{color: 'blue', fontSize: '12px', 'marginLeft': '3px'}} />
</Tooltip>
}
/>
</CheckboxGroupFormField>
DateFormField
配置项 | 类型 | 必填 | 默认值 | 功能/备注 |
---|---|---|---|---|
jsxtype | string | optional | single | single/cascade 单独、级联 |
jsxfrom | string | optional | - | 开始日期 |
jsxto | string | optional | - | 结束日期 |
panel | string | optional | "day" | 何种面板,枚举值为"month","year"和"day" |
autoMatchWidth | boolean | optional | false | 从 1.8.11 版本支持,在级联状态下输入框自动匹配宽度 |
除此之外,支持除 onSelect,uxcore-calendar 的所有 props。
NumberInputFormField
配置项 | 类型 | 必填 | 默认值 | 功能/备注 |
---|---|---|---|---|
jsxplaceholder | string | optional | "" | 占位符 |
jsxtype | string | optional | "" | 目前支持 "money", "cnmobile" 和 "card", 提供三种格式化显示的方法。"money"的格式为123 121 121.213 121 ,"cnmobile"的格式为 86 1565 7263 8223 , "card" 的格式为 3321 3123 3243 4343 |
fixedNum | number | optional | - | 锁定小数位 |
delimiter | string | optional | ' ' | 分隔符 |
formatOnBlur | bool | optional | false | 在失焦时进行格式化(6.2.0 后支持) |
CascadeSelectFormField
配置项 | 类型 | 必填 | 默认值 | 功能/备注 |
---|---|---|---|---|
jsxdata | object | required | - | 级联选择框,只支持直接传入 data 初始化,格式见 Usage 中的 casData,length 为必须传的 key,告诉 field 有几层级联。 |
jsxplaceholder | string | optional | "请下拉选择" | 占位符 |
jsxstyle | object | optional | - | 与 react 传入 style 的方式相同,修改选择框的样式 |
getPopupContainer | function():React Element | optional | - | 弹出的菜单渲染在哪个容器中,需返回一个 DOM Node |
PickableFormField
配置项 | 类型 | 必填 | 默认值 | 功能/备注 |
---|---|---|---|---|
multiple | boolean | optional | true | 是否支持多选 |
value | string/number | required | - | pickable Item 对应的值 |
type | string | optional | normal | 样式风格,可选值为normal,simple,hook |
max | number | optional | 99 | 最大显示的数字,超过 max,显示 max+ |
EditorFormField
配置项 | 类型 | 必填 | 默认值 | 功能/备注 |
---|---|---|---|---|
placeholder | string | optional | "" | 占位符 |
jsxcontent | string | optional | "" | 已废弃,默认值直接通过 Form 的 jsxvalues 即可传递 |
jsxconfig | object | optional | {} | 用户自定义的配置项,tinyMCE 的配置项,官方文档中所有 init 部分的配置在这里完成,详细见 http://www.tinymce.com/wiki.php/Configuration |
API
setContent(content):设置 EditorFormField 的值,很不幸,EditorFormField 无法做成完全受控的组件,因为 setContent 操作会导致搜狗等中文输入法使用障碍,因此 EditorFormField 的值重置通过这个 API 来完成,或者也可以使用 Form 的 setValues 方法。
OtherFormField
OtherFormField 是一个特殊的 FormField,它用来和其他 FormField 一起完成布局(比如在一行排列等),如果需要一些装饰类的东西,可以以子元素的形式传入到这个 Field 里。 他也可以用于布局中的占位。
ButtonGroupFormField
ButtonGroupFormField 是一个特殊的 FormField,它用来生成一些特定的表单按钮,这是为了与 Grid 相结合而准备的。如果需要自定义一些按钮,请使用 OtherFormField 和 uxcore-button 相结合来使用。 你可以像这样使用它:
`
javascript var Button = require('uxcore-button');
`