JSF - Change panelGroup by using ajax calls - Beans, EL and? - java

I have to make a sort of switch of some panelGroup UI.
About the view section, i made this :
<h:panelGroup layout="block" id="profile_content">
<h:panelGroup layout="block" styleClass="content_title">
Profilo Utente
</h:panelGroup>
<h:panelGroup rendered="#{selector.profile_page=='main'}">
<ui:include src="/profile/profile_main.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{selector.profile_page=='edit'}">
<ui:include src="/profile/profile_edit.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{selector.profile_page=='insert'}">
<ui:include src="/profile/profile_articles.xhtml" />
</h:panelGroup>
</h:panelGroup>
Now, to change this value, i written an exclusive JavaBean, called Selector :
#ManagedBean(name="selector")
#RequestScoped
public class Selector {
#ManagedProperty(value="#{param.profile_page}")
private String profile_page;
public String getProfile_page() {
if(profile_page==null || profile_page.trim().isEmpty()) {
this.profile_page="main";
}
return profile_page;
}
public void setProfile_page(String profile_page) { this.profile_page=profile_page; }
}
So, right now succeeds my problem : when i change the "context" by using some h:commandButton, i'd like to use asynch call to the server. This is my Button Panel :
<h:commandButton value="EDIT">
<f:ajax event="action" execute="???" render=":profile_content"/>
</h:commandButton>
<h:commandButton value="PM">
<f:ajax event="action" execute="???" render=":profile_content"/>
</h:commandButton>
<h:commandButton value="ARTICLES">
<f:ajax event="action" execute="???" render=":profile_content"/>
</h:commandButton>
I don't know what to put on execute, so that i edit the Beans value and i change the context by using render=":profile_content"
Hope this question is comprehendible. Forgive me about language :)
Cheers

Use f:setPropertyActionListener. You don't need to override the default of f:ajax's execute attribute (which is #this, the sole button).
E.g.
<h:commandButton value="EDIT">
<f:setPropertyActionListener target="#{selector.profile_page}" value="edit" />
<f:ajax event="action" render=":profile_content"/>
</h:commandButton>
Note that the Java Coding Conventions recommends CamelCase over under_score. I'd suggest to fix profile_page to be profilePage. This is Java, not PHP.

Related

Load in java chords of dynamic primefaces dragable components

I am trying to load in java chords of dynamic primefaces dragable components.
My code has this look:
Primefaces
<ui:repeat value="#{bbean.list}" var="dato">
<h:panelGroup id="conpnl#{loop.index}" layout="block">
<p:outputLabel value="#{dato.desc}" />
<p:selectOneMenu id="datoCombo#{loop.index}">
<f:selectItem itemValue="" itemLabel="" />
<f:selectItems value="#{dato.values}" var="values"
itemLabel="#{value.descripcion}" itemValue="#{value.codigo}" />
</p:selectOneMenu>
<p:draggable for="conpnl#{loop.index}" containment="parent"/>
</h:panelGroup>
</ui:repeat>
<h:panelGroup>
<p:commandButton id="saveChords" actionListener="#{bbean.saveChords}"
update="#form" oncomplete="client.setDirty(false);"/>
</h:panelGroup>
Java
public void saveChords() {
UIComponent theContainer = FacesContext.getCurrentInstance().getViewRoot().findComponent("mainForm:tabs:j_idt199:0:datoCombo");
//This is dinamically how the browser has named the component (this is a test)
}
but i am not able to do it due these problems:
1)The java instruction FacesContext.getCurrentInstance().getViewRoot().findComponent("mainForm:tabs:j_idt199:0:datoCombo");
doesn't retrieve any component, but this other one yes:
FacesContext.getCurrentInstance().getViewRoot().findComponent("mainForm:tabs:j_idt199:datoCombo");
How can i retrieve components defined dynamically inside ui:repeat?
2)If i could load the component in java side, how can i check its chords?

Dynamic dataTable form deletes its array when ajax is used

I have a dynamic dataTable that adds and removes objects. This works fine when I don't use ajax. However, when I use ajax, a problem occurs. Adding values initially is fine. However, when I start deleting objects, when I delete the last object, the items list gets deleted as well and becomes null. I am using jsf 2.2 with primefaces. I'm not sure what's causing this problem. My code is as follows.
item.xhtml
<h:panelGroup id="list">
<h:dataTable value="#{item.items}" var="object">
<h:column>
<!-- Figure out what these facets are or delete them -->
<f:facet name="keys">Keys</f:facet>
<p:inputText value="#{object.x}" />
</h:column>
<h:column headerText="Values">
<f:facet name="values">Values</f:facet>
<p:inputText value="#{object.y}" />
</h:column>
<h:column>
<h:commandLink value="Delete" action="#{user.removeObject(object)}">
<f:ajax execute="#form" render="#form" />
</h:commandLink>
</h:column>
</h:dataTable>
<h:commandButton value="add" action="#{user.addObject}">
<f:ajax execute="#form" render="#form" />
</h:commandButton>
</h:panelGroup>
item.java
#ManagedBean
#ViewScoped
public class Item implements Serializable{
public void addObject(){
Pair<String,String> tempPair = new Pair<String,String>("","");
items.add(tempPair);
return;
}
public void removeObject(Pair<String,String> i){
items.remove(i);
return;
}
}
UPDATE 1
I tried using jsf 2.1 instead, changing my viewAction to preRenderView, and my code works fine.
I think ajax is missing update properties. Try this:
<f:ajax execute="#form" render="#form" update="#form"/>
This is a bug in jsf 2.2.0. I replaced javax-faces-2.2.0.jar with javax-faces-2.2.1.jar and the issue disappeared.
Alternatively, another solution is to replace the <f:ajax> above with:
<f:ajax execute="#form" render=":form:list">
Apparently, the ajax call works fine in jsf 2.2.0 as long as the the whole form is not rendered.

Adding Dynamic content using JSF

hi chums I am new to JSF and I got stuck in JSF problem.I want to add dynamically my content in my JSF page.My requirment is that I have one facelets which I have to add in my page after some event.
My page contains
two fields 'user name' and 'answer'
and
two buttons 'login' and 'recover password'
Facelet contains
a field and just a button
Now I want that when I run my this page it should show only Page contents(described above)
and if user press the button 'recover password' then it should show the facelet under the components of page on the same page mean after pressing the button , page could include facelet.
But now when I run my code it show both as I haven't put any logic to add 2nd facelet dynamically.Here a patch of my code given below
<h:inputText id="txtLogin" styleClass="textEntry" required="true" requiredMessage="Username is required.">
</h:inputText>
<h:inputText id="answer" styleClass="textEntry" autocomplete="off" required="true" requiredMessage="Answer is required."></h:inputText>
<h:commandButton id="btnSave" value="Save" styleClass="formbutton" onclick="btnSave_Click" />
<h:commandButton id="btnRecover" value="Recover" styleClass="formbutton" onclick="btnRecover_Click"/>
Now I want when this btnRecover_click click then it include this facelet or run this code
<div class="divPadding">
<ui:include id="passrecov" src="ucPasswordRecovery.xhtml" rendered="false"/>
</div>
Keep in mind that I have to do this with JSF and don't want to do this with JavaScript
Thanks
I'll post a sample using with 1 column, remember that you could use another ui container.
<h:form>
<h:panelGrid id="login">
<h:panelGrid>
<h:inputText id="txtLogin" styleClass="textEntry" required="true"
requiredMessage="Username is required.">
</h:inputText>
<h:inputText id="answer" styleClass="textEntry" autocomplete="off"
required="true" requiredMessage="Answer is required.">
</h:inputText>
<h:commandButton id="btnSave" value="Save" styleClass="formbutton"
onclick="btnSave_Click" />
<h:commandButton id="btnRecover" value="Recover" styleClass="formbutton"
action="#{loginBean.showPassRecovery}" />
</h:panelGrid>
</h:panelGrid>
<h:panelGrid id="passRecovery">
<h:panelGrid rendered="#{not loginBean.loginEnabled}">
<ui:include id="passrecov" src="ucPasswordRecovery.xhtml" />
</h:panelGrid>
</h:panelGrid>
</h:form>
And your managed bean:
#ManagedBean
#ViewScoped
public class LoginBean {
private boolean loginEnabled;
public LoginBean() {
loginEnabled = true;
}
//getters and setters...
//this method will return void, so the page will be refreshed with the new
//loginEnabled value. this time the components inside "login" panelGrid won't be rendered
//but "passRecovery" panelGrid components will.
public void showPassRecovery() {
loginEnabled = false;
}
}

Is it possible to have a form with validation and to use rich:modalPanel for data entry too?

Richfaces 3.3.3, Jsf 1.2:
I have a a4j:form that uses some simple validation, mainly required="true" to ensure the form does not get submitted without some necessary data.
I also have some complex data to add (optionally) to the form, so I thought the best way to do this is to have a a4j:commandButton that displays a rich:modalPanel where the user can create the complex data set.
The created data is also displayed in a h:selectManyListbox that is reRendered when the modalPanel is closed.
That's the plan, at least. I have the following problems:
reRender works, but only if I prevent validation via immediate="true" - which in turn seems to prevent the selected data from the modalPanel to be present in the backing Bean
if I remove the immediate tag, the data gets updated, but only if there are no validation errors
What is the best way to get this to work the way I want? Is there another, better way?
UPDATE:
The Validation that fails is in some different part of the form, not in the data entered via the modalPanel, which is displayed in the Listbox
CODE:
modalPanel:
<rich:modalPanel id="addTrimming" domElementAttachment="parent" width="150" height="130">
<f:facet name="header">
<h:panelGroup>
<h:outputText value="Define Filter" />
</h:panelGroup>
</f:facet>
<f:facet name="controls">
<h:panelGroup>
<h:graphicImage value="/images/close.gif" styleClass="hidelink" id="hidelinkAddTrimming"/>
<rich:componentControl for="addTrimming" attachTo="hidelinkAddTrimming" operation="hide" event="onclick"/>
</h:panelGroup>
</f:facet>
<h:panelGrid id="trimsettings" columns="3">
<h:outputText value="Target:" style="font-weight:bold"/>
<h:inputText id="target" label="XML Filename" required="true" value="#{xmlCreator.trimTarget}">
</h:inputText>
<h:outputText value=""/>
<h:outputText value="Mode:"/>
<h:selectOneMenu value="#{xmlCreator.trimMode}">
<f:selectItem itemLabel="Quality" itemValue="quality"/>
<f:selectItem itemLabel="after Primer" itemValue="afterPrimer"/>
<f:selectItem itemLabel="fixed" itemValue="fixed"/>
<f:selectItem itemLabel="Median length" itemValue="median"/>
<f:selectItem itemLabel="Motif" itemValue="motif"/>
</h:selectOneMenu>
<h:outputText value=""/>
</h:panelGrid>
<h:panelGroup>
<a4j:commandButton value="OK" action="#{xmlCreator.createTrimming}" onclick="from:submit()">
<a4j:support event="oncomplete" ajaxSingle="true" immediate="true" reRender="trimsPanel"/>
</a4j:commandButton>
</h:panelGroup>
</rich:modalPanel>
relevant form part:
<h:outputText value="Trimming:"/>
<a4j:outputPanel id="trimsPanel">
<h:selectManyListbox id="trims" value="#{xmlCreator.selectedTrimmings}">
<f:selectItems value="#{si:toSelectTrimmingList(xmlCreator.trimmings)}"/>
</h:selectManyListbox>
</a4j:outputPanel>
<a4j:commandButton id="addTrimButton" immediate="true" value=" + Trimming">
<rich:componentControl for="addTrimming" attachTo="addTrimButton" operation="show" event="onclick"/>
</a4j:commandButton>
If you do it in one form than you should separate it into two: one will be your main form and another will be form inside modal panel. Thus you'll be able to submit modal panel independently of main form and your submit button in modal panel will look like this:
<a4j:commandButton value="OK" action="#{xmlCreator.createTrimming}" reRender="trimsPanel"/>
you should use process with immediate to send modalpanel's data to bean when closing panel with a a:commandButton or a:commandLink.
for this, modal panel data has to be valid as expected, so you will get valid new data and add it to h:selectManyListBox 's bean value and reRender h:selectManyListBox.
this should work. if not please post your a:form and modalPanel code full to check.

How to invoke a method with Openfaces/JSF without rendering page?

I am trying to invoke a Save method in a bean with Openfaces 3. While Firefox is not rendering the page, Internet Explorer does.
I'm currently using this code lines:
<o:commandLink value="Save" action="#{beanX.save}">
<h:graphicImage url="/images/save_48.png" />
</o:commandLink>
but I was trying o:ajax as well:
<o:commandLink value="Save" action="#{beanX.save}">
<h:graphicImage url="/images/save_48.png" />
<o:ajax event="click" render="#none" />
</o:commandLink>
Any ideas?
I've found a way to deal with using standard JSF components. Any ideas how to solve this issue with o:commandLink?
You can use <f:ajax> and render attribute in jsf2.0
<h:form>
<h:inputText value="#{managedBean.val1}" >
<f:ajax event="keyup" render="result" listener="#{managedBean.someThingToDoListener}"/>
</h:inputText>
<h:inputText value="#{managedBean.val2}" >
<f:ajax event="keyup" render="result" listener="#{managedBean.someThingToDoListener}"/>
</h:inputText>
<h:outputText id="result" value="#{managedBean.result}"/>
</h:form>
#ManagedBean(name = "managedBean")
public class Bean {
private String val1; // getter and setter
private String val2; // getter and setter
private String res; // getter and setter
...
public void someThingToDoListener(AjaxBehaviorEvent event) {
//res = some processing
}
}
Also See
how-to-update-a-value-displayed-in-the-page-without-refreshing
JSF2: Ajax in JSF – using f:ajax tag
Thank you Jigar Joshi. You've given me the key hint. It works with this code lines:
<h:commandLink value="Save">
<h:graphicImage url="/images/save_48.png" />
<f:ajax event="click" render="#none" listener="#{beanX.save}" />
</h:commandLink>
I've been to this website before, I was not thinking in assuming that o:commandLink might not be able to handle this, might be a bug?
Using h:commandLink instead of o:commandLink and f:ajax with the listener attribute solved my problem.

Categories