poll doesn't work with setted var - jsf

I want to use one html page with two ManagedBeans. Depending on the parameter in the URL, I want to set the bean name through JSTL variable. For example:
<c:set var="bean" value="#{webModule1}" scope="request" />
or
<c:set var="bean" value="#{webModule2}" scope="request" />
I have class which was use all this time, so for sure this works:
#ManagedBean(name = "webModule1")
#ViewScoped
public class WebModule1 implements Serializable {
protected WebModulesFormBean form;
#PostConstruct
public void init() {
if (!firstInit()){
this.form= new WebModulesFormBean();
}
//some code
}
public void process() {
if(this.form.isActive()){
//some code
}
}
}
And new one:
#ManagedBean(name = "webModule2")
#ViewScoped
public class WebModule2 extends WebModule1 {
public void process() {
if(this.form.isActive()){
//code with some changes
}
}
}
This solutions works with value attribute and form in not null, for example:
<p:treeTable value="#{bean.form.root}" var="node" id="modulesTree">
But I have problem with this piece of code:
<p:poll listener="#{bean.process()}" widgetVar="documentOutcome" autoStart="#{bean.form.start}" update="modulesTree" async="false"
interval="1" id="myPoll2" />
When listener is called, NullPointerException appears.
And this problem is with all p:polls (I have a few), so this is not a problem with method code.
Problem is that 'form' is null, although at the beginning variable 'form' is initialized and treeTable is shown at the page. So 'form' starts to be null when the listener is called.
Thanks!

I have a solution!
The problem was with:
<c:set var="bean" value="#{webModule1}" scope="request" />
scope="request" was not enough and in my understanding this scope meant that when poll was called, a new bean reference was created and form variable was null because it was not a firstInit().
scope="view" is the solution.
Thank you for comments!

Related

Trigger listener clicking on ace:textEntry

I'm using JSF 2.0 and I want to invoke a function defined in a Java controller when I click on an ace:textEntry.
I tried in this way:
<ace:textEntry readonly="true" value="#{myController.getValue()}"
onclick="#{myController.myFunc()}"/>
but when my page is open, the click event is called instantly.
So, I tried with:
<ace:textEntry readonly="true" value="#{myController.getValue()}">
<ace:ajax event="click" listener="#{myController.myFunc()}"/>
</ace:textEntry>
but my page is not rendered.
Is there another way to implement this behaviour ?
PS: I can use similar JSF components instead of ace:textEntry too.
First, you do not access getters directly in JSF for value backing - you access the property. Secondly, you should call the listener with the correct signature. To correct your example I would first rewrite the call like this,
<ace:textEntry readonly="true" value="#{myController.value}">
<ace:ajax event="click" listener="#{myController.myFunc}"/>
</ace:textEntry>
Then define MyController, like this;
#Named
#ViewScoped
public class MyController {
private value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public void myFunc(javax.faces.event.AjaxBehaviorEvent event) {
/* Do somethinig here... */
}
}

ViewScoped bean is recreated each ajax request using p:remoteCommand

I have a javascript function responsible to call 2 managed bean methods using <p:remoteCommand/> the problem is that in one method i have to generate a value and use it in the second method, but when I call to the second method the value is null and this is because the ManagedBean is recreated each request, here is my code:
javascriptFile.js
<script>
function executeProcess(){
method1();
method2();
}
</script>
myView.xhtml
<h:form>
<p:remoteCommand name="method1"
actionListener="#{controller.method1()}"
update="xComponent" />
<p:remoteCommand name="method2"
actionListener="#{controller.method2()}"
update="xComponent" />
</h:form>
Controller.java
#ManagedBean
#ViewScoped
public class SearchCarneStudent implements Serializable {
private String myValue;
public void method1(){
myValue="Hello";
}
public void method2(){
System.out.println(myValue); //<- This line is returning null because the bean is recreated each request
}
}
I hope you can help me
Thanks

#ConversationScoped bean reconstructed during page-to-page navigation

I just found a strange behavior when I change from one page to another.
I'm using CDI, Jsf 2.2 API 2.2.8, Omnifaces 2.2, Primefaces 5.2, wildfly 8.2.
Most of the controllers and pages work as expected, but some of them, when I access the page, call the method #PostConstruct, which starts the conversation, then, when I leave the page, the #PostConstruct is called again. I realized that something in page.xhtml is the cause, so I started to look for it. But is a strange behaviour anyway.
Following my code and some examples:
Controller which uses abstract class methos like beginconversation() and list()
import javax.inject.Named;
import javax.enterprise.context.ConversationScoped;
#Named
#ConversationScoped
public class PromptConfigurationController extends BaseController<PromptConfiguration> implements Serializable {
public PromptConfigurationController() {
super(PromptConfiguration.class);
}
#PostConstruct
public void init() {
list();
loadFilters();
}
}
Abstract class
public abstract class BaseController<T extends BaseEntity> {
public void list() {
logger.info("list()");
items = getService().findAll(entityClass);
item = null;
beginConversation();
}
protected void beginConversation() {
logger.info("beginConversation()");
if (conversation != null && conversation.isTransient()) {
conversation.begin();
conversation.setTimeout(CONVERSATION_TIMEOUT);
logger.info("Conversation iniciada: " + conversation.getId());
}
}
}
some xhtml pages which I found problem and the solution (when I found) was:
Error:
<f:convertDateTime pattern="#{webChatSearchController.dateHelper.getLocalizedDatePattern()}" />
The method above just return a pattern.
Working
<f:convertDateTime dateStyle="dd/MM/yyyy" pattern="dd/MM/yyyy" />
Error:
<p:commandButton id="commandButton-active" action="#{satisfactionSurveyController.changeQuestionStatus(true)}" update="form-content" binding="#{satisfactionSurveyController.activeButton}" value="#{bundle['common.active.3.message']}">
Working:
<p:commandButton id="commandButton-active" action="#{satisfactionSurveyController.changeQuestionStatus(true)}" update="form-content" value="#{bundle['common.active.3.message']}" disabled="#{satisfactionSurveyController.disableActiveButton}">
The problem was just the "binding".
Error:
<p:dataTable id="dataTable-group-email" var="emailMonitor" value="#{emailMonitorController.listEmailGroup}" selectionMode="single" rowKey="#{emailMonitor}" filteredValue="#{emailMonitorController.listEmailGroupFiltered}">
Working:
<p:dataTable id="dataTable-group-email" var="emailMonitor" value="#{emailMonitorController.listEmailGroup}" selectionMode="single" rowKey="#{emailMonitor}" >
Just removing 'filteredValue' started working. But without it, I can't use the filter properties.
The navigation is made by a menu of primefaces, all the pages are the same logic:
<p:menuitem id="satisfactionSurvey" action="#{satisfactionSurveyController.listPage}" value="#{bundle[satisfactionSurvey.message']}" ajax="false" immediate="true">
<f:param name="nocid" value="true" />
</p:menuitem>
and the Method:
public String listPage() {
return baseViewPath + "/list.xhtml?faces-redirect=true";
}

a4j:support in a reRender is not working

I have a button. If this is pressed, a checkbox should be rendered.
This of course works pretty well. The checkbox should, when changed call a function, which should just System.out.println() something so I see it's called.
The problem is: just the simple checkbox function, without the rerendering works pretty well. But as soon as the a4j:support is rerendered, it's not working, the System.out.println() is never called
This looks so easy, but I don't know why it's not working at all!
Any hint/trick?
This is old environment, so JSF 1.2 only.
My xhtml
<s:div id="sdBoolCheckboxtest">
#{testController.testRerenderBool}
<s:div id="sdRerender" rendered="#{testController.testRerenderBool}">
<h:selectBooleanCheckbox id="myscheckbox" value="#{testController.testBool}">
<a4j:support ajaxSingle="true" event="onclick" immediate="true"
status="globalStatus" action="#{testController.testCheckbox()}" />
</h:selectBooleanCheckbox>
</s:div>
</s:div>
</h:form>
My Java class:
#Name("testController")
#AutoCreate
public class TestController {
private boolean testBool = false;
public boolean isTestRerenderBool() {
return testRerenderBool;
}
public void setTestRerenderBool(boolean testRerenderBool) {
this.testRerenderBool = testRerenderBool;
}
private boolean testRerenderBool;
public void switchtestRerenderBool(){
System.out.println("switch");
testRerenderBool = !testRerenderBool;
}
public void testCheckbox(){
System.out.println("drin");
}
public boolean isTestBool() {
return testBool;
}
public void setTestBool(boolean testBool) {
this.testBool = testBool;
}
}
Okay, i got it working, with these changes:
First i added #Scope(ScopeType.CONVERSATION) to the TestController
#Name("testController")
#AutoCreate
#Scope(ScopeType.CONVERSATION)
public class TestController {
...
}
And as a second change, I changed the <s:div to an <a4j:outputPanel
<a4j:outputPanel id="sdBoolCheckboxtest">
This solved my problem, but I'm still wondering why I need the #Scope(ScopeType.CONVERSATION) (I found the hint with the a4j:outputPanel here)
Any explanation would be helpful, thanks!

ApplicationScoped Bean is null on rich:tab's actionListener-method

I'm using JSF 2.0 and Richfaces 3.3.2.
I'm having an issue on one of my pages.
First of all I have a main page which contains a rich:tabPanel with several rich:tabs, no problem there switching between them.
On the first tab of my page I have another tabPanel with some other tabs.
They all have an actionListener which will call the ViewScoped ManagedBean to edit some Data, which will be displayed on the clicked tab. The method to edit the data calls a method on an ApplicationScoped Bean which is correctly injected (It works in other tabs). When switching a tab on the second layer and the action-method is called, the ApplicationScoped Bean is null.
This only happens when I switch tabs (so it does not happen on the first tab, which is displayed by default) so I think it's related to the actionListener, but i can't figure out why. Unfortunately I can't provide the actual code but this is the rough structure of my page.
mainPage.xhtml
...
<rich:tabPanel>
<rich:tab>
<ui:include src="tabs/tab1.xhtml" />
</rich:tab>
otherTabs
</rich:tabPanel>
...
tab1.xhtml
...
<rich:tabPanel>
<rich:tab actionListener="#{viewScopedBean.method}">
<ui:include src="subtabs/subtab1.xhtml" />
</rich:tab>
<rich:tab actionListener="#{viewScopedBean.method2}">
<ui:include src="subtabs/subtab2.xhtml" />
</rich:tab>
</rich:tabPanel>
ViewScopedBean.java
#ManagedBean
#ViewScoped
public class ViewScopedBean {
#ManagedProperty(value="#{applicationBean}")
private ApplicationBean applicationBean;
private Data data;
public void init() {
...
data = applicationBean.retrieveData();
...
}
public void method(ActionEvent e) {
...
data = applicationBean.retrieveData();
...
}
public void method2(ActionEvent e) {
...
data = applicationBean.retrieveData();
...
}
// getters/setters
}
ApplicationBean.java
#ManagedBean
#ApplicationScoped
public class applicationBean {
public Data retrieveData() {
...
}
}
When clicking subtab2 I get a NullPointerException at the line data = applicationBean.getData(), so the applicationBean is null. This happens everytime on every tab I'm switching to, but never in the init() method, so the applicationBean should not be null.
I could not find any solution or hints on this problem and hope someone has an idea.
Thanks in advance
regards

Resources