GenerateForm
Form generator component that quickly renders form pages with a JSON Schema
.
Code Demonstration
Basic Usage
Render the form directly according to the JSON Schema
and get the form data.
View Code
<template>
<fm-generate-form
:data="jsonData"
ref="generateForm"
></fm-generate-form>
<el-button @click="handleSubmit">Submit</el-button>
</template>
<script setup>
import { ref } from 'vue'
import { ElMessageBox } from 'element-plus'
const generateForm = ref()
const jsonData = {"list":[{"type":"input","icon":"icon-input","options":{"width":"","defaultValue":"","required":false,"requiredMessage":"","dataType":"","dataTypeCheck":false,"dataTypeMessage":"","pattern":"","patternCheck":false,"patternMessage":"","validatorCheck":false,"validator":"","placeholder":"","customClass":"","disabled":false,"labelWidth":100,"isLabelWidth":false,"hidden":false,"dataBind":true,"showPassword":false,"remoteFunc":"func_z2lqyv1a","remoteOption":"option_z2lqyv1a"},"events":{"onChange":"","onFocus":"","onBlur":""},"name":"单行文本","key":"z2lqyv1a","model":"input_z2lqyv1a","rules":[]},{"type":"textarea","icon":"icon-diy-com-textarea","options":{"width":"","defaultValue":"","required":false,"requiredMessage":"","disabled":false,"pattern":"","patternMessage":"","validatorCheck":false,"validator":"","placeholder":"","customClass":"","labelWidth":100,"isLabelWidth":false,"hidden":false,"dataBind":true,"remoteFunc":"func_geb5vsy8","remoteOption":"option_geb5vsy8"},"events":{"onChange":"","onFocus":"","onBlur":""},"name":"多行文本","key":"geb5vsy8","model":"textarea_geb5vsy8","rules":[]},{"type":"radio","icon":"icon-radio-active","options":{"inline":false,"defaultValue":"","showLabel":false,"options":[{"value":"Option 1","label":"Option 1"},{"value":"Option 2","label":"Option 2"},{"value":"Option 3","label":"Option 3"}],"required":false,"requiredMessage":"","validatorCheck":false,"validator":"","width":"","remote":false,"remoteType":"datasource","remoteOption":"option_jg58x37w","remoteOptions":[],"props":{"value":"value","label":"label"},"remoteFunc":"func_jg58x37w","customClass":"","labelWidth":100,"isLabelWidth":false,"hidden":false,"dataBind":true,"disabled":false},"events":{"onChange":""},"name":"单选框组","key":"jg58x37w","model":"radio_jg58x37w","rules":[]}],"config":{"labelWidth":100,"labelPosition":"right","size":"default","customClass":"","ui":"element","layout":"horizontal","labelCol":3,"width":"100%","hideLabel":false,"hideErrorMessage":false,"eventScript":[{"key":"mounted","name":"mounted","func":""}],"dataSource":[]}}
const handleSubmit = () => {
generateForm.value.getData().then(data => {
ElMessageBox.alert(data, 'Form Data')
})
}
</script>
TIP
getData
is an asynchronous method. By default, form data is verified before data is obtained. Form data can be obtained only after the verification is successful.If you don't need form validation and want to get the form data directly, you can add the parameter getData(false)
that will not validate the form data.
Load Form Data
View Code
<template>
<fm-generate-form
:data="jsonData"
:value="editData"
ref="generateForm"
></fm-generate-form>
<el-button @click="handleSubmit" type="primary">Submit Data</el-button>
<el-button @click="handleSetData">Set New Data</el-button>
<el-button @click="handleReset" >Reset Form</el-button>
</template>
<script setup>
import { ref } from 'vue'
import { ElMessageBox } from 'element-plus'
const generateForm = ref()
const jsonData = {"list":[{"type":"input","icon":"icon-input","options":{"width":"","defaultValue":"","required":false,"requiredMessage":"","dataType":"","dataTypeCheck":false,"dataTypeMessage":"","pattern":"","patternCheck":false,"patternMessage":"","validatorCheck":false,"validator":"","placeholder":"","customClass":"","disabled":false,"labelWidth":100,"isLabelWidth":false,"hidden":false,"dataBind":true,"showPassword":false,"remoteFunc":"func_z2lqyv1a","remoteOption":"option_z2lqyv1a"},"events":{"onChange":"","onFocus":"","onBlur":""},"name":"单行文本","key":"z2lqyv1a","model":"input","rules":[]},{"type":"textarea","icon":"icon-diy-com-textarea","options":{"width":"","defaultValue":"","required":false,"requiredMessage":"","disabled":false,"pattern":"","patternMessage":"","validatorCheck":false,"validator":"","placeholder":"","customClass":"","labelWidth":100,"isLabelWidth":false,"hidden":false,"dataBind":true,"remoteFunc":"func_geb5vsy8","remoteOption":"option_geb5vsy8"},"events":{"onChange":"","onFocus":"","onBlur":""},"name":"多行文本","key":"geb5vsy8","model":"text","rules":[]},{"type":"radio","icon":"icon-radio-active","options":{"inline":false,"defaultValue":"","showLabel":false,"options":[{"value":"Option 1","label":"Option 1"},{"value":"Option 2","label":"Option 2"},{"value":"Option 3","label":"Option 3"}],"required":false,"requiredMessage":"","validatorCheck":false,"validator":"","width":"","remote":false,"remoteType":"datasource","remoteOption":"option_jg58x37w","remoteOptions":[],"props":{"value":"value","label":"label"},"remoteFunc":"func_jg58x37w","customClass":"","labelWidth":100,"isLabelWidth":false,"hidden":false,"dataBind":true,"disabled":false},"events":{"onChange":""},"name":"单选框组","key":"jg58x37w","model":"radio","rules":[]}],"config":{"labelWidth":100,"labelPosition":"right","size":"default","customClass":"","ui":"element","layout":"horizontal","labelCol":3,"width":"100%","hideLabel":false,"hideErrorMessage":false,"eventScript":[{"key":"mounted","name":"mounted","func":""}],"dataSource":[]}}
const editData = {
input: 'input',
text: 'text',
radio: 'Option 1'
}
const handleSubmit = () => {
generateForm.value.getData().then(data => {
ElMessageBox.alert(data, 'Form Data')
})
}
const handleReset = () => {
generateForm.value.reset()
}
const handleSetData = () => {
generateForm.value.setData({
input: 'new input',
text: 'new text',
radio: 'Option 3'
})
}
</script>
TIP
:value
assigns a value to the form that takes effect only when the form is initializing. The form is loaded with default data. Resetting the form does not clear the default data. setData
You can assign values dynamically after the form is initialized. Resetting the form will empty the form data.
Asynchronous Loading Form
View Code
<template>
<fm-generate-form
:data="jsonData"
ref="generateForm"
></fm-generate-form>
<el-button @click="handleLoad" >Load Form</el-button>
</template>
<script setup>
import { ref, nextTick } from 'vue'
const generateForm = ref()
const jsonData = ref({})
const handleLoad = () => {
// Assign json to the data property
jsonData.value = {"list":[{"type":"grid","icon":"icon-RectangleCopy","columns":[{"type":"col","options":{"span":12,"offset":0,"push":0,"pull":0,"xs":24,"sm":12,"md":12,"lg":12,"xl":12,"customClass":""},"list":[{"type":"select","icon":"icon-select","options":{"defaultValue":"","multiple":false,"disabled":false,"clearable":false,"placeholder":"","required":false,"requiredMessage":"","validatorCheck":false,"validator":"","showLabel":false,"width":"","options":[{"value":"1111"},{"value":"2222"},{"value":"3333"}],"remote":true,"remoteType":"datasource","remoteOption":"option_6lqq9bu5","filterable":false,"remoteOptions":[],"props":{"value":"value","label":"label"},"remoteFunc":"func_6lqq9bu5","customClass":"","labelWidth":100,"isLabelWidth":false,"hidden":false,"dataBind":true,"tableColumn":false,"remoteDataSource":"getoptions"},"events":{"onChange":"","onFocus":"","onBlur":""},"name":"下拉选择框","novalid":{},"key":"6lqq9bu5","model":"select_6lqq9bu5","rules":[]}],"key":"nhfkr3bc"}],"options":{"gutter":0,"justify":"start","align":"top","customClass":"","hidden":false,"flex":true,"responsive":true,"remoteFunc":"func_ugqp2jf3","remoteOption":"option_ugqp2jf3"},"name":"栅格布局","key":"ugqp2jf3","model":"grid_ugqp2jf3","rules":[]}],"config":{"labelWidth":100,"labelPosition":"right","size":"default","customClass":"","ui":"element","layout":"horizontal","labelCol":3,"width":"100%","hideLabel":false,"hideErrorMessage":false,"eventScript":[{"key":"mounted","name":"mounted","func":""}],"dataSource":[]}}
// Call the form's refresh again under nextTick, which is necessary to ensure that the form reloads the data
nextTick(() => {
generateForm.value.refresh()
})
}
</script>
Monitor Form Data Change
View Code
<template>
<fm-generate-form
:data="jsonData"
ref="generateForm"
@on-change="onChange"
></fm-generate-form>
<div>field value before changed :{{changeData.field}} --- field value after changed:{{changeData.value}}</div>
</template>
<script setup>
import { ref, reactive } from 'vue'
const jsonData = {"list":[{"type":"input","icon":"icon-input","options":{"width":"","defaultValue":"","required":false,"requiredMessage":"","dataType":"","dataTypeCheck":false,"dataTypeMessage":"","pattern":"","patternCheck":false,"patternMessage":"","validatorCheck":false,"validator":"","placeholder":"","customClass":"","disabled":false,"labelWidth":100,"isLabelWidth":false,"hidden":false,"dataBind":true,"showPassword":false,"remoteFunc":"func_wwyplsj9","remoteOption":"option_wwyplsj9","tableColumn":false},"events":{"onChange":"","onFocus":"","onBlur":""},"name":"单行文本","key":"wwyplsj9","model":"input","rules":[]},{"type":"textarea","icon":"icon-diy-com-textarea","options":{"width":"","defaultValue":"","required":false,"requiredMessage":"","disabled":false,"pattern":"","patternMessage":"","validatorCheck":false,"validator":"","placeholder":"","customClass":"","labelWidth":100,"isLabelWidth":false,"hidden":false,"dataBind":true,"remoteFunc":"func_2ay04pyh","remoteOption":"option_2ay04pyh","tableColumn":false},"events":{"onChange":"","onFocus":"","onBlur":""},"name":"多行文本","key":"2ay04pyh","model":"text","rules":[]}],"config":{"labelWidth":100,"labelPosition":"right","size":"default","customClass":"","ui":"element","layout":"horizontal","labelCol":3,"width":"100%","hideLabel":false,"hideErrorMessage":false,"eventScript":[{"key":"mounted","name":"mounted","func":""}],"dataSource":[]}}
const generateForm = ref()
const changeData = reactive({
field: '',
value: ''
})
const onChange = (field, value) => {
changeData.field = field
changeData.value = value
}
</script>
Dynamically Set Forms to Disable/Hidden
View Code
<template>
<fm-generate-form
:data="jsonData"
ref="generateForm"
></fm-generate-form>
<el-button type="primary" @click="handleHide">Hide Text Box</el-button>
<el-button type="primary" @click="handleDisplay">Display Text Box</el-button>
<el-button type="primary" @click="handleDisabled">Diaable Text Box</el-button>
<el-button type="primary" @click="handleEnabled">Enabled Text Box</el-button>
</template>
<script setup>
import { ref, reactive } from 'vue'
const generateForm = ref()
const jsonData = {"list":[{"type":"input","icon":"icon-input","options":{"width":"","defaultValue":"","required":false,"requiredMessage":"","dataType":"","dataTypeCheck":false,"dataTypeMessage":"","pattern":"","patternCheck":false,"patternMessage":"","validatorCheck":false,"validator":"","placeholder":"","customClass":"","disabled":false,"labelWidth":100,"isLabelWidth":false,"hidden":false,"dataBind":true,"showPassword":false,"remoteFunc":"func_wwyplsj9","remoteOption":"option_wwyplsj9","tableColumn":false},"events":{"onChange":"","onFocus":"","onBlur":""},"name":"单行文本","key":"wwyplsj9","model":"input","rules":[]},{"type":"textarea","icon":"icon-diy-com-textarea","options":{"width":"","defaultValue":"","required":false,"requiredMessage":"","disabled":false,"pattern":"","patternMessage":"","validatorCheck":false,"validator":"","placeholder":"","customClass":"","labelWidth":100,"isLabelWidth":false,"hidden":false,"dataBind":true,"remoteFunc":"func_2ay04pyh","remoteOption":"option_2ay04pyh","tableColumn":false},"events":{"onChange":"","onFocus":"","onBlur":""},"name":"多行文本","key":"2ay04pyh","model":"text","rules":[]},{"type":"radio","icon":"icon-radio-active","options":{"inline":false,"defaultValue":"","showLabel":false,"options":[{"value":"Option 1","label":"Option 1"},{"value":"Option 2","label":"Option 2"},{"value":"Option 3","label":"Option 3"}],"required":false,"requiredMessage":"","validatorCheck":false,"validator":"","width":"","remote":false,"remoteType":"datasource","remoteOption":"option_3esmng86","remoteOptions":[],"props":{"value":"value","label":"label"},"remoteFunc":"func_3esmng86","customClass":"","labelWidth":100,"isLabelWidth":false,"hidden":false,"dataBind":true,"disabled":false,"tableColumn":false},"events":{"onChange":""},"name":"单选框组","key":"3esmng86","model":"radio","rules":[]}],"config":{"labelWidth":100,"labelPosition":"right","size":"default","customClass":"","ui":"element","layout":"horizontal","labelCol":3,"width":"100%","hideLabel":false,"hideErrorMessage":false,"eventScript":[{"key":"mounted","name":"mounted","func":""}],"dataSource":[]}}
// input, text is the field ID configured in the field properties
const handleHide = () => {
generateForm.value.hide(['input', 'text'])
}
const handleDisplay = () => {
generateForm.value.display(['input', 'text'])
}
const handleDisabled = () => {
generateForm.value.disabled(['input', 'text'], true)
}
const handleEnabled = () => {
generateForm.value.disabled(['input', 'text'], false)
}
</script>
TIP
~~^3.6.0 移除Disable and enable actions modify the form's json Settings, you need to ensure that jsonData is responsive data, which is used reactive
Get Form Field Component Instance
You can get an instance of a component through Field ID to call the method with the form field component.
// Get the text box instance with id [input] and execute the focus method.
getComponent('input').focus()
//Get the subform instance with id[table] and hide an entire column with id[input]
getComponent('table').hide(['input'])
//Get the input component in the first row of the subform
getComponent('table.0.input')
TIP
If the form has multiple identical field identifications, getComponent returns an array containing all instances.
Dynamically Add Custom styles
View Code
<template>
<fm-generate-form
:data="jsonData"
ref="generateForm"
></fm-generate-form>
<el-button @click="handleAdd">Add Style</el-button>
<el-button @click="handleRemove">Remove Style</el-button>
</template>
<script setup>
import { ref, nextTick, onMounted } from 'vue'
const generateForm = ref()
const jsonData = ref({})
onMounted(() => {
jsonData.value = {"list":[{"type":"input","icon":"icon-input","options":{"width":"","defaultValue":"","required":false,"requiredMessage":"","dataType":"","dataTypeCheck":false,"dataTypeMessage":"","pattern":"","patternCheck":false,"patternMessage":"","validatorCheck":false,"validator":"","placeholder":"","customClass":"","disabled":false,"labelWidth":100,"isLabelWidth":false,"hidden":false,"dataBind":true,"showPassword":false,"remoteFunc":"func_syyx0jhb","remoteOption":"option_syyx0jhb"},"events":{"onChange":"","onFocus":"","onBlur":""},"name":"Input","key":"syyx0jhb","model":"input","rules":[]},{"type":"textarea","icon":"icon-diy-com-textarea","options":{"width":"","defaultValue":"","required":false,"requiredMessage":"","disabled":false,"pattern":"","patternMessage":"","validatorCheck":false,"validator":"","placeholder":"","customClass":"","labelWidth":100,"isLabelWidth":false,"hidden":false,"dataBind":true,"remoteFunc":"func_jxgb18ns","remoteOption":"option_jxgb18ns"},"events":{"onChange":"","onFocus":"","onBlur":""},"name":"Textarea","key":"jxgb18ns","model":"text","rules":[]},{"type":"radio","icon":"icon-radio-active","options":{"inline":false,"defaultValue":"","showLabel":false,"options":[{"value":"Option 1","label":"Option 1"},{"value":"Option 2","label":"Option 2"},{"value":"Option 3","label":"Option 3"}],"required":false,"requiredMessage":"","validatorCheck":false,"validator":"","width":"","remote":false,"remoteType":"datasource","remoteOption":"option_o6xn3cpa","remoteOptions":[],"props":{"value":"value","label":"label"},"remoteFunc":"func_o6xn3cpa","customClass":"","labelWidth":100,"isLabelWidth":false,"hidden":false,"dataBind":true,"disabled":false},"events":{"onChange":""},"name":"Radio","key":"o6xn3cpa","model":"radio","rules":[]}],"config":{"labelWidth":100,"labelPosition":"right","size":"default","customClass":"","ui":"element","layout":"horizontal","labelCol":3,"width":"100%","hideLabel":false,"hideErrorMessage":false,"eventScript":[{"key":"mounted","name":"mounted","func":""}],"dataSource":[]}}
nextTick(() => {
generateForm.value.refresh()
})
})
const handleAdd = () => {
generateForm.value.addClassName(['input', 'text'], 'custom-style')
}
const handleRemove = () => {
generateForm.value.removeClassName(['input', 'text'], 'custom-style')
}
</script>
<style>
.custom-style{
padding: 10px;
}
.custom-style .el-form-item__label{
font-size: 16px;
color: red;
}
</style>
API
Property
Parameter | Description | Type | Default |
---|---|---|---|
data | JSON data with entire form page information | object | {} |
value | Item value in the form | object | - |
remote | A remote method of form configuration | object | {} |
edit | Form editable state | boolean | true |
remote-option | Configure the dynamic options of the form | object | {} |
print-read | Print reading mode, form value text display | boolean | false |
Event
Event Name | Description | Callback Parameter |
---|---|---|
on-change | Triggered when form data changed | (field, value, data) field: The ID of the data changed field value: the value of the data changed field |
Method
Method Name | Description | Parameter |
---|---|---|
getData | Get the data for the form binding | (isValidate = true) => promise Passing false does not do form validation |
reset | Reset form data | () => promise^3.6.0 |
setData | Set form data | ({id: value}) => promise^3.6.0 |
hide | Hide form field | (fields: []) => void |
display | Display form field | (fields: []) => void |
disabled | Dynamically set whether a form field is disabled | (fields: [], disabled: true | false) => void |
refresh | Refresh the form. Call this method to reload the form when the form JSON changes | () => promise^3.6.0 |
getValue | Get the input value for the specified field | (field) => value |
getValues | Get the input value for the all fields | () => object |
sendRequest | Execute data source request | (name: Data source Name, args: Data source parameter) => promise |
getComponent | Gets the specified field component instance in the form | (field: field ID) => object | array |
addClassName | Adds style class to the form field list | (fields: [], className) |
removeClassName | Remove style class from the form field list | (fields: [], className) |
setRules | Set the form field validation rules | (field, rules) |
setOptions | To set the form field configuration items, please refer to Field Configurable Items | (fields, options) |
setOptionData | Dynamic option data assignment, required options.remote set as true | (fields, newData) |
refreshFieldDataSource | Refresh the data source data bound to the field | (field, args: Data source parameter) |
getFieldDataSource^3.5.4 | 获取字段绑定的数据源数据值 | (field) |
validate | Validation the data for the form field | (fields: []) => promise |
triggerEvent | call the js event that configured in the form | (eventName: Event name, args: Event parameter) |
exportPDF^3.5.8 | Export PDF, available when the form print-read property is true. return Blob (type: "application/pdf")type file | () => promise |
openDialog^3.6.3 | open dialogue box | (dialogId: Dialog box field identification) |
closeDialog^3.6.3 | close dialogue box | (dialogId: Dialog box field identification) |