JSF/AJAX Dynamic Menu - 404 issue - ajax

I am trying to make a dynamic menu such that when something is selected in the first selector, the second one is populated from the database based on the selection in the first one. Here is the .xhtml:
<f:view>
<h:form>
<h:selectOneMenu id="seasonSelector" value ="#{selector_bean.season}">
<f:ajax event="valueChange" listener="#{selector_bean.genEvents}"
execute="seasonSelector" render="eventSelector" />
<f:selectItems value ="#{selector_bean.seasons}" var ="s"
itemLabel="#{s.getRange()}"
itemValue="#{s}"></f:selectItems>
</h:selectOneMenu>
<h:selectOneMenu id="eventSelector">
<f:selectItems value ="#{selector_bean.events}" var ="e"
itemLabel="#{e.event_Name}"
itemValue="#{e}"></f:selectItems>
</h:selectOneMenu>
</h:form>
</f:view>
Here is the bean:
#ManagedBean(name = "selector_bean")
#Stateless
public class selector_bean implements Serializable{
#EJB
SeasonFacade sf;
#EJB
EventFacade ef;
#EJB
WrestlerFacade wf;
private Season season;
private Event event;
private List<Event> events;
private Match match;
private Wrestler wrestler;
public List<Season> getSeasons(){
return sf.findAll();
}
public void genEvents(AjaxBehaviorEvent event){
events = (ef.findBySeason(season));
}
// setters and getters after this
When I change the value of the first selectOneMenu, a popup box appears with this message:
httpError: There was an error communicating with the server, status: 404
I am new to both JSF and AJAX so feel free to tear me apart if I am doing it wrong. Thanks for any help!

Your #ManagedBean is behaving as an EJB with the #Stateless annotation. Remove it and instead set the scope of your bean to #ViewScoped:
#ManagedBean(name = "selectorBean")
#ViewScoped
public class SelectorBean implements Serializable{
//your implementation...
}
Also, make sure to follow the JavaBean naming conventions. I've changed the name of your class to start with capital letter.

Related

ui repeat to show one more value and method is not invoking in managed Bean in JSF2.2

<ui:repeat value="#{cc.attrs.bean.foo.foo1}" var="test" varStatus="test1">
<h:outputText value="#{test.prime}" title="#{test.primeNumber}" />
<h:outputText value="," rendered="#{!test1.last}" />
</ui:repeat>
I am getting a value example1,example2
Now after adding a new line:
<ui:repeat value="#{cc.attrs.bean.foo.foo1}" var="test" varStatus="test1">
<h:outputText value="#{cc.attrs.bean.testNo(test)}" rendered="#{test1.first}" />
<h:outputText value="#{test.prime}" title="#{test.primeNumber}" />
<h:outputText value="," rendered="#{!test1.last}" />
</ui:repeat>
I want my output something like this Hello- example1,example2......
But I am not able to get this output. In fact testNo(test) method is not invoked. What exactly is getting wrong over here. Thank you in advance
Manage bean method
private String testNo(Test test) {
List<Test11> type = Lists.newArrayList();
String some = someService.findTestNumber(test.getSomeNumber());
return some;
}
You need to make a basic MVC webapp. There are many tutorials about this, but example always helps: Your model is simple, two entities for a CompletedTest:
#Entity
public class CompletedTest {
#Id #GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String name;
#OneToMany(fetch=FetchType.EAGER)
private List<TestResult> results;
// getters and setters
}
and a TestResult:
#Entity
public class TestResult {
#Id #GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String result;
// constructors, getters, setters
}
Access your model through a service layer
#Stateless
public class TestService {
#Inject
private EntityManager em;
public CompletedTest findTestResultByName(String name) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<CompletedTest> q = cb.createQuery(CompletedTest.class);
Root<CompletedTest> tr = q.from(CompletedTest.class);
q.select(tr).where(cb.equal(tr.get("name"), name));
List<CompletedTest> testResults = em.createQuery(q).getResultList();
if ( testResults.size() > 0 ) return testResults.get(0);
else return null;
}
The create a controller to interface to your view:
#Model
public class TestResultController {
#Inject
private TestService testResultService;
private CompletedTest testResult;
#PostConstruct
public void init() {
testResult = testResultService.findTestResultByName("Test #1");
}
and finally your view is your JSF page:
<ui:repeat var="r" value="#{testResultController.testResult.results}" varStatus="tSt">
<h:outputText value="#{testResultController.testResult.name}: " rendered="#{tSt.first}" />
<h:outputText value="#{r.result}"/>
<h:outputText value=", " rendered="#{!tSt.last}" />
</ui:repeat>
As you can see, the JSF page accesses the Controller bean. In that bean is a PostConstruct annotation, which gets executed when the JSF page references the bean. The PostConstruct executes any code you need to initialize the bean, in this case a call to the service layer which loads a test result from the database. Of course, there is a bit of code I didn't include, such as creating a test or showing a list of CompletedTests so the user can choose which one he or she wants. You can do all that on a single page with a form and a drop-down list. Further, calling to the database every time the JSF page is loaded will result in poor performance, so there are more sophisticated mechanisms for caching Entities in memory, but that is beyond this simple answer.

JSF2.2, RequestScope and component persistence

My actual scenario is a simple JSF project that uses Mojarra 2.2.5.
I'm trying to get programmatically a component instance (via "findComponent" method or binding ...) and set some attributes (click on "ChangeColor" button).
After that, using any other action (for example clicking on "Send" button), the previous changes are ignored !!
It seems that changeColor method don't update the ViewState !
The sample code is the following:
<h:form id="form">
<h:panelGrid columns="1">
<h:inputText id="input" binding="#{page9.input}"/>
<h:commandButton value="Change BackColor" action="#{page9.changeColor}"/>
<h:commandButton value="Send" action="#{page9.dummy}" />
</h:panelGrid>
</h:form>
And the relative RequestScope bean
#ManagedBean(name="page9")
#RequestScoped
public class Page9 implements Serializable {
private static final long serialVersionUID = 1L;
private HtmlInputText input;
public HtmlInputText getInput() {
return input;
}
public void setInput(HtmlInputText input) {
this.input = input;
}
public void changeColor(){
FacesContext fc = FacesContext.getCurrentInstance();
HtmlInputText hit = (HtmlInputText) fc.getViewRoot().findComponent(":form:input");
hit.setStyle("background-color:blue");
}
public void dummy(){
}
}
Some important considerations:
1) I must use RequestScope for compatibility reasons.
2) Setting javax.faces.PARTIAL_STATE_SAVING to "false" all works fine (!).
3) Trying to use MyFaces 2.2.3 libraries all works fine (!).
What do you think about ?
Thanks.

Primefaces obtain inputText value in managedBean

My question should be trivial for someone who is familiar with Primefaces but I'm just starting. My question is:
When I put inputText component to my web page like this:
<h:form id="formularz">
<p:inputText id="workyears" value="#{appointentBean.year}" style="width: 40px;"/>
<h:form>
I would like to retrieve the inputed text directly from appointentBean. I mean I would like to create another method in appointentBean that will process inputed text so I need inputed text to be placed in referenced field year immediately. In another worlds I need my field year in appointentBean to be automaticaly updated while someone put text in inputText component. Something like submit? I hope you understand what I mean.
Here is my managedBean:
#ManagedBean
#ViewScoped
#SessionScoped
public class appointentBean{
private int year;
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
//Here I will put another method that will be operate on year value
}
You can do that using events like this (read more):
<h:form>
<p:inputText value="#{viewMBean.hello}">
<p:ajax event="keyup" update="hello" process="#this" />
</p:inputText>
<h:outputText id="hello" value="#{viewMBean.hello}" />
</h:form>
Here is the viewMBean:
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class ViewMBean implements Serializable {
private String hello;
public String getHello() {
return hello;
}
public void setHello(String hello) {
this.hello = hello;
}
}
PS: Welcome to Primefaces!!

Use single p:ajax to execute multiple actions

I have a p:selectOneMenu in my application, and when the selection takes place I need to call multiple back-end methods from different managed beans in order to perform different actions.
XHTML code:
<p:selectOneMenu id="selectMenu" value="#{userBean.selectedSite}"
converter="siteConverter" style="width:150px">
<p:ajax event="change" listener="#{bean2.changeSite}"
render="#form :comp1 :comp2 :comp3 :comp4" />
<f:selectItems value="#{userBean.sites}" var="site"
itemValue="#{site}" itemLabel="#{site.description}" />
<p:ajax event="change" listener="#{bean1.reset}"
update="#form :comp1 :comp2 :comp3 :comp4" />
</p:selectOneMenu>
Managed bean 1:
#ManagedBean(name="bean1")
#ViewScoped
public class Bean1 implements Serializable {
// ...
public void reset() {
loadEvents();
resetEvent();
}
}
Managed bean 2:
#ManagedBean(name="bean2")
#SessionScoped
public class Bean2 implements Serializable {
// ...
public void changeSite() {
FacesContext context = FacesContext.getCurrentInstance();
Bean1 bean = (Bean1) context.getApplication().evaluateExpressionGet(context, "#{bean1}", Bean1.class);
reload();
bean.loadEvents();
}
}
If, instead of using two different p:ajax components, I use a single p:ajax that calls a single method from Bean1, the page components listed under "update" are not correctly updated.
XHTML:
<p:ajax event="change" listener="#{bean1.singleMethod}"
update="#form :comp1 :comp2 :comp3 :comp4" />
Managed bean 1:
#ManagedBean(name="bean1")
#ViewScoped
public class Bean1 implements Serializable {
// ...
public void () singleMethod() {
FacesContext context = FacesContext.getCurrentInstance();
Bean2 bean = (Bean2) context.getApplication().evaluateExpressionGet(context, "#{bean2}", Bean2.class);
bean2.changeSite();
reset();
}
}
Changing the selected values updates the server side objects, but the page is not updated: if I press F5, the page shows the actual situation.
Moving the single global method to the session scoped bean (Bean2) does the job.

Copying value of a textbox to a nother using ajax in jsf

I am very new to ajax and trying to copy the value of one box to another. Here is my code:
<h:form>
<h:inputText value="#{ajaxBean.name}">
<f:ajax render="otherbox" execute="#this" event="keyup"></f:ajax>
</h:inputText>
<h:inputText id="otherbox" value="#{ajaxBean.name}"></h:inputText>
</h:form>
And the bean
#Named(value = "ajaxBean")
#Dependent
public class AjaxBean {
public AjaxBean() {
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
That code does not work. Can anyone help me?
Thanks
Your question is not about Ajax or JSF. It is a JavaScript question.
You can access and modify items with JavaScript.
Add this JavaScript codes between <h:head></h:head>
<script>
function copyField()
{
document.getElementById("field2").value = document.getElementById("field1").value;
}
</script>
And your page:
<h:form id="myform" prependId="false">
<h:inputText id="field1" value="#{myBean.name}" onkeyup="copyField();" />
<h:inputText id="field2" value="#{myBean.name}"></h:inputText>
</h:form>
Take attention to prependId="false" to avoid mixing ids.
See also:
JSF: Why prependId = false in a form?
I think you are mixing up JSF and CDI. #Dependent says that the bean is in the dependent pseudo-scope (which is anyways the default-scope for CDI-beans), so every time you make a request the bean will be reinstanciated and the bean can not hold any state. Look here for an explanation of the scopes and especially for what the dependent scope is used for.
So first of all you have to use some different scope, #RequestScoped should be enough for your task. And as I do not see any use of CDI here, use #ManagedBean instead of #Named - so the default scope for the bean will be the request scope.
Try this:
#ManagedBean
public class AjaxBean {
...
}

Resources