在ui:define中使用p:对话框失去焦点

时间:2015-09-18 13:26:26

标签: jsf jsf-2 primefaces

p:对话与ui:define一起使用是否有任何已知的焦点问题?当我打开通过ui:define。

加载的对话框时,我失去了焦点,因此无法点击

在PrimeFaces演示中,我复制了TreeTable - Basic示例,然后将其包装到ui:define中。代码如下:

testtemplate.xhtml:

<!DOCTYPE html>
<html   xmlns="http://www.w3c.org/1999/xhtml"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:p="http://primefaces.org/ui"
        xmlns:f="http://xmlns.jcp.org/jsf/core"
        xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
    <h:head>
        <link type="text/css" rel="stylesheet" href="/css/style.css" />
    </h:head>
    <h:body>
        <p:layout fullPage="true">

            <p:layoutUnit position="center">
                <ui:insert name="center" />
            </p:layoutUnit>

        </p:layout>
    </h:body>
</html>

basicpacked.xhtml:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    template="/testtemplate.xhtml">

    <ui:define name="center">
        <ui:include src="/basic.xhtml" />
    </ui:define>

</ui:composition>

其他以下组件只是从PrimeFaces演示中复制和粘贴。

basic.xhtml:

<!DOCTYPE html>
<html   xmlns="http://www.w3c.org/1999/xhtml"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:p="http://primefaces.org/ui"
        xmlns:f="http://xmlns.jcp.org/jsf/core"
        xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
    <h:head>
        <link type="text/css" rel="stylesheet" href="/css/style.css" />
    </h:head>
    <h:body>
        <h:form id="form">
            <p:treeTable value="#{ttBasicView.root}" var="document">
                <f:facet name="header">
                    Document Viewer
                </f:facet>
                <p:column headerText="Name">
                    <h:outputText value="#{document.name}" />
                </p:column>
                <p:column headerText="Size">
                    <h:outputText value="#{document.size}" />
                </p:column>
                <p:column headerText="Type">
                    <h:outputText value="#{document.type}" />
                </p:column>
                <p:column style="width:24px">
                    <p:commandLink update=":form:documentPanel" oncomplete="PF('documentDialog').show()" title="View Detail" styleClass="ui-icon ui-icon-search">
                        <f:setPropertyActionListener value="#{document}" target="#{ttBasicView.selectedDocument}" />
                    </p:commandLink>
                </p:column>
            </p:treeTable>

            <p:dialog id="dialog" header="Document Detail" showEffect="fade" widgetVar="documentDialog" modal="true" resizable="false">
                <p:outputPanel id="documentPanel">
                    <p:panelGrid  columns="2" columnClasses="label,value" rendered="#{not empty ttBasicView.selectedDocument}">
                        <h:outputLabel for="name" value="Name: " />
                        <h:outputText id="name" value="#{ttBasicView.selectedDocument.name}" style="font-weight:bold" />

                        <h:outputLabel for="size" value="Size: " />
                        <h:outputText id="size" value="#{ttBasicView.selectedDocument.size}" style="font-weight:bold" />

                        <h:outputLabel for="type" value="Type " />
                        <h:outputText id="type" value="#{ttBasicView.selectedDocument.type}" style="font-weight:bold" />
                    </p:panelGrid>
                </p:outputPanel>
            </p:dialog>
        </h:form>
    </h:body>
</html>

Document.java:

package test;

import java.io.Serializable;

public class Document implements Serializable, Comparable<Document> {

    private String name;

    private String size;

    private String type;

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

    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 String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    //Eclipse Generated hashCode and equals
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result + ((size == null) ? 0 : size.hashCode());
        result = prime * result + ((type == null) ? 0 : type.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Document other = (Document) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        if (size == null) {
            if (other.size != null)
                return false;
        } else if (!size.equals(other.size))
            return false;
        if (type == null) {
            if (other.type != null)
                return false;
        } else if (!type.equals(other.type))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return name;
    }

    public int compareTo(Document document) {
        return this.getName().compareTo(document.getName());
    }
}  

DocumentService.java:

package test;

import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;

@ManagedBean(name = "documentService")
@ApplicationScoped
public class DocumentService {

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

        TreeNode documents = new DefaultTreeNode(new Document("Documents", "-", "Folder"), root);
        TreeNode pictures = new DefaultTreeNode(new Document("Pictures", "-", "Folder"), root);
        TreeNode movies = new DefaultTreeNode(new Document("Movies", "-", "Folder"), root);

        TreeNode work = new DefaultTreeNode(new Document("Work", "-", "Folder"), documents);
        TreeNode primefaces = new DefaultTreeNode(new Document("PrimeFaces", "-", "Folder"), documents);

        //Documents
        TreeNode expenses = new DefaultTreeNode("document", new Document("Expenses.doc", "30 KB", "Word Document"), work);
        TreeNode resume = new DefaultTreeNode("document", new Document("Resume.doc", "10 KB", "Word Document"), work);
        TreeNode refdoc = new DefaultTreeNode("document", new Document("RefDoc.pages", "40 KB", "Pages Document"), primefaces);

        //Pictures
        TreeNode barca = new DefaultTreeNode("picture", new Document("barcelona.jpg", "30 KB", "JPEG Image"), pictures);
        TreeNode primelogo = new DefaultTreeNode("picture", new Document("logo.jpg", "45 KB", "JPEG Image"), pictures);
        TreeNode optimus = new DefaultTreeNode("picture", new Document("optimusprime.png", "96 KB", "PNG Image"), pictures);

        //Movies
        TreeNode pacino = new DefaultTreeNode(new Document("Al Pacino", "-", "Folder"), movies);
        TreeNode deniro = new DefaultTreeNode(new Document("Robert De Niro", "-", "Folder"), movies);

        TreeNode scarface = new DefaultTreeNode("mp3", new Document("Scarface", "15 GB", "Movie File"), pacino);
        TreeNode carlitosWay = new DefaultTreeNode("mp3", new Document("Carlitos' Way", "24 GB", "Movie File"), pacino);

        TreeNode goodfellas = new DefaultTreeNode("mp3", new Document("Goodfellas", "23 GB", "Movie File"), deniro);
        TreeNode untouchables = new DefaultTreeNode("mp3", new Document("Untouchables", "17 GB", "Movie File"), deniro);

        return root;
    }
}

BasicView.java:

package test;

import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import org.primefaces.model.TreeNode;

@ManagedBean(name="ttBasicView")
@ViewScoped
public class BasicView implements Serializable {

    private TreeNode root;

    private Document selectedDocument;

    @ManagedProperty("#{documentService}")
    private DocumentService service;

    @PostConstruct
    public void init() {
        root = service.createDocuments();
    }

    public TreeNode getRoot() {
        return root;
    }

    public void setService(DocumentService service) {
        this.service = service;
    }

    public Document getSelectedDocument() {
        return selectedDocument;
    }

    public void setSelectedDocument(Document selectedDocument) {
        this.selectedDocument = selectedDocument;
    }
}

1 个答案:

答案 0 :(得分:1)

好的,我自己找到了答案,确实存在焦点问题。合并p:layoutUnitp:dialog时会产生问题。 LayoutUnit吞噬其中任何Dialog的焦点。此问题的解决方案是将p:dialog放在p:layoutUnit之外。有一篇简短而精心撰写的文章可以找到here

为了演示目的,我将问题缩小到两个文件。

dialogCall.xhtml:

<ui:composition 
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">
    <h:form id="transactionForm">

        <p:commandLink value="Open Dialog..." update=":transactionForm:editTransactionPanel" oncomplete="PF('editTransactionDialog').show()" />

        <p:dialog id="editTransactionDialogId" header="B Edit Transaction" showEffect="fade" widgetVar="editTransactionDialog" modal="true" resizable="false">
            <p:outputPanel id="editTransactionPanel">
                <h:outputLabel value="Test" />
            </p:outputPanel>
        </p:dialog>

    </h:form>
</ui:composition>

dialogInclude.xhtml(将其称为工作演示):

<!DOCTYPE html>
<html lang="en"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui">
    <h:head />
    <h:body>
        <h:form id="transactionForm">
            <p:layout fullPage="true">

                <p:dialog id="editTransactionDialogId" header="B Edit Transaction" showEffect="fade" widgetVar="editTransactionDialog" modal="true" resizable="false">
                    <p:outputPanel id="editTransactionPanel">
                        <h:outputLabel value="Test" />
                    </p:outputPanel>
                </p:dialog>

                <p:layoutUnit position="center">

                    <p:commandLink value="Open Dialog..." update=":transactionForm:editTransactionPanel" oncomplete="PF('editTransactionDialog').show()" />

                </p:layoutUnit>
            </p:layout>
        </h:form>
    </h:body>
</html>

dialogInclude.xhtml(对于工作演示,请调用此方法):

<!DOCTYPE html>
<html lang="en"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui">
    <h:head />
    <h:body>
        <h:form id="transactionForm">
            <p:layout fullPage="true">

                <p:layoutUnit position="center">

                    <p:dialog id="editTransactionDialogId" header="B Edit Transaction" showEffect="fade" widgetVar="editTransactionDialog" modal="true" resizable="false">
                        <p:outputPanel id="editTransactionPanel">
                            <h:outputLabel value="Test" />
                        </p:outputPanel>
                    </p:dialog>

                    <p:commandLink value="Open Dialog..." update=":transactionForm:editTransactionPanel" oncomplete="PF('editTransactionDialog').show()" />

                </p:layoutUnit>
            </p:layout>
        </h:form>
    </h:body>
</html>