2016-07-19 20 views
4

Ich habe eine Klasse Dokument zum Erstellen einer Struktur mit einer Liste von Dokumentenobjekten.JSF Tree Validation Form auf Änderung Knoten

public class Document implements Serializable { 

    private String name; 

    private String size; 
    private List<Field> fields; 

    public Document(String name, String size, String type) { 
     this.name = name; 
     this.size = size; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getSize() { 
     return size; 
    } 

    public void setSize(String size) { 
     this.size = size; 
    } 

    public List<Field> getFields() { 
     return fields; 
    } 

    public void setFields(List<Field> fields) { 
    this.fields = fields; 
    } 
} 

Auch habe ich eine Field-Klasse für die Shop-relevante Informationen in Dokumenten

public class Field implements Serializable { 
private int fieldIndex; 
private String label; 
private String value; 

private List<Values> list; 

public Field() { 
} 

public int getFieldIndex() { 
    return fieldIndex; 
} 

public void setFieldIndex(int fieldIndex) { 
    this.fieldIndex = fieldIndex; 
} 

public Field(String label) { 
    this.label = label; 
} 

public String getLabel() { 
    return label; 
} 

public void setLabel(String label) { 
    this.label = label; 
} 

public String getValue() { 
    return value; 
} 

public void setValue(String value) { 
    this.value = value; 
} 


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


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

Mein ManagedBean einen Baum mit einigen Dokumenten erstellen und für jedes Dokument einig Daten speichern. Wenn ich den Baumknoten auswähle, wird eine dynamische Form mit jedem Feld und Eingaben für die Eingabe eines Wertes angezeigt.

@ManagedBean(name="treeSelectionView") 
@ViewScoped 
public class SelectionView implements Serializable { 

private TreeNode root1; 

private TreeNode selectedNode; 
private String email; 

private List<Field> fields; 

public String getEmail() { 
return email; 
} 

public void setEmail(String email) { 
this.email = email; 
} 

@PostConstruct 
public void init() { 

    TreeNode root = new DefaultTreeNode(new Document("Files", "-", "Folder"), null); 

    TreeNode documents = new DefaultTreeNode(new Document("Documents", "-", "Folder"), root); 

    Field f1=new Field(); 
    Field f2=new Field(); 
    Field f3=new Field(); 

    f1.setLabel("email"); 
    f1.setValue(""); 

    f2.setLabel("doc"); 
    f2.setValue(""); 

    f3.setLabel("otro"); 
    f3.setValue(""); 

    List<Field> fields=new ArrayList<Field>(); 
    fields.add(f1); 
    fields.add(f2); 
    fields.add(f3);   

    List<Field> fields1=new ArrayList<Field>(); 
    f1=new Field(); 
    f2=new Field(); 
    f3=new Field(); 

    f1.setLabel("email"); 
    f1.setValue(""); 

    f2.setLabel("doc"); 
    f2.setValue(""); 

    f3.setLabel("otro"); 
    f3.setValue(""); 

    fields1.add(f1); 
    fields1.add(f2); 
    fields1.add(f3); 

    List<Field> fields2=new ArrayList<Field>(); 

    f1=new Field(); 
    f2=new Field(); 
    f3=new Field(); 

    f1.setLabel("email"); 
    f1.setValue(""); 

    f2.setLabel("doc"); 
    f2.setValue(""); 

    f3.setLabel("otro"); 
    f3.setValue(""); 

    fields2.add(f1); 
    fields2.add(f2); 
    fields2.add(f3);   


    //Documents 
    Document d1= new Document("Expenses.doc", "30 KB", "Word Document"); 
    Document d2=new Document("Resume.doc", "10 KB", "Word Document"); 
    Document d3=new Document("RefDoc.pages", "40 KB", "Pages Document"); 

    d1.setFields(fields); 
    d2.setFields(fields1); 
    d3.setFields(fields2); 


    TreeNode expenses = new DefaultTreeNode("document",d1, documents); 
    TreeNode resume = new DefaultTreeNode("document", d2, documents); 
    TreeNode refdoc = new DefaultTreeNode("document",d3 , documents); 
    documents.setExpanded(true); 
    root1 = root; 
    root1.setExpanded(true); 
} 


public void onNodeDocumentSelect(NodeSelectEvent nodeSelected) { 
// fields=((Document)nodeSelected.getTreeNode().getData()).getFields(); 
    fields=((Document)selectedNode.getData()).getFields(); 
} 

public TreeNode getRoot1() { 
    return root1; 
} 

public TreeNode getSelectedNode() { 
    return selectedNode; 
} 

public void setSelectedNode(TreeNode selectedNode) { 
    this.selectedNode = selectedNode; 
} 

public List<Field> getFields() { 
    return fields; 
} 

public void setFields(List<Field> fields) { 
    this.fields = fields; 
} 
} 

Mein JSF sieht aus wie

<!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" 
    xmlns:p="http://primefaces.org/ui"> 
<h:head> 
<title>Default title</title> 
</h:head> 
<h:body> 
<h:panelGrid columns="2"> 
<h:form id="treeForm"> 
    <p:panel id="panel22" header="Documents" style="height:400px"> 
     <p:growl id="msgs" showDetail="true" /> 
     <p:tree value="#{treeSelectionView.root1}" var="doc" selectionMode="single" selection="#{treeSelectionView.selectedNode}" > 
      <p:ajax process="@this" event="select" update=":myForm:dymanicForm" listener="#{treeSelectionView.onNodeDocumentSelect}" />  
      <p:treeNode expandedIcon="ui-icon-folder-open" collapsedIcon="ui-icon-folder-collapsed"> 
       <h:outputText value="#{doc.name}"/> 
      </p:treeNode> 
      <p:treeNode type="document" icon="ui-icon-document" > 
       <h:outputText value="#{doc.name}" /> 
      </p:treeNode> 

     </p:tree> 
    </p:panel> 
</h:form> 
<h:form id="myForm"> 
<p:panel id="panel222" header="Info Doccs" style="height:400px"> 

    <p:panel id="dymanicForm" >  
     <ui:repeat value="#{treeSelectionView.fields}" var="componentMetadata"> 
      <h:panelGrid columns="3"> 
       <h:outputText value="#{componentMetadata.label}"/>: 
       <h:inputText id="field" value="#{componentMetadata.value}" 
       required="true" label="#{componentMetadata.label}"/> 
      <h:message for="field" style="color:red" /></h:panelGrid> 
     </ui:repeat> 
    </p:panel> 
    <h:commandButton value="Submit" action="result" /> 
    </p:panel> 
    </h:form> 
</h:panelGrid> 
</h:body> 
</html> 

Wenn ich die einreichen drücken Sie die Taste werden die Werte vorgelegt und speichern Sie in jedem Feld, auch die Validierungen abgefeuert werden. Aber ich muss wirklich den Übermittlungsbutton entfernen und das Formular validieren, wenn ich jeden Knoten verloren habe. Mit Beispiel, wenn ich im ersten Knoten bin, validiere das Formular nur, wenn ich den Fokus verloren habe, aber wenn die Formularvalidierung fehlschlägt, muss ich in diesem Knoten bleiben.

Wirklich ich schätze jede Hilfe, die Sie mir geben können. Vielen Dank im Voraus.

+0

wenn iu Verstehen Sie Ihre Frage, wenn Sie die Informationen einreichen, wenn alles in Ordnung ist, müssen Sie den Baum schließen, und wenn nicht müssen Sie den Baum offen lassen –

+0

@Neel ich reichte eine Antwort ein, bitte werfen Sie einen Blick :) –

Antwort

0

Ich wollte eine ähnliche Ansicht realisieren, und es dauerte einige Zeit, um herauszufinden.

Der Trick ist nicht erklärt das selection Attribut auf <p:tree, sondern nur die selectionMode und die Auswahl verwalten nur mit dem Hörer, manuell.

Dies bewirkt, dass die Auswahl in INVOKE_APPLICATION Phase anstelle von UPDATE_MODEL_VALUES ausgetauscht wird und die rechten Fensterreferenzen in Wertausdrücken beibehalten werden.

Darüber hinaus erfolgt die Validierung vor dem Selektionsaustausch, und bei Fehlschlagen wird der Selektionsaustausch verhindert.

Ich denke, das ist genau das, was Sie suchen:

<h:form> 
    <p:layout fullPage="false" stateful="false" style="height:400px"> 
     <p:layoutUnit position="center"> 
      <p:tree id="tree" var="data" nodeVar="node" value="#{testTreeBean.root}" 
       selectionMode="single" dynamic="true" animate="true" highlight="true" 
       style="border: 0"> 

       <p:ajax event="select" listener="#{testTreeBean.onSelect}" process="@form" 
        update="@this @form:details" /> 
       <p:ajax event="expand" process="@this" /> 
       <p:ajax event="collapse" process="@this" /> 

       <p:treeNode expandedIcon="ui-icon-folder-open" collapsedIcon="ui-icon-folder-collapsed"> 
        <p:outputPanel id="node"> 
         <h:outputText value="#{data.someText1} - #{data.someText2}" /> 
        </p:outputPanel> 
       </p:treeNode> 
      </p:tree> 
     </p:layoutUnit> 

     <p:layoutUnit position="east" size="65%" minSize="150"> 
      <p:outputPanel id="details" style="padding: 1em"> 
       <p:panelGrid columns="3" rendered="#{testTreeBean.data != null}"> 
        <p:outputLabel value="someLabel1" for="@next" /> 
        <p:inputText value="#{testTreeBean.data.someText1}" required="true" /> 
        <p:message for="@previous" /> 

        <p:outputLabel value="someLabel2" for="@next" /> 
        <p:inputText value="#{testTreeBean.data.someText2}" required="true" /> 
        <p:message for="@previous" /> 
       </p:panelGrid> 

       <h:outputText value="please select a node in the left pane" 
        rendered="#{testTreeBean.data == null}" /> 
      </p:outputPanel> 
     </p:layoutUnit> 
    </p:layout> 
</h:form> 

die Bohne:

@javax.faces.bean.ManagedBean 
@javax.faces.bean.ViewScoped 
public class TestTreeBean implements Serializable 
{ 
    private static final long serialVersionUID = 1L; 
    private TreeNode root; 
    private TreeNode selected; 

    // build a dummy tree...  
    @PostConstruct 
    public void init() 
    { 
     root = new DefaultTreeNode(); 
     for(int i = 0; i < 5; i++) 
     { 
      SomeData data = new SomeData("node " + i, String.valueOf(System.currentTimeMillis())); 
      TreeNode node = new DefaultTreeNode(data, root); 
      for(int j = 0; j < 5; j++) 
      { 
       SomeData subData = new SomeData("subNode " + i + "." + j, String.valueOf(System.currentTimeMillis())); 
       @SuppressWarnings("unused") 
       TreeNode subNode = new DefaultTreeNode(subData, node); 
      } 
     } 
    } 

    // handle selection swap manually 
    public void onSelect(NodeSelectEvent event) 
    { 
     if(selected != null) 
     { 
      selected.setSelected(false); 
     } 

     selected = event.getTreeNode(); 

     if(selected != null) 
     { 
      selected.setSelected(true); 
     } 
    } 

    // shortcut for getting the selected node data 
    public Object getData() 
    { 
     return selected == null ? null : selected.getData(); 
    } 

    public TreeNode getSelected() 
    { 
     return selected; 
    } 

    public TreeNode getRoot() 
    { 
     return root; 
    } 
} 

schließlich für die Vollständigkeit, die Dummy-Datenklasse:

public class SomeData implements Serializable 
{ 
    private String someText1; 
    private String someText2; 

    public SomeData() 
    { 
     super(); 
    } 

    public SomeData(String someText1, String someText2) 
    { 
     super(); 
     this.someText1 = someText1; 
     this.someText2 = someText2; 
    } 

    public String getSomeText1() 
    { 
     return someText1; 
    } 

    public void setSomeText1(String someText1) 
    { 
     this.someText1 = someText1; 
    } 

    public String getSomeText2() 
    { 
     return someText2; 
    } 

    public void setSomeText2(String someText2) 
    { 
     this.someText2 = someText2; 
    } 
} 

Glücklich Gartenarbeit :)