a4j:jsFunction与h:dataTable中的actionListener

时间:2010-03-18 13:17:38

标签: javascript jsf datatable

我在使用a4j:jsFunction和h:dataTable中的actionListener时遇到问题,当我想用​​a4j调用特定行的动作时:commandLink它完美无缺,但是当我想用a4j调用动作时:jsFunction &安培; actionListener总是在dataTable的最后一个元素上调用它 让我举个例子:

    <a4j:form ajaxSubmit="true" reRender="mainForm" id="mainForm">
        <a4j:region>
            <t:saveState value="#{ts.list}" />
        </a4j:region>

        <h:dataTable value="#{ts.list}" var="el" binding="#{ts.bind}">
        <h:column>#{el}</h:column>>
        <h:column>
            <a4j:commandLink actionListener="#{ts.rem}">
                    <h:outputText value="delete by CMDLink" />
                </a4j:commandLink>
            </h:column>
        <h:column>
                <a href="#" onclick="okClicked();">delete by okClicked</a>
                <a4j:jsFunction name="okClicked"
                    actionListener="#{ts.rem}"
                />
        </h:column>
   </h:dataTable>
    </a4j:form>

现在,bean的代码:

package com.sth;

import java.util.ArrayList;
import java.util.List;

import javax.faces.component.UIData;
import javax.faces.event.ActionEvent;

public class Ts {

    private List<String> list = new ArrayList<String>();
    private UIData bind;

    public Ts(){
        list.add("element1");
        list.add("element2");
        list.add("element3");
        list.add("element4");
    }

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public void rem(ActionEvent ae) {
        String toRem = (String) bind.getRowData();
        System.out.println("Deleting " + toRem);
        list.remove(toRem);
    }

    public UIData getBind() {
        return bind;
    }

    public void setBind(UIData bind) {
        this.bind = bind;
    }

}

当我使用a4j:commandLink删除元素时,它可以正常工作,但是当我使用a4j:jsFunction来调用actionListener时,它会调用对最后一个元素的操作:( 有任何想法吗? 干杯

3 个答案:

答案 0 :(得分:1)

您可以通过从&lt; h:datatable&gt; 控件

移出&lt; a4j:jsFunction&gt; 来实现目标

这是一个例子

 <a4j:form ajaxSubmit="true" reRender="mainForm" id="mainForm">

    <h:dataTable value="#{ts.list}" var="el" binding="#{ts.bind}">
      <h:column>#{el}</h:column>>
      <h:column>
            <a4j:commandButton 
                onclick="#{rich:component
                     ('confirmation')}.show();return false">Delete</a4j:commandButton>
      </h:column>
    </h:dataTable>
    <a4j:jsFunction name="remove" action="#{ts.remove(el)}" reRender="mainForm"/>
 </a4j:form>

确认对话框:

<rich:modalPanel id="confirmation" width="250" height="150">
        <f:facet name="header">
            <h:panelGrid columns="2">
                <h:graphicImage value="/img/delete.gif"/>
                <h:outputText value="Confirmation"/>
            </h:panelGrid>
        </f:facet>
        <h:panelGrid style="height: 100%">
            <h:panelGrid columns="2" cellpadding="5px">
                <h:graphicImage value="/img/error_large.gif"/>
                <h:outputText value="Delete ?" style="font-size: large;"/>
            </h:panelGrid>
            <h:panelGroup style="margin-top: 20px">
                <input type="button" value="Yes" style="width: 100px"
                       onclick="#{rich:component('confirmation')}.hide();remove();return false"/>
                <input type="button" value="No" style="width: 100px"
                       onclick="#{rich:component('confirmation')}.hide();return false"/>
            </h:panelGroup>
        </h:panelGrid>
    </rich:modalPanel>

答案 1 :(得分:0)

根据评论,事实证明你只想发起确认对话。您也可以使用a4j:commandLink,在onclick属性中调用它,让它返回true或false以允许或阻止操作。这是一个启动示例,就像您使用标准确认对话框一样:

<a4j:commandLink onclick="return confirm('Are you sure?');">

通过这种方式,您无需在数小时内挣扎/调试奇怪的a4j:jsFunction行为。

答案 2 :(得分:0)

我的理解是使用a4j:jsFunction标签:

<a4j:jsFunction name="okClicked" actionListener="#{ts.rem}" />

放置在数据表的列中,名为okClicked的JavaScript函数将添加到表中每行的HTML页面中。具有相同的名称,每个JavaScript函数都会覆盖前一个JavaScript函数的定义,因此当调用okClicked()时,实际上只执行最后定义的函数。这就是为什么调用actionListener调用“对最后一个元素的操作”的原因。

解决这个问题的方法是将行索引包含在由a4j:jsFunction标记创建的JavaScript函数名称的一部分中:

<h:dataTable value="#{ts.list}" var="el" binding="#{ts.bind}" rowIndexVar="index">
    <h:column>
        <a href="#" onclick="okClicked#{index}();">delete by okClicked</a>
        <a4j:jsFunction name="okClicked#{index}" actionListener="#{ts.rem}"/>
    </h:column>
</h:datatable>

我没有测试过上面的解决方案(我不知道是否会将#{ts.rem}绑定到JS函数actionListener而不是将其绑定到commandLink actionListener)但是如果onClick的{​​{1}}值不能直接起作用,则调用一个javaScript函数,该函数根据索引值构建的字符串创建函数名:

okClicked#{index}();

我不得不使用类似的东西,要求在数据表中有一个'jsFunction'网格,我有多个列要处理多行。

希望将来对其他人有用。