I'm using ICEfaces with ICEpush to push some data to the browser.
However, it does not work like planned: It does no AJAX, it just invokes the action and returns from the action like any other non-AJAX action does.
I'm using the newest ICEfaces and ICEpush versions and Tomahawk 7 and JSF 2.
It works with neither Servlet 2.5 nor Servlet 3.0.
These are the important parts of my bean (view scoped):
public AjaxTest() {
PushRenderer.addCurrentSession(PUSH_GROUP);
}
public void addText() throws InterruptedException {
for(int i = 0; i < 5; i++) {
lines.add("line " + i);
PushRenderer.render(PUSH_GROUP);
Thread.sleep(1000);
}
}
And this is a snippet of my form:
<h:panelGroup>
<h:dataTable id="ajaxTestTable" value="#{ajaxTest.lines}" var="line">
<h:column>
<h:outputText value="#{line}" />
</h:column>
</h:dataTable>
<h:commandButton id="startAjax" value="Start"
action="#{ajaxTest.addText}" />
</h:panelGroup>
Did I miss something? Thanks!
ICEfaces 2.0 is not yet integrated with MyFaces. Have you tried your application with the included Mojarra .jar files?
I'm only familiar with Icefaces 1.8, but it seems to me you're command button isn't ajax enabled. As well you have to use an actionListener instead of an action
You can use either the icefaces command button:
<ice:commandButton id="startAjax" value="Start"
actionListener="#{ajaxTest.addText}"/>
or the JSF 2 ajax tags:
<h:commandButton id="startAjax" value="Start">
<f:ajax listener="#{ajaxTest.addText}"/>
</h:commandButton>
Do you have some development tool that can validate the code? At least on Vaadin version of ICEPush you could not trust to their examples. On their official demo there was deprecated code and on their chat they gave code where imports were from another planet with the correct ones.
My Eclipse told that many imports were wrong and code had deprecated marks on some functions. These guys there develop so fast that their documents are permanently out of date. So, read carefully what your tool says about the code!
I also have the problem with integration of IceFaces (to use push) with the app which already use Richfaces. But it is possible to integrate the IcePush directly with almost any java-web-application (with Servlet Api).
You can see more details on http://achorniy.wordpress.com/2012/02/29/icepush-integration-to-web-application/
The idea is to use javascript-api(or jQuery-api) provided by IcePush. So, your page with javascript-api register itself as a listener to push notifications and in the callback you can call whatever javascript functions to update your page. In Richfaces example you may use ajaxUpdateFunction() which is actually backed by <a4j:jsFunction name="ajaxUpdateFunction" action="#{myBean.update} reRender="updatedComponent(s)" ajaxSingle="true"/> or perform ajax-request with jQuery. In your case (JSF-2.0) I think you can call jsf.ajax.request(this, event, {render:'ajaxTestTable'}) to update what you want (examples http://andyschwartz.wordpress.com/2009/07/31/whats-new-in-jsf-2/)
all you need to do on server-side - is to register IcePush servlet and initialize icePush connection on the client side with javascript api.
Related
I can't get the PrimeFaces 6.1 built-in ajax feature to work when using a liferay portal. I've started with the very initial use case example, that is the one shown in the PF User's Guide documentation and nothing happens, absolutely nothing happens.
xhtml side
<h:form id="form">
<h:inputText value="#{bEntityTree.text}">
<p:ajax process="#form" update="output" onstart="onStart" oncomplete="onComplete" onsuccess="onSuccess" onerror="onError"/>
</h:inputText>
<br/>
<h:outputText id="output" value="valor:#{bEntityTree.text}"/>
</h:form>
Bean side:
#ManagedBean(name = "bean")
#ViewScoped
public class Bean implements Serializable {
private static Logger logger = Logger.getLogger(BEntityTree.class);
private String text;
public Bean() {
logger.trace("bean created");
}
#PostConstruct
private void onPostConstruct() {
logger.trace("start");
}
public String getText() {
logger.trace("getting text:" + text);
return text;
}
public void setText(String text) {
logger.trace("setting text:" + text);
this.text = text;
}
}
JS side:
function onStart(){
console.log("onStart");
}
function onComplete(){
console.log("onComplete");
}
function onSuccess(){
console.log("onSuccess");
}
function onError(){
console.log("onError");
}
According to what the documentation states, each time the input changes an ajax request is sent to the server. My understanding is that the input changes when 'onchange' event is fired (default client side event). Well, every time I type a character in the <h:inputText> element nothing happens. When <p:inputText> looses the focus nothing happens, that is, <h:outputText> isn't updated and any trace console is displayed on the console of my chrome browser. The only trace log I get is the one from my IDE console:
[TRACE] Bean:<init>():bean created
[TRACE] Bean:onPostConstruct():start
[TRACE] Bean:getText():getting text:null
[TRACE] Bean:getText():getting text:null
I don't know what I'm doing wrong, what I'm missing.
Any help would be pretty appreciated.
I've just sorted the problem out. There were 2 problems. The first one (the less serious one) is that the js callbacks are being invoked wrong. The right way to invoke them should be as follows:
<p:ajax process="#form" update="output" onstart="onStart()" oncomplete="onComplete()" onsuccess="onSuccess()" onerror="onError()" />
The serious problem is related to a missing parameter in the liferay-portlet.xml config file.
Well, it maybe I should haved started saying that I was dealing with a Liferay portlet containing a JSF portlet which uses Primefaces. It all implies that liferay-portlet.xml config file is required. And this config file has to contain the following parameter:
<requires-namespaced-parameters>false</requires-namespaced-parameters>
The problem is that the default liferay-portlet.xml file, that is, the one that the eclipse IDE wizard creates DOES NOT automatically include such a parameter. After including such a parameter, it all works as expected.
UPDATE: The way I create the Liferay Plugin Project.
New > Project > Liferay Plugin Project
Plugin Type: portlet
Include Sample code -> unchecked
Launch New Portlet Wizard afer project is created -> checked
Next > JSF 2.x
Next > Primefaces
Finish
Steps when Wizard is displayed:
Portlet class: javax.portlet.faces.GenericFacesPortlet
Next
View template: Primefaces
Next
Finish
Major result after those steps is that file liferay-portlet.xml doesn't have the element:
<requires-namespaced-parameters>false</requires-namespaced-parameters>
Development settings:
Eclipse Java EE IDE for Web Developers
Version: Mars.2 Release (4.5.2) - Build id: 20160218-0600
Liferay IDE 2.2.4.201507230603-ga5
Any clarification would be appreciated.
First of all, I'm using JSF 2.2.7 and GlassFish 4 in NetBeans 8.0.
Second, sorry if I left any useful info out. This is my first question in here, so I may forget something. Also, english isn't my first language. Sorry for typos/grammar.
So, here's my problem: I'm uploading files with h:inputFile and I need an ajax listener for it.
After noticing that it wasn't working as I expected, I decided to do some testing with a listener that prints "Test", but it's never fired with h:inputFile. I've tried with h:commandButton and h:commandLink and they both work fine.
For further testing, I created a new project using the same test code and everything works, including the listener in h:inputFile.
What I want to know is why it doesn't work in my main project and why it works in the test project. What am I missing here? And how can I make it work in my main project?
Here are some (but not all, since I lost track) things that I've tried/checked so far, after looking for answers:
There are no nested forms. The said xhtml is in a ui:composition, but even taking that into account, there are no nested forms.
Its form has enctype="multipart/form-data"
I've tried changing the method to uploadTest(AjaxBehaviorEvent event) and the listener to listener="#{submitFormBean.uploadTest}" [without the ()]
I've played with the various event="..." and execute="..." (didn't think it would solve my problem, but, well, I had to try)
The code follows below:
xhtml
<h:form>
<h:commandButton id="btnTest">
<f:ajax listener="#{submitFormBean.uploadTest()}"/>` --> works in both projects`
</h:commandButton>
</h:form>
<h:form>
<h:commandLink id="lnkTest" value="Test">
<f:ajax listener="#{submitFormBean.uploadTest()}"/>` --> works in both projects`
</h:commandLink>
</h:form>
<h:form enctype="multipart/form-data">
<h:inputFile id="fileTest">
<f:ajax listener="#{submitFormBean.uploadTest()}"/>` --> works only in test project`
</h:inputFile>
</h:form>
bean
#ViewScoped
#ManagedBean(name = "submitFormBean")
public class SubmitFormBean{
public SubmitFormBean() {
}
public void uploadTest(){
System.out.println("Test");
}
}
Thanks in advance!
I was about to do what I needed in jQuery, but first I decided to try the following and it solved my problem:
right click project/properties/libraries
in the compile tab, I removed and readded the JSF 2.2.7 .jar
It was already there, but for some reason wasn't working. I still don't know what went wrong, but it's working now.
With multipart/form-data in JSF form, you have to do additional configuration to make it works.
You can refer to other questions:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated
JSF 2.0 File upload
And
How to use PrimeFaces p:fileUpload? Listener method is never invoked or UploadedFile is null
I'm trying to do some action in the ManagedBean based on the state of the checkbox.
Checkbox is here:
<p:selectBooleanCheckbox id="cb">
<p:ajax listener="#{myBB.checkboxChanged}"/>
</p:selectBooleanCheckbox>
The signature of the listener method is this:
public void checkboxChanged(AjaxBehaviorEvent event)
The listener method is called as expected, but I'm not sure how to get the state of the checkbox(if it is selected)
This is false all the time:
((SelectBooleanCheckbox)event.getSource()).isSelected()
Do I need to bind the value of the checkbox? I'd like to avoid that, because the checkboxes are generated from enum in a loop and I don't have any boolean where to bind it(the model is designed in a way that I'm adding/removing the instances of enum to a collection, not setting boolean properties)
I'm running the code on Tomcat 6.0.36 with Primefaces 3.5
JSF implementation is Apache Myfaces 2.1.10
Your code works as expected for me on Mojarra 2.2.1 and PrimeFaces 4.0RC1 as well as Mojarra 2.0.3 and PrimeFaces 3.5. Unfortunately I didn't have 2.1 handy. What version of PrimeFaces are you using? Can you post your complete code?
Lucas was right, everything is fine. The problem is I did not put the button in the form.
After adding <h:form> tag, everything is ok.
Trying to implement the JSF 2.2 example I have the following code:
<h:form prependId="false" enctype="multipart/form-data">
<!-- Now it's the AJAX file upload component -->
<h:inputFile id="fileUpload" value="#{someBean.file}" >
<f:ajax />
</h:inputFile>
<h:commandButton value="Upload" />
</h:form>
According to some JSF 2.2 this should work but in my case it is giving me the following error:
the request doesn't contain a multipart/form-data or multipart/mixed
stream, content type header is
application/x-www-form-urlencoded;charset=UTF-8
Looking into the request although I have set my form enctype correctly, the partial request submits:
Content-type:application/x-www-form-urlencoded;charset=UTF-8
Faces-Request:partial/ajax
Note that web.xml also was modified to:
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<multipart-config>
<location>c:\dotmp</location>
<max-file-size>20848820</max-file-size>
<max-request-size>418018841</max-request-size>
<file-size-threshold>1048576</file-size-threshold>
</multipart-config>
</servlet>
I am using Mojarra 2.2.0-m15 but tried this with earlier versions as well. Does anyone know any useful info about this issue, which I assume is a bug?
I'm not sure what's going on as I haven't seen this before. The following construct works for me when using the today's Mojarra 2.2.1 snapshot which you can download from the "implementation jar" link mentioned in What's new in JSF 2.2?
<h:form enctype="multipart/form-data">
<h:inputFile value="#{bean.file}" required="true">
<f:ajax listener="#{bean.handleFileUpload}" render="#form" />
</h:inputFile>
<h:messages />
</h:form>
with
private Part file;
public void handleFileUpload(AjaxBehaviorEvent event) {
System.out.println("file size: " + file.getSize());
System.out.println("file type: " + file.getContentType());
System.out.println("file info: " + file.getHeader("Content-Disposition"));
}
// ...
I recommend to give the newer Mojarra version a try. Apparently there was a bug in an older Mojarra version which failed to create a proper multipart/form-data request using the <iframe> hack which ultimately caused this error. The mXX versions are beta versions anyway and should not be relied upon for production. This error could theoretically also have been browser-specific, but it works currently fine for me in Chrome 26, Firefox 20 and IE 10.
The only issue which I'm seeing is that the hidden <iframe> is still visible in Chrome and Firefox as below:
It appears that they're forgotten to set frameborder attribute to 0 in the generated <iframe>. I've reported issue 2861 about that.
I fixed the JavaScript of JSF (and other parts) to enable Multipart requests with and without AJAX on servlet standard 2.
The JSF 2.2 file upload works beginning with servlet version 3. Furthermore the responsible transport layer called "IFrame Transport" was not in release state. So I added a transparent Multipart request, completed the transport layer and put all together to an upload tag:
<e:inputFile id="file" value="#{fileUpload.file}" filename="#{fileUpload.filename}"
mimeType="#{fileUpload.mimeType}"/>
The Tag works together with AJAX, with traditional page submits and with servlet standard 2 / 3. Not the nicest implementation, but it's working almost transparent. The solution is accessible at http://www.intersult.com/wiki/page/JSF%20Ext#section-JSF+Ext-FileUpload (Please use translation).
Comments welcomed.
I had the same problem with PrimeFaces <p:fileUpload mode="simple" using javax.faces-2.2.6.jar. The problem disappeared when I disabled ajax from my <h:commandButton. In my case it was OK to refresh the whole page.
I am in the middle of a migration from Richfaces 3.3.3 to Richfaces 4.3.0, which called for a JSF upgrade from 1.2 to 2.1. We are also using Spring Webflow 2.3.2 (upgraded from 2.1.1) for conversation definition. All beans are managed by Spring (no JSF managed beans). Several Richfaces components had to be adjusted for the application to work properly again. The problem I have now concerns the rich:pickList component, which looks like this (I took the showcase example and edited it to depict the problem):
<rich:pickList id="ownPicklist" value="#{listSelectBean.selectedCapitals}"
sourceCaption="Available cities" targetCaption="Selected cities"
listWidth="165px" listHeight="100px">
<a4j:ajax event="change" execute="#this" render="#{mainBean.dynamicRerenderList}" />
<f:selectItems value="#{listSelectBean.capitals}" var="capital"
itemValue="#{capital}" itemLabel="#{capital.name}" />
<f:converter converterId="CapitalsConverter" />
</rich:pickList>
Now unlike the showcase example, our ListSelectBean is a Spring bean and is defined like this:
<bean id="listSelectBean" class="com.xyz.example.bean.ListSelectBean" scope="request" />
The custom converter is registered in the faces-config.xml:
<converter>
<converter-id>CapitalsConverter</converter-id>
<converter-class>com.xyz.converter.CapitalsConverter</converter-class>
</converter>
As you can see we have an ajax event handler attached to the pickList, which dynamically calculates a list of components to be rerendered depending on the selected value(s) from the list. This list also contains the pickList itself, which normally has to be rerendered with much less elements to select from. The ajax response I get contains the full source list, but the target list is empty.
Now to the problem:
When I select an element from the left side it jumps to the right side and immediately back again.
I debugged the issue and learned that all the getters and setters of the listSelectBean are invoked correctly as different JSF phases are run through. The same example with JSF managed, request scoped beans works fine (which is in the Richfaces showcase), also with the ajax rerender on the component itself. I suspect a problem with the bean handling in Spring (Webflow). But I can't pinpoint it. Any help will be highly appreciated.
After long hours of debugging I finally found the solution to the problem. As RichFaces uses a HashSet during the rendering process it is important to have the hashCode() and equals() Methods overridden for complex objects (which is a good idea in general) used in the PickList. Otherwise selected objects won't be marked as selected.