wangeditor-team / wangEditor

wangEditor, open-source Web rich text editor 开源 Web 富文本编辑器
http://www.wangeditor.com/
MIT License
17.58k stars 3.32k forks source link

表格合并单元格功能 #5624

Open Chasonx911 opened 1 year ago

Chasonx911 commented 1 year ago

使用wangEditor的用户对合并单元格的功能还是比较期待的,由于业务需求,用自定义扩展简单实现了合并,问题很多,还是期待团队从基础功能上进行支持。 image

GhostyCHEN commented 1 year ago

你好,我目前也在做这方面的功能,是否方便提供一些代码让我少走点弯路 @Chasonx911

Chasonx911 commented 1 year ago

你好,我目前也在做这方面的功能,是否方便提供一些代码让我少走点弯路 @Chasonx911

一直在忙,回复比较慢,主要用到 自定义扩展功能的 ButtonMenu,实现思路大概如下:

1,定义各种扩展功能的class

2,在 TableBorder 功能中加了额外的事件监听,主要用来实现选中单元格效果,代码或许不能直接使用,只是提供一种思路

class TableBorder {
     ....
    isActive( editor ){

        if(this.editor == null){
          this.editor = editor
        }

        let tableWrapperEle = getTableWrapper( editor ).tableEle
        let tableWrapperId = tableWrapperEle.id;

        if(!isNotNull(this.config , tableWrapperId) || !this.config[tableWrapperId].eventHandler ){
          this.config[tableWrapperId] = {}
          this.config[tableWrapperId].showBorder = true

          this.addListenerHandler(tableWrapperEle)
          this.config[tableWrapperId].eventHandler = true
        }   
        return this.config[tableWrapperId].showBorder
    }

    addListenerHandler( tableWrapperEle ){
       ....
         this.bindMouseDown(tableId , tableEle)
      ....
    }
   // tableId 主要是用来实现对编辑器中的多个table Node 进行分别自定义配置
   bindMouseDown(tableId){

  }

 bindMouseMove( id ){
   // 监听鼠标选择了哪些td
 }

  setTdSelector( id ){
    // 设置选中单元格效果
  }

  //取消moveMove监听
  //给td Dom元素添加一些自定义属性
    ...
}

总的来说 TableBorder 扩展功能实现了表格整体的边框显示与隐藏、选择td效果,一些全局对象用来保存当前选中了哪个table ,此时再在其他的扩展功能中如:TableCellMerge,去实现合并/拆分单元格,因为扩展功能的 isActive 等方法都会传递editor对象,可通过editor对象获取到当前点击的 table id等信息

3,注册扩展功能

const tableBorder = {
  key : 'tableBorder',
  factory(){
    return new TableBorder()
  }
}
...
Boot.registerMenu( tableBorder )
...

4,编辑器配置功能菜单

editor.getConfig().hoverbarKeys['table'] = {
      menuKeys : [
        'enter', 'tableHeader',
        'tableFullWidth', 'insertTableRow',
        'deleteTableRow', 'insertTableCol',
        'deleteTableCol', 'deleteTable','|',
        'tableBorder' ,'tableBorderLeft' , 'tableBorderRight' , 'tableBorderTop' , 'tableBorderBottom',
        '|' , 'tableCellMerge','tableCellSplit',
        '|','tableRowCopy','tableCellCopy'
      ]
    }

5,在业务代码里面获取编辑器的table dom元素,再根据table id 从全局缓存中 或者 tr td 中获取自定义的一些信息格式化后进行后续操作。

GhostyCHEN commented 1 year ago

@Chasonx911 感谢您在忙碌中抽出时间来解答,您的帮助将节约我很多时间

GhostyCHEN commented 1 year ago

@Chasonx911 你好,有空深入聊下这个功能吗(我的微信RG9uZ0dlbm11),能提供demo更好啦!目前正在处理这个功能,目前还没什么思路

ddIvan commented 1 year ago

官网目前会出上面的相关功能吗

ddIvan commented 1 year ago

@Chasonx911 注册插件按钮这些我都没啥问题 主要是 如何定位table的首行或者首列 或者尾行 尾列 然后插入 一行或者列 ,官方没办法在尾部或者首列 插入,然后我还想做个 行列转换 有没思路提供下

GhostyCHEN commented 1 year ago

我尝试注册自定义插件,引入了tinymce的表格功能

Chasonx911 commented 1 year ago

@Chasonx911 注册插件按钮这些我都没啥问题 主要是 如何定位table的首行或者首列 或者尾行 尾列 然后插入 一行或者列 ,官方没办法在尾部或者首列 插入,然后我还想做个 行列转换 有没思路提供下

可以通过editor对象将node转换成table dom对象,然后给dom注册mousedown 或者其他事件就可以获取到当前点击是哪一行那一列,目前通过这种方式基本实现了业务需求,但还存在问题,若有其他更好的方式欢迎一起讨论

Chasonx911 commented 1 year ago

@GhostyCHEN 这是个不错的思路,tinymce的表格操作确实比较完善,期待分享出一些两者结合使用的demo

Chasonx911 commented 1 year ago

@ddIvan 作者暂停维护了

GhostyCHEN commented 1 year ago

@Chasonx911 image image

ddIvan commented 1 year ago

这么快就暂停维护拉 ,我昨天才 实现完 行列转换 上下插入行列 今天想来找找看怎么做 合并

ddIvan commented 1 year ago

@Chasonx911 你这个选中状态怎么弄 默认鼠标选择 没效果 尤其是空行

ddIvan commented 1 year ago

@GhostyCHEN 你这个怎么引入他的table插件 能不能提供部分代码 我参考下

GhostyCHEN commented 1 year ago

@ddIvan 我运用了这个插件https://juejin.cn/post/7244819740543598652?searchId=2023110211180699B581DFEE1AD5FAE97A 可以在wangeditor里面插入vue组件,基本思路就是这个

Chasonx911 commented 1 year ago

@Chasonx911 你这个选中状态怎么弄 默认鼠标选择 没效果 尤其是空行

在注册自定义事件获取到点击对象是哪个dom后,之后的一切操作都只是单纯的对dom进行更新了,比如选中一些单元格,可以获取mousedown时点击td的位置,mouseup时的td的位置,然后对选中的这些td增加选中样式,合并、拆分等都可以采用类似方式,当然这可能不是最好方式,欢迎讨论,采用上述引入 tinymce 表格也是不错的选择

Chasonx911 commented 1 year ago

@ddIvan 我运用了这个插件https://juejin.cn/post/7244819740543598652?searchId=2023110211180699B581DFEE1AD5FAE97A 可以在wangeditor里面插入vue组件,基本思路就是这个

感谢分享!

ddIvan commented 1 year ago

@Chasonx911 @GhostyCHEN 加入一个插件 里面是内容是一个DIV 然后 调用tinymce初始化 完没效果 是为什么

ddIvan commented 1 year ago
function RenderTinyMceHtml(elem, children, editor) {
    const h = MySnabbdom.default.h;
    // 构建 vnode
    var id = wangEditor.DomEditor.findKey(editor, elem).id;

    const newEditor = editor;
    function init_tinymce() {
        tinymce.init({
            selector: '#tinymce_area_' + id,
            plugins: "table",
            inline: true,
            language: 'zh_CN',//注意大小写
            menubar: false,
            toolbar: "table tabledelete | tableprops tablerowprops tablecellprops | tableinsertrowbefore tableinsertrowafter tabledeleterow | tableinsertcolbefore tableinsertcolafter tabledeletecol"
        });
    }

    var node = h('div', { props: { id: "tinymce_area_" + id}, style: { height: elem.height + 'px', width: '100%' }, hook: { insert: init_tinymce } });
    const vnode = h('span', {
        props: {
            id: "tinymce_" + id
        }
    }, node, '');

    return vnode;
}
ddIvan commented 1 year ago

是因为再wangeditor编辑状态下 无法对他进行初始化吗 只能在预览模式下 实现内联?

ddIvan commented 1 year ago

@GhostyCHEN 我也集成了tingmce 但是反向赋值的时候 table 会被重复解析 多出一个table 这个问题 怎么解决的

Xiaodonghao-web commented 10 months ago

@GhostyCHEN @ddIvan 我也集成了tingmce 但是反向赋值没有什么思路 方便解答一下吗 谢谢🙏

GhostyCHEN commented 10 months ago

@Xiaodonghao-web 能贴一下详细代码吗,或者加微信(DongGenmu)交流下

jschyz commented 4 months ago

https://github.com/nlulic/slate-table/tree/f0429e857eeda2a5323ffb729d04bab84bcb159a

这个库不错,可以看看

jschyz commented 4 months ago

2024-06-27 10 16 46

已实现,!