I have a simple JSF application with a form, one of the controls being a selectOneListbox:
<h:selectOneListbox style="width: 231px; height: 27px;position:absolute;left:400px;top:325px;" value="#{PatientsSearch.selectedDoctor}">
<f:selectItems value="#{PatientsSearch.doctors}" var="d" itemLabel="#{d.name}" itemValue="#{d.name}" />
</h:selectOneListbox>
When I run the application, I can see the list being populated (i.e. PatientsSearch.doctors is correctly retrieved), so I can choose one item from the selectOneListbox. After I choose the desired item, nothing works any more on that form. All the other buttons seem to be idle, they don't react to clicks any more. If however nothing is selected from the selectOneListbox, all buttons works as expected (i.e. they trigger their callbacks in the managed beans).
I debugged the application and noticed that indeed, after selecting an item in the list, the callbacks of the other buttons on the form don't get triggered when clicking them.
Also in the debugger I never see setSelectedDoctor() being called (see the snippet above) as I expected.
I'm using Mojarra 2.0.1 implementation of JSF.
What am I missing here ?
Update: This is the entire form:
<h:form style="width: 876px; background-color: #FED981; padding-left: 60px; padding-top: 30px; margin-left: 80px; margin-top: 40px; color: #804000; font-style: normal; font-family: Verdana, Arial, Sans-Serif">
<h:outputLabel style="position:absolute;left:200px;top:100px;" value="New appointment:"></h:outputLabel>
<br>
<br>
<h:inputText style="width: 259px;position:absolute;left:200px;top:120px;" binding="#{PatientsSearch.inputText1}" valueChangeListener="#{PatientsSearch.lookForName}" immediate="true" id="inputText1" />
<h:commandButton value ="Search patients by name:" style="width: 173px;position:absolute;left:465px;top:120px;" action="#{PatientsSearch.getPatientsByName}">
<f:param name="day" value="#{request.getParameter('day')}" />
<f:param name="month" value="#{request.getParameter('month')}" />
<f:param name="year" value="#{request.getParameter('year')}" />
</h:commandButton>
<br>
<h:panelGroup id="pn_DETAILS_GRP" style="overflow:auto;position:absolute;top:155px;left:200px;width:300px;height:150px;solid black">
<h:dataTable id="tb_USER_DETAILS" border="1" var="patient" value="#{PatientsSearch.patients}" style="width:300px;height:150px" rowClasses="oddRow, evenRow">
<h:column id="name">
<f:facet name="header">
<h:outputText value="Name" style="font-size:10pt"/>
</f:facet>
<h:outputText value="#{patient.name}" style="font-size:8pt"/>
</h:column>
<h:column id="phone">
<f:facet name="header">
<h:outputText value="Phone" style="font-size:10pt"/>
</f:facet>
<h:outputText value="#{patient.phoneMobile}" style="font-size:8pt"/>
</h:column>
<h:column>
<h:inputHidden id="patientId" value="#{patient.id}" />
</h:column>
</h:dataTable>
</h:panelGroup>
<h:inputHidden id="testId" />
<br><br><br>
<h:outputLabel value="Choose doctor:" style="width: 200px;position:absolute;left:200px;top:325px;"></h:outputLabel>
<h:selectOneListbox style="width: 231px; height: 27px;position:absolute;left:400px;top:325px;" value="#{PatientsSearch.selectedDoctor}" size="1">
<f:selectItems value="#{PatientsSearch.doctors}" var="d"
itemLabel="#{d.name}" itemValue="#{d.name}" />
</h:selectOneListbox>
<br><br><br>
<h:commandButton value="Schedule" style="position:absolute;left:200px;top:430px;" action="#{PatientsSearch.scheduleAppointment}">
<f:param name="day" value="#{request.getParameter('day')}" />
<f:param name="month" value="#{request.getParameter('month')}" />
<f:param name="year" value="#{request.getParameter('year')}" />
</h:commandButton>
</h:form>
As per comments, the problem is that the type for #{d.name} is not the same as #{PatientsSearch.selectedDoctor}. In such situation there is two solutions :
Keep everything you have the same, change the #{PatientsSearch.selectedDoctor} getter/setter to a String type.
Create a list of SelectItem in the backing bean and change the #{PatientsSearch.selectedDoctor} getter/setter to a String type. You will also be able to remove itemValue and itemLabel since the backing bean already provide ready Object for list components.
Change the itemValue attribute from the f:selectItems and create a custom converter
I prefer the second since it separate better the view. It should be changed like this :
<h:selectOneListbox style="width: 231px; height: 27px;position:absolute;left:400px;top:325px;" value="#{PatientsSearch.selectedDoctor}" size="1">
<f:selectItems value="#{PatientsSearch.doctors}" var="d" itemLabel="#{d.name}" />
<f:converter convertId="doctorConverter" />
</h:selectOneListbox>
Now for the converter, you can start it like this :
#FacesConverter(value="doctorConverter")
public class DoctorConverter implements Converter {
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
// Your code, select doctor from value ID for example.
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
// Your code, return doctor ID from value.
}
}
Related
This question already has answers here:
Display dynamic image from database or remote source with p:graphicImage and StreamedContent
(4 answers)
Backing beans (#ManagedBean) or CDI Beans (#Named)?
(5 answers)
Closed 2 years ago.
I'm relatively new to JSF and Primefaces.
I'm trying to build a document viewer that would display tiff, jpeg and pdf.
My UI has a left and a right layout.
Left layout contains a vertical grid of thumbnails of the docs.
User clicks on a thumbnail, and the right layout displays the doc (either via a p:graphicImage or via a p:documentViewer, depending on the thumbnail clicked).
For tiffs, I'm converting the image into PNG and then displaying (both, for the thumbnail and the main display).
For multi-page tiff files, I show only the first page as the left side thumbnail...and for the main display, I give Next and Previous buttons to navigate through the pages. The UI is something like this:
The problem:
When I click on the thumbnails, the backing method gets invoked twice as expected (the second call returning the StreamedContent with the actual data).
However, when I click the Prev and Next buttons, the same backing method is getting called only once -- just for phaseid=RENDER_RESPONSE.
(eventually, this causes the bean method to return only an empty StreamedContent and not one carrying the actual image data...so I don't get to see the other pages of the tiff)
The form:
<h:form id="mainform">
<p:layout fullPage="true" style="width:100%;height:100%">
<p:layoutUnit position="west" style="width:15%;overflow:scroll;" resizable="true">
<p:panelGrid header="Thumbnails" columns="1" class="thumbcell" >
<p:repeat value="#{viewerController.docIds}" var="docId">
<p:panelGrid style="padding:0px !important;" columns="1" rendered="#{docId.contains('img')}" >
<p:commandLink update=":mainform:renderpanel" action="#{viewerController.setSelectedDocId(docId)}">
<p:graphicImage value="#{viewerController.imageDocumentStream}" style="height: 100px; width: 90px; border: none !important; padding:0px;background: lightgrey;"
alt="#{viewerController.getDocumentName(docId)}">
<f:param name="id" value="#{docId}" />
</p:graphicImage>
</p:commandLink>
<p:outputLabel value="#{viewerController.getDocumentName(docId)}"/>
</p:panelGrid>
<p:panelGrid style="padding:0px !important;" columns="1" rendered="#{docId.contains('tif')}">
<p:commandLink update=":mainform:renderpanel" action="#{viewerController.setSelectedDocId(docId)}">
<p:graphicImage value="#{viewerController.tifDocumentStream}" style="height: 100px; width: 90px; border: none !important; padding:0px;background: lightgrey;"
alt="#{viewerController.getDocumentName(docId)}">
<f:param name="id" value="#{docId}" />
<f:param name="forThumbnail" value="true" />
</p:graphicImage>
</p:commandLink>
<p:outputLabel value="#{viewerController.getDocumentName(docId)}"/>
</p:panelGrid>
<p:panelGrid style="padding:0px !important;" columns="1" rendered="#{docId.contains('pdf')}">
<p:commandLink update=":mainform:renderpanel" action="#{viewerController.setSelectedDocId(docId)}">
<p:graphicImage value="#{viewerController.pdfFirstPageDocumentStream}" style="height: 100px; width: 90px; border: none !important; padding:0px;background: lightgrey;"
alt="#{viewerController.getDocumentName(docId)}">
<f:param name="id" value="#{docId}" />
</p:graphicImage>
</p:commandLink>
<p:outputLabel value="#{viewerController.getDocumentName(docId)}"/>
</p:panelGrid>
</p:repeat>
</p:panelGrid>
</p:layoutUnit>
<p:layoutUnit position="center" style="width:85%;">
<p:panel id="renderpanel">
<p:panelGrid style="padding:0px !important;" columns="1" rendered="#{viewerController.currentDocId.contains('tif')}">
<p:outputLabel value="#{viewerController.getDocumentName(viewerController.currentDocId)}"/>
<p:panelGrid style="padding:0px !important;" columns="3" id="tifPanelGrid">
<p:commandButton update=":mainform:renderpanel" action="#{viewerController.navigateTif('prev', viewerController.currentDocId)}"
id="prevButton" value="Prev" title="Previous page" disabled="#{viewerController.prevButtonDisable}"/>
<p:graphicImage rendered="#{viewerController.render}" id="tifPanel" value="#{viewerController.tifDocumentStream}" style="height: 600px; width: 800px; border: none !important; padding:0px;background: lightgrey;"
alt="#{viewerController.getDocumentName(viewerController.currentDocId)}">
<f:param name="id" value="#{viewerController.currentDocId}" />
<f:param name="forThumbnail" value="false" />
</p:graphicImage>
<p:commandButton update=":mainform:renderpanel" action="#{viewerController.navigateTif('next', viewerController.currentDocId)}"
id="nextButton" value="Next" title="Next page" disabled="#{viewerController.nextButtonDisable}"/>
</p:panelGrid>
</p:panelGrid>
<p:panelGrid style="padding:0px !important;" columns="1" rendered="#{viewerController.currentDocId.contains('img')}">
<p:outputLabel value="#{viewerController.getDocumentName(viewerController.currentDocId)}"/>
<p:graphicImage value="#{viewerController.imageDocumentStream}" style="height: 600px; width: 800px; border: none !important; padding:0px;background: lightgrey;"
alt="#{viewerController.getDocumentName(viewerController.currentDocId)}">
<f:param name="id" value="#{viewerController.currentDocId}" />
</p:graphicImage>
</p:panelGrid>
<p:panelGrid style="padding:0px !important;" columns="1" rendered="#{viewerController.currentDocId.contains('pdf')}">
<p:outputLabel value="#{viewerController.getDocumentName(viewerController.currentDocId)}"/>
<pe:documentViewer height="600" width="800" value="#{viewerController.pdfDocumentStream}" >
<f:param name="id" value="#{viewerController.currentDocId}" />
</pe:documentViewer>
</p:panelGrid>
</p:panel>
</p:layoutUnit>
</p:layout>
</h:form>
The controller class is annotated with these two:
javax.annotation.ManagedBean
javax.enterprise.context.SessionScoped
The backing method in the controller class, that is not getting invoked twice:
public StreamedContent getTifDocumentStream() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE ) {
return new DefaultStreamedContent();
} else {
String id = context.getExternalContext().getRequestParameterMap().get("id");
String forThumbnail = context.getExternalContext().getRequestParameterMap().get("forThumbnail");
Doc doc = tifDocMap.get(id);
InputStream is = this.convertTiffToPng(doc, forThumbnail);
return new DefaultStreamedContent(is);
}
}
I'm on this combination: SpringBoot + JoinFaces + PF 6.2
Can any body please advise what I'm doing wrong?
An alternate way I'm considering, to achieve the purpose:
May be, turn the pages of the tiff to individual PNGs beforehand, and then use galleria ...but it would be nice if I could get galleria to work with StreamedContent of each page dynamically.
I'm trying to filter a column using backing bean function.
<p:dataTable id="cars"
var="car"
value="#{manageAllCoursesBean.courses}"
filteredValue="#{manageAllCoursesBean.filteredCourse1}">
<f:facet name="header">
<p:outputPanel>
<p:inputText id="globalFilter"
onkeyup="PF('carsTable1').filter()"
style="width:250px"
placeholder="Entrer un mot clé"/>
</p:outputPanel>
</f:facet>
<p:column headerText="Name"
filterBy="#{car.name}"
sortBy="#{car.name}"
style="color: #400040; font-size: 10px; width: 150px; text-align:center">
<h:outputText value="#{car.name}" />
</p:column>
<p:column headerText="Teacher"
filteredBy="#{manageAllCoursesBean.findTeacherByIdCourse(car.id)}"
sortBy="#{manageAllCoursesBean.findTeacherByIdCourse(car.id)}"
style="color: #400040; font-size: 10px; width: 175px; text-align:center">
<h:outputText value="#{manageAllCoursesBean.findTeacherByIdCourse(car.id)}" />
</p:column>
</p:dataTable>
the backing bean method is:
public String findTeacherByIdCourse(String courseId) throws IOException
{
return serviceManager.findTeacherByCourseId(courseId);
}
the filter with Name is working as well.
However, is not the case with Teacher.
Have you please any idea about solving that ?.
Big thanks.
As described on Primefaces showcase, there's no way to use managed bean method with filterBy under p:column.
I proposed that solution:
You can convert your entity Course to a courseModel and then add teachers as a list of strings.
then in your managed bean will be :
List<CourrierModel> lacmss = new ArrayList<CourrierModel>();
DataModel allDatasAssociatedCE = new ListDataModel();
//...
allDatasAssociatedCE.setWrappedData(lacmes);
for(Course c: courses)
{
CourseModel cme = new CourseModel();
cme.setCourse(c);
cme.setTeachers(findTeacherByIdCourse(c));
lacmss.add(cme);
}
HTH.
How to update h:panelGroup using f:ajax.When, i select h:selectBooleanCheckbox getting value from officeAdd1 and set this value into headOfficeAdd1.Am getting officeAdd1 value in bean but i want to update value into headOfficeAdd1.
Thanks...
<h:form id="form">
<p:panel id="display">
<p:spacer width="20" />
<h:panelGrid columns="6">
<h:outputLabel value="Address:"
style="text-align: left;display: block;width:130px;" />
<p:inputTextarea
value="#{companyInformationBean.current.officeAdd1}"
autoResize="true" style="width:170px;" maxlength="150" />
</h:panelGrid>
<h:panelGrid columns="6">
<h:selectBooleanCheckbox id="remember"
value="#{companyInformationBean.current.checkBox}">
<f:ajax event="click" execute="#form"
listener="#{companyInformationBean.checkBoxValue}" />
</h:selectBooleanCheckbox>
<h:outputLabel value="Same as Registered Office Address"
style="text-align: left;display: block;" />
<p:spacer width="20" />
</h:panelGrid>
<p:spacer width="20" />
<h:panelGroup id="hidepanelgroup">
<h:panelGrid id="getaddress" columns="6">
<h:outputLabel value="Head Office Address:"
style="text-align: left;display: block;width:130px;" />
<p:inputTextarea id="headadd"
value="#{companyInformationBean.current.headOfficeAdd1}"
autoResize="true" style="width:170px;" maxlength="150" />
</h:panelGrid>
</h:panelGroup>
</p:panel>
</h:form>
Bean:
public void checkBoxValue()
{
if(current.getCheckBox()==true)
{
logger.info("getofadd"+current.getOfficeAdd1());
current.setHeadOfficeAdd1(current.getOfficeAdd1());
}
else
{
logger.info("checkbox value false");
}
}
You need to specify client IDs-to-render in the <f:ajax render> attribute.
Thus, given that the second textarea has an ID of headadd, this should do:
<f:ajax ... render="headadd" />
Unrelated to the concrete problem, comparing booleans against booleans in a boolean expression really doesn't make any sense. Just check the boolean itself directly.
if (current.getCheckBox())
By the way, try to use self-documenting property and method names. A property name of remember would be more suitable.
I have a dialog that contains a list of graphic images inside command links. When a command link is clicked, I want to pass the image name as action listener method argument.
Dialog's code:
<p:dialog id="idSchemaDlg5" widgetVar="schemaDlg" styleClass="maxSizeDialog" position="90,250" style="max-width:1000px;max-height: 1000px;" header="Schéma des circuits">
<c:forEach id="schemaDataGrid" items="#{historyGenerationBean.schemaList}" var="fileCircuits" varStatus="schemaNum">
<h:panelGrid columns="1">
<h:outputText value="SiteG2R #{historyGenerationBean.g2rNames.get(schemaNum.index)}" style="font-family: Tahoma, Geneva, sans-serif;color: #ED7905;font-size: 16px;font-weight: bold;"/>
<c:forEach items="#{fileCircuits}" var="pictureNamesList">
<h:panelGrid columns="#{pictureNamesList.size()}">
<c:forEach items="#{pictureNamesList}" var="imageName">
<h:form>
<h:panelGroup style="width:6px">
<p:commandLink actionListener="#{historyGenerationBean.fetchMlpppInformation(imageName)}" >
<p:graphicImage value="#{imageStreamer.image}" >
<f:param name="imgName" value="#{imageName}" />
</p:graphicImage>
</p:commandLink>
<h:outputText value="#{imageName}" style="width:50%; font-family: Tahoma, Geneva, sans-serif; font-size:70%;color:black;background-color:transparent;text-align:left;"/>
</h:panelGroup>
</h:form>
</c:forEach>
</h:panelGrid>
</c:forEach>
</h:panelGrid>
</c:forEach>
</p:dialog>
The action listener method is invoked, however I don't receive the argument imageName. It is null.
#ManagedBean(name = "historyGenerationBean")
#RequestScoped
public class HistoryGenerationBean implements Serializable {
#PostConstruct
public void init() {
String[] listRegion = new String[6];
circuitMlpppMap = new HashMap<>();
listRegion[0] = "Centre-Est";
regionOptions = createFilterOptions(genBean.getListRegion());
if (loginBean.connectedUserHasRole("ADMIN")) {
histories = generationHistoryFacade.findAll();
} else {
histories = loginBean.getConnectedUser().getGenerationHistoryList();
}
history = new GenerationHistory();
}
public void fetchMlpppInformation(String imgName) {
System.out.println("l'image sélectionnée est: " + imgName);
}
}
How can I fix this?
I was found the solution with .
<p:dialog id="idSchemaDlg5" widgetVar="schemaDlg" styleClass="maxSizeDialog" position="90,250" style="max-width:1000px;max-height: 1000px;" header="Schéma des circuits">
<h:form id="schemaFormId" dir="#{login.dir}">
<ui:repeat value="#{historyGenerationBean.schemaList}" var="fileCircuits" varStatus="schemaNum">
<ui:repeat value="#{fileCircuits}" var="pictureNamesList">
<table>
<tbody>
<tr>
<ui:repeat value="#{pictureNamesList}" var="imageName">
<td>
<h:panelGrid columns="1">
<p:commandLink action="#{historyGenerationBean.fetchMlpppInformation}" update=":schemaFormId" >
<p:graphicImage value="#{imageStreamer.image}">
<f:param name="imgName" value="#{imageName}" />
</p:graphicImage>
<f:param name="imgName2" value="#{imageName}" />
</p:commandLink>
<h:outputText value="#{imageName}" style="width:50%; font-family: Tahoma, Geneva, sans-serif; font-size:70%;color:black;background-color:transparent;text-align:left;"/>
</h:panelGrid>
</td>
</ui:repeat>
</tr>
</tbody>
</table>
</ui:repeat>
</h:form>
</p:dialog>
Many thanks to everyone who helped me(#BalusC too).
I am getting the following Error:
Cannot find component with identifier "myForm:display" referenced from "myForm_j_idt32".
my xhtml File :
<div id="divScreen" align="center">
<div id="divPage">
<ui:insert>
<ui:include src="/banner.xhtml"></ui:include>
</ui:insert>
<h:form id="menuBarForm">
<div id="menubar_link">
<p:commandLink value="Home" action="#{loginAct.homeNavigation}" style="color: #ffffff;margin-left: 10px;" ajax="false"></p:commandLink>
<p:commandLink action="#{loginAct.dologout}" style="color: #ffffff;margin-left: 10px;" value="Logout" ajax="false"></p:commandLink>
</div>
</h:form>
<div id="divMnuAndFrm">
<div id="divMnuContnr">
<h:form id="menuForm">
<p:menu style="width: 94%;" model="#{authMenuModel.model}"></p:menu>
</h:form>
</div>
<div id="divFrmContnrwithmenu">
<div style="height: 400px; margin: 10px 0px 0px 0px;width: 100%;">
<h:form id="myForm">
<p:dataTable
var="filem"
value="#{fileViewManagementPnation.data}"
rowKey="#{filem.ftype}"
paginator="true" rows="10"
selection="#{fileViewManagementPnation.selectedFile}"
selectionMode="single"
emptyMessage="No Files Found"
>
<p:ajax event="rowSelect" update="myForm:display" oncomplete="fileDialog.show()"/>
<f:facet name="header">
:: File Management ::
</f:facet>
<p:column sortBy="#{filem.ftype}" filterBy="#{filem.ftype}" headerText="FileType">
#{filem.ftype}
</p:column>
<p:column headerText="Version" sortBy="#{filem.version}">
#{filem.version}
</p:column>
<p:column headerText="Size">
#{filem.fsize}
</p:column>
<p:column headerText="File">
Action
</p:column>
</p:dataTable>
<p:dialog header="File Details" widgetVar="fileDialog" resizable="false" width="400"
showEffect="explode" hideEffect="explode">
<h:panelGrid id="display" columns="2" cellpadding="4">
<f:facet name="header_det">
<p:graphicImage value="/images/gep_logo.gif" />
</f:facet>
<h:outputText value="File Name : " />
<h:outputText value="#{fileViewManagementPnation.selectedFile.ftype}" id="ftype"/>
<h:outputText value="Size" />
<h:outputText value="#{fileViewManagementPnation.selectedFile.fsize}" id="size"/>
<h:outputText value="File Type :" />
<h:outputText value="#{fileViewManagementPnation.selectedFile.version}" id="version"/>
</h:panelGrid>
</p:dialog>
</h:form>
</div>
</div>
</div>
<div id="divFooter">
<p>Developed and Maintained by National Informatics Centre</p>
</div>
</div>
I am trying last two weeks to make it work but still am not getting any answers.
Please kindly help me in this issue.
You should be able to use update=":myForm:display" or update="display" instead of update="myForm:display".
Take a look at NamingContainer in JSF2/Primefaces, it'll give you a bit more background information. It's because myForm:display refers to nested NamingContainer within myForm which is called myForm, but you don't have that. The component you want to update is directly witin the same NamingContainer, namely myForm. So simply call one of the above mentioned and you should be fine.
You are not calling the right component.
You are calling a component withing the same form.
calling myForm:display will look for a component with id myForm inside the current form myForm as in :myForm:myForm:display which you do not have.
So you do not need to specify the full qualified name of the form. You can use the id of the component directly as in:
Both components (the calling component, and the called component) are inside the same form so use: update="display"
So instead you can either call the component directly as in the example above, or call it using its full qualified name update =":myForm:display"