如何以编程方式删除行<h:datatable> </h:datatable>

时间:2013-12-05 20:18:10

标签: jsf jsf-2

我有一张如下图所示的表格。

enter image description here

在上图中,您可以看到绿色添加按钮。当我点击它时,它会在数据表中创建一个新行,方法是将<f:ajax>发送到支持bean并进行渲染。

enter image description here

直到现在一切都很好。但我除了当我点击每行内部的十字按钮时,该行被删除。但它有一个bug。例如,当我点击第三行十字按钮时,它会从支持bean中删除该行,但不会从我的ui中删除。

在下面你可以看到我的支持bean和.xhtml文件。

@ManagedBean(name = "AddPollContorler")
@ViewScoped
public class AddPollControl {

    private List<Answer> answers = new ArrayList<Answer>();
    @PostConstruct
    public void init(){
        answers.add(new Answer());
        answers.add(new Answer());
    }

    public List<Answer> getAnswers() {
        return answers;
    }

    public void setAnswers(List<Answer> answers) {
        this.answers = answers;
    }

    public void addAnswer() {
        answers.add(new Answer());
    }

    public void removeAnswer() {
        String index=FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("index");
        if (StringUtil.isNumber(index))
            answers.remove(Integer.parseInt(index));
    }

}

.xhtml:

<div class="panel panel-success rgt">
    <div class="panel-heading rgt">
        <div style="float: left;">
        <h:commandLink styleClass="btn btn-success table-button" action="#{AddPollContorler.addAnswer}">
            <h:graphicImage library="img" name="add.png"            styleClass=" table-icon" />
            <f:ajax execute="answers" render="answers"></f:ajax>
            </h:commandLink>
        </div>
        <h4><h:outputText value="#{msg['protected.poll.add.answers']}"/></h4>
    </div>
    <div class="form-margin">
        <h:dataTable value="#{AddPollContorler.answers}" var="answer" id="answers" style="width:100%;">
        <h:column >
            <div class="input-group poll-answer" style="margin: 5px;">
            <span class="input-group-addon no-left-radius"><h:outputText value="#{CounterControler.index+1}" /></span>
            <h:inputText value="#{answer.text}" styleClass="form-control no-radius"/>
                <div class="input-group-addon no-right-radius poll-answer-remove" >
                <h:commandLink  action="#{AddPollContorler.removeAnswer}">
                    <h:graphicImage library="img" name="cross.png" />
                <f:param name="index" value="#{CounterControler.last}" />
                <f:ajax render="answers answers" />
                </h:commandLink>
            </div>
            </div>  
        </h:column>
        </h:dataTable>
    </div>
</div>

更新:2013/06/12

@ManagedBean(name="CounterControler")
public class CounterControl {
    private int index=0;
    public int getIndex(){
        return index++;
    }

    public int getLast(){
        return index-1;
    }
}

1 个答案:

答案 0 :(得分:0)

你的代码确实看起来很不错。 CounterControler内部如何运作? (没有给出来源)发送当前对象的替代方法可能是

  • 直接将对象作为参数(您需要一个适合的转换器),
  • 将其作为直接参数(action="#{AddPollContorler.removeAnswer(answer)},从EL 2.2开始工作)或
  • 直接从给定的ActionEvent
  • 中获取当前对象

最后一点看起来像

XHTML

<h:commandLink  action="#{AddPollContorler.removeAnswer}">
  <h:graphicImage library="img" name="cross.png" />
  <f:ajax render="answers" />
</h:commandLink>

托管bean

public void removeAnswer(ActionEvent ev) {
    Answer selectedItem = null;
    try {
        UIDataTable objHtmlDataTable = retrieveDataTable(
                                     (UIComponent)ev.getSource());
        selectedItem = (Answer) objHtmlDataTable.getRowData();
        answers.remove(answer);
    } catch (NullPointerException e) {
          // somehow couldn't find the element
    }
}

private static UIDataTable retrieveDataTable(UIComponent component) {
    if (component instanceof UIDataTable) {
        return (UIDataTable) component;
    }
    if (component.getParent() == null) {
        return null;
    }
    return retrieveDataTable(component.getParent());
}

我喜欢那个,因为它占据了前端的大部分逻辑。希望你能用一种策略清理你的行。

此外,您只需在answers

中提及<f:ajax render="answers" />一次

编辑:即使我不知道为什么 - 在<h:panelGroup layout="block" id=" answersWrapper">周围包裹<h:dataTable>并渲染该panelGroup为我工作。

<h:form id="myForm">
  <h:panelGroup id="answerWrapper" layout="block">
    <rich:dataTable value="#{myTestBean.answers}" var="answer" id="answers">
        <h:column >
            <h:outputText value="#{answer}"/>
            <h:commandButton  id="button" action="#{myTestBean.doTheAction}">
                <f:ajax render=":myForm:answerWrapper" />
            </h:commandButton>
        </h:column>
    </rich:dataTable>
  </h:panelGroup>
</h:form>