I have problem to display StreamedContent PDF in DocumentViewer from Primefaces Extensions (6.2.9) with PrimeFaces 6.2 and MyFaces 2.2.12. I read the same question, but it's an other situation.
Message: Missing PDF in PrimeFaces Extensions DocumentViewer
This is my xhtml code
<p:commandButton icon="fa fa-print" actionListener="#{bean.onPrerender}" />
Dialog code
<p:dialog id="dvDialog" widgetVar="dv_dialog" dynamic="true" header="Document" width="1200px" height="700px" modal="true">
<pe:documentViewer cache="true" height="500" value="#{bean.content}" download="report.pdf" />
</p:dialog>
This is my java code
private StreamedContent content;
public void onPrerender(ActionEvent actionEvent) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Document document = new Document();
PdfWriter.getInstance(document, out);
document.open();
for (int i = 0; i < 50; i++) {
document.add(
new Paragraph("All work and no play makes Jack a dull boy"));
}
document.close();
// content = new DefaultStreamedContent(
// new ByteArrayInputStream(out.toByteArray()), "application/pdf");
content = new ByteArrayContent(out.toByteArray(), "application/pdf");
} catch (Exception e) {
e.printStackTrace();
}
PrimeFaces.current().executeScript("PF('dv_dialog').show()");
}
public StreamedContent getContent() {
return content;
}
public void setContent(StreamedContent content) {
this.content = content;
}
The error message
PDF.js v1.10.88 (build: c62a1938)
Message: Missing PDF "http://localhost:8080/hoft/javax.faces.resource/dynamiccontent.properties.xhtml?ln=primefaces&v=6.2&pfdrid=1a55ef4c9448951fae5f493579cf80e1&pfdrt=sc&pfdrid_c=true&download=report.pdf".
have anyone clue, what is wrong with my code? it is actually the code in demo showcase Primeface-Extensions with modification.
My project use iframe and the documentviewer will display in a popup dialog. I also tried with #SessionScoped and #ViewScoped, but have no luck.
If I try it in stand alone project, it works (without iframe). May be someone can give clues, how to debug to find the problem.
Please help.... Thank you.
I get error message
pdf.viewer.js.xhtml?ln=primefaces-extensions&v=6.2.9:17581 GET http://localhost:8081/hoft/javax.faces.resource/dynamiccontent.properties.xhtml?ln=primefaces&v=6.2&pfdrid=3c954d24c76c30714a581092c23e1489&pfdrt=sc&pfdrid_c=true&download=report.pdf 404
PDFFetchStreamReader # pdf.viewer.js.xhtml?ln=primefaces-extensions&v=6.2.9:17581
getFullReader # pdf.viewer.js.xhtml?ln=primefaces-extensions&v=6.2.9:17527
(anonymous) # pdf.viewer.js.xhtml?ln=primefaces-extensions&v=6.2.9:4388
(anonymous) # pdf.viewer.js.xhtml?ln=primefaces-extensions&v=6.2.9:1002
resolveCall # pdf.viewer.js.xhtml?ln=primefaces-extensions&v=6.2.9:1001
_createStreamSink # pdf.viewer.js.xhtml?ln=primefaces-extensions&v=6.2.9:1266
MessageHandler._onComObjOnMessage # pdf.viewer.js.xhtml?ln=primefaces-extensions&v=6.2.9:1094
pdf.viewer.js.xhtml?ln=primefaces-extensions&v=6.2.9:19633 Uncaught (in promise) Error: Missing PDF file.
at pdf.viewer.js.xhtml?ln=primefaces-extensions&v=6.2.9:19633
I tried this using:
Java EE 7
GlassFish 4.1.2
PrimeFaces 6.2
PrimeFaces-Extensions 6.2.9
At the bean (class) code:
#ManagedBean
#ApplicationScoped
public class DocumentViewerController {
The scope is #ApplicationScoped. I have a private StreamedContent attribute. And two main public methods:
First method: It's called from actionListener attribute of a p:commandButton. The method receive a parameter (in my case).
public void onPrerender(Tramite tramite) {
tramiteSelected = tramite;
numeroTramite = tramite.getNumero();
contrato = tramite.getContrato();
}
Second method: It's used from a pe:documentViewer inside a dialog component, like this:
<pe:documentViewer id="certificadoViewer"
height="500px"
width="750px"
cache="false"
value="#{documentViewerController.certificado}"
download="certificado_#{documentViewerController.numero}_#{documentViewerController.contrato}.pdf" />
Note: The 2nd method works like a property (getter and setter). THAT'S THE TRICK.
The final code from my project is:
# Bean (DocumentViewerController.java):
package com.epmrpsd.certificado.consulta.controladores;
import com.epmrpsd.certificado.consulta.controladores.util.JsfUtil;
import com.epmrpsd.certificado.consulta.entidades.Tramite;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;
/**
*
* #author pbonilla
*/
#ManagedBean
#ApplicationScoped
public class DocumentViewerController {
private StreamedContent content;
private Integer numeroTramite;
private Integer contrato;
private Tramite tramiteSelected;
// Path where the file exists
private String pdfPathDirectory = "C:\\Users\\<user>\\certificados\\";
public void onPrerender(Tramite tramite) {
tramiteSelected = tramite;
numeroTramite = tramite.getNumero();
contrato = tramite.getContrato();
}
public StreamedContent getCertificado() {
InputStream stream = null;
try {
File file = new File(pdfPathDirectory + numeroTramite + "_" + contrato + ".pdf");
if (file.exists()) {
stream = new FileInputStream(file);
} else {
JsfUtil.addErrorMessage("Error", "No se ha encontrado el archivo");
}
this.content = new DefaultStreamedContent(stream, "application/pdf");
} catch (FileNotFoundException fnfex) {
JsfUtil.addErrorMessage("Error", "No se ha encontrado el archivo. Error: " + fnfex.getMessage());
fnfex.printStackTrace();
} catch (Exception e) {
JsfUtil.addErrorMessage("Error", "Se ha generado un error al cargar el certificado. Error: " + e.getMessage());
e.printStackTrace();
}
return content;
}
public void setCertificado(StreamedContent contenido) {
content = contenido;
}
public Tramite getTramiteSelected() {
return tramiteSelected;
}
public void setTramiteSelected(Tramite tramiteSelected) {
this.tramiteSelected = tramiteSelected;
}
public Integer getNumero() {
return numeroTramite;
}
public void setNumero(Integer numeroTramite) {
this.numeroTramite = numeroTramite;
}
public Integer getContrato() {
return contrato;
}
public void setContrato(Integer contrato) {
this.contrato = contrato;
}
}
# View (index.xhtml):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:pe="http://primefaces.org/ui/extensions">
<h:head>
<title>Consulta de Certificados Digitales</title>
<h:outputStylesheet library="css" name="epmrpsd.css" />
<h:outputStylesheet library="webjars" name="font-awesome/5.5.0/css/all-jsf.css" />
<h:outputStylesheet library="css" name="jsfcrud.css"/>
<h:outputScript library="js" name="jsfcrud.js"/>
<link rel="shortcut icon" type="image/png" href="#{resource['images/logo.png']}"/>
</h:head>
<h:body>
<div id="background" style="position: fixed;">
<h:form id="formCertificados">
<div class="ui-g" style="margin-top: 25px;">
<div class="ui-g-1"></div>
<div class="ui-g-10">
<p:growl id="mensajes" />
<Extra code> ...
<p:outputPanel id="pnlCertificado">
<p:dataTable id="tramitesTable"
value="#{tramiteController.items}"
var="tramite"
rowKey="#{tramite.id}"
selectionMode="single"
selection="#{tramiteController.selected}"
emptyMessage="No se encontraron trámites con los criterios dados"
rows="10"
rowsPerPageTemplate="10,20,30,40,50">
<p:column headerText="Número Trámite" >
<h:outputText value="#{tramite.numero}" />
</p:column>
<p:column headerText="Descripción" >
<h:outputText value="#{tramite.tipo.descripcion}" />
</p:column>
<p:column headerText="Número Contrato" >
<h:outputText value="#{tramite.contrato}" />
</p:column>
<p:column style="text-align: center" headerText="Acción" >
<center>
<p:commandButton id="viewCertificado"
styleClass="ui-priority-primary"
value="Ver certificado"
actionListener="#{documentViewerController.onPrerender(tramite)}"
update=":ViewCertificadoForm"
oncomplete="PF('ViewCertificadoDialog').show()" />
</center>
</p:column>
</p:dataTable>
</p:outputPanel>
</div>
<div class="ui-g-1"></div>
</div>
</h:form>
<ui:include src="ViewCertificado.xhtml"/>
</div>
</h:body>
</html>
And the final component for the view is (ViewCertificado.xhtml):
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:pe="http://primefaces.org/ui/extensions">
<ui:composition>
<p:dialog id="ViewCertificadoDlg"
widgetVar="ViewCertificadoDialog"
modal="true"
resizable="false"
appendTo="#(body)"
header="Certificado #{documentViewerController.contrato}">
<h:form id="ViewCertificadoForm">
<h:panelGroup id="display">
<p:panelGrid columns="1" rendered="#{documentViewerController.tramiteSelected != null}">
<pe:documentViewer id="certificadoViewer"
height="500px"
width="750px"
cache="false"
value="#{documentViewerController.certificado}"
download="certificado_#{documentViewerController.numero}_#{documentViewerController.contrato}.pdf" />
</p:panelGrid>
<p:commandButton value="Cerrar" onclick="ViewCertificadoDialog.hide()"/>
</h:panelGroup>
</h:form>
</p:dialog>
</ui:composition>
</html>
Related
I have a this simplified form to show the challenge:
It is a form with multiple tabs (2 in this MVCE).
My goal is to highlight both fields in case of validation failure (but only for tab it is failing for).
TabView (backing bean)
package betlista.so.pf.findComponent;
import com.sun.faces.component.visit.FullVisitContext;
import org.primefaces.PrimeFaces;
import org.springframework.stereotype.Component;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.component.UIViewRoot;
import javax.faces.component.visit.VisitCallback;
import javax.faces.component.visit.VisitContext;
import javax.faces.component.visit.VisitResult;
import javax.faces.context.FacesContext;
import java.util.LinkedList;
import java.util.List;
#Component
public class TabView {
List<TabData> tabData = new LinkedList<>();
{
tabData.add(new TabData("name 1", "val1-a", null));
tabData.add(new TabData("name b", "val1-b", "val2-b"));
}
public List<TabData> getTabsData() {
return tabData;
}
public void save() {
boolean isValid = isValid();
if (isValid) {
// continue ...
}
}
private boolean isValid() {
boolean isOk = isOk();
if (isOk) {
return true;
}
FacesMessage message = new FacesMessage("Not saved!");
message.setSeverity(FacesMessage.SEVERITY_ERROR);
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, message);
final UIViewRoot viewRoot = context.getViewRoot();
List<UIInput> componentList = new LinkedList<>();
viewRoot.visitTree(new FullVisitContext(context), new VisitCallback() {
#Override
public VisitResult visit(VisitContext context, UIComponent target) {
if (target != null) {
final String id = target.getId();
if ("val1".equals(id) || "val2".equals(id)) {
if (target instanceof UIInput) {
componentList.add((UIInput) target);
}
}
}
return VisitResult.ACCEPT;
}
});
for (UIInput uiInput: componentList) {
uiInput.setValid(false);
}
context.validationFailed();
PrimeFaces.current().ajax().update("form");
final UIComponent val1 = context.getViewRoot().findComponent("val1");
return false;
}
private boolean isOk() {
return false;
}
}
in this simplified version isOk() returns false.
In a validation I know whether data for 1st or second tab is not ok and I'm trying to find a way how to highlight those two fields in tab.
I tried initially context.getViewRoot().findComponent(...), but I'm not able to "find it" (returns null). So to have access to the components I used this:
List<UIInput> componentList = new LinkedList<>();
viewRoot.visitTree(new FullVisitContext(context), new VisitCallback() {
#Override
public VisitResult visit(VisitContext context, UIComponent target) {
if (target != null) {
final String id = target.getId();
if ("val1".equals(id) || "val2".equals(id)) {
if (target instanceof UIInput) {
componentList.add((UIInput) target);
}
}
}
return VisitResult.ACCEPT;
}
});
so I have (in this case) all 4 components (but let say only those for first tab are invalid).
I'm trying to find a way how to identified which component belong to which tab (not sure whether to rely on a an order in list).
I was trying dynamic ID's, but it's not working, e.g. I added tab name (tabName)as attribute and used
<p:inputText id="#{cc.attr.tabName}-val2" ... />
I found no way how to add some custom flag/attribute whatever to be able to link component to a tab.
I was reading that ID can be dynamic once I'd use EL custom function (I mean I can use concatenation), but I was not able to find a resource describing it (I have no web.xml).
Code is available in GitHub.
myTab.xhtml (custom component)
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.org/ui"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface>
<composite:attribute name="data" required="true" type="betlista.so.pf.findComponent.TabData" />
</composite:interface>
<composite:implementation>
<div class="ui-g">
<div class="ui-g-12">
<div class="ui-g-6">
<p:outputLabel value="Val 1:"/>
</div>
<div class="ui-g-6">
<p:inputText id="val1" value="#{cc.attrs.data.val1}" widgetVar="#{cc.attrs.data.tabName}-val1"/>
</div>
</div>
<div class="ui-g-12">
<div class="ui-g-6">
<p:outputLabel value="Val 2:"/>
</div>
<div class="ui-g-6">
<p:inputText id="val2" readonly="true" value="#{cc.attrs.data.val2}" widgetVar="#{cc.attrs.data.tabName}-val2"/>
</div>
</div>
</div>
</composite:implementation>
</html>
page.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!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:p="http://primefaces.org/ui"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:comp="http://xmlns.jcp.org/jsf/composite/comp">
<h:head>
<h:outputScript library="webjars" name="font-awesome/5.5.0/js/all.js"/>
</h:head>
<h:body styleClass="mainBody">
<h:form id="form">
<p:tabView id="tabView" value="#{tabView.tabsData}" var="tabVar">
<p:tab id="tab" title="#{tabVar.tabName}">
<comp:myTab data="#{tabVar}" />
</p:tab>
</p:tabView>
<p:commandButton value="Save" action="#{tabView.save()}" process="#form" update="#form" />
<p:growl id="growl" life="3000"/>
</h:form>
</h:body>
</html>
I got very confused by debugger...
The simplest solution is to add label like this:
<p:inputText id="val1" value="#{cc.attrs.data.val1}" label="someLabel1" />
...what I missed earlier is, that label is not a field therefor it was difficult to find it, it is available under stateHelper:
Probably better solution (despite label I cannot see in generated HTML) is to use custom attribute like this (I'd bet I tried that as well, apparently not):
<p:inputText id="val2" readonly="true" value="#{cc.attrs.data.val2}">
<f:attribute name="someAttribute" value="value2" />
</p:inputText>
and it's easily accessible:
Hi all I'm new to Java development, and I'm really confused about this.
im doing an web app and my problem is how to import file and put it in i directory. i have created the xhtml file :
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:jsf="http://xmlns.jcp.org/jsf"
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
xmlns:p="http://primefaces.org/ui"
template="/WEB-INF/template/template.xhtml">
<ui:define name="title">2G</ui:define>
<ui:define name="content">
<h:form>
<h1> <font color="orange" size="7" > 2G</font></h1>
</h:form>
<h2 >Choose 2 files </h2>
<h:form>
<p:fileUpload fileUploadListener="#{import_2G.save()}"
mode="advanced" dragDropSupport="true" update="messages"
sizeLimit="100000000000" allowTypes="/(\.|\/)(xls)$/" />
<p:growl id="messages" showDetail="true" />
</h:form>
</ui:define>
</ui:composition>
and this is the bean file :
#ManagedBean
#RequestScoped
public class Import_2G {
public Import_2G() { }
#EJB
private GestionCellRef2GLocal gestionCellRef2GLocal;
private UploadedFile uploadedFile;
public void save() throws IOException {
GestionCellRef2GRemote t = null;
Path folder = Paths.get("C:\\Upload");
String filename = FilenameUtils.getBaseName(uploadedFile.getFileName());
String extension = FilenameUtils.getExtension(uploadedFile.getFileName());
Path file = Files.createTempFile(folder, filename + "-", "." + extension);
if (file != null) {
FacesMessage message = new FacesMessage("Succesful", file.getFileName() + " was uploaded.");
FacesContext.getCurrentInstance().addMessage(null, message);
}
try (InputStream input = uploadedFile.getInputstream()) {
Files.copy(input, folder, StandardCopyOption.REPLACE_EXISTING);
}
}
}
any help guys ?
First start reading about naming conventions in Java. If you not respect the naming conventions and use underscores, scores and things like that, you will have some troubles.
Second, you forgot the enctype. When you wanna upload binary data, you must have put the attribute: enctype="multipart/form-data". Let's build a file upload.
First your form:
<h:form enctype="multipart/form-data">
<p:fileUpload value="#{import2G.file}"
mode="advanced" dragDropSupport="true"
sizeLimit="100000000"
allowTypes="/(\.|\/)(xls)$/"
update="messages"
fileUploadListener="#{import2G.save}" />
</h:form>
<p:growl id="messages" showDetail="true" />
And your backing bean:
public void save(FileUploadEvent e) {
FileUpload file = event.getFile();
String fileName = file.getFileName();
String contentType = file.getContentType();
byte[] content = file.getContents();
saveFile(content);
}
private void saveFile(byte[] data) {
FileOutputStream fos = new FileOutputStream(DIR_NAME);
fos.write(data);
fos.close();
}
Look the listener in the form; use import2G.save instead import2G.save(), this because a FileUpload parameter is passed to the listener in runtime.
The following is my code snippet in my abc.xhtml page :
<p:panelGrid id="pnlGrd_numOfLbl"
style="align:center; width:100%;" cellpadding="5">
<c:forEach var="i" begin="1" end="${specificationMB.numOfLbl}" >
<p:row>
<p:column width="50%">
<p:outputLabel value="Label ${i}" />
</p:column>
<p:column width="50%">
<p:inputText id="inputTxt_${i}" style="width:150px;" />
</p:column>
</p:row>
</c:forEach>
</panelGrid>
This is my panelGrid I am generating inputText dynamically depending
numOfLable. After generation say 2 will be generate user will add some
text to each inputText so my Question is How can I get value of dyanamically
generated inputbox.
Thanks.
This can easily be done with basics of JSF and primefaces. Here is full working Example:
XHTML File (I am using p:panel and ui:repeater)
<!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:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<f:view contentType="text/html">
<h:head>
<link rel=" stylesheet" type="text/css" href="css/style.css"></link>
</h:head>
<h:body>
<h:form>
<p:panel header="Panel">
<ui:repeat var="lbl" value="#{tBean.lblClassess}">
<p:row>
<p:column width="50%">
<p:outputLabel value="#{lbl.lbl} :" />
</p:column>
<p:column width="50%">
<p:inputText value="#{lbl.value}" />
</p:column>
</p:row>
</ui:repeat>
</p:panel>
<p:commandButton actionListener="#{tBean.submit}" value="Subtmi" update="values"></p:commandButton>
<p:outputPanel id="values">
<ui:repeat var="lbl" value="#{tBean.lblClassess}">
<p:row>
<p:column width="50%">
<p:outputLabel value="#{lbl.value} :" />
</p:column>
</p:row>
</ui:repeat>
</p:outputPanel>
</h:form>
</h:body>
</f:view>
<body>
</body>
</html>
Managed Bean
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;
#ManagedBean(name = "tBean")
#ViewScoped
public class TestBean {
private List<LabelClass> lblClassess;
public TestBean() {
lblClassess = new ArrayList<LabelClass>();
lblClassess.add(new LabelClass("First Label", ""));
lblClassess.add(new LabelClass("Second Label", ""));
lblClassess.add(new LabelClass("Third Label", ""));
}
public void submit(ActionEvent e) {
for (LabelClass lbl : lblClassess) {
System.out.println(lbl.getValue());
}
}
public List<LabelClass> getLblClassess() {
return lblClassess;
}
public void setLblClassess(List<LabelClass> lblClassess) {
this.lblClassess = lblClassess;
}
}
Label Class
public class LabelClass {
private String lbl;
private String value;
public LabelClass(String lbl, String value) {
super();
this.lbl = lbl;
this.value = value;
}
public String getLbl() {
return lbl;
}
public void setLbl(String lbl) {
this.lbl = lbl;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
Output
In order to get the values of your dynamically generated inputTexts. You may do something like this.
<input type="text" id="inputTxt_${i}" name="inputTxt_${i}" style="width:150px;" />
Then retrieve the text value by using this code in servlet
String inputText1 = request.getParameter("nameOfFirstInputText");
You can bind the value into the bean value object:
<input type="text" id="inputTxt_${i}" value="${specificationMB.getValue(i).value}" />
I´ve a data table with primefaces, that has a filter column. So when I access my xhtml it doesn´t show the populated data till I enter values in the filter. Or if I take out the filter it shows the populated data.
Here is my managed bean code:
#ManagedBean(name="estatusAdminMB")
#ViewScoped
public class EstatusAdminManagedBean implements Serializable {
private IEstatusService estatusService;
private List<MapeoEstatusDTO> mapeoEstatusList = new ArrayList<MapeoEstatusDTO>();
private List<MapeoEstatusDTO> filteredPorMapeoEstatusDTO = new ArrayList<MapeoEstatusDTO>();
private MapeoEstatusDTO selectedMapeoEstatus = new MapeoEstatusDTO();
/**
* Creates a new instance of EstatusAdminManagedBean
*/
public EstatusAdminManagedBean() {
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
mensajeriasService = (IMensajeriasService) context.getBean("MensajeriasService");
originadoresService = (IOriginadoresService) context.getBean("OriginadoresService");
estatusService = (IEstatusService) context.getBean("EstatusService");
populateMapeo();
}
private void populateMapeo() {
try {
mapeoEstatusList.clear();
mapeoEstatusList.addAll(estatusService.getMapeoEstatus());
System.out.println(mapeoEstatusList.size());
} catch (ServiceException ex) {
Logger.getLogger(EstatusAdminManagedBean.class.getName()).log(Level.SEVERE, null, ex);
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error",
"Ocurrió un error al cargar el mapeo."));
}
}
public void onRowSelect(SelectEvent event) {
FacesMessage msg = new FacesMessage("Mapeo Seleccionado", ((MapeoEstatusDTO) event.getObject()).getCodigo().getDescripcion());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public IEstatusService getEstatusService() {
return estatusService;
}
public void setEstatusService(IEstatusService estatusService) {
this.estatusService = estatusService;
}
public MapeoEstatusDTO getSelectedMapeoEstatus() {
return selectedMapeoEstatus;
}
public void setSelectedMapeoEstatus(MapeoEstatusDTO selectedMapeoEstatus) {
this.selectedMapeoEstatus = selectedMapeoEstatus;
}
public List<MapeoEstatusDTO> getFilteredPorMapeoEstatusDTO() {
return filteredPorMapeoEstatusDTO;
}
public void setFilteredPorMapeoEstatusDTO(List<MapeoEstatusDTO> filteredPorMapeoEstatusDTO) {
this.filteredPorMapeoEstatusDTO = filteredPorMapeoEstatusDTO;
}
}
and here is my xhtml code:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en-US"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
>
<h:body>
<ui:composition template="../template/Layout.xhtml">
<ui:define name="content">
<div class="frame">
<h:form id="mapeoForm">
<p:growl id="growl" showDetail="true" />
<p:spacer> </p:spacer>
<div style="text-align:center">
<h:outputText value="Mapeo de Estatus" />
</div>
<p:spacer> </p:spacer>
<div align="center">
<p:dataTable id="mapeoTable" var="c" value="#{estatusAdminMB.mapeoEstatusList}" paginator="true" rows="10"
selection="#{estatusAdminMB.selectedMapeoEstatus}" selectionMode="single"
filteredValue="#{estatusAdminMB.filteredPorMapeoEstatusDTO}"
emptyMessage="No hay registros" rowKey="#{c.idMapeo}" rowIndexVar="rowIndex">
<p:ajax event="rowSelect" listener="#{estatusAdminMB.onRowSelect}"
update=":mapeoForm:dialogUpdate, :mapeoForm:growl"
oncomplete="dialogUpdateW.show()"/>
<f:facet name="header">
Haz clic sobre cualquier registro para editar
</f:facet>
<p:column id="originadorColumn" filterBy="#{c.originadorDTO.nombre}"
headerText="Originador" filterMatchMode="contains">
<h:outputText value="#{c.originadorDTO.nombre}" />
</p:column>
<p:column headerText="Descripción Estatus Folio">
#{c.estatus.descripcion}
</p:column>
<p:column headerText="Descripción Tipificación">
#{c.tipificacion.DESCRIPCION_TIPIFICACION}
</p:column>
<p:column headerText="Descripción Estatus Geotracking">
#{c.codigo.descripcion}
</p:column>
</p:dataTable>
<p:dialog maximizable="true" minHeight="400" minWidth="400" style="overflow-y:auto; top:5px; bottom:5px;"
id="dialogUpdate" header="Editar Mapeo" widgetVar="dialogUpdateW" resizable="false"
showEffect="fade" hideEffect="explode">
<h:form id="updateMapForm">
<table id="display">
</table>
</h:form>
</p:dialog>
</div>
</h:form>
</div>
</ui:define>
</ui:composition>
</h:body>
</html>
Why am I not getting the data from the very begging???
Thanks for the help.
I have a web page which is including a sub-page that changes according to the element I choose in the primefaces dock menu (ui:include). Some sub pages include a custom composite component I implemented. The first page the web app shows has all his listeners working correctly. When I change sub-page via the dock menu, VideoStatusTable's listeners (composite component's listeners) won't work until I refresh the page in the browser (with F5) OR if I select the page again in the dock menu.
Here is the main page holding the dock menu.
<h:body style="width:100%;height:100%;position:relative;">
<h:panelGroup id="contentPanelGroup">
<ui:include src="#{Template.currentView.view}" />
</h:panelGroup>
<div id="header-wrapper">
<h:form id="headerForm" styleClass="titleSize" style="position:relative;height:100%;width:100%;">
</h:form>
</div>
<div id="footer-wrapper">
<h:form id="footerForm">
<h:graphicImage name="ctec.png" library="images" style="position:absolute;left:30px;bottom:10px;"/>
<p:dock>
<p:menuitem value="#{msgs.ViewEnum_TRANSFER}" icon="#{resource['images:hard-drive-download.png']}" action="#{Template.setWindow( 0 )}" update=":contentPanelGroup :headerForm :msgsArea" />
<p:menuitem value="#{msgs.ViewEnum_STATUS}" icon="#{resource['images:gears.png']}" action="#{Template.setWindow( 1 )}" update=":contentPanelGroup :headerForm :msgsArea"/>
<p:menuitem value="#{msgs.ViewEnum_ORGANIZATION}" icon="#{resource['images:folder.png']}" action="#{Template.setWindow( 2 )}" update=":contentPanelGroup :headerForm :msgsArea" />
<p:menuitem value="#{msgs.ViewEnum_VALIDATION}" icon="#{resource['images:chart-bar.png']}" action="#{Template.setWindow( 3 )}" update=":contentPanelGroup :headerForm :msgsArea" />
<p:menuitem value="#{msgs.ViewEnum_REPORT}" icon="#{resource['images:documents.png']}" action="#{Template.setWindow( 4 )}" update=":contentPanelGroup :headerForm :msgsArea" />
</p:dock>
</h:form>
</div>
<p:growl id="msgsArea" life="5000"/>
<ui:debug/>
</h:body>
TemplateBean looks like this:
#Named(value="Template") // CDI
#SessionScoped // CDI
public class TemplateBean implements Serializable {
private static final long serialVersionUID = -8230221469543897876L;
private Integer window = 2;
// Some getters ...
// Get Window
public Integer getWindow() {
return window;
}
public void setWindow( Integer window ) {
this.window = window;
FacesContext.getCurrentInstance().addMessage(
null,
new FacesMessage( FacesMessage.SEVERITY_INFO, getCurrentViewTitle(), getCurrentViewTitle() )
);
FacesContext.getCurrentInstance().addMessage(
null,
new FacesMessage( FacesMessage.SEVERITY_ERROR, getCurrentViewTitle(), getCurrentViewTitle() )
);
}
}
ViewEnum (which is used for choosing which view is shown):
public enum ViewEnum {
TRANSFER ( "hard-drive-download.png", "/private/VideoTransfer.xhtml" ),
STATUS ( "gears.png", "/private/ProcessStatus.xhtml" ),
ORGANIZATION ( "folder.png", "/private/DataOrganization.xhtml" ),
VALIDATION ( "chart-bar.png", "/private/ProcessValidation.xhtml" ),
REPORT ( "documents.png", "/private/ReportGeneration.xhtml" ),
;
private String iconFileName;
private String view;
private StreamedContent icon = null;
private ViewEnum( String iconFileName, String view ) {
this.iconFileName = iconFileName;
this.view = view;
}
public String getIconFileName() {
return this.iconFileName;
}
public String getTranslationKey() {
return "ViewEnum_" + this.toString();
}
public StreamedContent getIcon() {
// irrelevant code ...
}
public String getView() {
return this.view;
}
}
The custom component:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:composite="http://java.sun.com/jsf/composite"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:cmpnt="http://java.sun.com/jsf/composite/component">
<composite:interface componentType="videoStatusTableComponent">
<composite:attribute name="value" required="true"/>
<composite:attribute name="selection" required="true"/>
<composite:attribute name="selectionListener" required="true" method-signature="void listener(org.primefaces.event.SelectEvent)"/>
<composite:attribute name="selectionUpdate" required="false" default="#this"/>
<composite:attribute name="refreshListener" required="true" method-signature="void action()"/>
</composite:interface>
<composite:implementation>
<p:dataTable id="cmpntVideoList" var="video" value="#{cc.attrs.value}" rowKey="#{video.key}" style="clear:both;"
selection="#{cc.attrs.selection}" selectionMode="single" emptyMessage="#{cc.attrs.emptyValueListMsg}">
<p:ajax event="rowSelect" listener="${cc.selectionListener}" process="#this" update="${cc.attrs.selectionUpdate}"/>
<composite:insertFacet name="header"/>
<p:column headerText="Test">
#{video.humanReadableVideoId}
</p:column>
<f:facet name="footer">
<h:commandLink action="${cc.attrs.refreshListener}" style="float:right;">
<h:graphicImage library="images" name="button-rotate-cw_16.png"/>
<f:ajax render="cmpntVideoList" execute="#this"/>
</h:commandLink>
</f:facet>
</p:dataTable>
</composite:implementation>
</html>
#FacesComponent( "videoStatusTableComponent" )
public class VideoStatusTableComponent extends UINamingContainer {
public void selectionListener( org.primefaces.event.SelectEvent event ) {
FacesContext context = FacesContext.getCurrentInstance();
MethodExpression ajaxEventListener = (MethodExpression) getAttributes().get( "selectionListener" );
ajaxEventListener.invoke( context.getELContext(), new Object[] { event } );
}
}
The first sub-page (and its Bean), which includes the component:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:cmpnt="http://java.sun.com/jsf/composite/component">
<ui:composition>
<h:form id="contentForm">
<cmpnt:videoStatusTable id="transferingVideoList"
value="#{videoTransfer.tableModel}"
selection="#{videoTransfer.selectedTableReadyNotCompletelyTranferedVideo}"
selectionListener="${videoTransfer.onVideoSelection}"
selectionUpdate=":msgsArea"
refreshListener="${processStatus.refreshUncompletedVideos}"
>
</cmpnt:videoStatusTable>
</h:form>
</ui:composition>
</html>
#Named( value="videoTransfer" ) // CDI
#SessionScoped // CDI
public class VideoTransferBean implements Serializable {
private static final long serialVersionUID = -9019701853654362317L;
private VideoStatus selectedTableReadyNotCompletelyTranferedVideo;
private VideoStatusTableModel tableModel;
private List<Video> currentlyTranferingVideos = null;
// Other irrelevant code...
public VideoStatusTableModel getTableModel() {
return tableModel;
}
public void setSelectedTableReadyNotCompletelyTranferedVideo(VideoStatus selectedTableReadyNotCompletelyTranferedVideo) {
this.selectedTableReadyNotCompletelyTranferedVideo = selectedTableReadyNotCompletelyTranferedVideo;
}
public VideoStatus getSelectedTableReadyNotCompletelyTranferedVideo() {
return selectedTableReadyNotCompletelyTranferedVideo;
}
public void onVideoSelection( SelectEvent event ) {
FacesMessage msg = new FacesMessage( "Video Selected: " + ((VideoStatus) event.getObject()).getHumanReadableVideoId() );
FacesContext.getCurrentInstance().addMessage( null, msg );
}
}
Another sub-page that includes the same component (here the listeners don't work until I reload the page (via the dock or if I hit F5)):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:cmpnt="http://java.sun.com/jsf/composite/component"
>
<ui:composition>
<h:form id="contentForm">
<cmpnt:videoStatusTable
id="orphanVideoList"
value="#{DataOrganization.videoTableModel}"
selection="#{DataOrganization.selectedVideo}"
selectionListener="#{DataOrganization.onOrphanVideoSelection}"
selectionUpdate=":msgsArea"
refreshListener="#{DataOrganization.refreshOrphanVideos}"
/>
</h:form>
</ui:composition>
</html>
#Named(value="DataOrganization") // CDI
#SessionScoped // CDI
public class DataOrganizationBean implements Serializable, MonitoredBean {
private static final long serialVersionUID = 1686055743669628317L;
// Constants and variables
#EJB
private DataOrganizationEJB controller;
private Integer companyEntityID = null;
private VideoStatusTableModel videoTableModel;
private VideoStatus selectedVideo;
public void refreshOrphanVideos() {
setOrphanVideos(controller.getOrphanVideos(getCompanyEntityID()));
}
public void onOrphanVideoSelection(org.primefaces.event.SelectEvent event) {
this.setSelectedVideo(((VideoStatus) event.getObject()));
}
public VideoStatusTableModel getVideoTableModel() {
return videoTableModel;
}
public VideoStatus getSelectedVideo() {
return selectedVideo;
}
public void setSelectedVideo(VideoStatus selectedVideo) {
this.selectedVideo = selectedVideo;
}
}
Does anyone have a clue on how to avoid reloading the web page to get the component's listeners to work?
In web XML I have set the STATE_SAVING_METHOD to client.
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
N.B.:
I use JSF 2.0, Glassfish 3.1.2.2, Primefaces 3.4.
Thanks!
**** UPDATED ****
I found out the problem really comes from the components. If I use the exact same code without the use of components everything works fine.
Did anyone encountered this problem?
This looks very similar to some behaviors I have noticed and this issue found at: http://java.net/jira/browse/JAVASERVERFACES-2050
I had the same issue but you really should avoid doing this! You should do less generic components. It worked for me.