Форма проверки дерева JSF на узле изменения

jsf primefaces tree

408 просмотра

1 ответ

43 Репутация автора

У меня есть класс Document для создания дерева со списком объектов документа.

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;
  }
}  

Также у меня есть класс Field для хранения соответствующей информации в документах.

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;
}
} 

Мой ManagedBean создает дерево с некоторыми документами и сохраняет некоторые данные для каждого документа. Когда я выбираю узел дерева, он показывает динамическую форму с каждым полем и входами для ввода некоторого значения.

@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;
}
}

Мой JSF выглядит как

<!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>

Когда я нажимаю кнопку отправки, значения отправляются и сохраняются в каждом поле, также запускаются проверки. Но мне действительно нужно удалить кнопку отправки и проверить форму, когда я потерял фокус на каждом узле. Например, если я нахожусь в первом узле, проверьте форму только тогда, когда я потерял фокус, но если проверка формы не удалась, мне нужно остаться в этом узле.

Я действительно ценю любую помощь, которую вы мне можете оказать. Заранее большое спасибо.

Автор: user1217167 Источник Размещён: 19.07.2016 12:01

Ответы (1)


0 плюса

5873 Репутация автора

Я хотел реализовать аналогичную точку зрения, и мне потребовалось довольно много времени, чтобы понять.

Трюк является не объявить selectionатрибут <p:tree, но только selectionModeи управлять выбором только со слушателем, вручную.

Это заставляет выбор поменяться местами INVOKE_APPLICATIONвместо фазы UPDATE_MODEL_VALUES, сохраняя ссылки правой панели в выражениях значений.

Кроме того, проверка происходит перед заменой выбора и, в случае неудачи, замена выбора предотвращается.

Я думаю, что это именно то, что вы ищете:

<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>

Боб:

@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;
    }
}

наконец, для полноты, фиктивный класс данных:

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;
    }
}

Счастливого садоводства :)

Автор: Michele Mariotti Размещён: 02.06.2017 09:36
Вопросы из категории :
32x32