Hi,
Can we request this new api for your future version?
I asked to share more information on how your plugin works, it is still unclear how you are designing it. Can you share a video demo with explanation?
Hi,
The whole plugin is a docx template designer. when plugin is loading, it post an request to backend to get the table and field informatin from database and then populate to the left tree in the plugin panel. we need the Table and Field translation at the same time. so you can see it like the following:
we need drag the treenode to add merge field to the docx. so, in normal cursor location, it’s ok.
we just need to remove the translation from the dragged treenode text and then wrap it in mergefield. But for list of table data, we need <<TableStart>>
and <<TableEnd>>
mergefield. so that the docx template can be used to populate data list from database.
So, is there any unclear?
Thank you for the reply. Is data, obtained from the database via POST request, static? You also mentioned dragging a treenode – do I understand that you are not dragging exact item from the list, e.g. model
item from the screenshot? Please provide more details the workflow you are designing, as of now I do not understand why mentioned <<TableStart>>
and <<TableEnd>>
are different.
data, obtained from the database via ajax GET request in the plugin code.
then, populate it to the plugin panel with a Tree list in the plugin code:
function createTree(data, parentText = null) {
const ul = document.createElement(‘ul’);
ul.className = ‘tree-list’;
data.forEach(item => {
const li = document.createElement('li');
li.className = 'tree-node expanded';
// 创建容器 div
const contentDiv = document.createElement('div');
contentDiv.className = 'node-content';
// 如果有子节点,添加展开/折叠箭头
const hasChildren = item.children && item.children.length > 0;
if (hasChildren) {
const arrow = document.createElement('span');
arrow.className = 'icon-arrow icon-arrow-down';
arrow.addEventListener('click', function(e) {
e.stopPropagation();
const parentLi = e.target.closest('.tree-node');
if (parentLi) {
const isExpanded = parentLi.classList.contains('expanded');
if (isExpanded) {
parentLi.classList.remove('expanded');
e.target.className = 'icon-arrow icon-arrow-right';
} else {
parentLi.classList.add('expanded');
e.target.className = 'icon-arrow icon-arrow-down';
}
}
});
contentDiv.appendChild(arrow);
} else {
// 如果没有子节点,添加空白占位符保持对齐
const spacer = document.createElement('span');
spacer.className = 'icon-spacer';
contentDiv.appendChild(spacer);
}
// 创建图标元素
const icon = document.createElement('span');
if (item.text === '数据源') {
icon.className = 'icon-database';
} else if (item.text === '动作') { // 确保这个判断条件正确
icon.className = 'icon-action';
}else if (item.text === '子模板') {
icon.className = 'icon-subreport';
} else if (parentText === '数据源') {
icon.className = 'icon-table';
} else if (parentText === '子模板') {
icon.className = 'icon-subtemplate';
} else {
const hasChildren = item.children && item.children.length > 0;
icon.className = hasChildren ? 'icon-folder-opened' : 'icon-file';
}
// 创建文本节点
const textSpan = document.createElement('span');
textSpan.className = 'node-text';
textSpan.textContent = item.text;
// 组装节点
contentDiv.appendChild(icon);
contentDiv.appendChild(textSpan);
li.appendChild(contentDiv);
// 设置拖拽
li.setAttribute('draggable', 'true');
// li.addEventListener('dragstart', dragStart);
// // 添加选中事件
// li.addEventListener('click', function(e) {
// e.stopPropagation();
// const allTextSpans = document.querySelectorAll('.node-text');
// allTextSpans.forEach(span => span.classList.remove('highlighted')); // 移除高亮类
// textSpan.classList.add('highlighted'); // 添加高亮类到当前文本
// });
// 添加双击事件
if (parentText === '子模板') {
li.addEventListener('dblclick', function() {
window.parent.parent.postMessage({ type: 'openDocEditor', payload: item }, '*'); // 发送消息到父窗口
});
}
if (hasChildren) {
const childrenContainer = document.createElement('div');
childrenContainer.className = 'children';
childrenContainer.appendChild(createTree(item.children, item.text));
li.appendChild(childrenContainer);
}
ul.appendChild(li);
});
return ul;
}
if we don’t know the dropping target is in table cell, we cannot wrap the field code with <<TableStart>>
and <<TableEnd>>
, we need that.
for normal paragraph dropping target, we can wrap the normarl field code with plugin code
For the table cell class you can its classType
with GetClassType
method:
Hi,
I still don’t know how. We should to get the object ander mouse first and then judge it whether tablecell object or not.
Correct, you need to get the object and then run check with GetClassType
method. For instance, if it returns true, then do this, otherwise do that.
Is there getobject api to get the object under mouse?