动态表单_动态表单设计 - CSDN
精华内容
参与话题
  • 动态表单的简单实现

    2020-07-30 23:32:19
    动态表单的简历实现,包括整个流程:设计表单--入库保存---填写表单---表单的展示。功能都实现了,只是没有做很很细致的调整,只是一个demo
  • 动态表单及动态建表实现原理

    万次阅读 2013-07-20 21:56:52
     项目中往往需要动态的创建一个表单,或者添加一个新的数据模板,这时候因为需要在运行时动态的创建表以及动态的维护表字段甚至表关系 使得普通java解决方案变得困难重重。   2 实现工具 Hibernate + Spring ...

      1 应用场景
      项目中往往需要动态的创建一个表单,或者添加一个新的数据模板,这时候因为需要在运行时动态的创建表以及动态的维护表字段甚至表关系 使得普通java解决方案变得困难重重。 

        2 实现工具

    Hibernate + Spring + Groovy +Freemarker

    Hibernate 作用很简单负责创建数据库表这样可以避免我们自己去写复杂的sql和判断。

    Spring 作为桥梁起到连接纽带的作用。

    Groovy做为动态语言,在项目运行时根据模板创建访问数据库,或者控制层代码。

    Freamker 可以根据提前定义好的模板生成 hibernate配置文件,以及Groovy代码。

     

        3 实现原理

      首先创建Form 和 FromAttribute 两张表关系一对多。Form表记录表单的名称,类别,甚至是作为在动态生成表单时的css样式信息。FromAttribute记录表单字段信息,如名称,类别等。有了表单以及表单项的信息后就可以创建数据库表了。

    测试代码:
    public void testGenerator() {
            Form form = formService.getAll().get(0);
            List<FormAttribute> list = formAttributeService
                    .getAttributeListByFormId(form.getId());
            form.setFormAttributeList(list);
            DbGenerator dg = new DbGenerator(form, dataSource);
            dg.generator();
        }

    DbGenerator

    import java.io.IOException;
    import java.io.StringWriter;
    import java.io.Writer;
    import java.sql.SQLException;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Properties;

    import javax.sql.DataSource;

    import org.hibernate.tool.hbm2ddl.SchemaExport;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;



    import freemarker.template.Configuration;
    import freemarker.template.Template;
    import freemarker.template.TemplateException;

    public class DbGenerator {
        
        
    private DataSource dataSource;
        
    protected Map root = new HashMap();
        
    private static Logger log = LoggerFactory.getLogger(FormGenerator.class);
        
    protected String path;
        
    protected String packageName;

        
    private Form form;

        
    protected Configuration getConfig(String resource) {

            Configuration cfg 
    = new Configuration();
            cfg.setDefaultEncoding(
    "UTF-8");
            cfg.setClassForTemplateLoading(
    this.getClass(), resource);
            
    return cfg;
        }


        
    public DbGenerator(Form form ,DataSource dataSource) {
            
    this.form = form;
            
    this.dataSource = dataSource;
        }


        
    public void generator() {
            
    if(null == form.getFormAttributeList() || form.getFormAttributeList().size() == 0){
                
    return ;
            }

            Template t;
            
    try {
                t 
    = getConfig("/template").getTemplate("hibernate.ftl");
                Writer out 
    = new StringWriter();
                t.process(getMapContext(), out);
                String xml 
    = out.toString();
                createTable(xml);
                log.debug(xml);
            }
     catch (IOException e) {
                e.printStackTrace();
            }
     catch (TemplateException e) {
                e.printStackTrace();
            }

        }


        @SuppressWarnings(
    "unchecked")
        Map getMapContext() 
    {
            root.put(
    "entity", form);
            
    return root;
        }


        
    public void createTable(String xml) {
            org.hibernate.cfg.Configuration conf 
    = new org.hibernate.cfg.Configuration();
            conf.configure(
    "/hibernate/hibernate.cfg.xml");
            Properties extraProperties 
    = new Properties();
            extraProperties.put(
    "hibernate.hbm2ddl.auto""create");
            conf.addProperties(extraProperties);

            conf.addXML(xml);

            SchemaExport dbExport;
            
    try {
                dbExport 
    = new SchemaExport(conf, dataSource.getConnection());
                
    // dbExport.setOutputFile(path);
                dbExport.create(falsetrue);
            }
     catch (SQLException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }


    }


    class hibernateGenerator {

    }
    hibernate.ftl
    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE hibernate-mapping 
      PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
             "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
    >

    <hibernate-mapping>
        
    <class
            
    name="${entity.name}"
            table="`${entity.tableName}`"
            dynamic-update="false"
            dynamic-insert="false"
            select-before-update="false"
            optimistic-lock="version">
            
    <id
                
    name="id"
                column="id"
                type="java.lang.String"
                unsaved-value="null">
                
    <generator class="uuid" />
            
    </id>
            
    <#if entity.formAttributeList?exists>
                
    <#list entity.formAttributeList as attr>
                    
    <#if attr.name == "id">                
                    
    <#else>
            
    <property
                
    name="${attr.name}"
                type="java.lang.String"
                update="true"
                insert="true"
                access="property"
                column="`${attr.columnName}`"
                length="${attr.length}"
                not-null="false"
                unique="false"
            />
            
                    
    </#if>
                
    </#list>
            
    </#if>
           
        
    </class>

    </hibernate-mapping>
    hibernate.cfg.xml
    <!DOCTYPE hibernate-configuration
        PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"
    >

    <hibernate-configuration>
    <session-factory>
            
    <property name="dialect">org.hibernate.dialect.SQLServerDialect</property>
        
    <property name="connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>
        
    <property name="connection.url">jdbc:jtds:sqlserver://127.0.0.1:1433;databasename=struts;SelectMethod=cursor</property>
        
    <property name="connection.username">sa</property>
        
    <property name="connection.password">sa</property>
        
        
    <property name="show_sql">true</property>
        
    <property name="hibernate.hbm2ddl.auto">update</property>

    <!--  
        <mapping resource="hibernate/FormAttribute.hbm.xml" />
        <mapping resource="hibernate/Form.hbm.xml" />
        
    -->
    </session-factory>

    </hibernate-configuration>
     创建好数据库后 就要利用groovy动态创建访问代码了:先看测试代码 再看具体实现:
    public void testGroovy() {
            Form form 
    = formService.get("1");
            List
    <FormAttribute> list = formAttributeService
                    .getAttributeListByFormId(form.getId());
            form.setFormAttributeList(list);
            FormGenerator fg 
    = new FormGenerator(form);
            String groovycode 
    = fg.generator();
            ClassLoader parent 
    = getClass().getClassLoader();
            GroovyClassLoader loader 
    = new GroovyClassLoader(parent);
            Class groovyClass 
    = loader.parseClass(groovycode);
            GroovyObject groovyObject 
    = null;
            
    try {
                groovyObject 
    = (GroovyObject) groovyClass.newInstance();
            }
     catch (InstantiationException e) {
                e.printStackTrace();
            }
     catch (IllegalAccessException e) {
                e.printStackTrace();
            }

            
    // map中key为formAttribute中描述该表单字段在数据库中的名称c_columnName
            
    // 具体情况根据formAttribute而定
            Map map = new HashMap();
            map.put(
    "name""limq");
            
    // 调用insert方法插入数据
            int c = (Integer) groovyObject.invokeMethod("insert", map);

            
    // 调用getAll方法获得所有动态表中的数据
            Object o = groovyObject.invokeMethod("getAll"null);
            List list2 
    = (List) o;
            Object obj 
    = list2.get(0);
            
    try {
                String tname 
    = (String) BeanUtils.getDeclaredProperty(obj, "name");
                System.out.println(tname);
            }
     catch (IllegalAccessException e) {
                e.printStackTrace();
            }
     catch (NoSuchFieldException e) {
                e.printStackTrace();
            }

            
    // 调用search方法查询动态表
            List<Map> returnList = (List) groovyObject.invokeMethod("search", map);
            
    for (Map map2 : returnList) {
                
    // 同理此处根据FromAttribute而定
                System.out.println(map2.get("id"));
                System.out.println(map2.get(
    "name"));
                System.out.println(map2.get(
    "type"));
            }

        }
    FormGenerator : 创建访问数据库Groovy代码

    public class FormGenerator {
        
    protected  Map root = new HashMap();
        
    private static Logger log = LoggerFactory.getLogger(FormGenerator.class);
            
    protected String path ;
            
    protected String packageName ;
            
    private Form form ; 
            
    protected Configuration getConfig(String resource) {
                
                 Configuration cfg 
    = new Configuration();
                cfg.setDefaultEncoding(
    "UTF-8");
                cfg.setClassForTemplateLoading(
    this.getClass(), resource);
                
    return cfg;
            }

            
            
    public FormGenerator(Form form){
                
    this.form = form;
            }

            
            
    public String generator(){
                String returnstr 
    = null;
                Template t;
                
    try {
                    t 
    = getConfig("/template").getTemplate("FormService.ftl");
                    
    //Writer out = new OutputStreamWriter(new FileOutputStream(new File(path)),"UTF-8");
                    Writer out = new StringWriter();
                    t.process(getMapContext(), out);
                    returnstr 
    = out.toString();
                    log.debug(returnstr);
                }
     catch (IOException e) {
                    e.printStackTrace();
                }
     catch (TemplateException e) {
                    e.printStackTrace();
                }

                
    return returnstr;
            }

            
            @SuppressWarnings(
    "unchecked")
            Map getMapContext() 
    {
                root.put(
    "entity", form);
                root.put(
    "insert", SqlHelper.buildInsertStatement(form));
                root.put(
    "update", SqlHelper.buildUpdateStatement(form));
                
                root.put(
    "insertParameter", SqlHelper.buildInsertparameter(form));
                root.put(
    "updateParameter", SqlHelper.buildUpdateparameter(form));
                
                root.put(
    "delete", SqlHelper.buildDeleteStatement(form));
                root.put(
    "query",  SqlHelper.buildQueryStatement(form));    
                
    return root;
            }

    }
    FormService.ftl
    import java.sql.ResultSet
    import java.sql.SQLException
    import java.sql.Types 
    import org.springframework.jdbc.core.RowMapper
    import org.springframework.jdbc.core.RowMapperResultSetExtractor
    import com.glnpu.sige.core.dao.DataSourceFactory
    import org.apache.commons.lang.builder.ToStringBuilder;
    import org.apache.commons.lang.builder.ToStringStyle;

    class ${entity.name?cap_first}Dao {
         def insert 
    = '${insert}'
         def delete 
    = '${delete}'
         def update 
    = '${update}'
         def 
    int insert( entity){
            def Object[] params 
    = [${insertParameter}]
            
    <#assign size = entity.formAttributeList?size/>
            def 
    int[] types=[<#list 1..size+1 as p>Types.VARCHAR,<#rt/></#list>]
            
    return DataSourceFactory.getJdbcTemplate().update(insert, params, types)
        }

         def 
    int update( entity){
            def Object[] params 
    = [${updateParameter}]
            
    return DataSourceFactory.getJdbcTemplate().update(update, params)
        }

         def 
    int delete(String entityId){
            def Object[] params 
    =[entityId]
            
    return DataSourceFactory.getJdbcTemplate().update(delete, params)
        }


        def search(entity)
    {
            $
    {query}
            println(query);
            
    return DataSourceFactory.getJdbcTemplate().queryForList(query);
            
        }

        
    }

     

        以上代码示意了如何利用 freemarker 生成 Groovy 和 hibernate 相关代码,以及如何利用Groovy动态的对数据库进行创建和增删改查操作,了解以上的原理后就可以方便的在运行时利用freemarker生成表示层页面以及代码来进行展示。
    展开全文
  • 动态生成form表单,不在为表单烦恼

    万次阅读 2020-07-28 12:09:40
    具有数据收集、校验和提交功能的表单生成器,包含input、复选框、单选框、输入框、下拉选择框等元素以及省市区三级联动、时间选择、日期选择、颜色选择、文件/图片上传功能,支持事件扩展。 欢迎大家star学习交流...

    form-create

    version npm JS gzip size

    具有动态渲染、数据收集、校验和提交功能的表单生成器,动态生成Form表单。支持双向数据绑定和事件扩展,组件包含有复选框、单选框、输入框、下拉选择框等表单元素以及省市区三级联动,时间选择,日期选择,颜色选择,滑块,评分,框架,文件/图片上传等功能组件。


    Github | Gitee | Npm | form-create 文档

    本项目还在不断开发完善中,如有建议或问题请在这里提出

    1.3 版本重大更新

    • 优化和精简内部结构
    • 支持 双向数据绑定!!!
    • 支持 全局方法快速创建表单
    • 新增 option.mounted事件,当组件加载完成后触发
    • 修复 一些BUG

    示例 代码

    [外链图片转存失败(img-9WaH7m0h-1563496700162)(https://raw.githubusercontent.com/xaboy/form-create/dev/images/sample110.jpg)]

    安装

    npm install form-create
    

    OR

    git clone https://github.com/xaboy/form-create.git
    cd form-create
    npm install
    

    引入

    浏览器:

    <!-- import Vue 2.5.16-->
    <script src="https://cdn.bootcss.com/vue/2.5.13/vue.min.js"></script>
    
    <!-- import iview 2.14.3-->
    <link rel="stylesheet" href="https://cdn.bootcss.com/iview/2.13.0/styles/iview.css">
    <script src="https://cdn.bootcss.com/iview/2.13.0/iview.min.js"></script>
    
    <!-- 省市区三级联动json数据,不使用三级联动不需要引入 -->
    <script src="district/province_city_area.js"></script>
    
    <!-- 模拟数据,实际使用中不需要引入 -->
    <script src="demo/mock.js"></script>
    
    <!-- import formCreate -->
    <script src="dist/form-create.min.js"></script>
    

    NodeJs:

    //三级联动数据,不使用三级联动不需要引入
    import 'form-create/district/province_city_area.js'
    //示例规则,实际使用中不需要引入
    import 'form-create/mock.js'
    import Vue from 'vue';
    import iView from 'iview';
    import 'iview/dist/styles/iview.css';
    import formCreat from 'form-create'
    Vue.use(iView);
    Vue.use(formCreat)
    

    注意! iview版本为2.14.3,Vue版本为2.5.*

    使用

    //示例规则
    let rules = window.mock;
    new Vue({
        data:{
            formData:{}	
        },
        mounted:function(){
            let root = document.getElementById('app'),that = this;
            $f = this.$formCreate(mock,{
                el:root,
                onSubmit:function (formData) {
                    console.log(formData);
                    //提交状态
                    $f.btn.loading();
                    //点击状态
                    //$f.btn.finish();
                    //创建第二个表单
                    $f2 = that.$formCreate(mock,root);
                }
                });
            //动态添加表单元素
            $f.append($r,'goods_name');
            //绑定表单数据到formData
            $f.model(this.formData);
            
        }
    })
    

    $formCreate 表单生成器参数

    • rules 表单生成规则:Array [inputRule,selectRule,…],可使用$formCreate.maker 快速生成规则
    • options 初始化配置参数:Object (详细见底部 createOptions)

    $formCreate.maker 组件规则生成器

    除hidden外,其他配置方式全部相同.详细参考表单元素规则

    props,event,slot传入参数为对象,例({key:value,…})

    validate,options传入参数为数组,例([options,options,…])

    model(obj,field = ‘’) 将在组件绑定到obj.field ,field为空默认时为rule.field

    $formCreate.maker指的是 vue内部的 this.$formCreate.maker 或者 window.formCreate.maker

    • hidden 生成隐藏字段
    $formCreate.maker.hidden(field,value)
    
    • input 生成input输入框
    $formCreate.maker.input(title,field,value)
    
    • radio 生成单选框
    $formCreate.maker.radio(title,field,value)
    
    • checkbox 生成复选框
    $formCreate.maker.radio(title,field,value) //value为array类型
    
    • select 生成select选择器
    $formCreate.maker.select(title,field,value) //多选是value为array类型
    
    • switch 生成switch开关
    $formCreate.maker.switch(title,field,value)
    
    • datepicker 生成日期选择器组件,别名date
    $formCreate.maker.date(title,field,value) //type为daterange或datetimerange时 value为array类型
    
    • timepicker 生成时间选择器组件,别名time
    $formCreate.maker.time(title,field,value) //type为timerange时 value为array类型
    
    • inputnumber 生成数字输入框,别名number
    $formCreate.maker.number(title,field,value)
    
    • colorpicker 生成颜色选择器组件,别名color
    $formCreate.maker.color(title,field,value)
    
    • cascader 生成多级联动组件`
    $formCreate.maker.cascader(title,field,value) //value为array类型
    
    • upload 生成上传组件`
    $formCreate.maker.upload(title,field,value)
    
    • rate 生成评分组件`
    $formCreate.maker.rate(title,field,value)
    
    • slider 生成滑块组件`
    $formCreate.maker.rate(title,field,value) //props range为true时 value为array类型
    
    • frame 生成框架组件`
    $formCreate.maker.frame(title,field,value)
    

    $f 实例方法

    • formData() 获取表单的value
    • getValue(field) 获取指定字段的value
    • model(obj) 绑定表单组件到obj对象,支持双向数据绑定。结构{field:{value,rule:{props,validate,options,slot,event}}}

    当修改后没有生效时 请尝试用vm.$set方法修改

    • changeField(field,value) 修改指定字段的value
    • resetFields() 重置表单
    • destroy() 销毁表单
    • removeField(field) 删除指定字段
    • fields() 获得表单所有字段名称
    • closeModal() 关闭frame组件的弹出框
    • submit() 表单验证通过后提交表单,触发onSubmit事件
    • validate(successFn,errorFn) 表单验证,如果验证通过执行successFn,未通过则执行errorFn
    • validateField(field,callback) 表单验证指定字段
        $f.validateField(field,(errMsg)=>{
            if(errMsg){
                //TODO 验证未通过
            }else{
                //TODO 验证通过
            }
        });
    
    • prepend(rule,field = undefined) 在field的字段之前输入指定表单元素,不传入field默认在第一个
        $f.prepend({
           type:"input",
           title:"商品简介",
           field:"goods_info",
           value:"",
           props: {
               "type": "text",
               "placeholder": "请输入商品简介",
           },
           validate:[
               { required: true, message: '请输入商品简介', trigger: 'blur' },
           ],
       });
    
    • append(rule,field = undefined) 在field的字段之前输入指定表单元素,不传入field默认在最后一个
        $f.append($formCreate.maker.upload('产品主图','logo','http://img1.touxiang.cn/uploads/20131030/30-075657_191.jpg')
            .props({
                  "action": "",
                  "maxLength": 1,
                  "multiple": false,
                  "type": "select",
                  "uploadType": "image",
                  "name": "file",
                  "onSuccess": function () {
                      return 'http://img1.touxiang.cn/uploads/20131030/30-075657_191.jpg';
                  }
            })
            .validate({required:true, type: 'array', min: 1, message: '请上传1张图片', trigger: 'change'})
        ,'goods_name');
    
    • submitStatus(props) 修改表单提交按钮状态
        $f.submitStatus({
            //按钮类型,可选值为primary、ghost、dashed、text、info、success、warning、error或者不设置
            type:"primary",
            //按钮大小,可选值为large、small、default或者不设置
            size:"large",
            //按钮形状,可选值为circle或者不设置
            shape:undefined,
            //开启后,按钮的长度为 100%
            long:true,
            //设置button原生的type,可选值为button、submit、reset
            htmlType:"button",
            //设置按钮为禁用状态
            disabled:false,
            //设置按钮的图标类型
            icon:"ios-upload",
            //按钮文字提示
            innerText:"提交",
            //设置按钮为加载中状态
            loading:false
        })
    
    • btn.loading() 让表单提交按钮进入loading状态
    • btn.finish() 让表单提交按钮恢复正常状态

    rules 表单元素规则

    hidden 隐藏字段

    maker快速生成:

    $formCreate.maker.hidden('id','14');
    

    原始参数:

    hiddenRule:
    {
      type:"hidden",//必填!
      //字段名称
      field:"id", //必填!
      //input值
      value:"14" //必填!
    }
    

    input 输入框

    规则说明

    maker快速生成:

    $formCreate.maker.input("商品名称","goods_name","iphone 7").props({
         clearable:true,
         placeholder: "请输入商品名称"
    }).validate([
         { required: true, message: '请输入goods_name', trigger: 'blur' },
    ]);
    

    原始参数:

    inputRule :
    {
            type:"input",//必填! 
            //label名称
            title:"商品名称",//必填!
            //字段名称
            field:"goods_name",//必填!
            //input值
            value:"iphone 7",
            props: {
                
                //输入框类型,可选值为 text、password、textarea、url、email、date
                "type": "text", //必填!
                //是否显示清空按钮
                "clearable":false, 
                //设置输入框为禁用状态
                "disabled": false, 
                //设置输入框为只读
                "readonly": false,
                //文本域默认行数,仅在 textarea 类型下有效
                "rows": 4, 
                //自适应内容高度,仅在 textarea 类型下有效,可传入对象,如 { minRows: 2, maxRows: 6 }
                "autosize": false, 
                //将用户的输入转换为 Number 类型
                "number": false, 
                //自动获取焦点
                "autofocus": false, 
                //原生的自动完成功能,可选值为 off 和 on
                "autocomplete": "off", 
                //占位文本
                "placeholder": "请输入商品名称", 
                //输入框尺寸,可选值为large、small、default或者不设置
                "size": "default",
                //原生的 spellcheck 属性
                "spellcheck": false,
            },
            event:{
                //按下回车键时触发
                enter:(event)=>{},
                //设置 icon 属性后,点击图标时触发
                click:(event)=>{},
                //数据改变时触发
                change:(event)=>{},
                //输入框聚焦时触发
                focus:(event)=>{},
                //输入框失去焦点时触发
                blur:(event)=>{},
                //原生的 keyup 事件
                keyup:(event)=>{},
                //原生的 keydown 事件
                keydown:(event)=>{},
                //原生的 keypress 事件
                keypress:(event)=>{},
            },
            validate:[
                { required: true, message: '请输入goods_name', trigger: 'blur' },
            ],
        }
    

    radio 单选框

    规则说明

    maker快速生成:

    $formCreate.maker.radio("是否包邮","is_postage","0").options([
         {value:"0",label:"不包邮",disabled:false},
         {value:"1",label:"包邮",disabled:true},
    ]);
    

    原始参数:

    radioRule :
    {
            type:"radio",//必填!
            //label名称
            title:"是否包邮",//必填!
            //字段名称
            field:"is_postage",//必填!
            //input值
            value:"0",
            //可选参数
            options:[
                {value:"0",label:"不包邮",disabled:false},
                {value:"1",label:"包邮",disabled:true},
            ],//必填!
            props: {
            	//可选值为 button 或不填,为 button 时使用按钮样式
                "type":undefined, 
                //单选框的尺寸,可选值为 large、small、default 或者不设置
                "size":"default", 
                //是否垂直排列,按钮样式下无效
                "vertical":false, 
            },
            event:{
                //在选项状态发生改变时触发,返回当前状态。通过修改外部的数据改变时不会触发
                change:(...arg)=>{},
            },
            validate:[],
        }
    

    checkbox 复选框

    规则说明

    maker快速生成:

    $formCreate.maker.checkbox("标签","label",["1","2","3"]).options([
         {value:"1",label:"好用",disabled:true},
         {value:"2",label:"方便",disabled:false},
         {value:"3",label:"实用",disabled:false},
         {value:"4",label:"有效",disabled:false},
    ]);
    

    原始参数:

    checkboxRule :
    {
            type:"checkbox",//必填!
            //label名称
            title:"标签",//必填!
            //字段名称
            field:"label",//必填!
            //input值
            value:[
                "1","2","3"
            ],
            //可选参数
            options:[
                {value:"1",label:"好用",disabled:true},
                {value:"2",label:"方便",disabled:false},
                {value:"3",label:"实用",disabled:false},
                {value:"4",label:"有效",disabled:false},
            ],//必填!
            props: {
            	//多选框组的尺寸,可选值为 large、small、default 或者不设置
                "size":"default", 
            },
            event:{
                //只在单独使用时有效。在选项状态发生改变时触发,通过修改外部的数据改变时不会触发
                change:(...arg)=>{},
            },
            validate:[],
        }
    

    select 选择器

    规则说明

    maker快速生成:

    $formCreate.maker.select("产品分类","cate_id",["104","105"]).options([
         {"value": "104", "label": "生态蔬菜", "disabled": false},
         {"value": "105", "label": "新鲜水果", "disabled": false},
    ]);
    

    原始参数:

    selectRule :
    {
            type: "select",//必填!
            field: "cate_id",//必填!
            title: "产品分类",//必填!
            //input值
            value: ["104","105"],
            //可选参数
            options: [
                {"value": "104", "label": "生态蔬菜", "disabled": false},
                {"value": "105", "label": "新鲜水果", "disabled": false},
            ],//必填!
            props: {
           	 	//是否支持多选
                "multiple": true, 
                //是否可以清空选项,只在单选时有效
                "clearable": false,
                //是否支持搜索
                "filterable": true, 
                
                // 暂不支持远程搜索
                // "remote": false, //是否使用远程搜索
                // "remote-method":Function, //远程搜索的方法
                // "loading": false, //当前是否正在远程搜索
                // "loading-text": "加载中", //远程搜索中的文字提示
                //选择框大小,可选值为large、small、default或者不填
                "size":"default", 
                //选择框默认文字
                "placeholder": "请选择", 
                 //当下拉列表为空时显示的内容
                "not-found-text": "无匹配数据",
                //弹窗的展开方向,可选值为 bottom 和 top
                "placement": "bottom", 
                //是否禁用
                "disabled": false, 
            },
            event:{
                //选中的Option变化时触发,返回 value
                change:(checked)=>{},
                //搜索词改变时触发
                'query-change':(keyword)=>{},
            },
            validate:[],
        }
    

    switch 开关

    规则说明

    maker快速生成:

    $formCreate.maker.switch("是否上架","is_show","1").options([
         {"value": "104", "label": "生态蔬菜", "disabled": false},
         {"value": "105", "label": "新鲜水果", "disabled": false},
    ]).slot({open:"上架",close:"下架"}).props({"trueValue":"1","falseValue":"0"});
    

    原始参数:

    switchRule :
    {
            type:"switch",//必填!
            //label名称
            title:"是否上架",//必填!
            //字段名称
            field:"is_show",//必填!
            //input值
            value:"1",
            props: {
            	//开关的尺寸,可选值为large、small、default或者不写。建议开关如果使用了2个汉字的文字,使用 large。
                "size":"default", 
                //禁用开关
                "disabled":false,
                //选中时的值,当使用类似 1 和 0 来判断是否选中时会很有用
                "trueValue":"1", 
                //没有选中时的值,当使用类似 1 和 0 来判断是否选中时会很有用
                "falseValue":"0", 
            },
            slot: {
            	//自定义显示打开时的内容
                open:"上架", 
                //自定义显示关闭时的内容
                close:"下架", 
            },
            event:{
                //开关变化时触发,返回当前的状态 0 | 1
                change:(bool)=>{},
            },
            validate:[],
        }
    

    DatePicker 日期选择器

    规则说明

    maker快速生成:

    $formCreate.maker.date("活动日期","section_day",['2018-02-20', new Date()])
      .props({
        "type": "datetimerange",
      	"placeholder":"请选择活动日期", 
    });
    

    原始参数:

    DatePickerRule :
    {
            type: "DatePicker",//必填!
            field: "section_day",//必填!
            title: "活动日期",//必填!
            //input值, type为daterange,datetimerange value为数组 [start_value,end_value]
            value: ['2018-02-20', new Date()], 
            props: {
                
                //显示类型,可选值为 date、daterange、datetime、datetimerange、year、month
                "type": "datetimerange",//必填!
                //展示的日期格式
                "format": "yyyy-MM-dd HH:mm:ss", 
                //日期选择器出现的位置,可选值为toptop-starttop-endbottombottom-startbottom-endleftleft-startleft-endrightright-startright-end
                "placement": "bottom-start", 
                //占位文本
                "placeholder":"请选择获得时间", 
                //是否显示底部控制栏,开启后,选择完日期,选择器不会主动关闭,需用户确认后才可关闭
                "confirm":false, 
                //尺寸,可选值为large、small、default或者不设置
                "size":"default", 
                //是否禁用选择器
                "disabled":false, 
                //是否显示清除按钮
                "clearable":true, 
                //完全只读,开启后不会弹出选择器
                "readonly":false, 
                //文本框是否可以输入
                "editable":false, 
            },
            event:{
                //日期发生变化时触发,已经格式化后的日期,比如 2016-01-01
                change:(value)=>{},
                //弹出日历和关闭日历时触发 true | false
                'open-change':(bool)=>{},
                //在 confirm 模式或 clearable = true 时有效,在清空日期时触发
                clear:(...arg)=>{},
            },
            validate:[],
        }
    

    TimePicker 时间选择器

    规则说明

    maker快速生成:

    $formCreate.maker.time("活动时间","section_time",[])
      .props({
        "type": "timerange",
      	"placeholder":"请选择活动时间", 
    });
    

    原始参数:

    TimePickerRule :
    {
            type: "TimePicker",//必填!
            field: "section_time",//必填!
            title: "活动时间",//必填!
            //input值, type为timerange value为数组 [start_value,end_value]
            value: [], 
            props: {
                //显示类型,可选值为 time、timerange
                "type": "timerange", //必填!
                //展示的时间格式
                "format": "HH:mm:ss", 
                //下拉列表的时间间隔,数组的三项分别对应小时、分钟、秒。例如设置为 [1, 15] 时,分钟会显示:00、15、30、45。
                "steps": [], 
                //时间选择器出现的位置,可选值为toptop-starttop-endbottombottom-startbottom-endleftleft-startleft-endrightright-startright-end
                "placement": "bottom-start", 
                //占位文本
                "placeholder":"请选择活动时间", 
                //是否显示底部控制栏,开启后,选择完日期,选择器不会主动关闭,需用户确认后才可关闭
                "confirm":false, 
                //尺寸,可选值为large、small、default或者不设置
                "size":"default",
                //是否禁用选择器
                "disabled":false, 
                //是否显示清除按钮
                "clearable":true, 
                //完全只读,开启后不会弹出选择器
                "readonly":false, 
                //文本框是否可以输入
                "editable":false, 
            },
            event:{
                //时间发生变化时触发 已经格式化后的时间,比如 09:41:00
                change:(checked)=>{},
                //弹出浮层和关闭浮层时触发 true | false
                'open-change':(bool)=>{},
                //在清空日期时触发
                clear:(...arg)=>{},
            },
            validate:[],
        }
    

    InputNumber 数字输入框

    规则说明

    maker快速生成:

    $formCreate.maker.number("排序","sort",1)
      .props({
        "type": "timerange",
      	"precision":0, 
    });
    

    原始参数:

    InputNumberRule :
    {
            type: "InputNumber",//必填!
            field: "sort",//必填!
            title: "排序",//必填!
            //input值
            value: 1,
            props: {
            	//最大值
                "max": undefined, 
                //最小值
                "min": undefined, 
                //每次改变的步伐,可以是小数
                "step": 1, 
                //输入框尺寸,可选值为large、small、default或者不填
                "size":"default", 
                //设置禁用状态
                "disabled":false, 
                //是否设置为只读
                "readonly":false, 
                //是否可编辑
                "editable":true, 
                //数值精度
                "precision":0, 
            },
            event:{
                //数值改变时的回调,返回当前值
                change:(value)=>{},
                //聚焦时触发
                focus:(event)=>{},
                //失焦时触发
                blur:(event)=>{},
            },
            validate:[],
        }
    

    ColorPicker 颜色选择器

    规则说明

    maker快速生成:

    $formCreate.maker.color("颜色","color",'#ff7271')
      .props({
        "format":"hex"
    });
    

    原始参数:

    ColorPickerRule :
    {
            type: "ColorPicker",//必填!
            field: "color",//必填!
            title: "颜色",//必填!
            //input值
            value: '#ff7271', 
            props: {
            	//是否支持透明度选择
                "alpha": false, 
                //是否支持色彩选择
                "hue": true, 
                //是否显示推荐的颜色预设
                "recommend": false, 
                //尺寸,可选值为large、small、default或者不设置
                "size":"default", 
                //自定义颜色预设
                "colors":[], 
                //颜色的格式,可选值为 hsl、hsv、hex、rgb,开启 alpha 时为 rgb,其它为 hex
                "format":"hex", 
            },
            event:{
                //当绑定值变化时触发,返回当前值
                change:(color)=>{},
                //聚焦时触发 面板中当前显示的颜色发生改变时触发
                'active-change':(color)=>{},
            },
            validate:[],
        }
    

    Cascader 多级联动

    规则说明

    maker快速生成:

    $formCreate.maker.cascader("所在区域","address",['陕西省','西安市','新城区'])
      .props({
        data:window.province,
      	placeholder:'请选择所在区域',
    });
    

    原始参数:

    CascaderRule:
    {
            type:"cascader",//必填!
            title:"所在区域",//必填!
            field:"address",//必填!
            //input值
            value:['陕西省','西安市','新城区'],
            props:{
                //可选项的数据源,格式参照示例说明
                data:window.province || [],//必填!
                //选择后展示的函数,用于自定义显示格式
                renderFormat:label => label.join(' / '),
                //是否禁用选择器
                disabled:false,
                //是否支持清除
                clearable:true,
                //输入框占位符
                placeholder:'请选择',
                //次级菜单展开方式,可选值为 click 或 hover
                trigger:'click',
                //当此项为 true 时,点选每级菜单选项值都会发生变化,具体见上面的示例
                changeOnSelect:false,
                //输入框大小,可选值为large和small或者不填
                size:undefined,
                //动态获取数据,数据源需标识 loading
                loadData:()=>{},
                //是否支持搜索
                filterable:false,
                //当搜索列表为空时显示的内容
                notFoundText:'无匹配数据',
                //是否将弹层放置于 body 内,在 Tabs、带有 fixed 的 Table 列内使用时,建议添加此属性,它将不受父级样式影响,从而达到更好的效果
                transfer:false,
            },
            event:{
                //选择完成后的回调,返回值 value 即已选值 value,selectedData 为已选项的具体数据
                change:(value, selectedData)=>{},
                //展开和关闭弹窗时触发
                'visible-change':bool=>{}
            },
            validate:[],
    
        }
    

    Upload 上传

    规则说明

    maker快速生成:

    $formCreate.maker.upload("轮播图","pic",['http://img1.touxiang.cn/uploads/20131030/30-075657_191.jpg','http://img1.touxiang.cn/uploads/20131030/30-075657_191.jpg'])
      .props({
        "action": "",
        "maxLength": 1,
        "multiple": false,
        "type": "select",
        "uploadType": "image",
        "name": "file",
        "onSuccess": function () {
            return 'http://img1.touxiang.cn/uploads/20131030/30-075657_191.jpg';
        }
    }).validate({required:true, type: 'array', min: 1, message: '请上传1张图片', trigger: 'change'});
    

    原始参数:

    UploadRule :
    {
            type: "Upload",//必填!
            field: "pic",//必填!
            title: "轮播图",//必填!
            //input值,当maxLength等与1时值为字符串,大于1时值为数组
            value: ['http://img1.touxiang.cn/uploads/20131030/30-075657_191.jpg','http://img1.touxiang.cn/uploads/20131030/30-075657_191.jpg'], //input值
            props: {
                //上传控件的类型,可选值为 select(点击选择),drag(支持拖拽)
                "type":"select", //必填!
                //上传文件类型,可选值为 image(图片上传),file(文件上传)
                "uploadType":"image", //必填!
                //上传的地址
                "action": "", //必填! 
                //上传的文件字段名
                "name":"", 
                //上传时附带的额外参数
                "data":{}, 
                //设置上传的请求头部
                "headers": {}, 
                //是否支持多选文件
                "multiple": true,
                //支持发送 cookie 凭证信息
                "withCredentials":false, 
    
                //不支持
                // "showUploadList":false, //是否显示已上传文件列表
                // "defaultFileList":[], // 默认已上传的文件列表
    			
                //接受上传的文件类型
                "accept":"",
                //支持的文件类型,与 accept 不同的是,format 是识别文件的后缀名,accept 为 input 标签原生的 accept 属性,会在选择文件时过滤,可以两者结合使用
                "format":[], 
                //文件大小限制,单位 kb
                "maxSize":undefined, 
                //可上传文件数量
                "maxLength":1,
                //上传文件之前的钩子,参数为上传的文件,若返回 false 或者 Promise 则停止上传
                "beforeUpload":()=>{}, 
                //文件上传时的钩子,返回字段为 event, file, fileList
                "onProgress":()=>{}, 
                //文件上传成功时的钩子,返回字段为 response, file, fileList,若需有把文件添加到文件列表中,在函数值返回即可
                "onSuccess":function () {
                    return 'http://img1.touxiang.cn/uploads/20131030/30-075657_191.jpg';
                }, //必填!
                //文件上传失败时的钩子,返回字段为 error, file, fileList
                "onError":(error, file, fileList)=>{}, 
                //点击已上传的文件链接时的钩子,返回字段为 file, 可以通过 file.response 拿到服务端返回数据
                "onPreview":()=>{}, 
                //文件列表移除文件时的钩子,返回字段为 file, fileList
                "onRemove":()=>{}, 
                //文件格式验证失败时的钩子,返回字段为 file, fileList
                "onFormatError":()=>{}, 
                //文件超出指定大小限制时的钩子,返回字段为 file, fileList
                "onExceededSize":()=>{}, 
                //辅助操作按钮的图标 ,设置为false将不显示
                handleIcon:'ionic',
                //点击辅助操作按钮事件
                onHandle:(src)=>{},
                //是否可删除,设置为false是不显示删除按钮
                allowRemove:true,
            },
        }
    

    Slider 滑块

    规则说明

    maker快速生成:

    $formCreate.maker.slider('滑块','slider',[0,52]).props({
            "min": 0,
            "max": 100,
            "showTip":"always",
      		"range": true
        });
    

    原始参数:

    SliderRule :
    {
         type:"slider",
         field:"slider",
         title:"滑块",
          value:[0,50], //滑块选定的值。普通模式下,数据格式为数字,在双滑块模式下,数据格式为长度是2的数组,且每项都为数字
         props:{
              "min": 0, //最小值
             "max": 100, //最大值
             "step": 1, //步长,取值建议能被(max - min)整除
             "disabled": false, //是否禁用滑块
             "range": true, //是否开启双滑块模式
             "showInput":false, //是否显示数字输入框,仅在单滑块模式下有效
             "showStops":true, //是否显示间断点,建议在 step 不密集时使用
              "showTip":"hover", //提示的显示控制,可选值为 hover(悬停,默认)、always(总是可见)、never(不可见)
             "tipFormat":undefined, //Slider 会把当前值传给 tip-format,并在 Tooltip 中显示 tip-format 的返回值,若为 null,则隐藏 Tooltip
             "inputSize":"small", //数字输入框的尺寸,可选值为large、small、default或者不填,仅在开启 show-input 时有效
         },
          event:{
             //在松开滑动时触发,返回当前的选值,在滑动过程中不会触发
             change:(value)=>{},
             //滑动条数据变化时触发,返回当前的选值,在滑动过程中实时触发
             input:(value)=>{},
         },
         validate:[]
     }
    

    Rate 评分

    规则说明

    maker快速生成:

    $formCreate.maker.rate('推荐级别','rate',2)
            .props({
                "count": 10,
                "allowHalf": false
            }).validate({required:true,type:'number',min:3, message: '请大于3颗星',trigger:'change'});
    

    原始参数:

    RateRule :
    {
            type:"rate",
            field:"rate",
            title:"推荐级别",
            value:3.5,
            props:{
                "count": 10, //star 总数
                "allowHalf": true, //是否允许半选
                "disabled": false, //是否只读,无法进行交互
                "showText": true, //是否显示提示文字
                "clearable": true, //是否可以取消选择
            },
            event:{
                //评分改变时触发
                change:(value)=>{},
            },
            validate:[
                {required:true,type:'number',min:3, message: '请大于3颗星',trigger:'change'}
            ]
    }
    

    Frame 框架

    规则说明

    maker快速生成:

    maker.frame('素材','fodder',["http://img1.touxiang.cn/uploads/20131030/30-075657_191.jpg"]).props({
            src:"iframe.html",
            maxLength:2,
            type:"image"
        }).validate([
            {required:true, type: 'array', min: 2, message: '请选择2张图片', trigger: 'change'}
        ]).event({
                  remove:()=>{return false;}
    })
    

    原始参数:

    FrameRule :
    {
            type:"frame",
            title:"素材",
            field:"fodder",
            value:["http://img1.touxiang.cn/uploads/20131030/30-075657_191.jpg"],
            props:{
                type:"image", //frame类型,有input,file,image
                src:"iframe.html", //iframe地址
                maxLength:2, //value的最大数量
                icon:'folder', //打开弹出框的按钮图标
                height:"220px", //弹出框高度
                width:"350px", //弹出框宽度
                spin:false, //是否显示加载动画
                title:"请选择", //弹出框标题
                handleIcon: true, //操作按钮的图标 ,设置为false将不显示,设置为true为默认的预览图标,类型为file时默认为false,image类型默认为true
                allowRemove:true, //是否可删除,设置为false是不显示删除按钮
            },
            event:{
                change:()=>{console.log('change')}, //value改变时触发
                open:()=>{console.log('open')}, //打开弹出层回调
                ok:()=>{console.log('ok')}, //点击确定时的回调
                handle:undefined, //点击操作按钮事件,默认为图片预览
                remove:()=>{return false;} //点击删除按钮事件,返回false将不删除
            },
            validate:[
                {required:true, type: 'array', min: 5, message: '请选择5张图片', trigger: 'change'}
            ],
        }
    

    全局配置 createOptions

    {
        //插入节点,默认document.body
        el:null,
        //form配置
        form:{
        
            //是否开启行内表单模式
            inline:false,
            //表单域标签的位置,可选值为 left、right、top
            labelPosition:'right',
            //表单域标签的宽度,所有的 FormItem 都会继承 Form 组件的 label-width 的值
            labelWidth:125,
            //是否显示校验错误信息
            showMessage:true,
            //原生的 autocomplete 属性,可选值为 off 或 on
            autocomplete:'off',
        },
        //文件上传全局配置
        upload:{
        
            //上传文件之前的钩子,参数为上传的文件,若返回 false 或者 Promise 则停止上传
            beforeUpload:()=>{},
            //文件上传时的钩子,返回字段为 event, file, fileList
            onProgress:(event, file, fileList)=>{},
            //文件上传成功时的钩子,返回字段为 response, file, fileList,若需有把文件添加到文件列表中,在函数值返回即可
            onSuccess:(response, file, fileList)=>{
                // return 'filePath';
            },
            //文件上传失败时的钩子,返回字段为 error, file, fileList
            onError:(error, file, fileList)=>{},
            //点击已上传的文件链接时的钩子,返回字段为 file, 可以通过 file.response 拿到服务端返回数据
            onPreview:(file)=>{},
            //文件列表移除文件时的钩子,返回字段为 file, fileList
            onRemove:(file, fileList)=>{},
            //文件格式验证失败时的钩子,返回字段为 file, fileList
            onFormatError:(file, fileList)=>{},
            //文件超出指定大小限制时的钩子,返回字段为 file, fileList
            onExceededSize:(file, fileList)=>{},
            //辅助操作按钮的图标 ,设置为false将不显示
            handleIcon:'ios-eye-outline',
            //点击辅助操作按钮事件
            onHandle:(src)=>{},
            //是否可删除,设置为false是不显示删除按钮
            allowRemove:true,
        },
        
        //表单提交事件
        onSubmit:(formData)=>{},
        
        //提交按钮配置,设置为false时不显示按钮
        submitBtn:{
        
            //按钮类型,可选值为primary、ghost、dashed、text、info、success、warning、error或者不设置
            type:"primary",
            //按钮大小,可选值为large、small、default或者不设置
            size:"large",
            //按钮形状,可选值为circle或者不设置
            shape:undefined,
            //开启后,按钮的长度为 100%
            long:true,
            //设置button原生的type,可选值为button、submit、reset
            htmlType:"button",
            //设置按钮为禁用状态
            disabled:false,
            //设置按钮的图标类型
            icon:"ios-upload",
            //按钮文字提示
            innerText:"提交",
            //设置按钮为加载中状态
            loading:false,
        }
    }
    

    form-builder PHP现代化表单生成器

    展开全文
  • 【转】动态表单设计与实现

    千次阅读 2011-10-07 23:00:23
    动态表单的意义 对于动态表单的探讨现在越来越多了。原因无非是表单在信息管理系统中的重要作用,基本上采用表单+流程就可以实现一个OA系统。然而数量众多的表单和易变动性让开发人员感到疲惫。为了让开发人员把...

     

    动态表单的意义
      对于动态表单的探讨现在越来越多了。原因无非是表单在信息管理系统中的重要作用,基本上采用表单+流程就可以实现一个OA系统。然而数量众多的表单和易变动性让开发人员感到疲惫。为了让开发人员把注意力集中在业务流程上来,也可以让系统操作人员参与到表单的管理,就出现了动态表单技术。

    信息管理系统

       通常情况下,表单加流程,就构成了一个信息管理系统。
       在对信息管理系统的探索中我们发现,按业务的量和成熟度,我们可以将业务系统是分为大业务系统和小业务系统。大业务具有业务量大且成熟稳定的特点。而小业务大部分也是新业务,具有业务量小和动态多变的特点。这些特点主要体现在业务流程和表单上的不同。

    业务特点

       往往对新业务没有一个很好的系统支持,因为新业务的特性是市场前景不明,业务量小,表单和业务流程都随着业务的发展不断在变,越具有快速成长性的新业务可能变化更多。为一个新的业务开发一个独立的系统支持,从业务运营者角度看成本大,从系统开发者角度看难度更大。通常只有当新业务逐步发展,逐步稳定下来,业务量上去了,变成了一个大业务,才可以考虑建立独立系统支持或者移植到原有的大业务系统中去。所以对许多新业务的系统支持上比较薄弱。
      从现状来看,由于新业务没有系统支持,所以大部分采用各种excel表单的方式进行管理,一项业务的办理都是通过excel表单的流转。当然比纸制的要先进。不过,无序和低效表现得比较明显。 
      从技术上讲,新业务系统的开发需要解决可定制表单和流程的技术难题。本篇主要讨论如何为多变的表单提供一个解决方案。 我们看到许多业务都是由表单驱动,比如申请开通业务填写申请单,业务实施填写施工单。不过,随着业务的发展,这些表单包括字段和显示格式都在变。很显然,固定表单的开发无法满足这类用户业务需求。而作为软件开发者在做需求分析的时候,希望通过要求用户签字确认的方式来限制用户需求的变化,这样的做法不合情理,技术没有真正为生产服务。那么如何在新业务的发展阶段支持业务中多变的表单呢,我们就提出了动态表单


    动态表单的实现思路

       分析一个表单,主要包含字段、数据,和表现形式这三个元素。数据和字段是成对出现的,可以进行格式化存入数据库或者xml文档。而表现形式可以采用html作为表单模板。现在html功能强大,可以表现复杂的表格。在没有OA系统的时候大部分表格是用word或者excel格式制作而成的,他们都有另存为html的功能。

       设计动态表单模型,基本的思路应该是数据和表现显示的分离。抛开表现层,一个表单包含的若干个字段和填写的数据。所谓动态,就是这些字段名称可能改变,数量可能有增减。
    动态表单

     

       如何实现表现层。有一个思路也是动态生成表现层。实现一个表单设计器,把需要的字段类型从字段库里拖出来,摆在合适的位置,保存生成表单,系统可以通过这个表单录入数据。但即使我们可以把这个设计器做得很完美,定义表现层的这个过程也是一个非常繁琐,还可能要考虑打印的效果。所以对于复杂表单,这个方法不可取,要改变思路。   
       从现状况出发,因为已经有excel的表单存在,表现显示已经确定了。这是静态的。我们可以稍做修改,在其中插入字段名标签和数据项标签,用来对应动态表单字段名称和数据项。然后实现一个“表单解析器”。从这个预先定义好的模版中提取字段名称和数据项生成一个动态表单,并将这个模版做为展示页面。从用户操作的角度上看,在现有的excel表单的基础上设计显然简便多了,即使是一个新的表单,用excel设计界面也会比在我们实现的设计器中要简单而且精确,还可以预缆打印效果。从实现来看,动态表单的解析器比设计器要容易,而且更加符合需求。解析器的思路可取。
      解析器的实现是对特殊处理过的html文件进行解析,技术上可以使用功能强大的正则表达式。
      
    动态表单解析器







    数据标签的设计 
      生活中我们用到各种表单,需要填写各种表格。表单的作用是按固定的格式填写数据,让数据有条理。抛开排列位置次序等表现方式不管,表单是多个字段名称和紧跟其后需要输入数据组成,字段和数据总是一一对应。需要输入的数据可能多种类型,常用的是文本、单选、多选。在设计的动态表单的解析器时,需要使用特定字符组成的标签来表示字段域和数据域,以及不同类型的数据域。我们在总结html解析实践上总结出如下比较恰当的标签表示。
    文本输入框样式:#字段名称#   @@
    单选按钮样式:#字段名称#   @a1;a2;a3@ 
    复选框样式:#字段名称#   @b1,b2,b3@ 
    文本域样式:#字段名称#   @textarea@ 
      同一张表单里应该避免相同的字段名称; 在“#”之间部分的字段才是系统所识别的字段;一对“#”对应一对“@” ; 字段名称与输入域只能是左右排列的关系,既“##”与“@@”只能是左右排列。
      考虑到多个表单之间可能存在的数据继承的关系。也是为了方便录入,希望填写表但B的时候部分数据是从已经填写的表单A中继承过来。两个表单中的#字段名称# 要相同。
      考虑到统计和打印显示查找等需要。需要把一些特殊的字段定义成关键字。在设计表单时候要字段名称要与关键字保持一致。



    表单数据的查询
      动态表单如何实现方便的查询。比较动态表单的数据和固定表单的数据结构,一个固定表单是存放一条记录,这条记录是包含了表单内的n个字段,而一个动态表单,是一个字段一条记录,所以有n条记录。所以针对动态表单的查询,是需要牺牲效率。如何提高效率,可以设置一些关键字段,这些字段和表单信息在一起。针对关键字段的查询效率就高很多了。



    动态表单之间的关系
      假设,一个业务进程有AB两个表单。为方便使用,A表单中某些字段的数据(比如业务编号)填写完后,B表单中相同字段需要继承下来。如何解决这个问题。在制作表单模板的时候,需要注意的是相同字段名称的书写方式要相同,比如不能多一个空格之类的。然后在程序实现B表单的填写时候读取A表单的数据,在相同字段对应的位置显示。


    动态表单的局限性
      动态表单可维护性好,可以在很多信息管理系统中得到应用。但是毕竟是动态的,要损失掉效率。当系统数据量大,而且业务及表单结构稳定的情况下,固定表单是更好的方式。所以动态表当的适用范围是,是具有业务量小和动态多变的特点的业务系统,通常是一些新业务或是小业务。

    动态表单的特殊应用
      假设我们只需关注字段和数据,而不必关注表单的表现形式,或只需要简单的按顺序排列字段就可以满足需要。也没有复杂的业务的概念,表单之间没有复杂的数据继承的关系,独立表单就可以作为业务的流转实体。这样就可以去掉了表单模板的部分和业务概念的部分,这个动态表单模型就更加简化。只需要操作Form,FormPattern,FormData,Field四个对象就可以了。这个模型的应用还是广泛存在的,比如学生的档案信息。

    动态表单数据库设计

    业务表t_service
    一个业务包含了多个工单样式
    表字段 
    id:业务编号
    departmentId :业务管理单位(中心节点)
    serviceName:业务名称 
    serviceType:业务类型,初始化14种业务
    formPatternCount:工单样式数量,默认0 
    pictureFilename:业务流程图片文件 
    isAnnexAllowed:是否允许上传附件;0不允许,1表示允许
    workingDay:任务计划总施工时间 
    version:版本号。定义业务名称相同时候提示并自动生成一个新的版本,如果存在新的版本则在申请业务的时候给出最新版本。统计报表按业务名称相同 。 定义一个新版本的业务,旧版本自动作废。
    Locked: 是否锁定,锁定后不能被申请 
    creator:创建人
    dateCreated:创建时间
    dateUpdated:更新时间,字段更新,表示表单也更新, 
    modifier:修改人


    工单样式表t_formPattern

    记录表单样式
    根据模版生成表单样式。
    表字段
     
    id:编号
    templateId:模版编号,空或-1或模版不存在也表示不使用模版
    formPatternType:表单样式类型,申请单 applicationForm,施工单 workingForm
    formPatternName:表单名称
    serviceId:业务编号,在系统中需要选定业务上传模版生成表单样式。 creator:创建人
    dateCreated:创建时间
    dateUpdated:更新时间,字段更新,表示表单也更新, 
    modifier:修改人

    工单表t_form 
    表单实体,继承自表单样式,可以填写数据。 
    申请单相对与一个业务是唯一的,如果是工单,没有状态。
    表字段 
    id:表单编号,系统自动生成的流水号
    formPatternId:表单样式编号
    serviceId:业务编号,来自formPattern.serviceId,为了查询方便增加
    formNumber 工单业务编号,工单编号是实际流转中的工单唯一标识。实施管理员输入,如果已经存在相同编号,系统需要提醒 
    applicationId:申请(单)编号,表示该表单对应的申请单编号,来自Form.id and formPattern.formPatternType= applicationForm creator:创建人
    dateCreated:创建时间
    dateUpdated:更新时间,字段更新,表示表单也更新, 
    modifier:修改人

    字段表t_field
     
    记录表单定义的字段。字段包含有类型,枚举型数据去字点表查
    表字段 
    id:编号
    formPatternId:表单样式编号
    filedName:字段名称,从模版中提取出来
    fieldTag:数据标签,用于与模版上的标签匹配,如果是 @@表示,使用序列关联
    inputType:字段输入类型,输入框 text,下拉框(枚举型)select。单选radio,多选checkbox 
    creator:创建人
    dateCreated:创建时间
    dateUpdated:更新时间,字段更新,表示表单也更新, 
    modifier:修改人

    模版表t_template
     
    定义表单的模版,表单通过模版打印。 
    通过excle导出html文件,上传。
    样式规则:
    字段名称使用“#字段名称#”表示
    字段名称对应的填写数据处使用“@@”表示
    如果是枚举型的字段使用“@枚举域1; 枚举域2; 枚举域3@”表示
    表字段 
    编号id
    模版名称templateName
    模版路径filename
    原文件名称sourceFilename 
    creator:创建人
    dateCreated:创建时间
    dateUpdated:更新时间,字段更新,表示表单也更新, 
    modifier:修改人

    数据表t_formData 
    用于存放字段内的数据,字段内容支持最大1000个字符
    表字段 
    id:编号
    fromId:表单编号。 
    fieldId:字段编号
    content:数据内容,支持最大1000个字符 
    creator:创建人
    dateCreated:创建时间
    dateUpdated:更新时间,字段更新,表示表单也更新, 
    modifier:修改人

    T_keyfield关键字段表 
    需要中fromdata.content表中读到数据利用触发器tr_formdata_keyfield写到form表中去,
    表字段
    Id
    KeyfieldName:关键字段名字,例如“#工单编号#”
    mappingTable:对应表,例如“t_form,t_application”
    mappingField:在t_Form表中对应的字段 例如“formNumber”
    mappingCondition:表的条件,例如where id = v_formid and id<>applicationid;
    disable:是否执行,1表示执行,2表示不执行
    如果需要更新两个表,写两条记录,如果没有对应表则不其作用
    触发器代码,例如
    if v_fieldname='#工单编号#' then
    update t_form
    set formnumber = v_content,
    modifier = v_modifier,
    dateupdated = sysdate
    where id = v_formid and id<>applicationid;
    end if;
    if v_fieldname='申请单号#' then
    update t_form
    set formnumber = v_content,
    modifier = v_modifier,
    dateupdated = sysdate
    where id = v_formid and id=applicationid;
    update t_application
    set applicationnumber = v_content,
    dateupdated = sysdate,
    modifier = v_modifier
    where applicationid = v_formid;
    end if;




    动态表单数据库设计

     

     

    转自 : http://www.chasion.com/freeform.asp

     

    展开全文
  • 动态表单 (一)动态表单的定义

    千次阅读 热门讨论 2013-12-10 11:05:25
    什么是动态表单?  根据爱因斯坦相对论有动态表单说明是有静态表单的存在,生活中乃至世界任何两个有质量的物体都是运动的,这只是相对论的狭隘解析即狭义相对论,平常我们讨论的也往往是狭义相对论,这一理论的...
    • 什么是动态表单?

                   根据爱因斯坦相对论有动态表单说明是有静态表单的存在,生活中乃至世界任何两个有质量的物体都是运动的,这只是相对论的狭隘解析即狭义相对论,平常我们讨论的也往往是狭义相对论,这一理论的提出给物理学带来了革命性的变化,共同奠定了现代物理学的基础。相对论极大地改变了人类对宇宙和自然的“常识性”观念,丰富了我们的常识。

                看到动态表单也许你会想到动态、静态网页,它们和动态表单有什么区别呢?我觉的它们本质没有区别只是生成的时间不同而已,静态网页在编码阶段即可固定,以后它的内容也不会再有所改变;动态网页虽然编码阶段结构也确定了但是它的内容可以改变,可以让用户自己选择、可以和用户交互。

                动态表单的目的是为了根据业务流程不同灵活设计显示页面,显然,在业务流程设计阶段不用过多的考虑表单如何实现,将业务流程与表单显示分离开了,充分体现了MVC思想,我们可以把动态表单看成了V层的具体实现。

    • 动态表单建模

                  记得前几天看了一本小书叫《成交》,深刻剖析了一个大型IT公司的发展历程以及各个人物的思想活动里面有一句“攻城为下,攻心为上”,这句话说的的确很对,在生成表单时只有知道表单核心组成元素才能组装出表单,生成动态表单时也展现出了另一个编程思想OOP面向对象编程,生成表单也就是组装过程,按照这个思想我们把表单拆分、建模,持久化到数据库中。

               下图是抽象出来的表单类图

               

     

                     一个表单是由多个表单域组成,每个表单域有名称、输入框类型、输入数据类型,如果是列表框还会有条目的添加,这就是最简单的动态表单,如果表单上还有一些复杂控件会麻烦一些但是流程是一样的

     

    • 持久化到数据库中

                   将表单数据保存到数据库中,等需要的时候直接从数据库里面加载即可,看一下生成的一些表。

               

              

               

    •  表单的显示

                      下一篇博客中将介绍表单显示,通过freemarker插件来动态显示页面!

    展开全文
  • 动态表单

    2016-03-09 13:58:16
    自定义动态表单 整体描述:通过XML配置完成表单及表单控件的定义、通过对XML的解析完成表单及表单控件的展示、表单的验证控制、表单数据的加载、表单相关操作的接口设计,实现动态表单动态表单组件为独立的开发...
  • form表单验证是几乎所有web项目或者APP都会遇到的,那么通常遇到的表单验证情况主要分为以下三种: 1.form表单中的表单项项都是写死的 意思是说,表单项不是根据动态数据加载出来的。那么只需要写好对应的验证规则...
  • 由于做项目的需要做一个不定项的form表单,即可以动态生成表单项的form表单,自己利用element-ui的el-form表单制作了一个,如下动图: 此动态form表单是基于element-ui里的el-form表单基础上进行修改而来,它实现...
  • 1.一个表单对应数据库的一张或多张物理表(主从表),这种设计在很多业务的情况下,其数据库的物理表会不断膨胀,同时,当修改表单时,其对应的物理表结构也需要修改,当物理表有很多数据时,改变物理表scheme会锁表...
  • 浅析动态表单

    千次阅读 热门讨论 2013-11-23 14:01:31
    动态表单的应用非常广泛,面对复杂的需求要求,在一些情况下使用动态表单能够解决很多问题。与一般的需求一样,动态表单主要包含两部分:动态表单的定义和显示、动态表单内容的接收与存储。 用例分析: 表单就不用说...
  • 动态表单绘制完毕后由后台解析并存储到数据库,可以自己手动添加定制的宏组件。 数据库主要只有2张表,但是会动态地创建表单数据的表,表单越多,创建出来的表越多。 以下是目前此项目的一些截图: 下载地址: ....
  • iview 动态表单验证prop用法

    千次阅读 2019-01-30 09:36:33
    prop的写法::prop="'items.' + index + '.name'" var cv_arr = [ { 'name': 'items.0.name', 'method': 'NotNull' } ] 自定义写法
  • Vue+Element动态生成新表单并添加验证

    万次阅读 多人点赞 2018-08-25 14:54:40
    官方文档中有写用v-for来实现新增表单,但是那是单表单的新增,现在多表单的新增,可以考虑的实现方法是先写死一个必须的表单,需要新增的两个表单放在一个div里,在div中使用v-for生成,达到同时新增的效果 ...
  • 这个是我根据循环动态添加的表单,现在要进行验证 ,是用vue element写的 ,代码如下: ![图片说明](https://img-ask.csdn.net/upload/201806/13/1528870655_544636.png) ![图片说明]...
  • Activiti 动态表单

    万次阅读 2018-10-17 18:30:35
    目录 目录 Activiti表单 手册对表单的阐述 生成动态表单的步骤 动态表单的定义 ...获取启动事件上定义的动态表单 ...根据动态表单定义前端渲染(开发人员自己写代码...其中动态表单和外置表单是是Activiti提供的表单...
  • vue中动态绑定表单元素的属性

    万次阅读 2016-12-27 14:38:46
    在vue中有时候可能想像使用jq一样给某个元素添加属性,如$('#select1').attr('disabled','disabled')这种方法也能实现,但是在vue中能用vue的方法还是尽量不要使用jq 使用vue的方法来添加属性可以这样:...
  • JS动态创建from表单

    万次阅读 2016-12-04 16:33:27
    //js动态创建form 提交表单 function formSubmit(elementValue) {  var turnForm = document.createElement("form");   //一定要加入到body中!!   document.body.appendChild(turnForm);  turnForm....
  • 基于bootstrap拖拽布局完成的web表单设计器

    万次阅读 热门讨论 2018-07-24 09:13:13
    本人是一名java开发程序员,前段时间公司要制作一个bpm项目,项目中需要一个表单设计器,以达到设计动态表单的功能; 然后我在网上找了半天,免费开源的几乎都不适用,最后勉强找到一个bootstrap的布局样式设计器。...
  • jQuery动态给form表单赋值

    千次阅读 2017-10-18 21:18:36
    由于粗心没对form表单设置post方式提交导致传递的参数传不到后台 $("#elecfeeForm").attr("action","${pageContext.request.contextPath}/elecmanager/transferpower/exportElecFees.do?yearMonth="+yearMonth); $(...
  • vue动态添加表单并验证

    千次阅读 2018-11-19 20:40:58
    Vue中的表单验证很简单,但若是动态添加的表单,如通过v-for循环出来的动态表单,就需要想额外的办法了。  查找资料,一篇文章写的很详细,原文在这里。但我按照文章里的步骤做完之后,怎么都不生效。最后检查了很...
1 2 3 4 5 ... 20
收藏数 165,521
精华内容 66,208
关键字:

动态表单