Is it possible to use EL in ui:repeat? [duplicate] - jsf

This question already has an answer here:
How to use EL with <ui:repeat var> in id attribute of a JSF component
(1 answer)
Closed 7 years ago.
Mojarra 2.1.29
I've read that usually it's not necessary to use EL to generate id-attribute dynamically. I also know that the id-attribute resolved at view-building phase. But in our projects we have to write some Selenium tests which are goign to use some html-attribute in the generated markup. So, I decided to specify the id-attribute dynamically. How can I do that for the following <ui:repeat>:
#ManagedBean
#SessionScoped
public class Bean{
private List<Integer> values;
//GET, SET
public Bean(){
values = Arrays.asList(1,2,5,7,8,9);
}
}
<ui:repeat value="#{bean.values}" var="value">
<h:outputText id="#{value}" /> <!-- not legal, resolved to null -->
</ui:repeat>
Maybe I should specify another attribute fo Selenium instead?

If you provide a fixed id like the following.
<ui:repeat value="#{bean.values}" var="value">
<h:outputText id="elementId" />
</ui:repeat>
The element you need will have ids generated as,
parentId:0:elementId
parentId:1:elementId
parentId:2:elementId
and so on.

Related

Primefaces binding datatable with viewscope

I'm currently building an xhtml page based on Primefaces 3.5 (which I can't update...not lucky this time!).
In this page I need to build dynamically different datatables so I thought that unique way to achieve my task is through the binding method.
So I've made:
<p:dataTable id="bindQTable" var="item"
value="#{bindingHtmlTableClass.items}"
binding="#{bindingHtmlTableClass.dataTable}">
<p:column headerText="Name Column">
<h:outputText value="#{item}" />
</p:column>
<p:column>
<p:commandButton value="remove"
action="#{bindingHtmlTableClass.remove}" />
</p:column>
</p:dataTable>
and the bean:
#ManagedBean(name="bindingHtmlTableClass")
#RequestScoped
public class BindingHtmlTableClass implements Serializable{
private List<String> items;
private DataTable dataTable;
#PostConstruct
private void buildUp(){
System.out.println("postconstruct!");
items = new ArrayList<String>();
items.add("X");
items.add("Y");
}
...getters,setters...
}
The problem now is that I would need to update the tables and especially after a poll period I need to update the values within them.
But i'm in a Request Scope and I can't use a View Scope because of binding.
Is there a better way to implement such thing?
EDIT 4 BalusC: why i need binding the datatable? Because i need to show a datatable linked to a serie of different connection to different installation of RabbitMQ, which is not a known number. My boss asked me to put each RabbitMQ server in a different DataTable where each queue is represented in a different row. Each column needs to show actual queue size plus a button or more to manage the queue (purging, deleting...).
Thanks!

h:commandLink with Java bean

I have a datalist"gouvernorats" extracted from a data table and each item of the list is a command link that outcome an other page which contains a list "villes" referenced to the item. My code doesn't work.I ask someone to help me running it.
gouvernorat.xhtml
<c:forEach varStatus="#{stat}" items="gouvernoratbean.gouvernorats" var="gouv"><c:set var="villes" scope="request" value="${gouv.getvilles}"/>
<h:commandLink action="ville" actionListener="#{gouvernoratbean.showville}" value="#{gouv.nomGouv}"><f:setPropertyActionListener target="#{requestscope.gouv}" value="#{gouv}"></f:setPropertyActionListener>
</h:commandLink></c:forEach>
ville.xhtml
<p:dataList value="#{requestScope.gouvernoratbean.showville}" var="ville" >
<h:outputText><h2>#{ville.nomVille}</h2> </h:outputText> </p:dataList>
gouvernoratbean.java
public void showville(ActionEvent event){Villes=gouv.getVilles();}
No idea what your actual question is..
But it may not working as you have not referenced your bean properly in this part of the xhtml:
items="gouvernoratbean.gouvernorats"
Should be:
items="#{gouvernoratbean.gouvernorats}".

How to use component binding in JSF right ? (request-scoped component in session scoped bean)

Mojara 2.1.21
I've updated my question based on comments. I have two situation where a component is bound to server session bean. (Additional links with information: Binding attribute causes duplicate component ID found in the view and https://stackoverflow.com/a/12512672/2692917)
Version 1:
single.xhtml:
<h:outputText value=... binding="#{mysessionbean.out}" />
java:
#SessionScoped #Named public class Mysessionbean {
UIOutput out;
//getter and setter ....
}
Version 2:
template.xhtml:
<h:outputText value=... binding="#{mysessionbean.out}"
view1.xhtml:
<ui:composition template="template.xhtml" />
view2.xhtml:
<ui:composition template="template.xhtml" />
java:
#SessionScoped #Named public class Mysessionbean {
UIOutput out;
//getter and setter ....
}
Version 1 is ok. (At least I've not encounter any errors so far). But in version 2 the duplicate id error is occured if I navigate from one page to another. Why does it happen ?
Is it safe to use (request-scoped) component (in version 1) with session scoped binding ?
Are there another use cases to consider ?
Edit:
Functional requirement 1:
I want to use Primefaces datatable in a view. I need some info from this datatable. (Such as selected row or row index). So binding the datatable helps me to retrieve this info.
Functional requirement 2:
Components binding in composite components. They will be bound to session scoped bean. (And used mainly on one page, but what if I used it on another page ?
Requirements 3
The situation as in "Version 2". Template with primefaces menu and session scoped binding. For this I've used the EL-Binding.
In JSF 2.x, unless you want to manipulate components programmatically (which is at its own also rather fishy), there is no sensible real world use case to bind components to a backing bean. For sure not if they are further not been used in the backing bean itself, or if it are solely their attributes which are been flattened out.
As to the functional requirement of getting the current row of the data table, there are much better ways listed here, How can I pass selected row to commandLink inside dataTable?, for example if your environment supports EL 2.2:
<h:dataTable value="#{bean.items}" var="item">
<h:column>
<h:commandLink value="Foo" action="#{bean.foo(item)}" />
The two last requirements are totally unclear. At least, if you're doing something like:
<x:someComponent binding="#{bean.someComponent}" />
with in bean
someComponent.setSomeAttribute(someAttribute);
someComponent.setOtherAttribute(otherAttribute);
then you should instead be doing
<x:someComponent someAttribute="#{bean.someAttribute}" otherAttribute="#{bean.otherAttribute}" />
Or, if you intend to be able to use the component somewhere else in the view like so
<h:inputText ... required="#{not empty param[bean.save.clientId]}" />
...
<h:commandButton binding="#{bean.save}" ... />
and the instance is further nowhere been used in the bean, then just get rid of the unnecessary property altogether:
<h:inputText ... required="#{not empty param[save.clientId]}" />
...
<h:commandButton binding="#{save}" ... />
If there is really, really no way for some unclear reason, then split all request scoped properties of the session scoped bean out into a separate request scoped bean which you in turn bind to form actions. The session scoped one can just be injected as a #ManagedProperty of the request scoped one.
See also:
Binding attribute causes duplicate component ID found in the view
How does the 'binding' attribute work in JSF? When and how should it be used?
We ran into a similar problem and I just want to share our solution:
Problem:
In a view there was a (extended largely customized) datatable.
<x:dataTable binding="#{bean.someSomeDataTable}" />
After navigating to another page and back we wanted the datatable to have the exact same state. Previously we solved that by binding the datatable to to backing bean. This worked fine with JSPs. With Facelets we could not do that (Duplicate ID errors). So we used the binding, but only saved/restored the state of the datatable component.
public HtmlDataTable getSomeDataTable()
{
HtmlDataTable htmlDataTable = new HtmlDataTable();
if (tableState != null)
htmlDataTable.restoreState(FacesContext.getCurrentInstance(), tableState);
return htmlDataTable;
}
public void setSomeDataTable(HtmlDataTable table)
{
tableState = table.saveState(FacesContext.getCurrentInstance());
}

How to access object methods using dataTable in JSF?

I'm working with LastFM api, let's say I have a class called Artist which I call in this dataTable:
<h:dataTable var="artist" value="#{personEAO.topArtists}" >
<h:column>Artist : #{artist.name} </h:column>
</h:dataTable>
Artit have a field which refers to his picture :
artist.getImageURL(ImageSize.LARGE)
Which works fine, but how do I call this method in my jsf page using dataTable ?
I searched around for Javadocs, but I couldn't find them anywhere. The answer depends on what kind of constant ImageSize.LARGE is.
If ImageSize is an enum, just do:
<h:graphicImage value="#{artist.getImageURL('LARGE')}" />
But if it isn't and is thus a public static constant, then one of the ways is to wrap it in some helper bean which returns exactly that:
<h:graphicImage value="#{artist.getImageURL(someHelperBean.ImageSize_LARGE)}" />
I of course assume that your environment supports EL 2.2.

How to display value of List#size() in JSF EL?

I'd like to know if there's a way to bind the returned value of a method into a JSF component.
I'll explain myself better.
Let's say I have a class like this:
public class Document {
private List<Attachment> attachments;
//getter and setter here
}
this class is exposed to jsf through a registered managed bean in a property called currentDocument, and used in a jsf this way
<h:outputText value="#{myManagedBean.currentDocument.attachment.size}" />
This isn't correct, I know. But what is the correct way to do this?
Am I supposed to create an attribute on the Document class, let's say numberOfAttachments, and bind to that, or there's a way to bind directly on a method's return value?
If you're running an EL 2.2 capable container (Tomcat 7, Glassfish 3, JBoss AS 6 or newer, all implementing Servlet 3.0), or are using JBoss EL, then you should be able to invoke non-getter methods by EL:
<h:outputText value="#{myManagedBean.currentDocument.attachment.size()}" />
An alternative is to use JSTL fn:length():
<html xmlns:fn="http://java.sun.com/jsp/jstl/functions" ...>
...
<h:outputText value="#{fn:length(myManagedBean.currentDocument.attachment)}" />
If none of that is possible for you for some reason, then your best bet is to create an EL function yourself
<h:outputText value="#{my:size(myManagedBean.currentDocument.attachment)}" />
or to add an extra getter method to #{myManagedBean} which returns exactly that.
<h:outputText value="#{myManagedBean.currentDocumentAttachmentSize}" />
See also:
Invoke direct methods or methods with arguments / variables / parameters in EL

Resources