Load in java chords of dynamic primefaces dragable components - java

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?

Related

Primefaces / JSF: selectOneMenu value is not set, ajax listener not called

I am using Primefaces and JSF to develop this frontend. My issue is that one of my selectonemenus never sets its value binding, "selectedGroup", so the second dropdown is never populated. My backing bean is being called to "update" the second selectonemenu, but the listener of that ajax is not called, nor is selectedGroup ever set. This code is effectively identical to the Showcase for "Select". I even verified that the showcase code works from scratch (which i did not doubt), but fail to see how my situation is any different from that example.
Other stackoverflow questions on this topic indicate that something was left out, but none of those suggestions matched my issue.
I have two selectOneMenus, like so.
<h:form id="outerForm">
<p:panel id="outerPanel">
<p:panelGrid id="outerPanelGrid">
<h:outputLabel for="groupSelection" value="Group: "/>
<p:selectOneMenu id="groupSelection" value="#{myBean.selectedGroup}" >
<p:ajax update="commandSelection"
listener="#{myBean.handleGroupSelection}" />
<f:selectItem itemLabel="---Please Select Group---" itemValue=""/>
<f:selectItems var="group" value="#{myBean.groups}"
itemLabel="#{group.name}" itemValue="#{group.name}" />
</p:selectOneMenu>
<h:outputLabel for="commandSelection" value="Command: "/>
<p:selectOneMenu id="commandSelection" value="#{myBean.command}">
<f:selectItems value="#{myBean.commandStringsList}"/>
</p:selectOneMenu>
</p:panelGrid>
</p:panel>
</h:form>
This page is being displayed in the "center" portion of my layout template like so..
<ui:define id="content" name="content">
<p:panel id="contentPanel" style="float:left; border:none">
<ui:include src="#{anotherBean.currentView}.xhtml"/>
</p:panel>
</ui:define>
The backing bean DOES use some data classes to contain some of the data which is populated, but I thought i was doing everything correct to map it into the view. For the most part, I am using Strings, though.
Does anyone see what I am missing? At the very least, is this xhtml valid?
I should also mention that this page was working before I created and used a template. Basically, I was rendering it in a tab of a tabview using ui:include in the body of index.xhtml. Though I did not notice initially, this page stopped working sometime after I incorporated the template (poor testing on my part, I know).
<f:selectItems var="group" value="#{myBean.groups}"
itemLabel="#{group.name}" itemValue="#{group.name}" />
you can't specify selectItems this way. translation has to be bidirectional. use a converter!
<f:selectItems var="group" value="#{myBean.groups}"
itemLabel="#{group.name}" itemValue="#{group}"
converter="groupConverter"/>

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.

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

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.

Categories