【问题标题】:Executing JavaScript on multi-row table rendering在多行表渲染上执行 JavaScript
【发布时间】:2021-12-17 04:38:40
【问题描述】:

我正在使用基于 Primefaces 的自定义框架来显示数据表,它看起来像这样:

<xy:dataTable id="tableId" value="#{lazyTableBean.dates}" var="date">
    <xy:column id="nameColumnId">
        <xy:outputText id="nameOutputId" value="date.name"/>
    </xy:column>

    <xy:column id="actionColumnId">
        <xy:actionButton id="actionButtonId" label="Button"
            action="#{someBean.someAction(date.id)}"/>                          
    </xy:column>
</xy:dataTable>

现在我想设置按钮的工具提示。由于该框架的 actionButton 组件没有 title 属性,因此我使用 JavaScript 对其进行更改:

var rows = // getting the table content row components here

// iterating through table rows and setting the button tooltip to the name of the corresponding date
for (const row of rows) {
    var myTooltip = row.children.item(0).textContent;
    row.children.item(1).firstChild.setAttribute("title", myTooltip);
}

当我在文件末尾导入 JS 脚本时,这基本上可以正常工作。 但是,有几个 AJAX 事件(例如,在对表格进行排序或过滤时,或者在使用分页时......)会重新打印表格内容。由于没有再次触发 JS 脚本,因此在这种情况下不会设置工具提示。

现在我计划在某个适当的位置(例如,在重新渲染的组件内部)简单地导入脚本,以便在渲染按钮时执行它。但是,我还没有找到合适的地方让它工作。当我把它放在列中时:

<xy:dataTable id="tableId" value="#{lazyTableBean.dates}" var="date">
    <xy:column id="nameColumnId">
        <xy:outputText id="nameColumnId" value="date.name"/>
    </xy:column>

    <xy:column id="actionColumnId">
        <xy:actionButton id="actionColumnId" label="Button"
            action="#{someBean.someAction(date.id)}"/> 
        <h:outputScript library="js" name="addTooltipToTableButtons.js" />                
    </xy:column>
</xy:dataTable>    

这会导致只有第一行正确设置其工具提示,所有其他行保留其通用的。但是在 AJAX 事件上,会发生正确的行为,所有行都正确设置了它们的工具提示。如果最后还导入了脚本,也会发生相同的行为。我猜这与动态打印具有相同列组件的多行的表格格式有关,但这只是猜测。

将它放在表中(直接在&lt;/xy:dataTable&gt; 之前)根本不会执行任何脚本。

我对 JavaScript 完全陌生,我们只是在使用这种方法,直到我们的自定义框架支持设置任意属性。我希望你有一个想法(或解释为什么它不会那样工作) - 在此先感谢!

问候

【问题讨论】:

  • outputScript 移到它不属于那里的表之外。您可以使用一些简单的 Jquery 来查找所有按钮并添加 Title 属性。
  • 好的,但是 JQuery 版本会在 Ajax 事件之后再次神奇地执行吗?还没有使用 JQuery 的经验。
  • 只需将 oncomplete="yourJs()" 添加到您的 AJAX 事件中,即可在任何 AJAX 事件完成后调用此自定义 JS。

标签: javascript html jsf primefaces


【解决方案1】:

如果有人对我的解决方案感兴趣,我使用 MutationObserver 来处理事件,除了页面加载时的“正常”JS。

整个 JS 文件是这样的:

var table = ...; // get table by normal means

for (var i = 0, row; row = table.rows[i]; i++) {
    var tooltip = row.cells[0].textContent;
    row.cells[1].firstChild.setAttribute(tooltip);
}

var observer = new MutationObserver(function( mutations ) {
  mutations.forEach(function( mutation ) {
    var newNodes = mutation.addedNodes;
    if( newNodes !== null ) {
        var $nodes = $( newNodes );
        $nodes.each(function() {
            var tooltip = this.cells[0].textContent;
            this.cells[1].firstChild.setAttribute(tooltip);
        });
    }
  });    
});

var config = { 
    attributes: true, 
    childList: true, 
    characterData: true 
};
 
observer.observe(table.children.item(1), config);

【讨论】:

    最近更新 更多