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.
Related
I have a <p:panelGrid> like this:
<p:panelGrid style="margin:inherit !important; width: 100%;
display: flex !important;"
styleClass="new_player_panel">
<p:row>
<p:column>
<p:outputLabel value="Name in passport: " />
</p:column>
<p:column>
<p:inputText id="nameInPassport"
value="#{firstPlayerLoginManagedBean.surnameInPassport}"
required="true">
</p:inputText>
</p:column>
<p:column>
<p:message for="nameInPassport" display="icon" />
</p:column>
</p:row>
<p:row>
<p:column>
<p:outputLabel value="Firstname in passport:" />
</p:column>
<p:column>
<p:inputText id="firstnameInPassport" label="Utazási"
value="#{firstPlayerLoginManagedBean.firstnameInPassport}"
required="true">
</p:inputText>
</p:column>
<p:column>
<p:message for="firstnameInPassport" display="icon" />
</p:column>
</p:row>
</p:panelGrid>
and so on.
I tried to create this with dataGrid(managedbean, inputfields in lists), but <p:dataGrid> is not the perfect way to do my task exactly. I want to get behavior like this: If I click the plus icon next to the nationality field then creates another <p:inputText> for my second nationality and the other part of the form stay in the same state, and the new field push down the other fields. I have to use it a lot parts of my application. thanks in advance.
You can use <ui:repeat> to achieve this functionality, this is how you can achieve this functionality:
*.xhtml page, you build nationality field dynamically after you press "Add Nationality" button.
<h:outputPanel id="nationality_container">
<ui:repeat value="#{bean.passport.nationalities}" var="nationality">
<h:outputLabel value="#{bean.getNationalyLabel(nationality)}"
<h:inputText value="#{nationality}"/>
</ui:repeat>
</h:outputPanel>
<h:commandButton value="Add Nationality" listener="#{bean.addNationality}" update="nationality_container"/>
Backing Bean:
public Bean{
private Passport passport;
//adding new nationality and set its index
public void addNationality(){ //adding new nationality and set its index
passport.getNationalities.add(new Nationality(passport.getNationalities.size()));
}
//this method return you appropriate label, for id = 1 it's "First Nationality", and so on
public String getNationalityLabel(Nationality nationality){
if(nationality.id == 1){
return "Nationality";
}else if(nationality.id == 2){
return "Second nationality";
}
...
}
}
Object passport which encapsulates List<Nationality> nationalities;
public Passport{
...
private List<Nationality> nationalities;
...
}
Object Nationality with parameter index to store its index, first, second, third.
public Nationality{
int index; //1,2,3... first, second, third nationality, etc...
String nationality;
public Nationality(int index){
this.index = index;
}
}
Of course you can find a more elegant solution for your task, but using <ui:repeat> tag is required.
Pay attention that I didn't test this code, this is only general idea how this functionality should be implemented.
I have a problem with JSF.
I make a page with JSF and dataTable of primefaces, but I realized that when I use a var into datatable, JSF reload a same get method many times.
I don't know if because the JSF or my Program, someone can help me?
<p:dataTable var="Usuario" value="#{usuarioBean.listaUsuario}"
paginator="true" rows="10" selection="#{usuarioBean.usuario}"
rowKey="#{Usuario.id}"
id="dataTable"
paginatorPosition="bottom">
<p:column headerText="ID" style="width: 10px">
<h:outputText value="#{Usuario.id}"/>
</p:column>
<p:column headerText="Nome">
<h:outputText value="#{Usuario.nome}"/>
</p:column>
<p:column headerText="E-mail">
<h:outputText value="#{Usuario.email}"/>
</p:column>
<p:column headerText="Telefone" style="width: 10px">
<h:outputText value="#{Usuario.telefone}"/>
</p:column>
<p:column headerText="Editar" style="width: 10px;">
<p:commandLink id="btnEditar" action="#{usuarioBean.ChamareditarUsuario()}" ajax="false" title="Editar">
<h:graphicImage value="/resources/img/editar.png" style="position: relative; top: 25%; left: 25%;" />
<f:setPropertyActionListener value="#{Usuario}" target="#{usuarioBean.usuario}" />
</p:commandLink>
</p:column>
<p:column headerText="Excluir" style="width: 10px;">
<p:commandLink id="btnDeletar" title="Deletar" action="#{usuarioBean.deletarUsuario()}" update="dataTable">
<h:graphicImage value="/resources/img/deletar.png" style="position: relative; top: 25%; left: 25%;"/>
<f:setPropertyActionListener value="#{Usuario}" target="#{usuarioBean.usuario}" />
</p:commandLink>
</p:column>
<p:column selectionMode="single" width="1%"/>
</p:dataTable>
#ManagedBean
#RequestScoped
public class UsuarioBean {
private Usuario usuario = new Usuario();
private String campo;
private String valor;
private List<Usuario> listaUsuario;
private String acesso;
private List<Acesso> listaAcesso;
You can understand a little more in this question:
Why JSF calls getters multiple times
Basiclly, a getter is called several times, is part of the JSF lifecycle.
Cheers.
Show your usuarioBean - what Scope does it have?
If it has no Scope (or the wrong scope), the bean will be reconstructed, every time you access #usuarioBean.listaUsuario- which will happen 4 times per iteration in your example.
To avoid that, make it #RequestScoped, so it lives as long as the current Request.
Sidenode: h:datatable is not the primefaces component. it would be p:datatable with the right Namespace imported.
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.
}
}
So I am attempting to pass object values from a bean into a primefaces datatable (using primefaces 3.4 currently), howevever I'm facing two problems with this.
1. I cannot seem to find any way to display (or represent) a boolean value within a column in a datatable. Every time I attempt this, the table returns back totally empty (even though without the boolean column the other columns are populated with data from the bean).
2. The other bigger problem (more to do with java I think than primefaces) is that I have currently 26 different Objects I get from Siebels CRM ONDemand cloud solution, each containing their own datatypes and attribute values. I cannot for the life of me figure out how to, based on a drop down selection of a specific object display that objects fields dynamically within a primefaces datatable. So far I have just managed to display some of the fields for 1 of these objects as a sort of prototype but I am having the problem with the boolean value being display also its a nightmare.
Anybody have any sort of similar experiences ? or suggestions? I've been puzzled by this for over 2 weeks now and I am going absolutely crazy!
I can provide code examples or other details if needed :)
Thanks a lot I really appreciate any help !
Reggie
Html code:
<p:panel header ="Source Environment" style="margin-bottom:5px;">
<p:dataTable draggableColumns="true" id="tableFieldSet1" value="#{ODComBean.fields}" var="tableFieldSet1" rowKey="#{ODComBean.fields}" selectionMode ="multiple" style="font-family:sans-serif; width:max-content;">
<p:panel header="OD Object Selection" style="margin-bottom:5px;">
<h:panelGrid columns="2" cellpadding="5">
<p:selectOneMenu immediate ="true" id="pickList" value="#{ODComBean.fieldSetData}" effect="fade" style="font-size: 12px; font-family:sans-serif;" >
<f:selectItems value="#{ODComBean.fieldSet}" itemLabel="#{fieldSet.objectName}" var="fieldSet"/>
<p:ajax event="change" update="#form" />
</p:selectOneMenu>
</h:panelGrid>
</p:panel>
<p:panel header ="Source Environment" style="margin-bottom:5px;">
<p:dataTable draggableColumns="true" id="tableFieldSet1" value="#{ODComBean.fields}" var="tableFieldSet1" rowKey="#{ODComBean.fields}" selectionMode ="multiple" style="font-family:sans-serif; width:max-content;">
<p:column headerText="Type" styleClass="singleLine" style="height: 10px; font-size: 8pt;">
<h:outputText value="#{tableFieldSet1.fieldType}"/>
</p:column>
<p:column headerText="Required">
<p:graphicImage value="/resources/images/tick.png" rendered="#{tableFieldSet1.readOnly}"/>
<p:graphicImage value="/resources/images/red-cross.png" rendered="#{not tableFieldSet1.readOnly}"/>
</p:column>
<p:column headerText="Name" styleClass="singleLine" style="height: 10px; font-size: 8pt;">
<h:outputText value="#{tableFieldSet1.name}"/>
</p:column>
<p:column headerText ="Display Name" styleClass="singleLine" style="height: 10px; font-size: 8pt;">
<h:outputText value="#{tableFieldSet1.displayName}"/>
</p:column>
<p:column headerText="Default Value" styleClass="singleLine" style="height: 10px; font-size: 8pt;">
<h:outputText value="#{tableFieldSet1.defaultValue}"/>
</p:column>
<p:column headerText="Generic Integration Tag" styleClass="singleLine" style="height: 10px; font-size: 8pt;">
<h:outputText value="#{tableFieldSet1.genericIntegrationTag}"/>
</p:column>
<p:column headerText ="Integration Tag" styleClass="singleLine" style="height: 10px; font-size: 8pt;">
<h:outputText value="#{tableFieldSet1.integrationTag}"/>
</p:column>
<p:column headerText ="Translations" styleClass="singleLine" style="height: 10px; font-size: 8pt;">
<h:outputText value="#{tableFieldSet1.listOfFieldTranslations}"/>
</p:column>
<p:column headerText ="Validation Error" styleClass="singleLine" style="height: 10px; font-size: 8pt;">
<h:outputText value="#{tableFieldSet1.validationErrorMsg}"/>
</p:column>
<!-- When I add the next Column it will only show data for the first line, and display a <div half tag in the last column... strange... !-->
</p:dataTable>
</p:panel>
if you want to use a h:outputText, you can set its converter to something that you implemented and inside that converter, decide about the display value.
Otherwise, if you like to view an icon according to the value,
you can do like this :
<p:column headerText="My Boolean Value">
<p:graphicImage value="/resources/images/tick.png" rendered="#{MODEL.boolean}"/>
<p:graphicImage value="/resources/images/red-cross.png" rendered="#{not MODEL.boolean}"/>
</p:column>
I hope this is helpful :)
Output panel with layout set to inline produce a <span> tag with the style class you provide.
You can for example use the jquery-ui icons provided by the framework. Like this:
<p:outputPanel layout="inline" styleClass="ui-icon ui-icon-circle-check" rendered="#{project.inBudget}" />
<p:outputPanel layout="inline" styleClass="ui-icon ui-icon-circle-close" rendered="#{!project.inBudget}" />
You could simply use a check mark symbol for true and empty String, or x symbol for false.
<p:column headerText="Required" style="text-align: center">
<h:outputText value="#{tableFieldSet1.readOnly ? '✓' : ''}"/>
</p:column>
In JSF is it possible to have a datatable displays records as follows?
[Name ][Last Name][Age]
1. John Doe 20
Extra info on record 1
2. John Smith 20
Extra info on record 2
Thank you
I'm sure there are a number of ways you could do this.
If you don't mind nesting tables, you can use the panelGrid tag and CSS.
View:
<f:view>
<h:dataTable value="#{peopleBean.people}" var="row">
<h:column id="column1">
<f:facet name="header">
<h:panelGrid columns="3" columnClasses="cell,cell,age">
<h:outputText value="First Name" />
<h:outputText value="Last Name" />
<h:outputText value="Age" />
</h:panelGrid>
</f:facet>
<h:panelGrid columns="3" columnClasses="cell,cell,age">
<h:outputText value="#{row.firstname}" />
<h:outputText value="#{row.lastname}" />
<h:outputText value="#{row.age}" />
</h:panelGrid>
<h:outputText styleClass="extra" value="#{row.extraInfo}" />
</h:column>
</h:dataTable>
</f:view>
Stylesheet:
TABLE {
width: 100%;
}
TABLE TR TD {
text-align: left;
}
.cell {
width: 40%;
}
.age {
width: 20%;
}
.extra {
background-color: silver;
padding: 4px;
display: block;
width: 100%;
}
Third libraries, such as RichFaces, allow you to do that with the principle of subTable.
You can check this example from RichFaces. It is a little more complicated compared as what you want to do, but it shows the usage of subTable component...