Issue with EJB/JSF2.0 - jsf-2

I'm currently practicing JSF and EJB, but right now I can't get the page to show the information requested, this have input text and submit button (input.xhtml) and the expected result is to show the text submitted.
/input.xhtml #16,56 value="#{welcome.name}": Target Unreachable, identifier 'welcome' resolved to null
I've tried everything to fix it, this is part of the input.xthml
<ui:define name="content">
<h:form>
<h:panelGrid columns="3">
<h:outputText value="Name:"/>
<h:inputText value="#{welcome.name}" title="name" id="name"
required="true" />
<h:message for="name" style="color: red"/>
</h:panelGrid>
<h:commandButton action="show" value="submit"/>
</h:form>
</ui:define>
</ui:composition>
This is the bean.
#ManagedBean
#RequestScoped
public class Welcome {
private String name;
private String message;
public String getMessage() {
return "Hello " + name;
}
public void setMessage(String message) {
this.message = message;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

The code looks fine and it should work just fine. I only don't see how this is related to JPA and EJB. You would have exactly the same problem when you removed JPA/EJB from your testcase, right? You can just leave those tags and this detail out of the question.
As to the concrete problem, because you omitted the import declarations, I can given the symptoms only guess that you're actually importing #ManagedBean from the javax.annotation package instead of the javax.faces.bean package. The former won't make the bean to be managed by JSF, but the latter wil do. Check and fix your imports. Note that the #RequestScoped also needs to be from the same package, not from the javax.enterprise.context package.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
#ManagedBean
#RequestScoped
public class Welcome {
// ...
}

write like this
#ManagedBean(name="welcome")
#RequestScoped
public class welcome implements Serializable {
private String name;
}
In html write like this
<h:inputText value="#{welcome.name}" title="name" id="name"
required="true" />

Related

Using backing bean value in javascript

<h:form prependId="false" id="vt_sel_form">
<p:panelGrid styleClass="center" columns="2">
<p:commandButton value="GO" oncomplete="alert(#{test.i})" actionListener="#{test.testfxn()}" update="#this"/>
</p:panelGrid>
</h:form>
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ViewScoped
#ManagedBean(name = "test")
public class TestClass implements Serializable {
int i ;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
public void testfxn() {
setI(i++);
//i=i+10;
System.out.println("i" + i);
}
}
Here, alert(#{test.i}) is always displaying 0. How do i get backing bean value that changes when I click the commandButton. It works when I click button twice. It used to work fine when I used a4j:commandButton.
That's just because alert(#{test.i}); is evaluated when the commandButton is rendered. You can see the changed value by telling JSF to render the script again:
<h:commandButton value="click me" action="#{testClass.testfxn()}">
<f:ajax render="out" />
</h:commandButton>
<h:panelGroup id="out">
<h:outputScript>
alert(#{testClass.i});
</h:outputScript>
</h:panelGroup>
Unlike Richfaces where you can directly call javascript function, primefaces you need to have javascript function as:
function_name(xhr, status, args)
Using listed CommandButton as Example:
<p:commandButton value="GO" oncomplete="alert(#{test.i})" actionListener="#{test.testfxn()}" update="#this"/>
In function test.testfxn() we have:
public void testfxn(){
RequestContext reqCtx = RequestContext.getCurrentInstance();
i = i++;
reqCtx.addCallbackParam("i", i);
}
Here,In function call to backing bean from actionlistener the variables are added to RequestContext.
Now In javascript function:
function draw(xhr, status, args) {
console.log("We are into draw function");
jsonString = JSON.parse(args.i); //json variable is taken out from args variable.
console.log("The value of i "+ i);
}

Ajax dynamically adding textbox is not working in PrimeFaces v3.5

My h:form contains a p:selectOneMenu component, which has two values single and multiple. The h:form also contains a default p:inputText. My objective is to add multiple p:inputText component only when value multiple is selected. Please see the attached screenshot-
Below is my view, which suppose to send ajax request, whenever icon button is clicked-
<h:form>
<p:panel header="Dynamically Add textbox">
<p:selectOneMenu id="runType" value="#{repeateRun.runType}">
<f:selectItems value="#{repeateRun.runList}" var="runType" itemLabel="#{runType}" itemValue="#{runType}" />
<p:ajax update="outPanel" listener="#{repeateRun.renderComponent}" />
</p:selectOneMenu>
<h:panelGrid id="runList">
<ui:repeat value="#{repeateRun.runs}" var="run">
<p:inputText value="#{run.runValue}" />
</ui:repeat>
</h:panelGrid>
<p:outputPanel id="outPanel">
<p:commandButton update="runList" icon="ui-icon-plusthick" title="Add more" rendered="#{repeateRun.showAddButton}">
<f:ajax render="runList" listener="#{repeateRun.addRun}" />
</p:commandButton>
</p:outputPanel>
</p:panel>
</h:form>
The #ViewScoped #ManagedBean RepeateRun is following-
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;
#ManagedBean
#ViewScoped
public class RepeateRun implements Serializable {
private static final long serialVersionUID = 1L;
private List<String> runList;
private List<Run> runs;
private int runValue;
private String runType;
private boolean showAddButton = false;
private static final String SINGLE = "Single";
private static final String MULTIPLE = "Multiple";
//Note : Getters Setters are removed while putting here
#PostConstruct
public void initBean() {
this.setRunList(this.populateRunList());
this.setRuns(this.populateRuns());
}
public void addRun() {
if (this.runs == null) {
this.setRuns(this.populateRuns());
} else {
this.runs.add(this.defaultRun());
}
}
public void renderComponent() {
if (this.getRunType().equals(SINGLE)) {
this.setShowAddButton(false);
} else {
this.setShowAddButton(true);
}
}
private List<String> populateRunList() {
List<String> runList = new ArrayList<String>();
runList.add(SINGLE);
runList.add(MULTIPLE);
return runList;
}
private Run defaultRun() {
Run defaultRun = new Run();
defaultRun.setRunValue(1);
return defaultRun;
}
private List<Run> populateRuns() {
List<Run> runs = new ArrayList<Run>();
runs.add(this.defaultRun());
return runs;
}
}
So after selecting the value Multiple in f:selectItems the plus icon button comes but the button is not invoking attached method i.e. addRun. To confirm the method addRun call after clicking, I put some sysout statements in addRun method. I saw that sysout is not flushed. At the same time I saw some xml response in the firebug.
Where is the problem?
The problem was with f:ajax which doesn't work with p:commandButton. Below are the culprit lines-
<p:commandButton update="runList" icon="ui-icon-plusthick" title="Add more" rendered="#{repeateRun.showAddButton}">
<f:ajax render="runList" listener="#{repeateRun.addRun}" />
</p:commandButton>
The above lines should be replaced with below line
<p:commandButton actionListener="#{repeateRun.addRun}" update="runList" icon="ui-icon-plusthick" title="Add more" rendered="#{repeateRun.showAddButton}" />

Multiple instances of a composite component in a view?

I read many similar questions, but I cannot figure out how to solve my problem:
I wrote a composite component backed by a view-scoped, self-contained managed bean.
The component consists of an autocomplete textbox with a button that opens a dialog. The user can select an item either by name (autocomplete) or selecting a node in a tree (dialog).
The backing bean implements all the stuff needed (data access, tree-logics etc) and should expose the selected item (as a POJO).
Now I have 2 problems:
Due to the complexity of the tree management, selectedObj property is accessed by a getter and a setter that do some stuff in the bean: they are not simply accessing a class field. Now I'm passing the entire bean as an attribute. How can I just make the bean's selectedObj the "value" attribute of my composite component?
How can I use multiple instance of my component in the same view?
Here is an example of the component:
<cc:interface>
<cc:attribute name="bean" type="com.yankee.OUTreeBean" required="true"/>
<cc:attribute name="listener" method-signature="void listener()"/>
</cc:interface>
<cc:implementation>
<p:dialog id="#{cc.id}_dialog" widgetVar="_dlg" header="Select OU" modal="true" dynamic="true" >
<p:toolbar>
<!-- some buttons to refresh, expand, collapse etc. -->
</p:toolbar>
<p:tree id="#{cc.id}_tree" value="#{cc.attrs.bean.root}" var="node"
selectionMode="single"
selection="#{cc.attrs.bean.selectedNode}">
<p:ajax event="select" update="#form" listener="#{cc.attrs.listener}" oncomplete="if (!args.validationFailed) _dlg.hide()" />
<p:treeNode>
<h:outputText value="#{node.OU_NAME}" />
</p:treeNode>
</p:tree>
</p:dialog>
<p:autoComplete id="#{cc.id}_inner" value="#{cc.attrs.bean.selectedObj}" completeMethod="#{cc.attrs.bean.completeObj}"
var="obj" itemLabel="#{obj.OU_NAME}" itemValue="#{obj}"
forceSelection="true"
converter="ouConverter"
multiple="false"
minQueryLength="2">
<p:ajax event="itemSelect" listener="#{cc.attrs.listener}" update="#form"/>
</p:autoComplete>
<div style="float: right">
<p:commandButton id="bSearch" icon="ui-icon-search" onclick="_dlg.show()"/>
</div>
</cc:implementation>
The backing bean of the COMPONENT:
#ManagedBean
#ViewScoped
public class OUTreeBean implements Serializable {
private static final long serialVersionUID = 1L;
private List<OU> data; // Data as plain list
protected TreeNode root; // root node of data as a tree
protected TreeNode selectedNode;
#PostConstruct
private void init() throws SQLException {
refreshData();
}
public OU getSelectedObj() {
if (selectedNode == null) {
return null;
}
return ((OU) selectedNode.getData());
}
public void setSelectedObj(OU ou) {
// Find the right tree node and do whatever needed
}
public TreeNode selectedNode getSelectedNode() {
// Blah blah
}
public void setSelectedNode(TreeNode selectedNode) {
// Blah blah
}
public List<OU> completeObj(String namePattern) {
// Autocomplete handler
}
public void refreshData() {
// Blah blah
}
// etc...
}
The using page excerpt:
<ism:selectOUTree id="cbSelectOu" bean="#{myBean.ouFilterBean}" listener="#{myBean.onOUChange}"/>
The backing bean of the PAGE:
#ManagedBean
#ViewScoped
public class MyBean implements Serializable {
private static final long serialVersionUID = 1L;
#ManagedProperty("#{oUTreeBean}")
private OUTreeBean ouFilterBean;
public void onOUChange() throws SQLException {
// Blah blah
}
}
I had the same problem few days ago. Just like you I used ManagedBean as an object that should do the job. After some time I figured out that I should just create FacesComponent. I'm new in JSF so it wasn't that easy to find the solution but it solved all my problems. This is how does it work:
view.xhtml
<h:body>
<cc:interface componentType="playerComponent">
<cc:attribute name="playerId" required="true"/>
</cc:interface>
<cc:implementation>
<c:set var="inplaceId" value="inplace-#{cc.attrs.playerId}" />
<c:set var="outputId" value="output-#{cc.attrs.playerId}" />
<h:form id="form-#{cc.attrs.playerId}">
<p:inplace editor="false" widgetVar="#{inplaceId}">
<h:inputText value="#{cc.player.name}" id="outputId"/>
<p:commandButton onclick="#{inplaceId}.save()" action="#{cc.save}" update="#{outputId}" value="save" />
<p:commandButton onclick="#{inplaceId}.cancel()" update="#{outputId}" value="cancel" />
</p:inplace>
</h:form>
</cc:implementation>
</h:body>
PlayerComponent.java
#FacesComponent("playerComponent")
public class PlayerComponent extends UINamingContainer {
private Player player;
private void init() {
Object idObj = getAttributes().get("playerId");
if (idObj != null) {
// create player object
}
}
public void save() {
// save player object
}
public Player getPlayer() {
if (player == null) {
init();
}
return player
}
}
Player.java (entity)
public class Player {
private name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
As I wrote I'm new in JSF and probably player object should be created in different way (using #PostConstruct on in constructor?) but this work.

Is there any JSF Select Time Zone component out there?

I have been looking for this for a while and haven't found it. It is surprisingly complicated as shown in this old IceFaces tutorial.
What is needed is a UIInput component that will set a java.util.TimeZone property, allowing the user to select it from a map or a list on the screen. Before I dive in to write one for myself -- does anyone know of an available component that does this?
Use <h:selectOneMenu> to represent a dropdown list. Use <f:selectItems> to feed it with a E[], List<E>, SelectItem[] or List<SelectItem> as value.
Here's how it can look like at its simplest:
#ManagedBean
#ViewScoped
public class Bean implements Serializable {
private String timeZoneID; // +getter +setter
private String[] timeZoneIDs; // +getter only
#PostConstruct
public void init() {
timeZoneIDs = TimeZone.getAvailableIDs();
// You may want to store it in an application scoped bean instead.
}
public void submit() {
System.out.println("Selected time zone: " + TimeZone.getTimeZone(timeZoneID));
}
// ...
}
with this view:
<h:form>
<h:selectOneMenu value="#{bean.timeZoneID}" required="true">
<f:selectItem itemValue="#{null}" itemLabel="Select timezone..." />
<f:selectItems value="#{bean.timeZoneIDs}" />
</h:selectOneMenu>
<h:commandButton value="submit" action="#{bean.submit}" />
<h:messages/>
</h:form>
If you want to make it a fullworthy TimeZone property, you'd need to bring in a #FacesConverter(forClass=TimeZone.class) which should be pretty straightforward enough.

PrimeFaces 3.0.M3 Cell Editor does not update value

I have read there, but i can't take edited value from primefaces datatable cellEditor, it gives me unedited value. i am using jpa.
xhtml page:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui"
template="/templates/masterLayout.xhtml">
<ui:define name="windowTitle">
learn
</ui:define>
<ui:define name="content">
<h:form>
<p:dataTable value="#{lesson.lessonValue}" var="l" style="width: 400px">
<p:ajax event="rowEdit" listener="#{lesson.onEditRow}"/>
<p:column headerText="Lessons" style="width: 300px">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{l.lessonName}"/>
</f:facet>
<f:facet name="input">
<p:inputText value="#{l.lessonName}" style="width: 100%"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Options">
<p:rowEditor />
</p:column>
</p:dataTable>
</h:form>
</ui:define>
</ui:composition>
lesson.java:
public class lesson implements Serializable {
private String name;
protected EntityLesson[] lessonList;
public String getName() { return name; }
public void setName(String newValue) { name = newValue; }
EntityManagerFactory emf = Persistence.createEntityManagerFactory("DefaultPU");
public EntityLesson[] getLessonValue() {
EntityManager em = emf.createEntityManager();
List<EntityLesson> result;
try {
EntityTransaction entr = em.getTransaction();
boolean committed = false;
entr.begin();
try {
Query query = em.createQuery("SELECT l FROM EntityLesson l");
result = query.getResultList();
entr.commit();
committed = true;
lessonList = new EntityLesson[result.size()];
lessonList = result.toArray(lessonList);
} finally {
if (!committed) entr.rollback();
}
} finally {
em.close();
}
return lessonList;
}
public void onEditRow(RowEditEvent event) {
EntityLesson editedLesson = (EntityLesson)event.getObject();//gives me unedited value
............................
............................
}
EntityLesson.java:
#Entity
#Table(name="lessonaaa")
public class EntityLesson implements Serializable {
#Id
#Column(name="Lesson_Id", nullable=false)
#GeneratedValue(strategy= GenerationType.IDENTITY)
private int lessonId;
#Column(name="Lessson", nullable=false, length=65)
private String lessonName;
public int getLessonId() { return lessonId; }
public void setLessonId(int lessonId) { this.lessonId = lessonId; }
public String getLessonName() { return lessonName; }
public void setLesson (String lessonName) { this.lessonName = lessonName; }
}
The problem occurs because of the JSF lifecycle:
When your dataTable is displayed it executes the JPQL to retrieve the list of lessons. After that they are displayed.
Now you edit on entity and hit save, the edited entity in the list has now the new value.
But what happens next, is that the list is fetched another time and then the listener method is executed with the newly fetched enitiy.
You can solve the problem if you store the list of entities in a local attribute in the view bean and fill it in the post construct method (annotated by #PostContruct) and you have to make the view bean #SessionScoped. Then use this list for the datatable.
My problem is similar:
The 'dataTable' contains as 'value' a list of entities:
<p:dataTable id="category" var="category" value="#{categoriesBacking.categoriesListEdit}">
If I select one for edit, the object which is passed to the event contains the previously unmodified value. I observed that this is due to the fact that dataTable's value is a list. As a work-around (to be able to use the component) I added a 'filterBy' to any of the 'column'. If the dataTable will contain only one value, that value will be interpreted correctly by the passed event in the managed bean.
!!! The event's object will be the modified instance.
I also use:
<p:ajax event="rowEdit" update="#this" listener="#{categoriesBacking.onEditRow}" />
instead of dataTable's 'rowEditListener'.
Again, this is just a workaround.
I have almost exactly the same code except instead of using the <p:ajax> tag I am instead using the rowEditListener attribute of dataTable. Try this instead:
<p:dataTable ... rowEditListener="#{lesson.onEditRow}" ... >
...
This kind of problems are generally related to your backing bean. Your "lesson" class needs #ManagedBean (javax.faces.bean.ManagedBean) annotation. Simply add
#ManagedBean (name="YourBeanName")
#ViewScoped
just before public class lesson implements Serializable { line in your lesson.java

Resources