Using c:foreach with Richfaces 4 - jsf

My problem is that I am trying to make dynamic tabs with tabPanel, so I want to read some information about that tabs from my bean. And that is why I am using c:foreach. So here is that piece of code:
<a4j:outputPanel id="output">
<rich:tabPanel width="40%" headerAlignment="right" switchType="client" binding="#{searchRequest.tabPanel}">
<rich:tab header="#{lang.tab_basic}" id="tabBasic" name="tabBasic">
............Content of the first non-dynamic tab..............
</rich:tab>
<c:forEach items="#{searchSession.tabs}" var="tab">
<rich:tab name="#{tab.name}" >
<f:facet name="label">
<h:panelGrid columns="2">
<h:outputText value="#{tab.name}" />
<h:graphicImage value="images/icons/delete.gif"
style="width:12px; height:12px;"
onclick="myFunc('#{tab.name}'); Event.stop(event);"/>
</h:panelGrid>
</f:facet>
<h:outputText value="#{tab.html}" escape="false"/>
</rich:tab>
</c:forEach>
</rich:tabPanel>
</a4j:outputPanel>
Everything seems clear to me, but as usual, there is something that I don't see, so I would be very thankful if someone could tell me what is that.

I don't think there is a label facet for rich:tab (at least its not mentioned in the docs).

Related

How to use BlockUI with treetable

I am working with javaEE, and for my project i used TreeTable and BlockUI to block this table, but i want to make a button appear even if it is blocked
<p:blockUI block=":form:treeTable" widgetVar="tbd" blocked="#{ManagedBean.condition}" />
<h:form id="form">
<p:treeTable id="treeTable" ... >
<f:facet name="header">
<p:commandButton value="SomeAction" actionListener="#{ManagedBean.someAction}" update=":form"/>
</f:facet>
in my example i want to make my commanbutton appear as available even if i use BlockUI
thantk you
This is not a functional problem but a design problem.
As is, the CommandButton is part of the TreeTable, so the CommandButton must be blocked if the TreeTable is blocked.
For sure Raziels answer will work, but a clean solution would be to move the button out of the TreeTable.
<h:form id="form">
<p:commandButton
value="SomeAction"
actionListener="#{ManagedBean.someAction}"
update=":form"
/>
<p:treeTable
id="treeTable"
...
/>
<p:blockUI
block=":form:treeTable"
widgetVar="tbd"
blocked="#{ManagedBean.condition}"
/>
</h:form>
I already Solved this problem by using z-index:99999 inside a style tag
so your code should be like :
<p:blockUI block=":form:treeTable" widgetVar="tbd" blocked="# {ManagedBean.condition}" />
<h:form id="form">
<p:treeTable id="treeTable" ... >
<f:facet name="header">
<p:commandButton value="SomeAction" style="z-index: 99999" actionListener="#{ManagedBean.someAction}" update=":form"/>
</f:facet>

How to use c:forEach with p:dataTable and p:columnGroup?

I want to use a special form of grouping 'dynamic' columns. This is however not supported as stated in my other question. Using c:forEach was suggested as a possible solution
Which is correct way to use c:forEach for defining table header and colums.
My code BEFORE:
<p:dataTable id="resultTable" var="result" value="#{myBean.searchResults}" scrollable="true">
<p:columns value="#{myBean.columns}" var="column" columnIndexVar="colIndex">
<f:facet name="header" >
<h:outputText value="#{column.header}"/>
</f:facet>
<h:outputText value="#{result[column.property]}"/>
</p:columns>
</p:dataTable>
and code AFTER transformation (didn't work - table is not displayed):
<p:dataTable id="resultTable" var="result" value="#{myBean.searchResults}" scrollable="true">
<p:columnGroup type="header">
<p:row>
<c:forEach items="#{myBean.columns}" var="column">
<p:column headerText="#{column.header}"/>
</c:forEach>
</p:row>
</p:columnGroup>
<c:forEach items="#{myBean.columns}" var="column" >
<p:column>
<h:outputText value="#{result[column.property]}"/>
</p:column>
</c:forEach>
</p:dataTable>
PrimeFaces version 3.4.1
The "by the book" way to create dynamic columns would be to use the "Dynamic Columns" feature of the data table.
Any way, I did something very similar to what you are trying to do in the past, using c:forEach. The only difference was that I was not using p:columnGroup at the same time.
So, code like
<p:dataTable id="resultTable" var="result" value="#{myBean.searchResults}" scrollable="true">
<c:forEach items="#{myBean.columns}" var="column" >
<p:column headerText="#{column.header}">
<h:outputText value="#{result[column.property]}"/>
</p:column>
</c:forEach>
</p:dataTable>
should really work. When you do this way, you add p:column objets in the component tree before the p:datatable analyze the tree. So, this does the trick.
Beware that this can lead to problems in edge, ajax cases. So, if you can, just stick to the built-in dynamic columns feature.

How to update a dynamically generated datatable without touching the rest of the page?

I have a setup in a view, where I display datatables dynamically. That is happening inside a p:accordion-Element, which is generating the tabs dynamically (and therefore the datatables inside).
The user now has the possibility (well, should have..) to add, edit and remove objects to the datatable and therefore to the object that is represented by the tab.
The add- and edit-functions work via dialogs. After successful adding or editing I want to update the datatable containing the data.
If I update the whole accordion-panel I lose the focus on the current tab which is really bad for the user-experience, especially because the other sub-pages of the project always only update the datatable.
After some googling I found out that I can't generate the IDs of JSF-components dynamically, what would make the whole thing a process of minutes.
I also do not have any index I could use to "cheat" and save in my backing-bean when I open the dialog.
I also found out that I could work-around this issue by using JSTL but this is prohibited due to a limited set of allowed languages.
The current setup looks like this:
<p:accordionPanel id="academicYearAccordionPanel"
value="#{academicYearAndClassController.academicYears}"
var="academicYear" multiple="true" dynamic="true" activeIndex="-1"
style="width:100%;">
<p:tab id="academicYear-#{academicYear.academicYear}" title="Jahrgang - #{academicYear.academicYear}">
<p:outputPanel style="float:right">
<p:commandButton value="Löschen" icon="ui-icon-close"
actionListener="#{academicYearAndClassController.setAcademicYear(academicYear)}"
process="#this"
oncomplete="PF('wConfirmAcademicYearDelete').show();">
</p:commandButton>
</p:outputPanel>
<p:spacer style="height:50px;" />
<p:separator />
<!-- Tabcontent -->
<p:outputPanel>
<p:outputPanel style="float:right">
<p:commandButton value="Hinzufügen" icon="ui-icon-plusthick"
actionListener="#{academicYearAndClassController.setAcademicYear(academicYear)}"
process="#this"
oncomplete="PF('wAddSchoolclassDialog').show();">
</p:commandButton>
</p:outputPanel>
<h:panelGrid columns="2">
<h:outputText
value="Klassen des #{academicYear.academicYear}. Jahrgangs" />
<p:spacer style="height:50px;" />
</h:panelGrid>
<p:dataTable emptyMessage="Keine Klassen vorhanden"
id="schoolclassTable"
var="schoolclass"
selection="#{academicYearAndClassController.schoolclass}"
value="#{academicYearAndClassController.getSchoolclasses(academicYear)}"
selectionMode="single" rowKey="#{schoolclass.name}"
scrollable="true" scrollHeight="500">
<p:column headerText="Name">
<h:outputText value="#{schoolclass.identifier}" />
</p:column>
<p:column headerText="Klassenlehrkraft">
<h:outputText
value="#{schoolclass.teacher.name} (#{schoolclass.teacher.symbol})" />
</p:column>
<p:column headerText="Klassenraum">
<h:outputText
value="#{schoolclass.room.name} (#{schoolclass.room.locationName})" />
</p:column>
</p:dataTable>
</p:outputPanel>
</p:tab>
</p:accordionPanel>
I want to update the element with the ID schoolclassTable. How can I achieve this?

rich:modalPanel reloading page on hide

I have a JSF page using richfaces with a few help buttons like this:
<rich:componentControl for="panelHelp" event="oncomplete" operation="show" />
The panel called is this:
<rich:modalPanel id="panelHelp" minHeight="250" minWidth="500"
keepVisualState="true" resizeable="true" moveable="true">
<f:facet name="header">
<h:outputText value="Help" />
</f:facet>
<f:facet name="controls">
<h:commandLink value="">
<h:graphicImage value="/close2.png" title="Close" />
<rich:componentControl for="panelHelp" event="onclick" operation="hide" />
</h:commandLink>
</f:facet>
<h:panelGrid columns="1" width="100%">
<h:outputText escape="false" id="txtHelp"
value="#{msgHelp}" style="width: 100%; height: 190px" />
</h:panelGrid>
</rich:modalPanel>
However, whenever I press the button to close the panel, it reloads the whole page, instead of simply hiding the panel.
Am I doing something wrong, or is there a better way to do this?
I'm using richfaces version 3.3.3
Use a4j:commandLink instead of h:commandLink and provide an a4j:support as well. This should fix the problem.
It's reloading the entire page because of your use of the <h:commandLink/>, which is going to trigger the entire JSF request processing lifecycle. To get your desired results you don't need the command link component. All you really need is:
<f:facet name="controls">
<h:graphicImage id="closeButton" value="/close2.png" title="Close" />
<rich:componentControl attachTo="closeButton" for="panelHelp" event="onclick" operation="hide" />
</f:facet>
What we're doing here is firing the <rich:componentControl/> on click of the image; there's no need for a link. I'm assuming you're using Richfaces 3.X. (RF 4.X has deprecated the attachTo attribute)
Above answer will work in Richfaces 3.x, If you are using Richfaces 4.x then the given code will work.
<f:facet name="controls">
<h:graphicImage value="/close2.png" >
<rich:componentControl target="closeButton" operation="hide" event="click" />
</h:graphicImage>
</f:facet>
Add disableDefault="true" attribute to your rich:componentControl to disable default behavior of the link on click.

Primefaces DataGrid - CommandLink is not working

i have an issue with nested UI components which is probably a known bug in PrimeFaces and Mojara. However I have no idea how can i solve it.
We have a image gallery with uploader and I want to be able to delete images from the datagrid, so
XHTML:
<h:form enctype="multipart/form-data">
<p:fileUpload fileUploadListener="#{pictureManagementBean.handleFileUpload}"
mode="advanced"
update="gallery messages"
auto="true"
allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
/>
<p:growl id="messages" showDetail="true"/>
<p:dataGrid var="item" value="#{pictureManagementBean.pictures}" id="gallery">
<p:panel header="#{item.pictureName}" style="text-align:center">
<h:panelGrid columns="1" style="width:100%">
<p:graphicImage value="#{item.thumbnailDir}" />
<h:outputText value="#{item.createdate.toString()}" />
<p:commandLink value="Delete"
action="#{pictureManagementBean.removePicture(item.idpicture)}" ajax="false"/>
</h:panelGrid>
</p:panel>
</p:dataGrid>
</h:form>
Basically what is not working at the momment - at all - is the commandLink Delete in the DataGrid. The rest is fine.
Is there any walkaround to this? I've tried: columns, ajax, no ajax... nothing works. All i can do is get the button outside the DataGrid. But that's not really what I want.
Any help apprecieated.
[small thing: surprisingly I have used commandLink in DataTable and Columns with no problem! ]
Primefaces 3.4RC1 from maven. (didnt work on 3.3.1 either)
ok so I've found one thing:
inside <p:dataGrid> if I use anything BUT p:columns its not working.
But then the view is terrible... should I just use CSS to fix it?
#Maple_shaft you are so right!
correct code:
<p:dataGrid var="item" value="#{pictureManagementBean.pictures}" id="gallery">
<p:column>
<p:panel header="#{item.pictureName}" style="text-align:center">
<h:panelGrid columns="1" style="width:100%">
<p:graphicImage value="#{item.thumbnailDir}" />
<h:outputText value="#{item.createdate.toString()}" />
<p:commandLink value="Delete"
action="#{pictureManagementBean.removePicture(item.idpicture)}" ajax="false"/>
</h:panelGrid>
</p:panel>
</p:column>
</p:dataGrid>
So just simple column element. I've just places it wrong before. Thanks so much.
Of course backing bean is #ViewScoped!

Resources