I would like to display a form using a bean with the framework JSF and primefaces.
It is very simple to do with dataTable as followed but it is also not suitable at all for this form.
<p:dataTable value="#{utilisateur.questionnaire.questions}" var="question" styleClass="borderless" class="ui-g">
<p:column value="" class="ui-g-2">#{question.titreQuestion}</p:column>
<p:column value="" class="ui-g-5">#{question.question}</p:column>
<p:column value="" class="ui-g-5"><h:inputText id="firstName" value="default}" label=""></h:inputText></p:column>
</p:dataTable>
<h:commandButton value="Submit" action="../admin.xhtml"></h:commandButton>
As you can see below it does not look very professional. There is an empty head bar. Moreover, sometimes a question has no title in the left column so there is an empty cell (which would not be important if the cell had not a background color).
Thus, have you any recommendation of a tag for this type of form where I could have two string (retrieved via the bean using #{utilisateur.questionnaire.questions}) on the first line and the inputText on the second one and so on.
I have tried with h:panelGrid, unfortunately you cannot have * value="#{utilisateur.questionnaire.questions}" * inside the tag...
Related
I'm having some trouble with primefaces datatables and dynamic overlay for each row.
Basically I have a main datatable containing a certain number of rows. For each row, I have a button and a linked overlay that, when clicked, shows a small datatable in the overlay (it lists the lasts changes concerning the row).
Here is the simplified code:
//the main datatable
<p:dataTable id="terminauxDataTable" var="terminalBean" widgetVar="dataTableWidgetVar" value="#{cc.attrs.listAllTerminals}"
filteredValue="#{cc.attrs.listFilteredTerminals}">
...
<p:columnGroup>
<p:row>
<p:commandButton id="changelogButton"
type="button"/>
<p:overlayPanel id="changelogPanel" for="changelogButton"
dynamic="true">
//the small datatable for each row
<p:dataTable var="changelog" value="#{terminalBean.lastChangelogs}">
<p:column headerText="#{msg['commun.changelog.table.label.date']}">
<h:outputText value="#{changelog.dateHr}">
<f:converter converterId="dateTimeConverter" />
</h:outputText>
</p:column>
... some other colums
</p:dataTable>
</p:overlayPanel>
</p:row></p:column></p:datatable>
everything works fine at first sight. When I click on any button i do get the content that I want to load. it's supposed to look like this :
http://i.stack.imgur.com/n9GrW.png
(sorry, cannot post image directly)
Problems start to arise as soon as I make any filtering od sorting on the main datatable.
If a specific button was never clicked since page load, the overlay and the contained datatable are load successfuly. It dosen't matter if I applied a filter or a sort.
If I already clicked a button at least once and then I apply a sort/filter, if I try to click again on the button the overlay is shown but is empty, there is no datatable inside.
here is an exemple of a click after a filter on a button that was clicked before :
http://i.stack.imgur.com/eLGLo.png
Do you have any lead on how to address this problem ?
Thank you
Using the overlay opitimally with a datatable, requires a little different approach as can be seen in the PrimeFaces showcase of the overlayPanel
You need to put the overlayPanel outside the datatable, put a updatable container in there, e.g. an outputPanel and on the button in your column, update the panel and call the show function of the overlay panel with a specific parameter. Something like this:
<p:dataTable>
....
<p:column style="width:32px;text-align: center">
<p:commandButton update=":form:terminalDetail" oncomplete="PF('myTerminalOP').show('#{component.clientId}')" icon="ui-icon-search" title="Details">
<f:setPropertyActionListener value="#{selectedTerminal}" target="#{mySelectionView.selectedTerminal}" />
</p:commandButton>
</p:column>
</p:dataTable>
<p:overlayPanel widgetVar="myOP" showEffect="fade" hideEffect="fade" dismissable="false" showCloseIcon="true">
<p:outputPanel id="terminalDetail" style="text-align:center;">
...
</p:outputPanel>
</p:overlayPanel>
(Disclaimer: done on my phone, so typos may be there)
On latest version of primeng we can do this.
Triggering the event based on element #id. By doing the toggle from typescript, I was able to pin point the element I need to attach the overlay panel to.
HTML:
<div>
<p-table>
<--loop the data-->
<button pButton (click)="showOP($event, rowwiseData, 'button'+rowIndex)" [id]="'button'+rowIndex"></button>
</p-table>
</div>
<--outside of the table add the overlay menu-->
<p-menu #menu [popup]="true" [model]="panelData"></p-menu>
TS File:
panelData: any;
#ViewChild('menu', {static: false}) op: OverlayPanel;
<!--Call and point the event to the correct element using unique #id-->
showOverlayPanel($event: MouseEvent, rowwiseData: any, id:string) {
this.panelData = rowwiseData;
this.op.toggle($event,document.getElementById(id));
}
I have a counter in a column of a datatable. Once the counter reaches a certain time, I need to change the background color of that column only. The data for the table is being pulled from a database. I'm using a4j:poll to reRender the column but the issue is that the entire table is rendered. Some code below:
<a4j:region>
<h:form>
<a4j:poll id="poll" interval="1000" enabled="true" reRender="blink" limitToList="true" />
</h:form>
</a4j:region>
<h:form id="form1">
<a4j:outputPanel id="panel1" ajaxRendered="true">
<h:dataTable id="blinks" styleClass="tableClass" value="#{bean.list}" var="_item">
<h:column id="blink">
<f:facet name="header">
<h:outputText value="Header1" />
</f:facet>
<div id="div1" class="#{bean.check() ? 'red' :''}">
<h:outputText value="Counter text (counts seconds)" />
</h:column>
</h:dataTable>
</a4j:outputPanel>
</h:form>
If you meet the following minimum req' JSF 2.0, EL 2.1 and Servlet 2.5
You can try out the Ajax#updateColumn() by Omnifaces , there is an example on how to use it in the showcase
Note that Ajax#updateRow() and Ajax#updateColumn() can only update
cell content when it has been wrapped in some container component with
a fixed ID.
Maybe you can use a push server side events to trigger the update on client side instead of use polling which performs full form.
http://livedemo.exadel.com/richfaces-demo/richfaces/push.jsf?tab=choices&cid=987178
A full description how to use this: Using RichFaces Push and DataTable Ajax Keys for Partial Tables Updates
you should re render by column id, but because you have data which coming from database, and it is a one list, can you confirm what you can do call which real can update one column?
I have a Primefaces Datatable and each column filled with a OutputLabel. When the String in this label has to many characters, the text is not visible.
I'm looking for a way, to show a MouseOver-window or hint to show the full text. What would be the most painless way? Thanks in advance.
You can Use Primeface Tooltip component.
<p:tooltip value="<CONTENT_OF_TOOLTIP>" for="<COMPONENT_ID_ON_WHICH_TOOLTIP_WILL_APPEAR>" />
Even though the IDs generated in Primefaces Datable inner components are different over iteration of List, if you put p:tooltip also in table as in below example, primefaces will also generated dynamic IDs to p:tooltip component also.
Example:
<p:dataTable value="#{heroMBean.herosList}" var="h">
<p:column headerText="Name">
<h:outputText id="hname" value="#{h.name}"/>
<p:tooltip for="hname" value="#{h.name}"></p:tooltip>
</p:column>
<p:column headerText="Universe">
<h:outputText id="huniverse" value="#{h.universe}"/>
</p:column>
</p:dataTable>
I am using JSF2.0 with Prime Faces 3.2. I have a data table with a column that has two command buttons. The second command button is rendered based on a condition. Everything works well until the data table is filtered. Once filtered the first command button without the rendered attribute calls my actionListener without any issues, whereas the second command button with the rendered attribute does not.
PS:The reason i am using f:param intead of setPropertyActionListener is because of a bug in primefaces datatable that passes the wrong row's id when filtered.
Here is my code, any insight into this issue would be great.
<p:column headerText="Column1" filterMatchMode="contains" filterBy="#{item.name}" sortBy="#{item.name}">
<h:outputText value="#{item.name}" style="float:left" />
<span class="inlineButton">
<p:commandButton id="selectBtn" icon="select"
oncomplete="dialog1.show()" actionListener="#{controller.setItem}">
<f:param name="itemId" value="#{item.id}"/>
</p:commandButton>
<p:commandButton id="delBtn" icon="delete"
actionListener="#{controller.setItem}"
oncomplete="delConfirm.show()"
rendered="#{not empty item.id}">
<f:param name="itemId" value="#{item.id}"/>
</p:commandButton>
</span>
</p:column>
i am using facelets jsf 2.0 with primefaces 3.0.M2 component library.
i am trying to achieve dynamic numbers of rows including iput fields that are filled when a datatable selection occurs.
whenever a selection is made the dynamic rows generated correctly with input fields but after the first selection for following selections dynamic row count changes correctly but the input fields does not update and keeps showing inputs from the first selection.
here is how i iterate list in facelet;
<ui:repeat value="#{goalEntranceBean.selectedCard.parameterList}" var="prmBean" >
<li><h:outputText value="#{prmBean.lookUp.value}"/></li>
<li>
<h:outputText value="Weight:"/>
<p:inputText id="wx" required="true" value="#{prmBean.weight}">
</p:inputText>
<h:outputText value="Percent:"/>
<p:inputText required="true" value="#{prmBean.percent}">
</p:inputText>
</li>
</ui:repeat>
my bean where i get the list of cards and set the selectedCard with rowSelect event in datatable.
#ManagedBean(name = "goalEntranceBean")
#ViewScoped
public class GoalEntranceAction implements Serializable {
private List<ScoreCard> personalCards = new ArrayList<ScoreCard>();
private ScoreCard selectedCard = new ScoreCard();
......
}
when i checked in debug mode i can see the true list but in screen the elements does not change.
This is a common problem (gets asked every couple of days). To make long story short, inputs inside ui:repeat do not work, period.
It is a problem with JSF, a long standing, famous one. Maybe it will be fixed. Maybe not, it seems that no one really cares (I mean - an input? in a... ui:repeat? such crazy scenario!).
A quick-fix is to use a h:dataTable, possibly ungodly abused with css to make it look like a list. A long-fix is to use some iterator from a different library. Primefaces has an element that should work that renders an unordered list.
thanks for your replies. Sorry for forget sharing the solution.
As i mentioned above i have primefaces datatable.
On row selection event i render datatable and want to update the cells of that datatable.
USING p:inputtext easily solved my problem. Now i can change the data on screen and i can see the values after update operation on screen. I don't understand the reason but it works.
<p:dataTable var="orgPrmBean"
value="#{scoreCardOperationsBean.selectedCard.orgParameterList}"
emptyMessage="#{labels.norecord}"
rowKey="#{orgPrmBean.id}"
>
<p:columnGroup type="header">
<p:row>
<p:column headerText="Parameters" colspan="3" style="text-align:left;width:480;"/>
</p:row>
</p:columnGroup>
<p:column style="text-align:left;width:200px;">
<h:outputText value="#{orgPrmBean.info}"/>
</p:column>
<p:column style="text-align:left;width:180px;">
<p:inputText value="#{orgPrmBean.weight}"
rendered="#{scoreCardOperationsBean.selectedCard.goalEdit}">
<f:convertNumber maxFractionDigits="0"/>
</p:inputText>
</p:column>
</p:dataTable>
It IS possible to make it work, but the solution is to bind the inputs to a backing bean, and update the values of the controls in the backing bean via listeners (using the new value received in the argument). Obviously this isn't a good solution if you have a complex form, as you need to add a listener/control in the backing bean for each control in the page, but it's practical if you just have one or two inputs.