Updating composite overlayPanel - jsf-2

Based on this subject, I would like to update a <p:overlayPanel> from a datatable to a composite component
View
<h:form id="myForm">
<p:dataTable id="myTable" ...>
<p:column headerText="1">
<p:commandLink id="link"
actionListener="#{bean.update}"
update=":toto" value="Val" />
<p:overlayPanel id="panel" for="link">
<my:view id="toto">
</p:overlayPanel>
</p:column>
</p:dataTable>
</h:form>
Composite
<composite:implementation>
<span id="#{cc.clientId}">
<p:dataTable id="toto" ...>
</p:dataTable>
</span>
</composite:implementation>
However I always get an error message saying that :toto component id can not be reached.
So, how can I access the dataTable placed in the composite ?
EDIT : Actually I changed my mind concerning the utilisation of p:overlayPanel for a p:datatable because of the creation of dynamic ids. I replaced this by a p:dialog and it works great.

Related

Get sibling element from PrimeFaces datatable row

I have a datatable created in PrimeFaces which receives and render a list of objects. At the end of the row I have a commandButton element and when it is used it do some stuff on the managedBean on the server.
All the data about the current row is retrieved using an object id placed in the command button in the param attribute.
The problem is that I have a selectOneMenu element and it is not related to the object. I select one value that affects the logic behind.
Here is the table:
<h:panelGrid id="panel" columns="2" bgcolor="#cce4ff"
cellpadding="10" cellspacing="1" rendered="#{indexBean.showChannelList}"
style="margin-top: 10px; margin-left: 100px;">
<p:dataTable var="program" value="#{indexBean.programList}" style="width:1000px;"
paginator="True" rows="10" rowIndexVar="row" sortBy="#{program.id}"
paginatorPosition="bottom" widgetVar="programDT" id="programDT">
... That the select
<p:column headerText="text" width="15%">
<h:selectOneMenu id="select-valability" value="#{indexBean.valabilitySelected}" disabled="#{indexBean.disabled}" style="font-size: small;">
<f:selectItems value="#{indexBean.listValabilities}" />
<f:param value="#{program.id}" />
<f:ajax resetValues="true" />
</h:selectOneMenu>
</p:column>
... and there is the command button
<p:column headerText="text" width="20%" style="text-align: center;">
<h:commandButton id="cmd-button-id" value="gen JSON" action="#{indexBean.action}"
style="width: 200px; height: 30px;"
class="ui-button ui-widget ui-state-default ui-corner-all"
>
<f:param name="programId" value="#{program.id}" />
</h:commandButton>
</p:column>
I want to be able to get the value of the select element from that specific row from which the action was triggered.
I've try with context.findComponent() but it gives me null even if I put the absolute path to the element with the index generated by JSF table as form:table:index:staticIdOfSelect.
I don't know how to get the sibling element. That was another though.
From the bean class:
#ManagedBean
#SessionScoped
public class IndexBean
I'm really stuck here.
Thanks in advance!
Use some element on the row to set an ajax listener in the bean to store the data and then update="the element" you want to get the information from.

Want to show a data table populated with data after a button click

I want to write a code in this way, that If I click on a button a data table appears populated with data. before that there should not be the data table in view.
<p:commandButton value="Go" styleClass="apply_button" actionListener="#{searchBean.getUserList}">
<f:attribute name="trigram" value="#{searchBean.trigram}"/>
<f:attribute name="firstName" value="#{searchBean.firstName}"/>
<f:attribute name="lastName" value="#{searchBean.lastName}"/>
</p:commandButton>
here the method getUserList() returns a list of data that should be populated in the data table.and it works.
<p:dataTable value="#{searchBean.listUser}" var="user">
<p:column headerText="Trigram">
<h:outputText value="#{searchBean.trigram}"/>
</p:column>
</p:dataTable>
It shows in the Data Table after I click on the button, But the Data Table appears before the button click with empty fields. How can I modify my codes to show make the Data Table appear after my button click?
Codes are within the <h:form> Tag.
And the Managed Bean searchBean is in #ViewScoped.
You can initialize a simple getter/setter :
private boolean visible = false; // getter/setter
public void getUserList(ActionEvent event)
{
setVisible(true);
// Your code
}
And modify your view like this :
<p:commandButton value="Go" styleClass="apply_button" actionListener="#{searchBean.getUserList}" update="table-wrapper">
<f:attribute name="trigram" value="#{searchBean.trigram}"/>
<f:attribute name="firstName" value="#{searchBean.firstName}"/>
<f:attribute name="lastName" value="#{searchBean.lastName}"/>
</p:commandButton>
<h:panelGroup id="table-wrapper">
<p:dataTable rendered="#{searchBean.visible}" value="#{searchBean.listUser}" var="user">
<p:column headerText="Trigram">
<h:outputText value="#{searchBean.trigram}"/>
</p:column>
</p:dataTable>
</h:panelGroup>
Note the update attribute on button, h:panelGroup wrapper and rendered attribute on table.

Primefaces component not refreshing

I have been looking at Primefaces 3.4.2 since IceFaces 3.2.0 has too many issues. I have a dataGrid of vehicles which are contained in a panel. I have an add button and each vehicle panel contains a remove button.
The add works fine; it adds a new vehicle panel each time. The issue is when I delete a vehicle, the panel is removed, but the value(s) remain. For instance, if I have 3 vehicles with the year as 2008, 2010, 2012, and then I delete the first vehicle, you'd think you would see 2 panels remaining with the year as 2010, and 2012. Instead, I see 2008 and 2012. The backing bean is doing it correctly and I do see the correct values if I manually refresh the screen. Now that I have presented my case here's the code:
<p:dataGrid id="vehicleGrid" var="currentVehicle" value="#{vehicleInfoBean.getVehicleList()}" columns="#{vehicleInfoBean.getVehicleList().size()}" styleClass="vehicleInfoPanel" rowIndexVar="rowIdx">
<p:panel header="VEHICLE ##{rowIdx+1}:" style="width:100%" styleClass="textEntryInputTable">
<h:panelGrid columns="1" style="width:100%" styleClass="vehicleInfoPanel">
<ui:include src="../components/vehicleinfo/vehiclecomponents.xhtml">
<ui:param name="currentVehicle" value="#{currentVehicle}" />
<ui:param name="labelOnly" value="false" />
</ui:include>
<div class="deleteButton">
<p:commandButton value="Remove" label="Delete Vehicle" action="#{vehicleInfoBean.deleteVehicle}" update=":vehicleInfoForm:vehicleGrid" process="#this">
<f:setPropertyActionListener value="#{currentVehicle}" target="#{vehicleInfoBean.currentVehicle}" />
</p:commandButton>
</div>
</h:panelGrid>
</p:panel>
</p:dataGrid>
Any ideas? I have tried all sorts of update values including #form, but it's all the same. I haven't used a dataGrid before but I need the iterative capabilities that ice:panelSeries has.
UPDATE: Here's the code in the include:
<h:panelGrid columns="2">
<p:inputText id="vinInput" styleClass="stdFieldControl" value="#{currentVehicle.vin}" label=""
required="true" requiredMessage="VIN is required" >
<p:ajax update="#this vinMsg"/>
</p:inputText>
<p:message id="vinMsg" for="vinInput" errorClass="ui-state-error-text"/>
<p:outputLabel value="-----OR-----"/>
</h:panelGrid>
1/14/2013 - Updated code
<p:dataGrid id="vehicleGrid" var="currentVehicle" value="#{vehicleInfoBean.getVehicleList()}" columns="#{vehicleInfoBean.getVehicleList().size()}" styleClass="vehicleInfoPanel" rowIndexVar="rowIdx">
<p:panel header="VEHICLE ##{rowIdx+1}:" style="width:100%" styleClass="textEntryInputTable">
<h:panelGrid columns="1" style="width:100%" styleClass="vehicleInfoPanel">
<p:inputText id="vinInput" styleClass="stdFieldControl" value="#{currentVehicle.vin}" label="" required="#{empty param['vehicleGrid:0:btnDelete'] and empty param['btnAdd']}" requiredMessage="VIN is required" >
</p:inputText>
<p:message id="vinMsg" for="vinInput" errorClass="ui-state-error-text"/>
<p:outputLabel value="-----OR-----"/>
<h:inputText id="yearInput" styleClass="stdFieldControl" value="#{currentVehicle.year}" label=""
required="#{empty param['vehicleGrid:0:btnDelete']}" requiredMessage="Year is required">
</h:inputText>
<p:message id="yearMsg" for="yearInput"
errorClass="ui-state-error-text"/>
<div class="deleteButton">
<p:commandButton id="btnDelete" value="Remove" label="Delete Vehicle" action="#{vehicleInfoBean.deleteVehicle}" update="#form">
<f:setPropertyActionListener value="#{currentVehicle}" target="#{vehicleInfoBean.currentVehicle}" />
</p:commandButton>
</div>
</h:panelGrid>
</p:panel>
</p:dataGrid>
The add code looks like this:
<div class="addButton" style="padding-left: 2.17%; float: left; clear: both">
<p:commandButton id="btnAdd" value="AddVehicle" label="Add Vehicle" actionListener="#{vehicleInfoBean.addVehicle}" update="vehicleGrid"/>
</div>
Instead of putting the check on the buttons, I decided to set the required attribute of the components referring to the buttons. This code works if I hardcode the iterator index. For example, required="#{empty param['vehicleGrid:0:btnDelete']}". This code points to the first delete button in the panelGrid. What I need is to dynamically derive the index to this - required="#{empty param['vehicleGrid:#{rowIdx}:btnDelete']}". The add button was easy since it doesn't reside in an iterator. How do I code the param in a way that I can dynically refer to the rowId of the panelGrid? The RowId looks confusing but this is coded in a way that each Vehicle Panel is displayed next to the previous panel. The row in this case can be thought of as a column. Anyone have any ideas?

How to get rid of the auto generated j_idt ID in composite component

I'm using below composite component:
<composite:interface>
<composite:attribute name="inputId" />
</composite:interface>
<composite:implementation>
<h:panelGrid id="myTableId">
<h:inputText id="#{cc.attrs.inputId}" value="..." />
...
</h:panelGrid>
</composite:implementation>
And I'm using it in my form as below:
<h:form id="myForm">
<myCompositeComp:test inputId="myInputTextBoxId" />
<h:form>
I've verified the view source for the page and this is how it is generated:
<table id="myForm:j_idt90:myTableId">
...
<input type="text" id="myForm:j_idt90:myInputTextBoxId" />
</table>
How can I get rid of j_idt90 here? Is it the id of my composite component? I read from one of BalusC post that this issue will get fixed if I declare id as static. But I'm not able to identify the place to declare it in my code. Also can I assume <h:panelGrid> is a kind of UINamingContainer?
Yes it is the id of your composite component, <h:panelGrid> is not a UINaminContainer but the composite component is (it has to be, otherwise you would have duplicate IDs if you use it several times inside the same form for example).
Why do you need to get rid of the ID? You can set it yourself if that solves your problem:
<h:form id="myForm">
<myCompositeComp:test id="myComp" attr1="" attr2="" />
<h:form>
the genereated html should look like this:
<table id="myForm:myComp:myTableId">
....
<input type="text" id="myForm:myComp:myInputTextBoxId"
</table>

JSF 2.0 Edit user szenario

I have programmed a little application in which you can register and edit your data. For the authenticity I used a bean class called Authenticity. This class contains an object of Customer (which is a database entity) and methods to login and to logout.
Now I´ve created a page for editing the user: A form with many inputTexts which have the value of authenticity.curUser./(properties). It look like this:
<h:form>
<h:panelGrid columns="2" cellpadding="4px" width="600">
<h:outputText value="firstname:" />
<h:inputText value="#{authenticity.curUser.firstname}"/>
<h:outputText value="lastname:"/>
<h:inputText value="#{authenticity.curUser.lastname}" />
<h:outputText value="street:"/>
<h:inputText value="#{authenticity.curUser.street}" />
<h:outputText value="housebumber"/>
<h:inputText value="#{authenticity.curUser.housenumber}" />
<h:outputText value="Zip:"/>
<h:inputText value="#{authenticity.curUser.zip}" />
<h:outputText value="City:"/>
<h:inputText value="#{authenticity.curUser.city}" />
<h:outputText value="Land"/>
<h:inputText value="#{authenticity.curUser.country}" />
<h:outputText value="email:"/>
<h:inputText value="#{authenticity.curUser.email}" />
<h:outputText value="password:"/>
<h:inputSecret value="#{authenticity.curUser.password}" />
<h:commandButton action="#{authenticity.editUser}" value="Edit" />
</h:panelGrid>
</h:form>
My question now is whether there are better solutions for this problem. Should a AuthenticityBean be actually able to edit the user? Or should I create a extra bean?
I would use a completely separate view scoped bean which holds a brand new copy of the entity representing the logged-in user. Only when the form is successfully edited and saved, then the currently logged-in user can be replaced (the form bean can just access it as a #ManagedProperty).
If you were reusing the same entity in the form; imagine that you're ajax-updating some fields and then cancels/closes the form. The currently logged-in user would then still have the "Wrong" field values in the remnant of the session. This is not correct.

Resources