I'm in the middle of building a web application (Spring 4, Primefaces 5.1 and JPA).
While one of my xhtml-pages has no problems working with its ManagedBean, the others won't really work. To be more specific, the UI input components (like inputText) won't call any setters from the managed Beans.
I've already run my Tomcat (8) on debug mode, which showed me that the page calls the get-methods, but no set-methods at all. If I try to persist something, all values are null (or 0, in case of an int-value). (it even persists an object into the database with all values null, though I have declared some #NotNull constraints which should be taken to the database configuration via JPA)
So, question is: How can I make my inputFields work with the fields of my ManagedBean? (Eclipse also shows me in the editor, that theoretically, the connection to the fields is there, it knows the managed bean, the field and the get-/set-methods)
SoftwareManagedBean.java
#ManagedBean(name = "swmb")
#ViewScoped
public class SoftwareManagedBean extends AssetManagedBean implements
Serializable {
private String bezeichnung;
private Software neueSoftware;
// +some more private fields, every single one with its get-/set-method
#Override
public String getBezeichnung() {
return super.getBezeichnung();
}
#Override
public void setBezeichnung(final String bezeichnung) {
super.setBezeichnung(bezeichnung);
}
//instantiante the field "neueSoftware"
public void createEmptySoftware(){
if(neueSoftware != null)
return;
this.neueSoftware = new Software();
}
//Persist Software with values from inputFields
public void addSoftware() {
createEmptySoftware();
neueSoftware.setBezeichnung(getBezeichnung());
softwareService.addSoftware(neueSoftware);
//...
neueSoftware = null;
}
viewSoftware.xhtml
<h:body>
<p:dialog header="Neue Software anlegen" widgetVar="SwNeuDialog" width="60%"
closeOnEscape="true" draggable="false" resizable="false" position="center">
<h:form id="SwDlgForm">
<h:panelGrid columns="3" border="0" >
<p:outputLabel for="swBezeichnung" value="Bezeichnung: " />
<p:inputText id="swBezeichnung" value="#{swmb.bezeichnung}"
label="Bezeichnung" required="true" />
<f:verbatim/>
<p:outputLabel for="swKategorie" value="Kategorie: " />
<p:selectOneMenu id="swKategorie" value="#{swmb.kategorie}" label="Kategorie" required="true" >
<f:selectItem itemLabel="Kategorie wählen" value="#{null}" noSelectionOption="true"/>
<f:selectItems value="#{swmb.kategorieListe}" var="kat" itemLabel="#{kat.bezeichnung}" itemValue="#{kat}"/>
</p:selectOneMenu>
<p:commandButton value="neue Kategorie hinzufügen" />
<!-- + some more input fields -->
<p:commandButton value="Speichern" action="#{swmb.addSoftware()}" onclick="PF('SwNeuDialog').hide()" resetValues="true" process="#this"/>
<p:commandButton value="Abbrechen" onclick="PF('SwNeuDialog').hide()" resetValues="true" process="#this"/>
</h:panelGrid>
</h:form>
</p:dialog>
<!-- dataTable -->
</h:body>
AssetManagedBean.java
#ManagedBean
public abstract class AssetManagedBean {
//name of the hard-/software
private String bezeichnung;
//+ some more fields with get-/set methods
public String getBezeichnung() {
return bezeichnung;
}
public void setBezeichnung(String bezeichnung) {
this.bezeichnung = bezeichnung;
}
I hope that code is sufficient to see the problem, since the rest of the code follows the same structure. I think, the problem could lie within the xhtml file, but I don't see where or why. I've got the SpringBeanFacesELResolver (or however it is called), I've already looked through the code and compared it to another xhtml page and its Managed Bean, but there are no differences anymore. (though one is working, one not)
My debugger showed, how the working class/page (viewAdministration.xhtml) called the get-/set methods of the managed bean:
opening dialog window: get...(), set...()
clicking the commandButton to submit/persist: get() (old Value), set() (new Value), get() (new Value)
Another get() (called by the add... method)
(+ another get() for the dataTable on the main page)
on viewSoftware.xhtml, it looks like this:
opening dialog window: get()
clicking the commandButton to submit/persist:
another get() called by the addSoftware method
As you can see, when I try to submit, there is no set or get.
So, to summarize:
no setter called by trying to submit
the code on viewSoftware.xhtml and SoftwareManagedBean is similar to another, functioning ManagedBean + xhtml page (I've compared it again and again)
annotations in Managed Beans are the same (#ManagedBean, #ViewScoped)
the inputFields are inside a form (
I'm totally clueless, but I think it is some small mistake from my side that I can't just see.
I've searched through the web and especially stackoverflow, but all the problems and answers I've found couldn't help me finding what's wrong
Even without inheriting from a superclass it won't work (tried that out too)
I hope, you can help me. If this post is lacking some information, I'm sorry about that, I tried my best to not let this post grow too big and still get as much relevant information in it as possible.
So, I have found my mistake (or at least, I think I have). Only took me 2 weeks, but anyway...
I tried to test it out more specifically, wrote test classes and an xhtml page. Nothing worked (from simple Input over Dates to own classes).
The solution to this problem was to disable ajax on my commandButton (ajax="false"). When I tried to understand more of it, I realized that the commandButton opening the dialog window was nested in a facet inside a dataTable, and thus it had problems to properly set the values of the input fields.
So, thank you for your help. Maybe/hopefully this can or will help some other people later as well.
From the first glance at the code, without reading it whole, try putting process="SwDlgForm" on your command buttons, instead of process="#this". If that doesn't solve the problem, I'll read more carefully and try to help.
Related
This question already has answers here:
How to populate options of h:selectOneMenu from database?
(5 answers)
Closed 7 years ago.
Recently I did [CRUD Enterprise Application in NetBeans][1.] I made my own scenario for it namely storing scores for player. I have tree tables player, game and playerGame table. Every thing works fine with player and game table (add, remove, edit) as in tutorial form youtube but, I have problem with linked table (playerGame). When I try generate JSF Form From Entity using netBeans Palette I am getting this code
<h:selectOneMenu id="fkGameId" value="#{controller.playerGame.fkGameId}" title="FkGameId" required="true" requiredMessage="The FkGameId field is required.">
<!-- TODO: update below reference to list of available items-->
<f:selectItems value="#{fixme}"/>
</h:selectOneMenu>
Also I have tried this
<h:selectOneMenu id="fkPlayerId" value="#{controller.player.playerId}" title="FkPlayerId" required="true" requiredMessage="The FkPlayerId field is required.">
<!-- TODO: update below reference to list of available items-->
<f:selectItems value="#{controller.player.playerGameList}"/>
</h:selectOneMenu>
but with no result
in place where foreign keys to playerId and gameId should be inputed by palette.
My question is what I have to do to fix this, it would be nice to see similar example on linked tables but I didn't found anything (only one simple table examples I have found) I am newbie in JavaEE and this was my first tutorial ever in this subject and to be honest I don't know how to name thing properly.
Also trying to find the solution for the problem I did JavaServer Faces tutorial form netbeans website Generating JSF CRUD Application form Databases. The tutorial was pretty straight forward and I had no problem with it and it works fine with the same scenario (I was able to select foreign keys form dropdown list and create playerGame record). I have tried solve this problem based on JSF pages form this tutorial but the pages are generated using netBeans command JSF Pages form Entity Classes I because I have no experience in Java EE like mentioned before I have failed to solve the problem.
P.S. I you need me to provide more information please just ask.
UPDATE:
It is partially working now thanks to Geinmachi
Partial SOLUTION:
In my controller class I have added
private String playerList;
public String getPlayerList() {
return playerList;
}
public void setPlayerList(String playerList) {
this.playerList = playerList;
}
private List<Player> playerLists;
public List<Player> getPlayerLists() {
return playerLists;
}
public void setPlayerLists(List<Player> playerLists) {
this.playerLists = playerLists;
}
#PostConstruct
public void init(){
playerLists = playerFacade.findAll();
// playerLists = new ArrayList<>();
// playerLists.add( new Player(player.getPlayerId()));
}
public void submit(){
System.out.println("Selected Player: " + playerList);
}
and my jsf code looks like
<h:selectOneMenu value="#{controller.playerList}">
<f:selectItem itemValue="#{null}" itemLabel="#{player.playerName}"/>
<f:selectItems value="#{controller.playerLists}" var="player" itemValue="#{player.playerId}" itemLabel="#{player.playerName}"/>
</h:selectOneMenu>
the was found in one of links given by Geinmachi.
However now I am getting javax.ejb.EJBException: Transaction aborted
when trying to insert data to database because partial solution doesn't get fk_game_id.
Given fields in PlayerGame entity (with getters/setters)
private Player fkPlayerId
private Game fkGameId
In controller:
private List<Player> playerList
private List<Game> gameList
form:
<h:form>
<h:outputText value="Choose player"/>
<h:selectOneMenu value="#{controller.playerGame.fkPlayerId}" converter="playerConverter">
<f:selectItems value="#{controller.playerList}" var="player"
itemValue="#{player}" itemLabel="#{player.playerName}"/>
</h:selectOneMenu>
<h:outputText value="Choose Game"/>
<h:selectOneMenu value="#{controller.playerGame.fkGameId}" converter="gameConverter">
<f:selectItems value="#{controller.gameList}" var="game"
itemValue="#{game}" itemLabel="#{game.gameName}"/>
</h:selectOneMenu>
<h:commandButton action="#{controller.createPlayerGame}" value="Link player with a game"/>
</h:form>
In your controller you need lists of all players and all games to choose from. You have to create converters for entities because on the HTML page they are just String and JSF expects Player and Game objects. For POJO JSF converter you can search in google and read here
See:
h:selectOneMenu wiki page
I'm trying to use an richfaces inputNumberSlider or inputNumberSpinner.
The problem is I'm not able to update the values in my beans.
Here are the 2 solutions I tried:
1)
<rich:inputNumberSlider value="#{skinningBean.currentSkin.topBar.bannerXOffset}"
valueChangeListener="#{skinningBean.valueBannerXOffSetChangeListener}"
onchange="A4J.findForm(this).submit()">
</rich:inputNumberSlider>
In the bean:
public void valueBannerXOffSetChangeListener(ValueChangeEvent event) {
System.out.println("x value changed");
currentSkin.getTopBar().setBannerXOffset((Integer) event.getNewValue());
}
2)
<rich:inputNumberSpinner value="#{skinningBean.currentSkin.topBar.bannerYOffset}">
<a4j:ajax event="change" render="preview" oncomplete="initSlider()" />
</rich:inputNumberSpinner>
This should just call my setter in the bean. I havw written two setter one which takes a String and one which takes an Integer. None of them is called
Although I need an a4j supprt anyway to rerender my items, a working solution for number 2 would be preferred
Try the following first, once you get it working you can add the oncomplete part:
<rich:inputNumberSpinner value="#{skinningBean.currentSkin.topBar.bannerYOffset}">
<a4j:ajax event="onchange" render="preview" action="#{bean.valueBannerXOffSetChangeListener}" />
</rich:inputNumberSpinner>
Possible you will need to redefine your bean function to not receive parameters.
Reference:
https://community.jboss.org/message/588944#588944
I'am using JSF/PF anf I can't make a graphicImage work. Reviewing the tons of topics published on forums, this PF's graphicImage seems to be so tricky. I am obviously doing somethig wrong, but, as long as I am replicating code that worked for others (see post), it must be something in the environment of the component. I hope to find a solution here, i'm stuck for weeks. Thanks
Here is my original question in PF forum:
I encounter a problem rendering the image. I have followed the code explained and I correctly retrieve the id for image to display in a separate method:
public StreamedContent getStreamedImage() {
StreamedContent streamedImage = null;
UIViewRoot uiRoot = FacesContext.getCurrentInstance().getViewRoot();
System.out.println(uiRoot.getClientId());
UIComponent component = FacesContext.getCurrentInstance().getViewRoot().findComponent("itemDataForm:imagesTbl:itemImgComp");
Map attributes = component.getAttributes();
Integer image_id = (Integer)attributes.get("item_img_id");
if(image_id != null && editionItem != null && editionItem.getImages() != null){
for(ItemImageView img : editionItem.getImages()){
if(image_id.intValue() == img.getId()){
streamedImage = new DefaultStreamedContent(new ByteArrayInputStream(img.getImage()), "image/jpeg");
}
}
}else{
streamedImage = new DefaultStreamedContent(new ByteArrayInputStream(editionItem.getImages().get(0).getImage()), "image/jpeg");
}
.......
I could't manage to retrieve the (always null) so I tried with attribute and it works. So, the DefaultStreamContent is loaded, by the image doesn't render at all. My code for xhtml:
<p:dataTable id="imagesTbl" var="itemImg" value="#{itemEditionBean.editionItem.images}">
<p:column>
<h:panelGrid columns="1">
<h:outputText value="#{itemImg.id}"/>
<p:graphicImage id="itemImgComp" value="#{itemEditionBean.streamedImage}">
<f:attribute name="item_img_id" value="#{itemImg.id}"/>
</p:graphicImage>
</h:panelGrid>
</p:column>
</p:dataTable>
Exactly the same that the code working in this topic above. PS: I have mt dataTable enclosed within a tab. Maybe a dependency on the enclosing component, or form, or what?
There is a huge amount of code from other related topics that can be viewed in the link below:
http://forum.primefaces.org/viewtopic.php?f=3&t=4163&p=39751
Based on another page I found on building dynamic images, <f:param .../> should be used to supply a parameter to the getStreamedImage() method rather than <f:attribute .../>. Are you using a ConversationScoped backing bean? I was having the same problem displaying dynamic images, but found that there is a problem using them with ConversationScoped beans. I switched my backing bean to Session scope and now it works fine.
Let say that I want to create a variable set of <rich:tab> elements within a <rich:tabPanel> component. So I tried to do that way:
<rich:tabPanel switchType="client" ...>
<ui:repeat value="#{myBean.myTabs}" var="tab">
<rich:tab name="#{tab.name}" label="#{tab.label}"/>
</ui:repeat>
</rich:tabPanel>
But it didn't work, as no tab is rendered. I also got the following message in the logs:
j_id174: tab panel has no enabled or rendered tabs!
This problem seems to be encountered by others people, for example here.
So as suggested by the previous thread, I replaced my <ui:repeat> by a <c:forEach> but the problem still occurs.
I have a way to solve this problem using the binding attribute of my <rich:tabPanel> component:
<rich:tabPanel switchType="client" binding="#{tabNavigationBean.tabPanel}"
</rich:tabPanel>
and then in my Java bean:
private HtmlTabPanel tabPanel; // + getter and setter
public void setTabPanel(HtmlTabPanel tabPanel) {
this.tabPanel = tabPanel;
if (tabPanel != null) {
createTabs();
}
}
private void createTabs() {
Application application = FacesContext.getCurrentInstance().getApplication();
HtmlTab newTab = null;
for (DedicatedPageTab dpt : getDedicatedPageTabs()) {
newTab = (HtmlTab) application.createComponent(HtmlTab.COMPONENT_TYPE);
newTab.setLabel(dpt.getLabel());
newTab.setName(dpt.getName());
tabPanel.getChildren().add(newTab);
}
}
This code is working.
However, my question is to know if I can solve my problem without using the binding attribute (i.e. a 100% pure XHTML solution)?
<a4j:outputPanel id="out">
<rich:tabPanel>
<c:forEach items="list" var="var">
<rich:tab label="#{var.name}" switchType="client">
content
</rich:tab>
</c:forEach>
</rich:tabPanel>
</a4j:outputPanel>
Yes, it is possible, but difficult. Here are some notes I have:
Use c:forEach to create tab tags inside tabPanel inside outputPanel. reRender outputPanel on tab removal, add, or name change
http://relation.to/11633.lace
http://devharbor.blogspot.com/2009/08/add-jsf-controls-dynamically-with.html
We also made use of templating, though I still have an outstanding issue for it: How to force the build phase in a JSF 1.2 page using JSTL?
http://facelets.java.net/nonav/docs/dev/docbook.html#template
Docs on templating
http://www.jsfcentral.com/articles/facelets_3.html
Templating tutorial
I have a problem with JSF. Can anyone say why this doesn't work?
<h:selectOneListbox
id="lang" size="5"
value="#{MbInstitution.node.lang}"
valueChangeListener="#{MbInstitution.changeLanguage}"
rendered="#{MbInstitution.view}"
>
<a4j:support event="onchange" reRender="shortDesc, fullDesc"/>
<f:selectItems value="#{MbInstitution.languagesByInstitute}"/>
</h:selectOneListbox>
<h:selectOneListbox
id="lang" size="5"
disabled="#{!MbInstitution.managingNew}"
value="#{MbInstitution.node.lang}"
rendered="#{!MbInstitution.view}"
>
<f:selectItems value="#{MbInstitution.availableLanguages}"/>
</h:selectOneListbox>
It says: "duplicate Id for a component instForm:lang"
I know that i have 2 elements with same Id, but one is rendered only when another isn't. So, i didn't think it would be a problem. Actually it's not a big problem at all as i don't need this id, but what if i needed then what would i do?
Your problem is that these two components are part of the JSF Component tree for this page. And even if they cannot be displayed at the same time, they share the same ID, which is not allowed by JSF.
I see three solutions to solve your problem:
First solution: Define two differents ID
Second solution: You can, as explained by Wayne Young, use a NamingContainer, which will prefix their ID by the ID of the NamingContainer.
Third solution: Use only one <h:selectOneListbox/> and then make the difference in the Java code.
<h:selectOneListbox id="lang" size="5" disabled="#{!MbInstitution.managingNew}" value="#{MbInstitution.node.lang}" valueChangeListener="#{MbInstitution.changeLanguage}">
<a4j:support event="onchange" reRender="shortDesc, fullDesc" rendered="#{MbInstitution.view}"/>
<f:selectItems value="#{MbInstitution.languages}"/>
</h:selectOneListbox>
Java code:
public List<SelectItem> getLanguage() {
if (isView()) {
return getLanguagesByInstitute();
} else {
return getAvailableLanguages();
}
}
public void changeLanguage(ValueChangeEvent evt) {
if (!isView()) {
return;
}
...
}
You'll have to use a different ID or put it in another naming container.
The Javadoc for UIComponent.setId() says:
The specified identifier must be
unique among all the components
(including facets) that are
descendents of the nearest ancestor
UIComponent that is a NamingContainer,
or within the scope of the entire
component tree if there is no such
ancestor that is a NamingContainer.