文本描述了在苍穹平台中实现特定功能的需求、思路和实现过程。需求背景是实现在某些场景下,通过点击树型控件将值动态插入到文本控件中的指定位置,如光标所在位置。解决方案的思路是参照苍穹中单据转换路线计算公式的功能来实现。实现过程中,首先创建了包含树型控件和多行文本控件的动态表单,并调整了布局。接着编写了一个插件,复制了单据转换中的逻辑,通过注册树型控件的各种事件监听器(如点击、勾选、拖拽等),实现了将树节点的内容插入到多行文本控件中指定位置的功能。详细代码展示了如何设置树型控件的属性、加载节点、处理事件等。
关键字:多行文本
一、需求背景
我们会有一些场景,比如输入的时候,是通过点击某些控件(常见的是树型控件),来把某些值动态的插入到一些文本控件中。如果是直接在文本控件后面添加,那么通过插件动态添加是比较简单的,但是有些场景需要添加到指定的位置,比如添加到光标所在的位置,苍穹也可以支持到这个地步。
二、思路与方案
发现苍穹中设置单据转换路线的时候,计算公式里面有一模一样的功能,那就直接照抄即可。如图:
三、实现过程
创建动态表单,放入树型控件和多行文本控件,简单调整下布局样式,如下图:
写插件,照抄单据转换里面的逻辑即可,核心代码:kd.bos.designer.botp.FormulaEditHelper#insertExpression(IFormView view, String buttonKey, String textFieldKey, String str);
详细代码(大部分是树型控件的使用代码):
package kd.demo.control.commonfield.textareafield.demo1; import kd.bos.designer.botp.FormulaEditHelper; import kd.bos.entity.tree.TreeNode; import kd.bos.form.control.TreeView; import kd.bos.form.control.events.*; import kd.bos.form.plugin.AbstractFormPlugin; import java.util.ArrayList; import java.util.EventObject; import java.util.List; public class CursorlocationInsert extends AbstractFormPlugin implements TreeNodeClickListener, TreeNodeCheckListener, TreeNodeQueryListener, TreeNodeDragListener { //树型控件 private final static String KEY_TREEVIEW1 = "kdec_treeviewap"; //多行文本 private final static String KEY_TEXTAREA = "kdec_textareafield"; /** * 注册控件事件 */ @Override public void registerListener(EventObject e) { super.registerListener(e); TreeView treeView = this.getView().getControl(KEY_TREEVIEW1); // 侦听树节点懒加载事件 treeView.addTreeNodeQueryListener(this); // 侦听树节点点击事件,Click treeView.addTreeNodeClickListener(this); // 侦听树节点勾选事件,Check:特别注意字母拼接差异Check、Click treeView.addTreeNodeCheckListener(this); // 侦听树节点拖拽移动事件 treeView.addTreeNodeDragListener(this); } /** * 界面加载,开始绑定数据事件 */ @Override public void beforeBindData(EventObject e) { super.beforeBindData(e); // 初始化树形控件的属性与第一层节点 TreeView treeView = this.getView().getControl(KEY_TREEVIEW1); treeView.setMulti(true); // 支持多选,不触发节点单击事件treeNodeClick,会触发节点双击事件treeNodeDoubleClick //treeView.setMulti(false); // 不支持多选,不触发复选节点事件 treeNodeCheck TreeNode root = new TreeNode("", "node1", "root node"); root.setChildren(new ArrayList<>()); // 需要懒加载的节点,需setChildren(new ArrayList<>()) treeView.addNode(root); treeView.setRootVisible(true); // 显示根节点 treeView.expand("node1"); // 展开节点 treeView.setDraggable(true); // 允许节点被拖拽 treeView.setDroppable(true); // 允许接收拖拽进的内容 } /** * 节点懒加载事件 * * @remark 节点需要setChildren(new ArrayList < > ()),当节点的children存在且isEmpty时,点击展开节点时触发事件 */ @Override public void queryTreeNodeChildren(TreeNodeEvent arg0) { String nodeId = (String) arg0.getNodeId(); List<TreeNode> childNodes = this.loadChildNode(nodeId); TreeView treeView = this.getView().getControl(KEY_TREEVIEW1); treeView.addNodes(childNodes); } @Override public void treeNodeClick(TreeNodeEvent evt) { //this.getView().showTipNotification(String.format("您点击了节点%s", evt.getNodeId())); //FormulaEditHelper.insertExpression(this.getView(), KEY_TREEVIEW1, KEY_LARGETEXT, evt.getNodeId().toString()); //树节点点击之后,把nodeId赋值给多行文本 FormulaEditHelper.insertExpression(this.getView(), KEY_TREEVIEW1, KEY_TEXTAREA, evt.getNodeId().toString()); } @Override public void treeNodeDoubleClick(TreeNodeEvent evt) { //this.getView().showTipNotification(String.format("您双击了节点%s", evt.getNodeId())); } /** * 复选节点事件 */ @Override public void treeNodeCheck(TreeNodeCheckEvent arg0) { TreeView treeView = this.getView().getControl(KEY_TREEVIEW1); // 树形控件 TreeView.TreeState treeState = treeView.getTreeState(); // 树形控件的状态 List<String> selectNodeIds = treeState.getCheckedNodeIds(); //if (selectNodeIds.isEmpty()) { // this.getView().showTipNotification("您没有勾选任何节点"); //} else { // this.getView().showTipNotification(String.format("您勾选了节点%s", StringUtils.join(selectNodeIds.toArray(), ","))); //} } /** * 拖拽节点时触发 */ @Override public void treeNodeDragged(TreeNodeDragEvent arg0) { String nodeId = (String) arg0.getNodeId(); String fromParentId = (String) arg0.getFromParentId(); String toParentId = (String) arg0.getToParentId(); // 把被拖动的节点,从原来的父节点下删除,添加到新的父节点下 TreeView treeView = this.getView().getControl(KEY_TREEVIEW1); treeView.deleteNode(nodeId); TreeNode node = new TreeNode(toParentId, nodeId, nodeId); treeView.addNode(node); } /** * 加载子节点 * * @param parentId * @return */ private List<TreeNode> loadChildNode(String parentId) { List<TreeNode> childNodes = new ArrayList<>(); // 演示代码,直接创建新的节点返回,略过读取数据库的环节 String id1 = parentId + ".1"; TreeNode node1 = new TreeNode(parentId, id1, id1); node1.setChildren(new ArrayList<>()); // 需要懒加载下级节点 childNodes.add(node1); String id2 = parentId + ".2"; TreeNode node2 = new TreeNode(parentId, id2, id2); node2.setChildren(new ArrayList<>()); // 需要懒加载下级节点 childNodes.add(node2); return childNodes; } }
四、效果图
表单插件绑定页面,预览即可看到效果。
五、开发环境版本
不限
六、注意事项
踩过的坑:试了多行文本和大文本,多行文本可以实现该效果,大文本不行,大文本只会追加到后面,并且有中文就不生效了。
元数据包和插件代码都上传到了附件,需求原型及实现过程都来自济宁分公司的王辉大哥,特此感谢
如果发现文章有什么问题欢迎大家指出,我将积极验证修改。如果有帮到你,还请来一波三连:关注,点赞,收藏。觉得有用也可以分享到公司云之家群,惠及其他同事,感谢您的耐心观看~~~
光标位置插入样例.zip(6.55KB)
推荐阅读