Your search did not match any results.
Form

Customize Fields at Runtime

The Form widget allows you to add/remove items and specify item visibility at runtime. The Form only updates the affected items and does not re-render the entire form.

In this demo, the "Show Address" checkbox specifies the visibility of address-related fields. Review the widget's code to see how to set the "HomeAddress" group's visible attribute.

Click the "Add phone" button to add a new phone editor. This action adds a new item to the items array of the "phones" group. Each phone editor contains a button that deletes it from the items array and the Form.

Copy to CodeSandBox
Apply
Reset
<template> <div> <div class="long-title"><h3>Personal details</h3></div> <div id="form-container"> <DxForm id="form" :col-count="2" :form-data="employee" > <DxGroupItem> <DxGroupItem caption="Personal Data"> <DxSimpleItem data-field="FirstName"/> <DxSimpleItem data-field="LastName"/> <DxSimpleItem :editor-options="checkBoxOptions" editor-type="dxCheckBox" /> </DxGroupItem> <DxGroupItem> <DxGroupItem :visible="isHomeAddressVisible" caption="Home Address" name="HomeAddress" > <DxSimpleItem data-field="Address"/> <DxSimpleItem data-field="City"/> </DxGroupItem> </DxGroupItem> </DxGroupItem> <DxGroupItem caption="Phones" name="phones-container" > <DxGroupItem item-type="group" name="phones" > <DxSimpleItem v-for="(phone, index) in phoneOptions" :key="'Phone' + (index + 1)" :data-field="'Phones[' + index + ']'" :editor-options="phone" > <DxLabel :text="'Phone ' + (index + 1)"/> </DxSimpleItem> </DxGroupItem> <DxButtonItem :button-options="addPhoneButtonOptions" css-class="add-phone-button" horizontal-alignment="left" /> </DxGroupItem> </DxForm> </div> </div> </template> <script> import { DxForm, DxSimpleItem, DxGroupItem, DxButtonItem, DxLabel } from 'devextreme-vue/form'; import service from './data.js'; export default { components: { DxForm, DxSimpleItem, DxGroupItem, DxButtonItem, DxLabel }, data() { const employee = service.getEmployee(); let isHomeAddressVisible = true; let phoneOptions = this.getPhonesOptions(employee.Phones); return { employee, isHomeAddressVisible, phoneOptions, checkBoxOptions: { text: 'Show Address', value: true, onValueChanged: (e) => { this.isHomeAddressVisible = e.component.option('value'); } }, addPhoneButtonOptions: { icon: 'add', text: 'Add phone', onClick: () => { this.employee.Phones.push(''); this.phoneOptions = this.getPhonesOptions(this.employee.Phones); } } }; }, methods: { getPhonesOptions(phones) { let options = []; for (let i = 0; i < phones.length; i++) { options.push(this.generateNewPhoneOptions(i)); } return options; }, generateNewPhoneOptions(index) { return { mask: '+1 (X00) 000-0000', maskRules: { 'X': /[01-9]/ }, buttons: [{ name: 'trash', location: 'after', options: { stylingMode: 'text', icon: 'trash', onClick: () => { this.employee.Phones.splice(index, 1); this.phoneOptions = this.getPhonesOptions(this.employee.Phones); } } }] }; } } }; </script> <style scoped> #form-container { margin: 10px 10px 30px; } .long-title h3 { font-family: 'Segoe UI Light', 'Helvetica Neue Light', 'Segoe UI', 'Helvetica Neue', 'Trebuchet MS', Verdana; font-weight: 200; font-size: 28px; text-align: center; margin-bottom: 20px; } .add-phone-button { margin-top: 10px; } </style>
import { createApp } from 'vue'; import App from './App.vue'; createApp(App).mount('#app');
<!DOCTYPE html> <html> <head> <title>DevExtreme Demo</title> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/20.2.4/css/dx.common.css" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/20.2.4/css/dx.light.css" /> <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" /> <script src="https://unpkg.com/core-js@2.4.1/client/shim.min.js"></script> <script src="https://unpkg.com/systemjs@0.21.3/dist/system.js"></script> <script type="text/javascript" src="config.js"></script> <script type="text/javascript"> System.import('./index.js'); </script> </head> <body class="dx-viewport"> <div class="demo-container"> <div id="app"> </div> </div> </body> </html>
const employee = { FirstName: 'John', LastName: 'Heart', Address: '351 S Hill St., Los Angeles, CA', City: 'Atlanta', Phones: ['8005552797', '8005953232'] }; export default { getEmployee() { return employee; } };
System.config({ transpiler: 'plugin-babel', meta: { '*.vue': { loader: 'vue-loader' }, }, paths: { 'npm:': 'https://unpkg.com/' }, map: { 'vue': 'npm:vue@3.0.0/dist/vue.esm-browser.js', 'vue-loader': 'npm:dx-systemjs-vue-browser@1.0.15/index.js', 'mitt': 'npm:mitt/dist/mitt.umd.js', 'rrule': 'npm:rrule@2.6.6/dist/es5/rrule.js', 'luxon': 'npm:luxon@1.25.0/build/global/luxon.min.js', 'es6-object-assign': 'npm:es6-object-assign@1.1.0', 'devextreme': 'npm:devextreme@20.2.4', 'devextreme-vue': 'npm:devextreme-vue@20.2.4', 'jszip': 'npm:jszip@3.5.0/dist/jszip.min.js', 'devextreme-quill': 'npm:devextreme-quill@0.9.7/dist/dx-quill.min.js', 'devexpress-diagram': 'npm:devexpress-diagram@2.0.5/dist/dx-diagram.js', 'devexpress-gantt': 'npm:devexpress-gantt@2.0.8/dist/dx-gantt.js', 'preact': 'npm:preact@10.5.7/dist/preact.js', 'preact/hooks': 'npm:preact@10.5.7/hooks/dist/hooks.js', 'plugin-babel': 'npm:systemjs-plugin-babel@0.0.25/plugin-babel.js', 'systemjs-babel-build': 'npm:systemjs-plugin-babel@0.0.25/systemjs-babel-browser.js' }, packages: { 'devextreme-vue': { main: 'index.js' }, 'devextreme': { defaultExtension: 'js' }, 'devextreme/events/utils': { main: 'index' }, 'devextreme/events': { main: 'index' }, 'es6-object-assign': { main: './index.js', defaultExtension: 'js' } }, babelOptions: { sourceMaps: false, stage0: true } });