Here is how to have immediateUpload in rich:fileUpload in RichFaces 4.0.0
maze_fr Dec 8, 2011 11:24 AMHello happy fellows,
I needed to have immediateUpload.
And also I neeed to check if the uploaded file is in the accepted types list in order to warn the user.
Actualy, if you try to upload a file not in the accepted types list, nothing happens... which is a little stupid.
So I made my version of fileUpload component and here is how to do your own. I won't be your architect, so you decide in what folder you put the sources, I won't tell you. I'm sure there is a more simple way, but that's the way I did it.
You need :
- RicheFaces 4.0.0.Final sources
- RicheFaces CDK 4.0.0.Final (there are only sources in it, so...)
- Your own custom taglib XML déclaration file
From RF sources, in "artifacts" folder, search for files containing "fileUpload". From that list, you have to :
1 - copy / paste the déclaration of fileUpload component from RF tablib to your custom taglib
2 - copy / paste the déclaration of fileUpload component from RF faces-config to your own
3 - copy / paste the déclaration of HTML_BASIC render kit from RF faces-config to your own
4 - copy / paste the déclaration fileupload.js and fileupload.ecss to your "resources" directory
5 - copy / paste AbstractFileUpload, UIFileUpload, FileUploadRenderer and FileUploadHandler classes to your project.
Here, it will ask you the CDK for CDK annotation use.
You have 2 solutions : add the CDK annotation sources to ur project or, with maven, add this to your POM file :
<dependency>
<groupId>org.richfaces.cdk</groupId>
<artifactId>annotations</artifactId>
<version>4.0.0.Final</version>
<scope>provided</scope>
</dependency>
6 - in all the pieces of code you copied / pasted, replace all references to RF classes that you copied / pasted to the classes you copied / pasted.
It doesn't sound very clear, I know. So in a more detailed way, here are where you have to make changes :
- cutom taglib : <handler-class>
- faces-config : <component-class>, <cdk:base-class>, <cdk:handler-class> and <renderer-class>
- in your Java classes, I guess you can find on your own what are the imports to replace, but also you need to replace :
- AbstractFileUpload : @JsfComponent handler
7 - replace the "types" by your owns. In a more detailed way :
- cutom taglib : <component-type> and <renderer-type>
- faces-config : <component-type>, <component-family> and <renderer-type>
- in your Java classes :
- AbstractFileUpload : @JsfRenderer, COMPONENT_TYPE and COMPONENT_FAMILY
- UIFileUpload : COMPONENT_TYPE, COMPONENT_FAMILY and setRendererType
8 - point to the good resources. In FileUploadRenderer, change the "library" of fileupload.ecss and fileupload.js to the folder where u put them.
From now it will get easier (code to copy / paste or delete).
9 - remove useless CSS code that has been forgotten : in fileupload.ecss, remove the line "height: 210px; /*TODO Remove it*/"... yes, I found it funny too...
10 - add missing code to the JS file :
- in "init" function, add the event "onadd" (it's the way I called it, choose your own way if you) at the end :
if (this.onadd) {
richfaces.Event.bind(this.element, "onadd", new Function("event", this.onadd));
}
- in "__addItem" function, in the last if, add the following pieces of code :
- before the end of the if :
if (this.immediateUpload) {
this.__startUpload();
}
- at the end of the if :
else {
richfaces.Event.fire(this.element, "onadd", fileName);
}
11 - now in the tag lib, add the attributes :
<attribute>
<name>onadd</name>
<type>java.lang.String</type>
</attribute>
<attribute>
<name>immediateUpload</name>
<type>boolean</type>
</attribute>
12 - in faces-config, add the properties :
<property>
<description>Javascript code executed when the add button is
clicked over this element.</description>
<display-name>Add Button Click Script</display-name>
<icon />
<property-name>onadd</property-name>
<property-class>java.lang.String</property-class>
<property-extension>
<cdk:event-name default="false">add</cdk:event-name>
<cdk:generate>true</cdk:generate>
<cdk:hidden>false</cdk:hidden>
<cdk:literal>false</cdk:literal>
<cdk:pass-through>true</cdk:pass-through>
<cdk:read-only>false</cdk:read-only>
<cdk:required>false</cdk:required>
</property-extension>
</property>
<property>
<property-name>immediateUpload</property-name>
<property-class>boolean</property-class>
<default-value>false</default-value>
<property-extension>
<cdk:generate>true</cdk:generate>
<cdk:hidden>false</cdk:hidden>
<cdk:literal>false</cdk:literal>
<cdk:pass-through>false</cdk:pass-through>
<cdk:read-only>false</cdk:read-only>
<cdk:required>false</cdk:required>
</property-extension>
</property>
13 - in the Java classes :
- AbstractFileUpload :
@Attribute(events = @EventName("add"))
public abstract String getOnadd();
@Attribute(defaultValue = "false")
public abstract boolean isImmediateUpload();
- UIFileUpload :
- in EVENT_NAMES, add the envent "add"
- in Properties, ad the porperties : "immediateUpload" and "onadd"
- add the getters and setters :
public String getOnadd() {
String value = (String) getStateHelper().eval(Properties.onadd);
return value;
}
public void setOnadd(String onadd) {
getStateHelper().put(Properties.onadd, onadd);
}
public boolean isImmediateUpload() {
Boolean value = (Boolean) getStateHelper().eval(Properties.immediateUpload, false);
return value;
}
public void setImmediateUpload(boolean immediateUpload) {
getStateHelper().put(Properties.immediateUpload, immediateUpload);
}
- FileUploadRenderer, in ATTRIBUTES_FOR_SCRIPT_HASH41 :
.generic("immediateUpload", "immediateUpload").defaultValue(false)
.generic("onadd", "onadd", "add");
That should be enough.
Have fun !
If anyone manage to find how to hide the "+ add" button when doing immediateUpload, I'm very interested.