之前实现了activiti工作流的动态表单功能,接下来准备实现activiti的外置表单功能,并且外置表单可以在线编辑。

activiti工作流在线表单设计功能实现可以分为2个部分:

1.在线表单设计功能。

2.表单与activiti工作流关联起来。

第一部分,在线表单设计功能可以使用ueditor 的插件WEB表单设计器实现。

第二部分,可以使用activiti工作流的外置表单 原理关联 WEB表单设计器 设计的表单。

主要难点在实现第一部分,具体效果图如下:

相关所有实现代码:

list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html >
<html>
<head><title>在线表单列表</title>
<%@include file="/common/base.jsp" %>
<script type="text/javascript">
$(function() {query();
})
function query(){$('#dg').datagrid('options').queryParams = parseParams("toolbar");$("#dg").datagrid('reload');//$("#dg").datagrid('load',parseParams("toolbar"));
}
function formatterName(value, row, index){ return row.addUser.name;
}
function formatOp(value, row, index){ var html = "";html += "<a href='javascript:openView(null,null,\""+value+"\")'>编辑</a>  ";html += "<a href='javascript:openDesign(\""+value+"\")'>设计</a>  ";html += "<a href='javascript:del(\""+value+"\")'>删除</a>";return html;
}
function openView(rowIndex,rowData,bizId){bizId = bizId || rowData.id;$('#win').window({title: '修改在线表单',width:450,height:350,modal:true});$('#subWin').attr("src",'page/online-form/add.jsp?bizId='+bizId) $('#win').window('open');
}
function openDesign(id){$('#win').window({title: '设计在线表单',width:1000,height:680,modal:true});$('#subWin').attr("src",'page/online-form/design.jsp?bizId='+id) $('#win').window('open');
}function add(){$('#win').window({title: '新增在线表单',width:450,height:350,modal:true});$('#subWin').attr("src",'page/online-form/add.jsp?bizId=') $('#win').window('open');
}
function del(id){$('#frm').mySubmit({url : 'OnlineFormController/delete?id='+id});
}
</script>
<style type="text/css">
</style>
</head><body><table id="dg" class="easyui-datagrid" title="内容管理" style="width:100%;height:auto;margin:0 auto;"data-options="singleSelect:true,collapsible:true,onDblClickRow:openView" url="OnlineFormController/list"rownumbers="true" toolbar="#toolbar"><thead><tr><th align="center" data-options="field:'key',width:200,align:'center'">表单名称</th><th align="center" data-options="field:'descr',width:600,align:'center'">描述</th><th align="center" formatter="formatterName" data-options="field:'addUserId',width:240,align:'center'">设计者</th><th align="center" formatter="formatDate" data-options="field:'addtime',width:150,align:'center'">日期</th><th align="center" data-options="field:'enabled',width:100,align:'center'">是否启用</th><th align="center" formatter="formatOp" data-options="field:'id',width:350,align:'center'">操作</th></tr></thead></table>
<div id="toolbar"><span>设计者:</span> <input class="easyui-validatebox"  name="addUser.name" ><a href="javascript:query()" class="easyui-linkbutton"data-options="iconCls:'icon-search'" style="width: 80px">查询</a><a href="javascript:add()" class="easyui-linkbutton"data-options="iconCls:'icon-add'" style="width: 80px">新增</a>
</div>
<div id="win"><iframe id="subWin" src=''width= "100%" height= "99%" marginheight= "0" marginwidth= "0" hspeace= "0" vspace= "0" frameborder= "0"  ></iframe>
</div>
<form id="frm" method="post" style="display:none;">
</form>
</body>
</html>

add.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %><%@page import="org.springframework.web.context.support.WebApplicationContextUtils"%>
<%@page import="org.springframework.context.ApplicationContext" %>
<%@page import="com.jy.service.onlineform.OnlineFormService" %>
<%ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(getServletContext());    OnlineFormService onlineFormService = (OnlineFormService)ctx.getBean("onlineFormService"); String bizId = request.getParameter("bizId");if(bizId != null && !bizId.equals("")){request.setAttribute("of", onlineFormService.getEntityById(bizId));}
%>
<!DOCTYPE html >
<html>
<head><title>新增文档</title>
<%@include file="/common/base.jsp" %>
<link rel="stylesheet" href="static/css/system/bootstrap/bootstrap.min.css" />
<script src="static/js/bootstrap/bootstrap.min.js"></script>
<style type="text/css">
.fitem{vertical-align: text-top;
}
tr{
height: 40px;
}
form div{margin-top:10px;
}
form div label{width:100px;text-align: right;
}
</style>
<script type="text/javascript">
function save(){$('#frm').mySubmit({url : 'OnlineFormController/save',success: function(res){window.parent.query();closeWin();}});return true;
}
</script>
</head>
<body><form id="frm" method="post"><input name="id" type="hidden" value="${of.id}"/><div><label for="key">表单名称:</label><input id="key" class="easyui-validatebox" value="${of.key}"  name="key" data-options="required:true" /></div><div><label for="descr">描述:</label><input id="descr" class="easyui-validatebox" value="${of.descr}"  name="descr" /></div><div><label for="enabled">是否启用:</label><select id="enabled" name="enabled"><option ${"启用".equals(of.enabled)? "selected" : ""}>启用</option><option ${"禁用".equals(of.enabled)? "selected" : ""}>禁用</option></select></div><div style="text-align: center; padding: 5px"><a href="javascript:save()" class="easyui-linkbutton" >保存</a>    <a href="javascript:closeWin()" class="easyui-linkbutton">取消</a></div>
</form>
</body>
</html>

design.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@page import="org.springframework.web.context.support.WebApplicationContextUtils"%>
<%@page import="org.springframework.context.ApplicationContext" %>
<%@page import="com.jy.service.onlineform.OnlineFormService" %>
<%ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(getServletContext());    OnlineFormService onlineFormService = (OnlineFormService)ctx.getBean("onlineFormService"); String bizId = request.getParameter("bizId");if(bizId != null && !bizId.equals("")){request.setAttribute("of", onlineFormService.getEntityById(bizId));}
%>
<!DOCTYPE html >
<html>
<head><title>设计表单</title>
<%@include file="/common/base.jsp" %>
<link rel="stylesheet" href="static/css/system/bootstrap/bootstrap.min.css" />
<script src="static/js/bootstrap/bootstrap.min.js"></script>
<style type="text/css">
.fitem{vertical-align: text-top;
}
tr{
height: 40px;
}
</style>
<script type="text/javascript">
function save(){$('#frm').mySubmit({url : 'OnlineFormController/design',success: function(res){closeWin();}});return true;
}
</script>
</head>
<body><div style="padding: 20px;"><form id="frm" method="post" target="mywin"><input type="hidden" name="id" value="${of.id}"><div style="font-size: 40px;width:100%;text-align: center;">表单设计<span style="font-size: 22px;">(表单名称:${of.key})</span></div ><button type="button" onclick="leipiFormDesign.exec('text');" class="btn btn-info btn-small">单行输入框</button><button type="button" onclick="leipiFormDesign.exec('textarea');" class="btn btn-info btn-small">多行输入框</button><button type="button" onclick="leipiFormDesign.exec('select');" class="btn btn-info btn-small">下拉菜单</button><button type="button" onclick="leipiFormDesign.exec('radios');" class="btn btn-info btn-small">单选框</button><button type="button" onclick="leipiFormDesign.exec('checkboxs');" class="btn btn-info btn-small">复选框</button><button type="button" onclick="leipiFormDesign.exec('macros');" class="btn btn-info btn-small">宏控件</button><button type="button" onclick="leipiFormDesign.exec('progressbar');" class="btn btn-info btn-small">进度条</button><button type="button" onclick="leipiFormDesign.exec('qrcode');" class="btn btn-info btn-small">二维码</button><div class="alert alert-warning" ><button type="button" class="close" data-dismiss="alert">×</button><strong>提醒:</strong>单选框和复选框,如:<code>{|-</code>选项<code>-|}</code>两边边界是防止误删除控件,程序会把它们替换为空,请不要手动删除!</div><textarea  style="width:100%;height:100%" name="html" id="container">${of.html}</textarea></form></div><!-- 配置文件 --><script type="text/javascript" src="static/plugins/ueditor/ueditor.config.js"></script><!-- 编辑器源码文件 --><script type="text/javascript" src="static/plugins/ueditor/ueditor.all.js"></script><script type="text/javascript" charset="utf-8" src="static/plugins/ueditor/lang/zh-cn/zh-cn.js"></script><!--Fromdesign扩展---><script type="text/javascript" charset="utf-8" src="static/plugins/ueditor/formdesign/leipi.formdesign.v4.js"></script><!-- 实例化编辑器 --><script type="text/javascript">
var leipiEditor = UE.getEditor('container',{//allowDivTransToP: false,//阻止转换div 为ptoolleipi:true,//是否显示,设计器的 toolbarstextarea: 'design_content',   //这里可以选择自己需要的工具按钮名称,此处仅选择如下五个toolbars:[['fullscreen', 'source', '|', 'undo', 'redo', '|','bold', 'italic', 'underline', 'fontborder', 'strikethrough',  'removeformat', '|', 'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist','|', 'fontfamily', 'fontsize', '|', 'indent', '|', 'justifyleft', 'justifycenter', 'justifyright', 'justifyjustify', '|',  'link', 'unlink',  '|',  'horizontal',  'spechars',  'wordimage', '|', 'inserttable', 'deletetable',  'mergecells',  'splittocells']],//focus时自动清空初始化时的内容//autoClearinitialContent:true,//关闭字数统计wordCount:false,//关闭elementPathelementPathEnabled:false,//默认的编辑区域高度initialFrameHeight:300//,iframeCssUrl:"/Public/css/bootstrap/css/bootstrap.css" //引入自身 css使编辑器兼容你网站css//更多其他参数,请参考ueditor.config.js中的配置项});var leipiFormDesign = {/*执行控件*/exec : function (method) {leipiEditor.execCommand(method);},/*Javascript 解析表单template 表单设计器里的Html内容fields 字段总数*/parse_form:function(template,fields){//正则  radios|checkboxs|select 匹配的边界 |--|  因为当使用 {} 时js报错var preg =  /(\|-<span(((?!<span).)*leipiplugins=\"(radios|checkboxs|select)\".*?)>(.*?)<\/span>-\||<(img|input|textarea|select).*?(<\/select>|<\/textarea>|\/>))/gi,preg_attr =/(\w+)=\"(.?|.+?)\"/gi,preg_group =/<input.*?\/>/gi;if(!fields) fields = 0;var template_parse = template,template_data = new Array(),add_fields=new Object(),checkboxs=0;var pno = 0;template.replace(preg, function(plugin,p1,p2,p3,p4,p5,p6){var parse_attr = new Array(),attr_arr_all = new Object(),name = '', select_dot = '' , is_new=false;var p0 = plugin;var tag = p6 ? p6 : p4;//alert(tag + " \n- t1 - "+p1 +" \n-2- " +p2+" \n-3- " +p3+" \n-4- " +p4+" \n-5- " +p5+" \n-6- " +p6);if(tag == 'radios' || tag == 'checkboxs'){plugin = p2;}else if(tag == 'select'){plugin = plugin.replace('|-','');plugin = plugin.replace('-|','');}plugin.replace(preg_attr, function(str0,attr,val) {if(attr=='name'){if(val=='leipiNewField'){is_new=true;fields++;val = 'data_'+fields;}name = val;}if(tag=='select' && attr=='value'){if(!attr_arr_all[attr]) attr_arr_all[attr] = '';attr_arr_all[attr] += select_dot + val;select_dot = ',';}else{attr_arr_all[attr] = val;}var oField = new Object();oField[attr] = val;parse_attr.push(oField);}) /*alert(JSON.stringify(parse_attr));return;*/if(tag =='checkboxs') /*复选组  多个字段 */{plugin = p0;plugin = plugin.replace('|-','');plugin = plugin.replace('-|','');var name = 'checkboxs_'+checkboxs;attr_arr_all['parse_name'] = name;attr_arr_all['name'] = '';attr_arr_all['value'] = '';attr_arr_all['content'] = '<span leipiplugins="checkboxs"  title="'+attr_arr_all['title']+'">';var dot_name ='', dot_value = '';p5.replace(preg_group, function(parse_group) {var is_new=false,option = new Object();parse_group.replace(preg_attr, function(str0,k,val) {if(k=='name'){if(val=='leipiNewField'){is_new=true;fields++;val = 'data_'+fields;}attr_arr_all['name'] += dot_name + val;dot_name = ',';}else if(k=='value'){attr_arr_all['value'] += dot_value + val;dot_value = ',';}option[k] = val;    });if(!attr_arr_all['options']) attr_arr_all['options'] = new Array();attr_arr_all['options'].push(option);//if(!option['checked']) option['checked'] = '';var checked = option['checked'] !=undefined ? 'checked="checked"' : '';attr_arr_all['content'] +='<input type="checkbox" name="'+option['name']+'" value="'+option['value']+'"  '+checked+'/>'+option['value']+' ';if(is_new){var arr = new Object();arr['name'] = option['name'];arr['leipiplugins'] = attr_arr_all['leipiplugins'];add_fields[option['name']] = arr;}});attr_arr_all['content'] += '</span>';//parsetemplate = template.replace(plugin,attr_arr_all['content']);template_parse = template_parse.replace(plugin,'{'+name+'}');template_parse = template_parse.replace('{|-','');template_parse = template_parse.replace('-|}','');template_data[pno] = attr_arr_all;checkboxs++;}else if(name){if(tag =='radios') /*单选组  一个字段*/{plugin = p0;plugin = plugin.replace('|-','');plugin = plugin.replace('-|','');attr_arr_all['value'] = '';attr_arr_all['content'] = '<span leipiplugins="radios" name="'+attr_arr_all['name']+'" title="'+attr_arr_all['title']+'">';var dot='';p5.replace(preg_group, function(parse_group) {var option = new Object();parse_group.replace(preg_attr, function(str0,k,val) {if(k=='value'){attr_arr_all['value'] += dot + val;dot = ',';}option[k] = val;    });option['name'] = attr_arr_all['name'];if(!attr_arr_all['options']) attr_arr_all['options'] = new Array();attr_arr_all['options'].push(option);//if(!option['checked']) option['checked'] = '';var checked = option['checked'] !=undefined ? 'checked="checked"' : '';attr_arr_all['content'] +='<input type="radio" name="'+attr_arr_all['name']+'" value="'+option['value']+'"  '+checked+'/>'+option['value']+' ';});attr_arr_all['content'] += '</span>';}else{attr_arr_all['content'] = is_new ? plugin.replace(/leipiNewField/,name) : plugin;}//attr_arr_all['itemid'] = fields;//attr_arr_all['tag'] = tag;template = template.replace(plugin,attr_arr_all['content']);template_parse = template_parse.replace(plugin,'{'+name+'}');template_parse = template_parse.replace('{|-','');template_parse = template_parse.replace('-|}','');if(is_new){var arr = new Object();arr['name'] = name;arr['leipiplugins'] = attr_arr_all['leipiplugins'];add_fields[arr['name']] = arr;}template_data[pno] = attr_arr_all;}pno++;})var parse_form = new Object({'fields':fields,//总字段数'template':template,//完整html'parse':template_parse,//控件替换为{data_1}的html'data':template_data,//控件属性'add_fields':add_fields//新增控件});return JSON.stringify(parse_form);},/*type  =  save 保存设计 versions 保存版本  close关闭 */fnCheckForm : function ( type ) {if(save()){return true;}if(leipiEditor.queryCommandState( 'source' ))leipiEditor.execCommand('source');//切换到编辑模式才提交,否则有bugif(leipiEditor.hasContents()){leipiEditor.sync();/*同步内容*/// alert("你点击了保存,这里可以异步提交....");//return false;var type_value='',formid=0,fields=$("#fields").val(),formeditor='';if( typeof type!=='undefined' ){type_value = type;}//获取表单设计器里的内容formeditor=leipiEditor.getContent();//解析表单设计器控件var parse_form = this.parse_form(formeditor,fields);//alert(parse_form);$("#leipi_type").val(type_value);$("#leipi_parse_form").val(parse_form);$("#saveform").attr("target","_blank");$("#saveform").attr("action","/index/parse.html");$("#saveform").submit();/*//异步提交数据$.ajax({type: 'POST',url : '/index/parse.html',//dataType : 'json',data : {'type' : type_value,'formid':formid,'parse_form':parse_form},success : function(data){if(confirm('查看js解析后,提交到服务器的数据,请临时允许弹窗')){win_parse=window.open('','','width=800,height=600');//这里临时查看,所以替换一下,实际情况下不需要替换  data  = data.replace(/<\/+textarea/,'<textarea');win_parse.document.write('<textarea style="width:100%;height:100%">'+data+'</textarea>');win_parse.focus();}/*if(data.success==1){alert('保存成功');$('#submitbtn').button('reset');}else{alert('保存失败!');}* /}});*/} else {alert('表单内容不能为空!')$('#submitbtn').button('reset');return false;}} ,/*预览表单*/fnReview : function (){if(leipiEditor.queryCommandState( 'source' ))leipiEditor.execCommand('source');/*切换到编辑模式才提交,否则部分浏览器有bug*/if(leipiEditor.hasContents()){leipiEditor.sync();       /*同步内容*//*设计form的target 然后提交至一个新的窗口进行预览*/var frm = $('#frm').get(0);frm.target="mywin";window.open('','mywin',"menubar=0,toolbar=0,status=0,resizable=1,left=0,top=0,scrollbars=1,width=" +(screen.availWidth-10) + ",height=" + (screen.availHeight-50) + "\"");frm.action="page/online-form/preview.jsp";frm.submit(); //提交表单} else {alert('表单内容不能为空!');return false;}}
};</script></body>
</html>

preview.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<%@ page   import= "com.jy.common.utils.UeditorTools "%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html >
<html>
<head><title>新增文档</title><%@include file="/common/base.jsp" %><link href="static/plugins/bootcss3.3.5/css/bootstrap.css?2029" rel="stylesheet" type="text/css">
<style type="text/css">
.fitem{vertical-align: text-top;
}
tr{
height: 40px;
}
</style>
<script type="text/javascript"></script>
</head>
<body><div class="container"><div class="page-header"><h1>预览表单 <small>如无问题请保存你的设计</small></h1></div><%= UeditorTools.formatStr(request.getParameter("html"))%></div><!--end container--></body>
</html>

OnlineFormController.java

package com.jy.controller.onlineform;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import com.jy.common.ajax.AjaxRes;
import com.jy.common.utils.base.Const;
import com.jy.common.utils.base.Tools;
import com.jy.common.utils.security.AccountShiroUtil;
import com.jy.controller.base.BaseController;
import com.jy.entity.onlineform.OnlineForm;
import com.jy.service.onlineform.OnlineFormService;@Controller
@RequestMapping("/OnlineFormController/")
public class OnlineFormController extends BaseController<Object>{@Autowiredprivate OnlineFormService onlineFormService;@RequestMapping(value="list")  @ResponseBodypublic List<OnlineForm> list(Model model,OnlineForm obj){List<OnlineForm> list = onlineFormService.list(obj);return list;}/*** 保存表单* @param obj* @return*/@RequestMapping(value="save")@ResponseBodypublic AjaxRes save(Model model,OnlineForm obj){AjaxRes ar=getAjaxRes();if (Tools.isEmpty(obj.getId())) {obj.setId(get32UUID());obj.setAddUserId(AccountShiroUtil.getCurrentUser().getAccountId());onlineFormService.insert(obj);}else{obj.setModUserId(AccountShiroUtil.getCurrentUser().getAccountId());onlineFormService.update(obj);}ar.setObj("");ar.setSucceedMsg(Const.SAVE_SUCCEED);
//      System.out.println(JsonUtil.toJson(content));return ar;}/*** 设计表单* @param obj* @return*/@RequestMapping(value="design")@ResponseBodypublic AjaxRes design(Model model,OnlineForm obj){AjaxRes ar=getAjaxRes();obj.setModUserId(AccountShiroUtil.getCurrentUser().getAccountId());onlineFormService.design(obj);ar.setObj("");ar.setSucceedMsg(Const.SAVE_SUCCEED);
//      System.out.println(JsonUtil.toJson(content));return ar;}/*** 删除记录* @param obj* @return*/@RequestMapping(value="delete")@ResponseBodypublic AjaxRes delete(Model model,OnlineForm obj){AjaxRes ar=getAjaxRes();onlineFormService.delete(obj);ar.setObj("");ar.setSucceedMsg(Const.DEL_SUCCEED);
//      System.out.println(JsonUtil.toJson(content));return ar;}
}

OnlineFormMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jy.repository.onlineform.OnlineFormDao"><resultMap id="onlineform" type="OnlineForm"><id column="id" jdbcType="VARCHAR" property="id"/><id column="key" property="key"/><id column="descr" property="descr"/><id column="html" jdbcType="CLOB" property="html"/><id column="enabled" property="enabled"/><id column="addUserId" property="addUserId"/><id column="addtime" property="addtime"/><id column="modUserId" property="modUserId"/><id column="modtime" property="modtime"/><association property="addUser"  resultMap="com.jy.repository.system.account.AccountDao.base" columnPrefix="a_"/>   <association property="modUser"  resultMap="com.jy.repository.system.account.AccountDao.base" columnPrefix="m_"/>   </resultMap> <select  id="list" resultMap="onlineform"   parameterType="OnlineForm">  select f.id,f.key,f.descr,f.enabled,f.addUserId,f.addtime,f.modUserId,f.modtime, a.name as a_namefrom online_form fLEFT JOIN jy_base_account a on f.addUserId = a.idwhere 1=1<if test="addUser != null and addUser.name != null and addUser.name != '' ">and  a.name=#{addUser.name}</if></select><select  id="getEntityById" resultMap="onlineform"   parameterType="String">  select f.*, a.name as a_namefrom online_form fLEFT JOIN jy_base_account a on f.addUserId = a.idwhere f.id=#{id}</select><insert id="insert"  parameterType="OnlineForm">    insert into online_form(id,key,descr,enabled,addUserId,addtime) values(#{id},#{key},#{descr},#{enabled},#{addUserId},sysdate)</insert><update id="update"  parameterType="OnlineForm">  update online_form set key=#{key},descr=#{descr},enabled=#{enabled},modUserId=#{modUserId},modtime=sysdatewhere id=#{id}</update><update id="design"  parameterType="OnlineForm">   update online_form set html=#{html,jdbcType=CLOB},modUserId=#{modUserId},modtime=sysdatewhere id=#{id}</update><update id="delete"  parameterType="OnlineForm"> delete from online_form where id=#{id}</update>
</mapper>

看到一直有人问UeditorTools这个类。其实挺简单的,我找了下,下面贴出来了。

com.jy.common.utils.UeditorTools

package com.jy.common.utils;public class UeditorTools {/*** 去掉分界符 {|- 和  -|}* @param str* @return*/public static String formatStr(String str){str = replaceAll(str,"{|-","");str = replaceAll(str,"-|}","");return str;}public static String replaceAll(String strAll,String oldStr,String newStr){return strAll.replaceAll(escapeExprSpecialWord(oldStr), "");}/** * 转义正则特殊字符 ($()*+.[]?\^{},|) * @param keyword * @return */  public static String escapeExprSpecialWord(String keyword) {  if (keyword != null && !keyword.equals("")) {  String[] fbsArr = { "\\", "$", "(", ")", "*", "+", ".", "[", "]", "?", "^", "{", "}", "|" };  for (String key : fbsArr) {  if (keyword.contains(key)) {  keyword = keyword.replace(key, "\\" + key);  }  }  }  return keyword;  }
}

activiti工作流在线表单设计功能(activiti + ueditor + Ueditor Web Form Design扩展 )相关推荐

  1. activiti工作流在线表单设计功能(activiti + ueditor + Ueditor Web Form De

    分享一下我老师大神的人工智能教程吧.零基础,通俗易懂!风趣幽默!http://www.captainbed.net/ 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 之前实现了 ...

  2. html在线表单生成,一种基于html5的在线表单设计系统的制作方法

    一种基于html5的在线表单设计系统的制作方法 [技术领域] [0001]本发明涉及计算机技术领域,尤其涉及一种基于HTML5的在线表单设计系统. [背景技术] [0002]现有很多表单设计工具大多数 ...

  3. 驰骋工作流引擎表单设计控件-字段类控件(2)

    2019独角兽企业重金招聘Python工程师标准>>> Technorati Tags: 开源工作流引擎, 驰骋.net工作流引擎, 开源表单引擎, ccform, ccflow, ...

  4. html表单注册功能的实现,仅一个form表单 js实现注册信息依次填写提交功能

    function one() { if (confirm("确定提交?")) { $("#one").hide(); $("#two").s ...

  5. activiti工作流连接mysql_Activiti工作流 安装myeclipse activiti设计插件并生成数据库表...

    从零开始学习Activiti工作流,记录下学习过程. 关于工作流的简介没什么好介绍了,只能说是个很有用的东西,数据库中23张表分别有什么用网上也有很详细的介绍,这里也不多加说明.activiti开发中 ...

  6. 若依Activiti工作流入门

    目录 前言 功能(若依Activiti工作流版本) 技术栈(若依Activiti工作流版本) 工作流引擎 Activiti简介 功能(Activiti工作流引擎) 技术栈(Activiti工作流引擎) ...

  7. Activiti工作流与业务整合实战

    Activiti工作流与业务整合实战 1. 业务背景 2.技术调研 JBPM vs Activiti选型对比 Activiti工作流特点 3.流程设计 4.架构设计 5.项目实战 5.1 maven配 ...

  8. Activiti工作流框架学习(一)环境的搭建和数据表的了解

    一.什么是工作流 工作流(Workflow),就是"业务过程的部分或整体在计算机应用环境下的自动化",它主要解决的是"使在多个参与者之间按照某种预定义的规则传递文档.信息 ...

  9. Activiti工作流视频教程-基于Activiti5工作流实战企业协同OA办公系统

    Activiti工作流视频教程-基于Activiti5工作流实战企业协同OA办公系统(spring-data-jpa.uur前台组件) 一.Activiti工作流视频教程课程内容简介 在工作流方面,使 ...

  10. Activiti工作流之流程分支

    回顾: Activiti工作流之简介与环境搭建 Activiti工作流之流程部署和相关操作 Activiti工作流之任务的运行/查询/完成 Activiti工作流之流程变量 Activiti工作流之历 ...

最新文章

  1. 一、多个txt文件合并成1个txt文件
  2. 别再问我 new 字符串创建了几个对象了!我来证明给你看!
  3. linux 内核 虚拟文件系统VFS 路径查找 path_lookup
  4. Windows内核工具Win64AST初步使用
  5. Linux SPI框架
  6. python父亲节祝福_父亲节祝福语精选简短 父亲节祝福语简短独特
  7. 【二维差分】Monitor
  8. 关于vue-cli3中配置请求跨域的问题
  9. Linux IO原理和零拷贝机制
  10. 英文拼写及语法检查软件
  11. 一、Docker之旅
  12. sysservers 中找不到服务器,请执行 sp_addlinkedserver 将该服务器添加到sysserver
  13. VS、Unity安装和使用Nuget包
  14. IDC销售系统前台模板知了云模板
  15. win 10 添加网络位置提示【输入的文件夹似乎无效,请选择另一个】解决办法
  16. java控制发送邮箱(qq邮箱、网易邮箱、新浪邮箱)
  17. qs计算机圣安排名,2020年QS世界大学排名圣安德鲁斯大学排名第100
  18. Linux快捷键大全
  19. springboot导入后Spring包飘红问题解决
  20. 【安装配置Git】最新版Git安装教程

热门文章

  1. 【原创】docker在Ubuntu下1小时快速学习
  2. python 画折线图 并标记
  3. matlab 怎么保存,matlab怎么保存程序
  4. 使用Dism++和Dism为优启通08PE添加驱动
  5. 04 Linux软件安装与卸载命令
  6. 哈希算法——论文整理(未完)
  7. 仿小米商城html网页源码
  8. java考试系统_Java实现在线考试系统与设计(学生功能)
  9. p2p终结者局域网控制软件的介绍和用法
  10. csdn 积分/c币获取方法