如何实现在光标所在位置插入数据原创
金蝶云社区-JeremyG
JeremyG
8人赞赏了该文章 2127次浏览 未经作者许可,禁止转载编辑于2022年04月16日 10:00:07

关键字:多行文本


一、需求背景

我们会有一些场景,比如输入的时候,是通过点击某些控件(常见的是树型控件),来把某些值动态的插入到一些文本控件中。如果是直接在文本控件后面添加,那么通过插件动态添加是比较简单的,但是有些场景需要添加到指定的位置,比如添加到光标所在的位置,苍穹也可以支持到这个地步。


二、思路与方案

发现苍穹中设置单据转换路线的时候,计算公式里面有一模一样的功能,那就直接照抄即可。如图:

image.png


三、实现过程

  1. 创建动态表单,放入树型控件和多行文本控件,简单调整下布局样式,如下图:

    image.png

  2. 写插件,照抄单据转换里面的逻辑即可,核心代码:kd.bos.designer.botp.FormulaEditHelper#insertExpression(IFormView view, String buttonKey, String textFieldKey, String str);

  3. 详细代码(大部分是树型控件的使用代码):



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;
    }
}



四、效果图

表单插件绑定页面,预览即可看到效果。

       image.png


五、开发环境版本

不限


六、注意事项

踩过的坑:试了多行文本和大文本,多行文本可以实现该效果,大文本不行,大文本只会追加到后面,并且有中文就不生效了。



元数据包和插件代码都上传到了附件,需求原型及实现过程都来自济宁分公司的王辉大哥,特此感谢



如果发现文章有什么问题欢迎大家指出,我将积极验证修改。如果有帮到你,还请来一波三连:关注,点赞,收藏。觉得有用也可以分享到公司云之家群,惠及其他同事,感谢您的耐心观看~~~

赞 8