Prime Faces InputText inside an ordered list - jsf-2

I have a requirement in primefaces to have an inputText inside an orderlist and on changing the inputText want to reflect it in the object model. But i suppose there is a bug or some kind of problem as whenever I submit the form there is a null pointer error. It says that the object is unreachable. The weird part is that it does show the correct data (ie. gets the data) but is unable to set it.
<p:orderList value="#{artifactController.uploadedFiles}"
var="uploadedFile" itemValue="#{uploadedFile}"
controlsLocation="left" id="artifactList"
converter="customUploadedFileConverter"
selection="#{artifactController.selectedUploadedFile}"
selectionMode="single">
<p:column style="width:25%">
<p:graphicImage
value="/faces/pages/image#{uploadedFile.imagePath}?mimeType=#{uploadedFile.mimeType}"
width="100" height="50">
</p:graphicImage>
</p:column>
<p:column style="width:75%;">
<p:inputText value = #{uploadedFile.fileName} ></p:inputText>
</p:column>
</p:orderList>
The Controller has all the setters and getters in place.
The input text shows the data while retrieving but fails to update the value in the controller. Isn't it supposed to work like that (similar to dataTable). It gives uploadedFile is unreachable error.

Related

Primefaces enum output facet updates wrong

I'm facing some problems using a primefaces cell editing table. So, I have a datatable, which contains an editable column. This datatable is populated through a list of jpa entity.
Focusing on wich matters, my editable cell, has an outputText in the output facet and a selectOneMenu in the input facet, which is populated by an enum.
My problem is that, datatable is correctly loaded at beginning, I can successfully edit the wanted field, selectOneMenu is correctly populated with enum. If I choose an option in the selectOneMenu, it gets fine, HOWEVER when I click outside the datatable (to quit editing mode), it gets a wrong value, since it gets the code, and it should get description.
My code:
Enum:
public enum EnumSimNao implements DetalheDominioEnum {
/**
* Sim
*/
S("Sim"),
/**
* Não
*/
N("Não");
Enum has a getter that refreshes the value based in some services. It always get those values from the service. I've tested it and the values are right here. When I say description, I mean "Sim" or "Nao", and the codes are respectively "S" or "N". From the database it comes a code, that is associated with enum through an #Enumerated attribute in an jpa entity. When I have #{tp.respostaObrigatoria.description} it returns me "Sim" or "Não" based on the returned code.
public String getDescription() {
DetalheEstaticoDominioEnumHelper.INSTANCE.fillDescriptions(this);
return description == null ? defaultDescription : description;
}
#Override
public void setDescription(String description) {
this.description = description;
}
xhtml:
<p:cellEditor>
<f:facet name="output">
<h:outputText
value="#{tp.respostaObrigatoria.description}" />
</f:facet>
<f:facet name="input">
<h:selectOneMenu value="#{tp.respostaObrigatoria}">
<f:selectItems value="#{Factories.enumSimNao}" var="simNao"
itemLabel="#{simNao.description}" itemValue="#{simNao}" />
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
tp is an entity whcih comes from a list that comes from backing bean:
So, when I edit the cell, I can see both descriptions ("Sim" or "Nao"), but when I exit the edit mode it shows "S" or "N". Finally, if I refresh the page, it gets the correct description value I had choose.
Do you have any tip?
Thanks
Primefaces 3.5 has this bug which apparently was filed under this issue http://code.google.com/p/primefaces/issues/detail?id=6116 and solved in version 3.5.15 which is only available on Elite version. Version 4.0 seems to have this fixed.
I found a workaround for 3.5 which involves re-rendering the form enclosing the datatable which is working fine for me.
What you need to do is to use an ajax event listener inside the selectOneMenu component which triggers the render of the form like this:
<p:cellEditor>
<f:facet name="output">
<h:outputText
value="#{tp.respostaObrigatoria.description}" />
</f:facet>
<f:facet name="input">
<h:selectOneMenu value="#{tp.respostaObrigatoria}">
<f:selectItems value="#{Factories.enumSimNao}" var="simNao"
itemLabel="#{simNao.description}" itemValue="#{simNao}" />
<f:ajax listener="#{bean.submit}" render="#form" />
</h:selectOneMenu>
</f:facet>
</p:cellEditor>

can't refresh a selectOneMenu

first excuse my english if it's not correct ...
I've a probleme with a primeface's component, I'm trying to refresh a p:selectOneMenu from a p:commandButton, but it's doesn't work (it 's work on another xhtml page, but not here and I can't understand why ...)
First I select an item from an p:autocomplete which update a backingbean's attribute ( for example : userChoose ).
then the p:commandButton is able to call his listener and add userChoose to a list, but i can't refresh the selectOneMenu that display the list. I have to use another p:commandButton to refresh the list.
My form is included into a p:tabMenu in another xhtml page.
<p:autoComplete id="acPojo" value="#{forumBean.user}"
completeMethod="#{autoCompleteBean.completeUser}"
converter="#{userConverter}" forceSelection="true"
var="usr" itemLabel="#{usr.loginUtilisateur}" itemValue="#{usr}">
<p:column>
<h:outputText value="#{usr.loginUtilisateur}"/>
</p:column>
</p:autoComplete>
<p:commandButton value="ajouter" process="acPojo #this "
udpate=":tabView:formSujet:listeUser" actionListener="#{forumBean.addUser}"/>
<p:selectOneMenu value="#{forumBean.user}" converter="#{userConverter}" var="us" id="listeUser"
itemValue="#{us}" itemLabel="#{us.loginUtilisateur}">
<f:selectItems value="#{forumBean.newSujet.listeUserAllowed}" var="User"
itemValue="#{User}" itemLabel="#{User.loginUtilisateur}" />
<p:column>
<h:outputText value="#{us.loginUtilisateur}"/>
</p:column>
<p:ajax process="#this" />
</p:selectOneMenu>
<p:commandButton id="refreshAdmin" icon="ui-icon-arrowrefresh-1-w"
update=":tabView:formSujet:listeUser" />
Thanks for help.
From your code:
udpate=":tabView:formSujet:listeUser"
This has at least 2 (potential) mistakes. The right attribute name is update, not udpate. The one on your other button has however the right attribute name.
It that still doesn't work, then the other potential mistake is that the client ID tabView:formSujet:listeUser does not exist in HTML DOM tree (and thus JavaScript/jQuery is unable to find and replace it). That can happen if the <p:tabView> is dynamic (i.e. you're using <p:tabView value="#{bean.tabs}" var="tab">, because it prepents the tab index number in the final client ID like so tabView:0:formSujet:listeUser if it's the 1st tab.
But, after all, as both the dropdownlist and the commandbutton are in the same NamingContainer parent, you don't need an absolute client ID at all. Just the relative client ID should suffice:
update="listeUser"
Fix that on your both buttons.
See also:
How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"

Initial sortorder for PrimeFaces datatable with multisort

I am trying to implement multisort on Primeface datatable. We are using Primefaces v3.5. I have created a new load method in the LazyLoadClass that takes the List of SortMeta> parameter.
But I am having issues in the initial load of the table. The List of SortMeta> is null when the load method is called. I have also tried without specifying the initial sortBy and sortOrder for the datatable. In both the cases the result is the same.
Seeing that we have this new class SortMeta to support multisort, I suspect that the way to specify the initial sort field and order would have also changed. But I couldn't find any example anywhere to point the difference. The manual 3.5 doesn't mention any difference.
Why we could be getting the List of SortMeta> as null? Any pointers on example code where multisort is used with Lazyload?
I was able to get this to work.
Essentially we need to provide the UIColumn in the SortMeta object for it to work. For the initial sort at render time, I had to find the component in my bean and assign that to the sortMeta.
Below is my code in the view xhtml
<p:dataTable id="transDataTable" var="trans"
value="#{myBean.transModel}" paginator="true" rows="50"
paginatorAlwaysVisible="false" lazy="true"
sortMode="multiple" sortBy="#{myBean.preSortOrder}"
resizableColumns="true">
<p:column headerText="User" sortBy="#{trans.user.name}" >
#{trans.user.name}
</p:column>
<p:column headerText="Company" sortBy="#{trans.companyName}">
#{trans.companyName}
</p:column>
<p:column headerText="Join Date" id="joinDateTime"
sortBy="#{trans.joinDateTime}" >
<h:outputText value="#{trans.joinDateTime}" />
</p:column>
</p:dataTable>
Here is my bean code called on #PostConstruct
/*
* method to build initial sort order for multisort
*/
private void buildSortOrder() {
UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
UIComponent column = viewRoot.findComponent("transDataTable:joinDateTime");
SortMeta sm1 = new SortMeta();
sm1.setSortBy((UIColumn)column);
sm1.setSortField("joinDateTime");
sm1.setSortOrder(SortOrder.DESCENDING);
preSortOrder.add(sm1);
}
I am not sure this is the right way to do this, but it works. I am usually uncomfortable when we have to use the ids from view in the bean code, as that can introduce bugs when people are not careful.
Thanks #CagatayCivici for the quick hint.

jsf validation for datatable

I want to validate the below datatable only if user doesn't enter any values in the given p:inputText field
<p:dataTable id="depositDataTable" value="#{pc_intimationDeposit.pendingRep.depositeBeans}" var="deposit">
<p:column style="text-align:right">
<h:outputText value="#{deposit.depParticulars}" />
</p:column>
<p:column id="value">
<h:inputText id="depositDetails" class="right_input" value="#{deposit.amnt}" tabindex="2" converterMessage="Please Enter Numbner's Only" validatorMessage="please">
<f:convertNumber pattern="##,####,##0.00" for="depositDetails" type="currency" />
</h:inputText>
<p:message id="errMsgDepositDetails" for="depositDetails" display="text"></p:message>
</p:column>
</p:dataTable>
pc_intimationDeposit.pendingRep.depositeBeans----> is a list(size 3) of depositBeans
i have used f:convertNumber for the entered values are correct to our requirements
but if user doesn't enter A SINGLE VALUE then i need validate for null check
i.e., user has to enter any one field
and i need to display the error message on top of the datatable used
please help me
Thank in you advance
If you want to have every depositDetail inputs populated, mark
them with required=true.
If you only want to have one of them filled, on your action method,
iterate over your model to ensure there's at least one not empty (you shouldn't have null values here):
boolean filled = false;
for (DepositeBean dep : depositeBeans){
if (!dep.getAmnt.equals("")){
filled = true;
}
}
if (!filled){
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage(FacesMessage.SEVERITY_ERROR, "You have to fill at least one deposit detail field", null));
}
For messages to be displayed, add an h:message tag and point it to your table:
<h:message for="depositDataTable" style="color:red" />

Toggle Image on select in JSF extendedDataTable

I am trying to get an image to swap back and forth based on if a row is selected in an extenedDataTable. I am able to display the image in the non-active state but can't figure out how to toggle it. Here is the table definition code:
<rich:extendedDataTable style="width: 800px; height: 150px;"
rowClasses="Row0,Row1" value="#{myBean.exceptions}" var="exception"
selectionMode="single" id="Table" selection="#{myBean.exceptionSelection}">
<a4j:ajax event="selectionchange" listener="#{myBean.rowListener}" render=""/>
Here is the column whose image I want to toggle. The idea is to change to an image called filledRadioButton in the same directory:
<rich:column id="selected_col" label="Selection">
<f:facet name="header">
<a4j:commandLink value="Selection" render="table"/>
</f:facet>
<h:graphicImage value="../resources/img/emptyRadioButton.jpg"/>
</rich:column>
Thanks
You can use the dataTable's ajaxKeys attribute to specifically reference a row (or rows) for ajax update. So to effect this :
Bind the ajaxKeys attribute of your data table to a Set<Integer> in your backing bean. This set will hold unique id type values that will refer to specific entities in your datatable to be updated in an ajax response.
Add the id attribute of the <h:graphicImage/> you wish to update via ajax to the render list of your <a4j:ajax/>. Set the value of the image to a dynamic expression so you can switch it out in the backing bean
<a4j:ajax event="selectionchange" listener="#{myBean.rowListener}" render="indicatorImg"/>
<h:graphicImage id="indicatorImg" value="#{myBean.desiredImagePath}"/>
Wire your ajax listener to add the id of the selected entity to the ajaxKeys Set and modify the desiredImagePath property as you see fit.
public void rowListener(AjaxBehaviourEvent evt){
//I assume you're already managing your selection properly
//Change the value of the desiredImagePath here too.
ajaxKeysSet.add(mySelection.getId()); //if you want to update multiple rows
OR
ajaxKeysSet = Collections.singleton(mySelection.getId()); //save a single id for ajax update
}

Resources