2016-11-24 3 views
0

JSF 및 Datatables에 문제가 있습니다. 내 bean에는 Datatable에 의존하여 뷰에 표시되는 개체 목록이 있습니다. 객체는 매우 간단하며 각각은 정수 (ID)와 문자열 ( 설명)로 구성됩니다.JSF Datatable : 단일 명령 단추를 통해 여러 행 제출

최종 목표는 하나 이상의 행 (h : inputtext 필드를 통해)을 동시에 편집 한 다음 버튼을 통해 변경 사항을 제출하는 전체 객체 목록을 사용자에게 인쇄하는 것입니다. 그리고 이것이 문제입니다. 이미 각 행의 편집/저장 버튼을 사용하여 시간당 하나의 행을 편집하여 "성공적으로"Datatables를 사용했지만 최종 사용자가 합계 500 행 이상으로 직면하게되므로이 경우 적용 할 수 없습니다. 여기

내가

콩을 (간체 및 추출) 사용되는 코드입니다 :

@ManagedBean 
@RequestedScope 
public class VlanBean { 

private DataModel<VlanWrapper> model; 

private List<VlanWrapper> vlans = new ArrayList<VlanWrapper>(); 

public VlanBean() { 
    vlans.add(new VlanWrapper(1, "")); 
    vlans.add(new VlanWrapper(2, "Prova2-2")); 
    vlans.add(new VlanWrapper(3, "")); 
    vlans.add(new VlanWrapper(4, "")); 
    vlans.add(new VlanWrapper(5, "")); 
    vlans.add(new VlanWrapper(6, "Prova3")); 
    vlans.add(new VlanWrapper(7, "")); 
    vlans.add(new VlanWrapper(8, "")); 
} 

public void commitChanges() 
{ 
    System.out.println("Before Model "); 

    for (VlanWrapper vw : model) 
    { 
     System.out.println("ModelOF " + vw.getId() + " - " + vw.getProject() + " - changed: " + vw.changed + ";"); 
    } 
} 

public DataModel<VlanWrapper> getModel() { 
    if (model == null) 
     model = new ListDataModel<VlanWrapper>(vlans); 
    return model; 
} 

public void setModel(DataModel<VlanWrapper> model) { 
    this.model = model; 
} 

public class VlanWrapper 
{ 
    private boolean changed; 
    private int id; 
    private String project; 

    public VlanWrapper(int id, String prj) 
    { 
     this.id = id; 
     this.project = prj; 
     changed = false; 
    } 

    public String getProject() { 
     return project; 
    } 

    public void setProject(String project) { 
     System.out.println("Setting PRJ.."); 
     changed = true; 
     this.project = project; 
    } 

    public int getId() { 
     return id; 
    } 

    public boolean isChanged() { 
     return changed; 
    } 
} 
} 

보기 :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
xmlns:f="http://java.sun.com/jsf/core" 
xmlns:h="http://java.sun.com/jsf/html" 
xmlns:ui="http://java.sun.com/jsf/facelets"> 
<h:head> 
</h:head> 
<h:body> 
<f:view> 
    <h:panelGroup> 
    <h:form> 
     <h:commandButton value="Commit changes to DB" action="#{VlanBean.commitChanges}"> 
     </h:commandButton> 
    </h:form> 


    <h:dataTable value="#{VlanBean.model}" var="vlans"> 
     <h:column><f:facet name="header">ID</f:facet>#{vlans.id}</h:column> 
     <h:column><f:facet name="header">Project</f:facet> 
      <h:inputText value="#{vlans.project}" immediate="true"/> 
     </h:column> 
    </h:dataTable> 
    </h:panelGroup> 

</f:view> 
</h:body> 
</html> 

문제는 모든 변경 사항은 내가보기에 할 것입니다 콩에 반영되지 않은 및 주위에 유용한 힌트/게시물 (일부는 아약스 강제로 업데이 트를 제안, 다른 자바 스크립트를 찾지 못했지만, 나는 그들 중 하나를 작동시키지 않았고 아무도 정말 clo 내가 원하는대로 사용하십시오).

나는 또한 ui : repeat를 시도했지만 동일한 동작을합니다. 어떤 아이디어/제안? 나는 Datatable을 사용할 의무가 없기 때문에 다른 솔루션/접근법을 열어 놓았습니다! advace에서

감사합니다, 알베르토 코드에서

답변

0

, 당신이 당신의 <h:inputText<f:form 부모로서해야한다는 경고를 받고되어야한다 거기 주변에는 형태는 없으며, 일반적으로 당신이 <h:datatable를 사용하지만, 당신이 가지고있는 형태는, 원하는 동작을 할 수 UIComponent Iteration의 모든 유형을 사용 <h:commandButton

를 둘러싸고있다. 편집 할 행을 먼저 선택해야하지만 다음과 같이 직접 수행 할 수 있습니다.

개체에 다른 속성을 추가했습니다. VlanWrapper :

private boolean changed; 
private boolean edit; 
private int id; 
private String project; 

// 세터 & 게터 ....

귀하의 facelet이 같은 수 :

<h:form> 
    <h:dataTable value="#{meod.vlans}" var="v" > 

     <h:column> 
      <f:facet name="header">Id</f:facet> 
      <h:outputLabel value="#{v.id}" />      
     </h:column> 

     <h:column> 
      <f:facet name="header">Project</f:facet> 
      <h:outputLabel rendered="#{not v.edit}" value="#{v.project}" /> 
      <h:inputText rendered="#{v.edit}" value="#{v.project}" > 
       <f:ajax event="blur" execute="@this" listener="#{meod.addToEditedList(e)}" render="@all"> 
        <f:param name="vlanedit" value="#{v.id}" /> 
        <f:param name="vlanproject" value="#{v.project}" /> 
       </f:ajax> 
      </h:inputText> 
     </h:column> 

     <h:column> 
      <f:facet name="header">Edit</f:facet> 
      <h:commandButton value="Edit" action="#{meod.edit(v)}"> 
       <f:ajax render="@form" /> 
      </h:commandButton> 
     </h:column> 
    </h:dataTable>    
    <h:commandButton value="Finalize Edit" action="#{meod.editSubmit()}" /> 
</h:form> 

편집하려는 행을 선택해야하는 이유는 edit 버튼을 누르면 전체 양식이 업데이트되어 업데이트하려는 내용으로 재생되므로이 작업을 수행해야하기 때문입니다.

backingbean :

이 달성 할 수있는 여러 가지 방법이 있습니다
@ManagedBean 
@ViewScoped 
public class Meod { 

    private List<VlanWrapper> vlans; 

    public Meod() { 

     vlans = new ArrayList<>(); 

     for (int i = 0; i < 11; i++) { 

      vlans.add(new VlanWrapper(i, "Project " + i)); 
     } 
    } 

    public void addToEditedList(AjaxBehaviorEvent e) { 

     Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap(); 

     int id = Integer.valueOf(params.get("vlanedit")); 
     String newProject = params.get("vlanproject"); 

     updateVlanInView(id, newProject); 
    } 

    private void updateVlanInView(int id, String proj) { 

     vlans.stream().filter(v -> v.getId() == id).forEach(v -> v.setProject(proj)); 
    } 

    public void edit(VlanWrapper vlan2Edit) { 
     vlan2Edit.setEdit(true); 
    } 

    public void editSubmit() { 
     vlans.forEach((v) -> v.setEdit(false)); 
    } 

    public List<VlanWrapper> getVlans() { 
     return vlans; 
    } 

    public void setVlans(List<VlanWrapper> vlans) { 
     this.vlans = vlans; 
    } 
} 

...하지만 아마도 더 나은 방법 요약 :

  • 당신이
  • <h:commandXXXEditableValueHolder의 양식에 있는지 확인 개체를 반복하는 데이터 테이블을 생성합니다.
  • 는 "새로운"속성 edit 입력 대신 출력 텍스트 구성 요소
  • 당신을 변경 한 후 값을 업데이트하는 DBService를 사용하여 렌더링할지 여부를 결정하는 것입니다.

희망이 도움이됩니다.

+0

답변 해 주셔서 감사합니다. 실제로 흐름에 대한 구현 속성이 필요하지 않습니다 구현해야하지만 그것은 아주 좋은 제안과 예제! 특히 아약스 부분! – kappaalby

0

데이터 테이블 다음에 </h:form> 태그를 이동하십시오. 이제 변경 사항이 포함되며 setProject 메소드가 제대로 호출됩니다.

<h:panelGroup> 
    <h:form> 
     <h:commandButton value="Commit changes to DB" action="#{VlanBean.commitChanges}"> 
     </h:commandButton> 

     <h:dataTable value="#{VlanBean.model}" var="vlans"> 
      <h:column><f:facet name="header">ID</f:facet>#{vlans.id}</h:column> 
      <h:column><f:facet name="header">Project</f:facet> 
      <h:inputText value="#{vlans.project}" immediate="true"/> 
      </h:column> 
     </h:dataTable> 
    </h:form> 
</h:panelGroup> 
+0

감사! 내가 잃어버린 조각 이었어! – kappaalby