multiple f:ajax calls in multiple h:selectOneMenu - java

Consider the following form:
1. User selects a value from the selectOneMenu "selectorDB"
2. Ajax call returns items for the second selectOneMenu and makes the whole "second" panelGroup rendered
3. User selects a value from the second selectOneMenu
4. Ajax call returns String which is placed inside of the inputText and panelGroup which contains that inputText rendered.
Everything works fine till im not selecting a value from the second selectOneMenu. Ajax of the fourth action is not even called. I've placed a couple of console System.outs to check if the listener is called and got nothing.
Is that possible to make something like the thing I'm attempting to do?
Thank you for any replies.
*.jsf:
<h:form>
<h:panelGroup id="first">
<h:outputLabel value="Select a database to make queries against" for="selectorDB" />
<h:selectOneMenu id="selectorDB" value="#{sparqlQuerier.chosenRing}">
<f:selectItem itemLabel="Select..." itemValue="0" />
<f:selectItems value="#{sparqlQuerier.ringTitles}" />
<f:ajax render="second third" listener="#{sparqlQuerier.firstListener}"/>
</h:selectOneMenu>
</h:panelGroup>
<br />
<h:panelGroup id="second">
<h:outputLabel rendered="#{sparqlQuerier.doRenderSecond}" value="Select a query to execute" for="selectorQuery" />
<h:selectOneMenu rendered="#{sparqlQuerier.doRenderSecond}" id="selectorQuery" value="#{sparqlQuerier.chosenQuery}">
<f:selectItem itemLabel="Select..." itemValue="0" />
<f:selectItems value="#{sparqlQuerier.queries}" />
<f:ajax render="third" listener="#{sparqlQuerier.secondListener}"/>
</h:selectOneMenu>
</h:panelGroup>
<br />
<h:panelGroup id="third">
<h:inputText rendered="#{sparqlQuerier.doRenderThird}" value="#{sparqlQuerier.queryBody}" onfocus="if (this.value == '#{sparqlQuerier.queryBody}') {this.value = '';}" onblur="if (this.value == '') {this.value ='#{sparqlQuerier.queryBody}';}" />
</h:panelGroup>
</h:form>
bean:
public void firstListener(AjaxBehaviorEvent event)
{
doRenderThird = false;
doRenderSecond = false;
if(chosenRing!=0)
{
doRenderSecond = true;
try
{
// returning rows from the database...
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
public void secondListener(AjaxBehaviorEvent event)
{
doRenderThird=false;
if(chosenQuery!=0)
{
if(chosenQuery==-1)
{
queryBody="body #1";
}
else
{
queryBody="body #2";
}
doRenderThird=true;
}
System.out.println(chosenQuery);
System.out.println(doRenderThird);
}

Related

PrimeFaces 8 - Lazy p:dataScroller - issue with Drag and Drop

We use a p:dataScroller with a LazyDataModel to display products that can be dragged from lazy loaded search results and dropped into a shopping cart.
When more than one chunk of results have been loaded, we are only able to drag/drop items from the most recent chunk of data. If I try to drop an item from the first chunk into my cart, it will incorrectly drop the corresponding item from the most recently loaded chunk in stead.
Example: After the DataScroller has performed 3 lazy loads (3 chunks displayed), if I try to drop the 5th item from the first or second chunk of results, the 5th item from the 3rd chunk of results will be returned by the DragDropEvent.getData() method.
Our Facelets template looks something like this. The droppable element is the sticky header, which is a div with id = headerPanel.
<h:body>
<h:form id="form1">
<p:growl id="msgs" showDetail="true" life="2000">
<p:autoUpdate />
</p:growl>
<h:panelGroup id="headerPanel" layout="block" styleClass="header">
<ui:include src="/WEB-INF/includes/layout/Header.xhtml" />
</h:panelGroup>
<p:droppable for="headerPanel"
scope="shoppingCartAdd"
datasource="productScroller"
hoverStyleClass="dragActive"
tolerance="touch">
<p:ajax listener="#{shoppingCart.addProductToShoppingCart}"
update="shoppingCartButton shoppingCartSidebar" />
</p:droppable>
<ui:include src="/WEB-INF/includes/layout/ShoppingCartBar.xhtml" />
<h:panelGroup id="contentPanel" layout="block" styleClass="content">
<ui:insert name="contentPanel">Content</ui:insert>
</h:panelGroup>
</h:form>
</h:body>
The p:draggable elements are inside a p:dataScroller in a ui-composition that defines the contentPanel from our Facelets template:
<ui:composition template="/WEB-INF/templates/Layout.xhtml">
<ui:param name="title" value="Product Search" />
<ui:define name="contentPanel">
<p:commandButton id="submitButton"
action="#{productSearchBean.searchAction}"
ajax="false"
value="Find All Products" />
<h:panelGrid id="resultsGrid" styleClass="resultsGrid">
<p:dataScroller id="productScroller"
buffer="5"
chunkSize="10"
lazy="true"
rendered="#{productSearchBean.productList.rowCount > 0}"
rowIndexVar="resultIndex"
styleClass="scroller"
value="#{productSearchBean.productList}"
var="rowProduct">
<p:panel id="searchResultsPanel"
header="#{resultIndex + 1} - Product ##{rowProduct.productId}"
closable="true"
toggleable="true"
styleClass="searchResultsPanel">
<h:panelGrid id="productDataGrid" columns="2" columnClasses="thumbnailPanel, textPanel">
<h:panelGroup id="imageDiv" layout="block" styleClass="thumbnailContainer">
<span class="alignmentHelper" />
<p:graphicImage id="thumbnailImage" styleClass="thumbnailImage" value="#{rowProduct.thumbnailUrl}" />
<p:draggable for="thumbnailImage" helper="clone" revert="true" scope="shoppingCartAdd" />
</h:panelGroup>
<h:panelGrid id="textDataGrid" columns="2" columnClasses="padRight, padLeft">
<h:outputText value="id:" /> #{rowProduct.productId}<br/>
<h:outputText value="name:" /> #{rowProduct.productName}<br/>
</h:panelGrid>
</h:panelGrid>
</p:panel>
</p:dataScroller>
</h:panelGrid>
</ui:define>
</ui:composition>
Here's the listener method that gets invoked on a drop event. As mentioned above, the DragDropEvent.getData() method returns the wrong data item if multiple lazy loads have occurred and the user is trying to drag/drop an item from anything but the most recent chunk of data:
public void addProductToShoppingCart(DragDropEvent shoppingCartDropEvent) {
Long draggedId = productIdFromDragDrop(shoppingCartDropEvent);
if (addProductToDefaultShoppingCart(userId, draggedId)) {
fetchShoppingCartProducts();
addSuccessMessage(draggedId);
}
else {
addErrorMessage(draggedId);
}
}
private Long productIdFromDragDrop(DragDropEvent productDroppedEvent) {
Long droppedProductId = null;
Object dropObj = productDroppedEvent.getData();
if (dropObj != null && dropObj instanceof ProductView) {
ProductView view = (ProductView) dropObj;
droppedProductId = view.getProductId();
}
return droppedProductId;
}
Thanks for reading :)

<p: ​selectOneMenu /> <f: selectItems> do not appear

I'm developing a java application using jsf and put the <p: ​​selectOneMenu /> component primefaces in my project,But the <p: ​​selectOneMenu /> <f: selectItems> component items do not appear and <selectOneMenu /> has disappeared
UPDATE
<h:panelGroup layout="block" styleClass="tamanho">
<p>Tamanho:</p> <p:selectOneMenu id="tamanhos" value="#{tamanho.tamanho}" styleClass="tamanho" effect="fold" editable="true">
<f:selectItem itemValue="#{null}" itemLabel="-- select one --" />
<f:selectItems value="#{tamanho.tamanhos_roupas}" />
</p:selectOneMenu>
#ManagedBean(name="tamanho")
#RequestScoped
public class Tamanho {
private String tamanho;
private List<SelectItem> tamanhos_roupas; // +getter (no setter necessary)
#PostConstruct
public void init() {
tamanhos_roupas = new ArrayList<SelectItem>();
tamanhos_roupas.add(new SelectItem("PP", "PP"));
tamanhos_roupas.add(new SelectItem("P", "P"));
tamanhos_roupas.add(new SelectItem("M", "M"));
tamanhos_roupas.add(new SelectItem("G", "G"));
tamanhos_roupas.add(new SelectItem("GG", "GG"));
}
public String getTamanho() {
return tamanho;
}
public void setTamanho(String tamanho) {
this.tamanho = tamanho;
}
public List<SelectItem> getTamanhos_roupas() {
return tamanhos_roupas;
}
}
Look how the copier of the primefaces was, disappeared itens the <p:selectOneMenu/>
page
I'm assuming "#{tamanho.tamanhos_roupas}" is a list that has values in it already, so what you need to do is add 'var', 'itemValue' and 'itemLabel' in your selectItems tag.
The 'var' attribute is the name of the variable of your list elements in every iteration, 'itemValue' is what #{tamanho.tamanho} value will be after selecting an option and 'itemLabel' is what will the user read to identify that option.
<h:panelGroup layout="block" styleClass="tamanho">
<p>Tamanho:</p> <p:selectOneMenu id="tamanhos" value="#{tamanho.tamanho}"
styleClass="tamanho" effect="fold" editable="true">
<f:selectItem itemValue="#{null}" itemLabel="-- select one --" />
<f:selectItems value="#{tamanho.tamanhos_roupas}" var="tamanho"
itemValue="#{tamanho}" itemLabel="#{tamanho.stringNome}" />
</p:selectOneMenu>
See, the way your code is written you are only giving your SelectOneMenu the information you have items to iterate, but you never tell him what is the name and value of those items.

Primefaces call ConfirmDialog from Backing

I would like to call confirmDialog via backing. This code works perfectly, but how can I set the message and set the actionlistener of the confirmDialog via backing? There is two condition, while:
The user check the option A on the checkbox (I omitted the code), then it should be directly print a text to console. --> This one is done by the code below
The user check the option B on the checkbox, then it should be show the confirmDialog and while the user press YES button, it should be call another function on the backing.
How to do that? Thanks.
<p:commandButton value="Execute" icon="ui-icon-circle-check" update="frmContent" actionListener="#{backing.validate}" />
<p:confirmDialog id="cfmDlg" widgetVar="wvCfmDlg" global="true" >
<p:commandButton value="Yes" type="button" styleClass="ui-confirmdialog-yes" icon="ui-icon-check" />
<p:commandButton value="No" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close" />
</p:confirmDialog>
In Backing:
public void validate() {
if(mode.equals("1")) {
System.out.println("OK");
} else {
//call confirmDialog and set message + action listener
RequestContext context = RequestContext.getCurrentInstance();
context.execute("wvCfmDlg.show();");
}
}
If I understood your question correctly.. I would do it in this way.
xhtml
<p:commandButton style="display: none"
widgetVar="confirmButton"
actionListener="#{backing.yesFunction}" >
<p:confirm header="Confirmation" message="Are you sure?" />
</p:commandButton>
<p:commandButton value="Execute"
actionListener="#{backing.validate}" />
<p:confirmDialog id="cfmDlg" global="true" >
<p:commandButton value="Yes" />
<p:commandButton value="No" />
</p:confirmDialog>
bean
public void validate() {
if(mode.equals("1")) {
System.out.println("OK");
} else {
RequestContext context = RequestContext.getCurrentInstance();
context.execute("PF('confirmButton').jq.click();");
}
}
Basically you add a hidden button (with p:confirm) in the usual way and you click it through jQuery.

h:selectOneMenu change event with p:ajax

I am trying to get the value from on change in h:selectOneMenu using p:ajax.
But I am getting null value always, dont know whats wrong below is the code.
<h:form>
<h:selectOneMenu id="selectMenu" value="#{userHomeController.gymsSelectType}">
<f:selectItem itemLabel="Close to me" itemValue="closest" />
<f:selectItem itemLabel="Visited by me" itemValue="visited" />
<p:ajax process="selectMenu" listener="#{userHomeController.selectMenuListener}" event="change" update=":home-form:panel" />
</h:selectOneMenu>
</h:form>
and the bean class is
public void selectMenuListener() {
System.out.println("-------- >> " + gymsSelectType); // here null coming
if (gymsSelectType.equals("a")) {
//
} else {
//
}
}
this is a viewscoped class.
and below setter for the variable gymsSelectType is also prints null
public void setGymsSelectType(String gymsSelectType) {
System.out.println("------------ >> "+gymsSelectType);
this.gymsSelectType = gymsSelectType;
}
Have your tries this
<p:ajax process="#this" listener="#{userHomeController.selectMenuListener}" event="change" update=":home-form:panel" />
Try this
<p:ajax partialSubmit="true" listener="#{userHomeController.selectMenuListener}" event="change" update=":home-form:panel" />

How to display and update a "sub-page" within a condition (using primefaces)

I have a scenario to achieve but I don't know how to do it(I'am using primefaces)
The scenario is:
I have a selectOneMenu that contain options that the user can choose one of them,
when the user choose an option ,a "form" or a "Sub-page" should appear below the selectOneMenu , the user should fill it.
The "Sub-page" change according to the choosen option
eg :option1 ---> Sub-Page1
option2 --->Sub-Page2 etc..
JSF
<h:selectOneMenu style="width:200px" immediate="true" value="#{ToolsKPI.myChoice}" onchange="submit()" valueChangeListener="#{BeanTest.selectChangeHandler}" required="true" >
<f:selectItems value="#{ToolsKPI.getMyListKPI()}" />
</h:selectOneMenu>
<p:panel rendered="#{BeanTest.showPanelBool}" >
<h1>KPI1</h1>
<br></br>
<h:inputText value="test1" />
</p:panel>
<p:panel rendered="#{BeanTest.showPanelBool1}" >
<br></br>
<h1>KPI2</h1>
<h:inputText value="test2" />
<h:inputText value="test3" />
</p:panel>
My Bean
public class BeanTest implements java.io.Serializable {
private String myChoice;
private boolean showPanelBool;
private boolean showPanelBool1;
public BeanTest() {
}
//getters ande setters
public void selectChangeHandler(ValueChangeEvent event){
myChoice = (String) event.getNewValue(); // Must however be the exact page URL. E.g. "contact.jsf".
FacesContext.getCurrentInstance().getExternalContext();
if(myChoice.equals("Number Of Closed issues") ){
this.showPanelBool = true;
} else{
this.showPanelBool = false;
this.showPanelBool1 = true;
}
FacesContext.getCurrentInstance().renderResponse();
}
}
You should really post some semblance of the code: a picture something. What you're probably looking for is a "p:outputPanel" component or something similar.
http://www.primefaces.org/showcase/ui/outputPanel.jsf
You can do something with a ValueChangeListener akin to
public void onSelectItem(ValueChangeEvent evt)
{
if("someValue".equals(evt.getNewValue())
showPageOne = true;//boolean
else
showPageTwo = true;//boolean
}
//JSF
<h:form id="myForm">
<h:selectOneMenu valueChangeListener="#{myBean.onSelectItem}" update="myForm">
<f:selectItems value="items">
</h:selectOneMenu>
<p:outputPanel rendered="#{myBean.showPageOne}">
hi I'm page one
</p:outputPanel>
<p:outputPanel rendered="#{myBean.showPageTwo}">
hi I'm page two
</p:outputPanel>
</h:form>
Sorry for the pseudo code, the examples on Primefaces will really help you here. OutputPanel has saved my bacon often. You'll need to specify an update target, but the example is really clear and easy to run. Play with it.
(Also Primefaces is fantastic you'll likely be very happy with their component suite)

Categories

Resources