# 自定义组件
Form.io渲染器允许创建自定义组件。这些可以通过在Form.io中扩展基本组件,然后在核心渲染器中注册它们来创建。这可以如下进行。
# 创建自定义组件
import Base from 'formiojs/components/_classes/component/Component';
import editForm from 'formiojs/components/table/Table.form'
export default class CheckMatrix extends Base {
constructor(component, options, data) {
super(component, options, data);
this.foo = 'bar';
}
static schema() {
return Base.schema({
type: 'checkmatrix',
numRows: 3,
numCols: 3
});
}
static builderInfo = {
title: 'Check Matrix',
group: 'basic',
icon: 'fa fa-table',
weight: 70,
documentation: 'http://help.form.io/userguide/#table',
schema: CheckMatrix.schema()
}
static editForm = editForm
/**
* Render returns an html string of the fully rendered component.
*
* @param children - If this class is extendended, the sub string is passed as children.
* @returns {string}
*/
render(children) {
// To make this dynamic, we could call this.renderTemplate('templatename', {}).
let tableClass = 'table ';
['striped', 'bordered', 'hover', 'condensed'].forEach((prop) => {
if (this.component[prop]) {
tableClass += `table-${prop} `;
}
});
let content = '';
for (let i = 0; i < this.component.numRows; i++) {
let row = '<tr>';
for (let j = 0; j < this.component.numCols; j++) {
let cell = '<td>';
cell += this.renderTemplate('input', {
input: {
type: 'input',
ref: `${this.component.key}-${i}`,
attr: {
id: `${this.component.key}-${i}-${j}`,
class: 'form-control',
type: 'checkbox',
}
}
});
cell += '</td>';
row += cell;
}
row += '</tr>';
content += row;
}
// Calling super.render will wrap it html as a component.
return super.render(`
<table class=${tableClass}>
<tbody>
${content}
</tbody>
</table>
`);
}
/**
* After the html string has been mounted into the dom, the dom element is returned here. Use refs to find specific
* elements to attach functionality to.
*
* @param element
* @returns {Promise}
*/
attach(element) {
const refs = {};
for (let i = 0; i < this.component.numRows; i++) {
refs[`${this.component.key}-${i}`] = 'multiple';
}
this.loadRefs(element, refs);
this.checks = [];
for (let i = 0; i < this.component.numRows; i++) {
this.checks[i] = Array.prototype.slice.call(this.refs[`${this.component.key}-${i}`], 0);
// Attach click events to each input in the row
this.checks[i].forEach(input => {
this.addEventListener(input, 'click', () => this.updateValue())
});
}
// Allow basic component functionality to attach like field logic and tooltips.
return super.attach(element);
}
/**
* Get the value of the component from the dom elements.
*
* @returns {Array}
*/
getValue() {
var value = [];
for (var rowIndex in this.checks) {
var row = this.checks[rowIndex];
value[rowIndex] = [];
for (var colIndex in row) {
var col = row[colIndex];
value[rowIndex][colIndex] = !!col.checked;
}
}
return value;
}
/**
* Set the value of the component into the dom elements.
*
* @param value
* @returns {boolean}
*/
setValue(value) {
if (!value) {
return;
}
for (var rowIndex in this.checks) {
var row = this.checks[rowIndex];
if (!value[rowIndex]) {
break;
}
for (var colIndex in row) {
var col = row[colIndex];
if (!value[rowIndex][colIndex]) {
return false;
}
let checked = value[rowIndex][colIndex] ? 1 : 0;
col.value = checked;
col.checked = checked;
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# 自定义编辑表单
Edit Form是将组件拖放到“表单”上时看到的表单,模态显示为带有表单的表单,您可以在其中配置表单。可以通过在editForm
方法的返回范围内提供Form.io JSON表单来完全自定义此编辑表单,如下所示。
export default class CheckMatrix extends Base {
static editForm() {
return {
components: [
{
type: 'textfield',
key: 'label',
label: 'Label'
}
]
};
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 注册组件
可以使用以下registerComponent
方法将组件注册到渲染器中。
import CheckMatrix from './CheckMatrix';
import { Formio } from 'formiojs';
Formio.registerComponent('checkmatrix', CheckMatrix);
1
2
3
2
3
# 注册一个插件
也可以通过插件系统注册组件。这样做如下。
MyPlugin.js
import CheckMatrix from './CheckMatrix';
import ButtonSelect from './ButtonSelect';
export default {
components: {
checkmatrix: CheckMatrix,
buttonselect: ButtonSelect
},
templates: {
bootstrap: {
checkmatrix: `<div>..TEMPLATE FOR CHECKMATRIX...</div>`,
buttonselect: `<div>....TEMPLATE FOR BUTTONSELECT...</div>`
},
bootstrap3: {
checkmatrix: `<div>..TEMPLATE FOR CHECKMATRIX...</div>`,
buttonselect: `<div>....TEMPLATE FOR BUTTONSELECT...</div>`
}
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import MyPlugin from './MyPlugin';
import { Formio } from 'formiojs';
Formio.use(MyPlugin);
1
2
3
2
3
← 模板 Fetch Plugin API →