How to render an element whose id is automatically generated in JSF? - jsf-2

I have primefaces'datatable placed on primefaces tabView..
I m using filtering on it. As new values are updated in the grid, I want to re-render the filters.
The filter id is generated as: tabViewId:ActiveTabIndex:DatatableID:ColumnName_filter.
On value change of input text, I want to re-render the filter.
<p:column width="40">
<h:inputText id="vendorInputTxt" value="#{articlePromo.proveedor}"
styleClass="inputTextStyle">
<f:ajax event="change" render=":categoryTabView:0:promotionDetail_dataTable:vendorColumnHeader_filter"
listener="#{promotionDetailManagedBean.onProveedorChange}" />
</h:inputText>
</p:column>
But it gives the error, contains an unknown id ':categoryTabView:0:promotionDetail_dataTable:vendorColumnHeader_filter' - cannot locate it in the context of the component vendorInputTxt
What is the right way to render the filter again?
Thanks,
Shikha

try a js call oncomplete to: widget_<dataTableId>.filter(); where the dataTableId is the id given to the dataTable.

Related

Rendering of an element depending on primefaces rating

I started using primafaces and I came up with the following scenario. The user rates and element and if the rating is valid then a span block appears or it hides depending the case. I am based on the example here: (http://www.primefaces.org/showcase/ui/input/rating.xhtml ) with the ajax approach. Note that a rate is valid if the user clicks on any star. So here's what I've done so far:
<h:form>
<p:panelGrid>
<p:row>
<p:column>
<p:rating value="#{searchBean.dateWeight}">
<p:ajax event="rate" listener="#{searchBean.addDatetoWeights}"
update="dates" render="dates" />
<p:ajax event="cancel"
listener="#{searchBean.removeDatefromWeights}"
update="dates" />
</p:rating>
<h:panelGroup id="dates" rendered="#{searchBean.dateRated}">
<h:outputText value="test"></h:outputText>
</h:panelGroup>
</p:column>
</p:row>
</p:panelGrid>
</h:form>
segment of the bean:
boolean dateRated;
int dateWeight;
public void addDatetoWeights(){
dateRated=true;
weights.put("date",dateWeight);
System.out.println(dateRated);
}
public void removeDatefromWeights(){
dateRated=false;
if(weights.containsKey("date"))
weights.remove("date");
}
Let's go back to the basics: HTML and JavaScript. It's important to also know them before diving into JSF. JSF is in the context of this question merely a HTML/JS code generator.
With <p:ajax update="dates"> you're basically telling JavaScript to grab the HTML element by the given ID and then replace its contents with the new contents retrieved from server in ajax response. However, as the <h:panelGroup id="dates"> is in first place never rendered to the HTML output, JavaScript can't find the element by document.getElementById() stuff in order to replace its contents and then just ignores the instruction.
Instead, the <p:ajax update="dates"> must refer a component which is always rendered, so that JavaScript can actually find it. Only its contents can be conditionally rendered.
Here's a rewrite:
<h:panelGroup id="dates">
<h:outputText value="test" rendered="#{searchBean.dateRated}" />
</h:panelGroup>
See also:
Why do I need to nest a component with rendered="#{some}" in another component when I want to ajax-update it?

Prime Faces InputText inside an ordered list

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.

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"

Select Item from many menu

Ok I have a simple many menu in wich I call a listener
<p:selectManyMenu style="width: 100%;" id="cmbsectores" valueChangeListener="#{mbcompletado.removeItem}">
<f:selectItems value="#{mbcompletado.sectores}"/>
<f:ajax update="#this"/>
</p:selectManyMenu>
I am looking the way I can use the ValueChangeEvent pass as parameter to detect which item was selected??
So I can use my business logic!
Do i need to use ajax tag? I found an itemSelect event in primeface, framework which I am using, but it only works on charts components!
Thanks in advance
Since you are already using PrimeFaces use p:ajax instead of f:ajax. The event is already set to the appropriate event (valueChanged).
To detect the selected values of the selectManyMenu the value attribute is necessary:
<p:selectManyMenu style="width: 100%;" id="cmbsectores"
value="#{mbcompletado.selectedSectores}">
<f:selectItems value="#{mbcompletado.sectores}"/>
<p:ajax/>
</p:selectManyMenu>
You can remove the valueChangeListener listener altogether.
For a more complete example see SelectManyMenu.
EDIT:
In your backing bean mbcompletado.selectedSectores should point to a collection of the same type like your mbcompletado.sectores. For example, if your sectores is a List of TypeA, selectedSectores should be also a List of the same type (TypeA).
Similar backing-bean structure can be found in the following example SelectManyCheckbox.
You need the <f:ajax listener> (or in this case better <p:ajax listener>) method instead. The ValueChangeListener serves an entirely different purpose and should only be used when you're really interested in both the old and new value, not when you're only interested in the new value.
E.g.
<p:selectManyMenu value="#{bean.selectedSectors>
<f:selectItems value="#{bean.availableSectors}"/>
<p:ajax listener="#{bean.selectedSectorsChanged}" />
</p:selectManyMenu>
with
private List<String> selectedSectors;
private List<String> availableSectors;
public void selectedSectorsChanged() {
System.out.println("Selected sectors are: " + selectedSectors); // Look, JSF has already set it.
// ...
}
See also:
When to use valueChangeListener or f:ajax listener?

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