精华内容
参与话题
问答
  • 动态表单

    千次阅读 2019-01-08 07:37:13
    随着计算机软件技术的不断完善和发展,国内的信息化建设的日益深入,越来越多的信息化系统开发和运行,人们越来越多的关注并参与到信息化建设中。于是逐渐产生了一个比较突出的矛盾,那就是人们日益增长的信息化建设...

        随着计算机软件技术的不断完善和发展,国内的信息化建设的日益深入,越来越多的信息化系统开发和运行,人们越来越多的关注并参与到信息化建设中。于是逐渐产生了一个比较突出的矛盾,那就是人们日益增长的信息化建设和运用的需求和使用和日益落伍的信息化建设的手段之间的矛盾。这个矛盾主要表现在
    1. 软件公司和系统集成公司接受的信息化建设的项目越来越多,而开发和实施人力不够。
    2. 项目进度要求日益提高,而传统的开发模式过于依赖慢速的编程。
    3. 系统要求越来越灵活,客户需求变更频繁,而传统的硬编码方式来适应客户需求变化的做法日益落后和低效率。
    4. 实施信息系统的地点从大中型城市向中小型城市扩展,信息系统实施点多面广,环境复杂多变,迫切需要控制单点实施时间,提高实施效率。
    5. 人力资源的不足和使用不合理,由于信息系统实施地点变多,传统的实施过程可能需要二次开发,需要编程,导致普通的没有编程能力的系统实施人员无法独立的完成实施任务,迫使具有编程能力的程序员过多的参与一线实施。而程序员是软件公司和系统集成公司内的比较高级的人力资源,频繁的参与一线实施是对人力资源的浪费,为此迫切需要功能强大简单易用的实施配套工具软件,提高普通实施人员的工作能力,减少系统现场实施对程序员的依赖。

        这个矛盾有一个比较典型的表现实例就是应用系统的用户数据输入界面,现在出现一些信息系统,客户要求其数据的输入界面可以任意修改。所谓数据输入界面,就是数据表单界面,包括WinForm表单和HTMLForm表单界面,是用户输入原始数据的主要工作区域,它很大程度上影响信息系统能处理的数据格式范围和精度。一些客户由于其自身工作业务的需要,频繁的要求信息提供的数据输入表单界面发生改变,比如新增修改和删除提示信息,文本框,单选复选框和列表框等等,同一个操作,在不同的状态下使用不同的数据输入表单。
        面对这种需求,传统的做法是获得应用系统当前的源代码,进入相应的IDE,进入它的数据表单设计器然后进行修改。比如对ASP.NET系统,使用VS.NET等IDE打开系统的源代码,进入WebForm表单设计器,修改表单界面,还可能修改一些后台程序,然后编译测试,更新应用系统。整个过程繁琐复杂耗时而且不可靠,而且只有有经验的程序员才能完成,水平不高的程序员或普通的系统实施人员是无法胜任这一系列操作。这种更新手段对信息系统的正常工作带来不小的影响。而且若没有系统的源代码或源代码版本不对,则此工作无法完成。
        现在有人开始使用配置文件或者用所谓的表单定义模板来实现动态的表单界面,应用系统运行时,根据需要加载不同的表单定义模板,根据表单定义模板中的定义数据动态的加载表单界面,这种处理模式能满足客户的修改表单输入界面的需求而不影响系统的正常运行,这个过程不需要程序的源代码,没有编译和测试,只要提供表单定义模板文件,一切都是自动完成的。
        但是这种动态表单模式带来一个问题,谁来提供表单定义模板文件。若没有配套工具,则需要手工编写模板文件,这个工作必然是枯燥低效,经常需要多次尝试着凑数据,编制过程非常烦心。若拥有方便易用的配套工具,则能大大加快制作表单定义模板的速度和准确性,提高系统实施人员的工作效率。这里的配套工具就是所见即所得的互换式图形化设计器,简称图形化设计器。
        图形化设计器是一种技术含量比较高的软件,它涉及到构造自定义的文档对象模型,高级的图形编程技术,复杂的用户界面事件的处理,这些技术手段是一般的信息系统开发过程所没有的,开发图形设计器难度大,时间长,工作量大,需要编写数万行的高效率的代码,这些都要求有专门对此有经验的开发者才能开发。一般的小型软件公司没能力开发,有些公司虽然有能力开发,但由于经济技术和时间的原因而一直未能开发出比较好的图形设计器(能开发图形设计器的人必然是高手,高手必然很忙)。但是若具有图形化设计器,则能成倍的加快表单定义模板的编制速度,能在短时间内完成大量的表单定义任务。
        图形化设计器有一种比较简单的开发模式,那就是模拟VS.NET的WinForm窗体设计器的运行原理,设计界面上的设计元素就是Windows控件,这些控件处于设计模式,可以直接拖拽操作来修改控件的位置和大小,这种方式实现简单,开发工作量小,但存在以下缺点:
    1. 程序运行缓慢而且消耗大量资源,由于Windows控件是一种重量级资源,当文档中包含很多设计元素时需要动态加载很多个Windows控件,这样程序运行缓慢而且消耗很多资源。
    2. Windows控件基本上是矩形的,当需要实现非矩形的设计元素时则很困难。
    3. 当需要绘制已有控件不支持的图形时需要编写新的控件。
    4. 文档重绘慢而且难于控制,文档重绘需要各个Windows控件的重绘,此时操作系统需要一个个通知这些控件重绘,需要进行大量不直接绘图的操作。
    5. 文档视图不能输出为图片,很难向其他应用程序开放编程接口。
        而图形设计器自己绘制图形时虽然实现复杂,但不会有上述缺点。程序运行快,可对图形进行全面的控制。XDesignerLib实现的就是自己绘制图形的图形化设计器。

        除了用于设计数据表单界面的图形化设计器,还有很多其他的领域需要图形化设计器。只要是图形化设计器,那就都需要解决类似的问题,其程序结构也大体一样。
        有鉴于此,本人开发了名为XHtmlFormDeisgner的HTML表单设计器,它能定义HTML表单,并能将其定义信息保存到XML文档,而且还能在设计器中直接预览设计出来的HTML表单.详细情况请查看 http://www.xdesigner.cn/_xhtmldesigner.aspx ,希望能给大家实现动态表单有所帮助.

    袁永福(http://www.xdesigner.cn) 2007-4-4

    展开全文
  • angular动态表单制作

    2020-11-28 20:38:41
    动态表单使用场景 有时候我们需要一个灵活的表单,这个表单可以根据用户的选择,或者服务器返回的信息进行重新配置,比如:增加或删除一组input元素、一组select元素,等等。 在这样的情况下,如果一开始就在模板里...
  • 1. 你曾见过的策略模式 现在电子产品种类繁多,尺寸多种多样,有时候你会忍不住想拆开看看里面啥样(想想小时候拆的玩具车还有遥控器

    1. 你曾见过的策略模式

    现在电子产品种类繁多,尺寸多种多样,有时候你会忍不住想拆开看看里面啥样(想想小时候拆的玩具车还有遥控器?),但是螺丝规格很多,螺丝刀尺寸也不少,如果每碰到一种规格就买一个螺丝刀,家里就得堆满螺丝刀了。所以现在人们都用多功能的螺丝刀套装,螺丝刀把只需要一个,碰到不同规格的螺丝只要换螺丝刀头就行了,很方便,体积也变小很多。

    再举个栗子,一辆车的轮胎有很多规格,在泥泞路段开的多的时候可以用泥地胎,在雪地开得多可以用雪地胎,高速公路上开的多的时候使用高性能轮胎,针对不同使用场景更换不同的轮胎即可,不需更换整个车。
    这些都是策略模式的实例,螺丝刀/车属于封装上下文,封装和使用不同的螺丝刀头/轮胎,螺丝刀头/轮胎这里就相当于策略,可以根据需求不同来更换不同的使用策略。
    在这些场景中,有以下特点:

    螺丝刀头/轮胎(策略)之间相互独立,但又可以相互替换;
    螺丝刀/车(封装上下文)可以根据需要的不同选用不同的策略;

    2. 实例的代码实现

    具体的例子我们用编程上的例子来演示,比较好量化。
    场景是这样的,某个电商网站希望举办一个活动,通过打折促销来销售库存物品,有的商品满 100 减 30,有的商品满 200 减 80,有的商品直接8折出售(想起被双十一支配的恐惧),这样的逻辑交给我们,我们要怎样去实现呢。

    通过判断输入的折扣类型来计算计算商品总价的方式,几个 if-else 就满足了需求,但是这样的做法的缺点也很明显:

    priceCalculate 函数随着折扣类型的增多,if-else 判断语句会变得越来越臃肿;
    如果增加了新的折扣类型或者折扣类型的算法有所改变,那么需要更改 priceCalculate 函数的实现,这是违反开放-封闭原则的;
    可复用性差,如果在其他的地方也有类似这样的算法,但规则不一样,上述代码不能复用;

    我们可以改造一下,将计算折扣的算法部分提取出来保存为一个对象,折扣的类型作为 key,这样索引的时候通过对象的键值索引调用具体的算法:

    api5878.com|58qp.gdhongkong.com

    https|https

    const DiscountMap = {
        minus100_30: function(price) {
            return price - Math.floor(price / 100) * 30
        },
        minus200_80: function(price) {
            return price - Math.floor(price / 200) * 80
        },
        percent80: function(price) {
            return price * 0.8
        }
    }
    
    /* 计算总售价*/
    function priceCalculate(discountType, price) {
        return DiscountMap[discountType] && DiscountMap[discountType](price)
    }
    
    priceCalculate('minus100_30', 270)
    priceCalculate('percent80', 250)
    
    // 输出: 210
    // 输出: 200
    

    展开全文
  • 如何设计动态表单

    2011-05-09 11:31:37
    公司前辈要我为动态设计一个动态表单,他稍微和我说了一下,但我不是很了解他的意思 不知道哪位仁兄做过这方面的研究,帮我解决下问题。 比如说我 有个界面要出售电脑:电脑有不同的档次。 我要在界面实现...
  • 基于Infopath实现WEB动态表单.初次接触Infopath,我就被它的强大的功能,灵活的表单制作方式,全面对Web Services的支持等特点深深的吸引了。曾经尝试用Infopath来完成一些MIS项目,Infopath却有一些我们难以逾越的...
  • 动态表单 (一)动态表单的定义

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

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

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

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

    • 动态表单建模

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

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

               

     

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

     

    • 持久化到数据库中

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

               

              

               

    •  表单的显示

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

    展开全文
  • 最近公司在做一个项目, 要求jsp页面的表单是动态,并且还要保存,以后还可以使用,急用, 怎么把动态表单保存起来, 然后得到表单再操作。 [b]问题补充:[/b] 就是一个jsp页面, 管理员可以通过自己选择的类型, ...
  • Activiti 动态表单

    千次阅读 2019-02-14 10:52:22
    动态表单 外置表单 普通表单 其中动态表单和外置表单是是Activiti提供的表单机制。 官方手册对表单的阐述 流程由流程参数驱动,Activiti支持复杂的对象(实现serializable接口),JPA实体,XML文档作为流程参数...

    原文地址:https://blog.csdn.net/sdufexsh/article/details/83111965

    Activiti表单

    1. 动态表单
    2. 外置表单
    3. 普通表单

    其中动态表单外置表单是是Activiti提供的表单机制。

    官方手册对表单的阐述

    流程由流程参数驱动,Activiti支持复杂的对象(实现serializable接口),JPA实体,XML文档作为流程参数,上述三类参数在Activiti中以字符串的形式存储。

    动态表单生成步骤

    流程启动和UserTask任务需要用户参与,用户与流程的交互通过表单来实现。Activiti对外暴露“表单属性定义集合”,使得任何一种前端技术都能基于“表单属性定义集合”来动态生成表单,步骤如下:

    1. 在开始事件和UserTask元素上定义表单元素
    2. 通过activiti提供的API获取表单元素定义、
    3. 前端动态生成表单(需要开发人员自己写代码实现)
    获取开始事件上的表单数据:StartFormData FormService.getStartFormData(String processDefinitionId) 
    获取任务元素上的表单数据:TaskFormdata FormService.getTaskFormData(String taskId)
    

     

    动态表单中元素的定义

    Activiti表单元素的字段

    public interface FormProperty extends Serializable {
     
        public String getId();
     
        public String getName();
     
        public FormType getType();
     
        public String getValue();
     
        public boolean isReadable();
     
        public boolean isWritable();
     
        public boolean isRequired();
    }
    

     示例说明

    动态表单依附于开始事件或UserTask元素,我们设计一个简单的请假审批流程,为开始事件和UserTask定义动态表单。

    以reason为例。

    1. 在Expression和variable未定义的情况下,activiti会将流程参数reason的值作为该表单元素的值。
    2. 若定义variable为myReason,activiti会将流程参数myReason的值作为该表单元素的值。
    3. 若定义variable为#{mo.reason},activiti会将流程参数mo中reason属性值的为该表单元素的值。

    获取启动流程上定义的动态表单

        @RequestMapping(value = "/start/{procDefId}", method = RequestMethod.GET)
        public String start_page(@PathVariable("procDefId") String procDefId, Model model) {
            StartFormData startFormData = formService.getStartFormData(procDefId);
            List<FormProperty> formProperties = startFormData.getFormProperties();
            ProcessDefinition pd = startFormData.getProcessDefinition();
            model.addAttribute("list", formProperties);
            model.addAttribute("pd", pd);
            return "process/start_page";
        }
    

    根据动态表单定义前端渲染(开发人员自己写代码)

     <form  method="post" action="<%=request.getContextPath()%>/process/start"> 
                <input type="hidden" name="procDefId" value="${procDefId}"/>
                <input type="hidden" name="data"  id="data"/>
                <div class="row form-group">
                    <div class="col-md-1 align-right">事项名称</div>
                    <div class="col-md-7">
                        <input  type="text"  name="procName" value="${proc.name}" 
                                class="width-100 form-control"  />
                    </div>
     
                </div>
                <c:forEach items="${list}" var="prop">
                    <!--设置隐藏域,统一处理-->
                    <div class="row form-group">
                        <div class="col-md-1 align-right">${prop.name}</div>
                        <div class="col-md-7">
                            <c:choose>
                                <c:when test="${prop.type.name=='string'}">
                                    <input  type="text" id="${prop.id}" name="${prop.id}" value="${prop.value}" 
                                            class="width-100 form-control"  />
                                </c:when>
                                <c:when test="${prop.type.name=='date'}">
                                    <div class="input-group">
                                        <input  type="text" id="${prop.id}"  name="${prop.id}" value="${prop.value}"  
                                                class="width-100 form-control date-picker-o"  data-date-format="${prop.type.getInformation('datePattern')}"/>
     
                                        <span class="input-group-addon">
                                            <i class="fa fa-calendar bigger-110"></i>
                                        </span>
                                    </div>
     
                                </c:when>
                                <c:when test="${prop.type.name=='enum'}">
                                    <select id="${prop.id}" name="${prop.id}">
                                        <option value="-1">----请选择---</option>
                                        <c:forEach  items="${prop.type.getInformation('values')}" var="item">
                                            <option value="${item.key}">${item.value}</option>
                                        </c:forEach>
                                    </select>
                                </c:when>
     
                                <c:when test="${prop.type.name=='boolean'}">
                                    <input  type="checkbox" id="${prop.id}" name="${prop.id}" value="${prop.value}" />
                                </c:when>
                            </c:choose>
     
                        </div>
                    </div>
                </c:forEach>
                <div class="row form-group align-right col-md-8">
                    <button class="btn btn-primary" id="startBtn">启动流程</button>
                </div>
            </form>
    

    做过web开发的同学一定都清楚,表单和后台的传值是依靠表单的name属性,那么会产生一个问题,不同的表单表单元素不同,难道要为每一个动态表单写一个后台接口吗?

    答案是:不必要,若每个动态表单都写一个后台接口,则失去了动态表单存在的意义。这意味需要我们做统一化处理,即前台将表单中元素的取值使用一个参数传入到后台,后台使用一个参数来接收。

    我的做法是在表单中设置一个隐藏域,在点击启动流程按钮的时候,将表单序列化后的取值赋值给该隐藏域,后台做统一的处理。

    表单效果(前端使用了bootstarp框架)

     

    获取待办任务

     待办任务列表

    获取UserTask上定义的动态表单 

        @RequestMapping("/task/{taskId}")
        public String taskPage(@PathVariable("taskId") String taskId, Model model) {
            Task task = this.taskService.createTaskQuery().taskId(taskId).singleResult();
            String processInstanceId = task.getProcessInstanceId();
            TaskFormData taskFormData = this.formService.getTaskFormData(taskId);
            ProcessInstance pi = this.runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
            List<FormProperty> list = taskFormData.getFormProperties();
            model.addAttribute("list", list);
            model.addAttribute("task", task);
            model.addAttribute("pi", pi);
            return "process/task_page";
        }
    

    表单元素的值是对应的流程参数的值。表单元素的值是对应的流程参数的值。表单元素的值是对应的流程参数的值。--重要的话说三遍。

     任务办理页面

    表单依然需要动态生成,并且根据表单元素的属性进行控制(本文是将启动流程表单页面和UserTask动态表单页面分开的,有兴趣的也可以合并为一个页面,控制逻辑要复杂一些)。

     需要说明,禁用的控件没有设置name属性,因此流程参数不会重复赋值

     总结

    动态表单适用于简单的逐级审批的流程,业务数据存储在参数表中驱动流程的运行,不需要用户自定义业务表,方便的同时也意味着无法处理复杂的流程。

    展开全文
  • WPF动态表单

    热门讨论 2011-09-21 16:34:48
    一个WPF动态创建表单的例子,对学习WPF很有帮助
  • extjs动态表单

    2019-03-26 01:19:24
    NULL 博文链接:https://rdman.iteye.com/blog/1144152
  • BootStrap 动态表单效果

    2020-10-19 18:29:58
    主要介绍了BootStrap 动态表单效果,实现代码分为js部分和html部分,代码简单易懂,非常不错,具有参考借鉴价值,需要的朋友可以参考下
  • 使用Vue生成动态表单

    2020-10-15 22:56:27
    主要介绍了Vue生成动态表单功能,这是小编第一次接这个需求,作为前端开发的我真的不知如何下手,今天小编通过一段代码给大家分享vue生成动态表单效果,需要的朋友可以参考下
  • 动态表单的简单实现

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

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

    2019-08-12 02:38:21
    vue-element-ui动态表单
  • Android动态表单

    千次阅读 2017-03-29 14:57:02
    前两天项目上用到了动态表单,哪种动态表单呢,就是表单结构要从服务器端抓取(后台会随时更改表单结构)。这可是难为死我了,网上找了不少,四处翻看不少文章,都没找到答案,没办法,只能自己做了。 动态表单目前...
  • activiti三种表单的demo实现 运行方式: 1,修改连接的数据库 2,sql文件在resources\sql下 3,访问地址http://localhost:8080/activiti-demo/main/index

空空如也

1 2 3 4 5 ... 20
收藏数 8,826
精华内容 3,530
关键字:

动态表单