JBoss Rich Faces SVN: r13854 - trunk/test-applications/jsp/src/main/java/rich.
by richfaces-svn-commits@lists.jboss.org
Author: adubovsky
Date: 2009-04-25 08:49:24 -0400 (Sat, 25 Apr 2009)
New Revision: 13854
Modified:
trunk/test-applications/jsp/src/main/java/rich/RichBean.java
Log:
fix mistake in boolean array
Modified: trunk/test-applications/jsp/src/main/java/rich/RichBean.java
===================================================================
--- trunk/test-applications/jsp/src/main/java/rich/RichBean.java 2009-04-25 12:48:05 UTC (rev 13853)
+++ trunk/test-applications/jsp/src/main/java/rich/RichBean.java 2009-04-25 12:49:24 UTC (rev 13854)
@@ -70,13 +70,13 @@
map.add("InplaceSelect", add("/InplaceSelect/InplaceSelect", new boolean [] {false, true, false}));
map.add("InplaceInput", add("/InplaceInput/InplaceInput", new boolean [] {false, true, false}));
map.add("Skinning", add("/Skinning/Skinning", new boolean [] {false, false, false}));
- map.add("HotKey", add("/HotKey/HotKey", new boolean [] {true, false, false}));
+ map.add("HotKey", add("/HotKey/HotKey", new boolean [] {false, false, false}));
map.add("Validator", add("/Validator/Validator", new boolean [] {true, true, true}));
map.add("DataGrid", add("/DataGrid/DataGrid", new boolean [] {false, true, false}));
map.add("ExtendedDataTable", add("/ExtendedDataTable/ExtendedDataTable", new boolean [] {false, true, false}));
- map.add("Editor", add("/Editor/Editor", new boolean [] {true, true, false}));
+ map.add("Editor", add("/Editor/Editor", new boolean [] {false, true, false}));
map.add("TreeAll", add("/TreeAll/tTree", new boolean [] {true, true, true}));
- map.add("TreeSwing", add("/TreeSwing/TreeSwing", new boolean [] {true, true, false}));
+ map.add("TreeSwing", add("/TreeSwing/TreeSwing", new boolean [] {false, true, false}));
map.add("Queue", add("/Queue/Queue", new boolean [] {false, true, true}));
map.add("LayoutComponents", add("/LayoutComponents/LayoutComponents", new boolean [] {true, true, true}));
Iterator<String> iterator = map.getSet().iterator();
17 years
JBoss Rich Faces SVN: r13853 - trunk/test-applications/jsp/src/main/java/util/event.
by richfaces-svn-commits@lists.jboss.org
Author: Vadim Mikovoz
Date: 2009-04-25 08:48:05 -0400 (Sat, 25 Apr 2009)
New Revision: 13853
Modified:
trunk/test-applications/jsp/src/main/java/util/event/Event.java
Log:
Modified: trunk/test-applications/jsp/src/main/java/util/event/Event.java
===================================================================
--- trunk/test-applications/jsp/src/main/java/util/event/Event.java 2009-04-25 12:38:26 UTC (rev 13852)
+++ trunk/test-applications/jsp/src/main/java/util/event/Event.java 2009-04-25 12:48:05 UTC (rev 13853)
@@ -130,9 +130,14 @@
private String onsetup;
private String onsave;
private String onsizeexceeded;
- private String onlistchanged;
+ private String onlistchanged;
+ private String onlistchange;
private String onload;
private String onunload;
+ private String oncopyclick;
+ private String oncopyallclick;
+ private String onremoveclick;
+ private String onremoveallclick;
public String getOnlistchanged() {
return onlistchanged;
@@ -141,7 +146,49 @@
public void setOnlistchanged(String onlistchanged) {
this.onlistchanged = onlistchanged;
}
+
+ public String getOnlistchange() {
+ return onlistchange;
+ }
+ public void setOnlistchange(String onlistchange) {
+ this.onlistchange = onlistchange;
+ }
+
+
+ public String getOncopyclick() {
+ return oncopyclick;
+ }
+
+ public void setOncopyclick(String oncopyclick) {
+ this.oncopyclick = oncopyclick;
+ }
+
+ public String getOncopyallclick() {
+ return oncopyallclick;
+ }
+
+ public void setOncopyallclick(String oncopyallclick) {
+ this.oncopyallclick = oncopyallclick;
+ }
+
+ public String getOnremoveclick() {
+ return onremoveclick;
+ }
+
+ public void setOnremoveclick(String onremoveclick) {
+ this.onremoveclick = onremoveclick;
+ }
+
+ public String getOnremoveallclick() {
+ return onremoveallclick;
+ }
+
+ public void setOnremoveallclick(String onremoveallclick) {
+ this.onremoveallclick = onremoveallclick;
+ }
+
+
public String getOnsetup() {
return onsetup;
}
@@ -178,6 +225,11 @@
public Event() {
/* Events for toolBar */
onlistchanged = "showEvent('infoFormID:infoSubview:onlistchangedInputID', 'onlistchanged work!')";
+ onlistchange = "showEvent('infoFormID:infoSubview:onlistchangeInputID', 'onlistchange work!')";
+ oncopyclick = "showEvent('infoFormID:infoSubview:oncopyclickInputID', 'oncopyclick work!')";
+ oncopyallclick = "showEvent('infoFormID:infoSubview:oncopyallclickInputID', 'oncopyallclick work!')";
+ onremoveclick = "showEvent('infoFormID:infoSubview:onremoveclickInputID', 'onremoveclick work!')";
+ onremoveallclick = "showEvent('infoFormID:infoSubview:onremoveallclickInputID', 'onremoveallclick work!')";
onsave = "showEvent('infoFormID:infoSubview:onsaveInputID', 'onsave work!')";
onsetup = "showEvent('infoFormID:infoSubview:onsetupInputID', 'onsetup work!')";
onitemclick = "showEvent('infoFormID:infoSubview:onitemclickInputID', 'onitemclick work!')";
@@ -425,7 +477,23 @@
public ArrayList<SelectItem> getOnupclickSI() {
return getEvent("onupclick");
}
-
+
+ public ArrayList<SelectItem> getOncopyclickSI() {
+ return getEvent("oncopyclick");
+ }
+
+ public ArrayList<SelectItem> getOncopyallclickSI() {
+ return getEvent("oncopyallclick");
+ }
+
+ public ArrayList<SelectItem> getOnremoveclickSI() {
+ return getEvent("onremoveclick");
+ }
+
+ public ArrayList<SelectItem> getOnremoveallclickSI() {
+ return getEvent("onremoveallclick");
+ }
+
public ArrayList<SelectItem> getOninitSI() {
return getEvent("oninit");
}
17 years
JBoss Rich Faces SVN: r13852 - trunk/ui/progressBAR/src/main/java/org/richfaces/renderkit.
by richfaces-svn-commits@lists.jboss.org
Author: pyaschenko
Date: 2009-04-25 08:38:26 -0400 (Sat, 25 Apr 2009)
New Revision: 13852
Modified:
trunk/ui/progressBAR/src/main/java/org/richfaces/renderkit/AbstractProgressBarRenderer.java
Log:
https://jira.jboss.org/jira/browse/RF-6751
Modified: trunk/ui/progressBAR/src/main/java/org/richfaces/renderkit/AbstractProgressBarRenderer.java
===================================================================
--- trunk/ui/progressBAR/src/main/java/org/richfaces/renderkit/AbstractProgressBarRenderer.java 2009-04-25 11:26:25 UTC (rev 13851)
+++ trunk/ui/progressBAR/src/main/java/org/richfaces/renderkit/AbstractProgressBarRenderer.java 2009-04-25 12:38:26 UTC (rev 13852)
@@ -395,6 +395,7 @@
String initialClass = (String) component.getAttributes().get(
"initialClass");
String style = (String) component.getAttributes().get("style");
+ if (null==style) style="";
ResponseWriter writer = context.getResponseWriter();
writer.startElement(HTML.DIV_ELEM, component);
getUtils().writeAttribute(writer, HTML.class_ATTRIBUTE, initialClass);
@@ -431,6 +432,8 @@
String clientId = component.getClientId(context);
String styleClass = (String) variables.getVariable("styleClass");
boolean isSimple = isSimpleMarkup(component);
+ String style = (String) component.getAttributes().get("style");
+ if (null==style) style="";
String shellClass = (!isSimple) ? "rich-progress-bar-shell-dig "
: "rich-progress-bar-shell ";
writer.startElement("div", component);
@@ -444,8 +447,7 @@
getUtils().writeAttribute(
writer,
"style",
- variables.getVariable("style")
- + (!isAjaxMode ? "display: none" : ""));
+ style + (!isAjaxMode ? "display: none" : ""));
getUtils().encodePassThruWithExclusions(context, component, "onsubmit");
encodeProgressBar(context, component, isSimple);
if (isAjaxMode) {
@@ -478,6 +480,7 @@
String width = String.valueOf(value.intValue());
String style = (String) component.getAttributes().get("style");
+ if (null==style) style="";
String completeClass = (String) component.getAttributes().get(
"completeClass");
@@ -648,6 +651,7 @@
String finishClass = (String) component.getAttributes().get(
"finishClass");
String style = (String) component.getAttributes().get("style");
+ if (null==style) style="";
ResponseWriter writer = context.getResponseWriter();
writer.startElement(HTML.DIV_ELEM, component);
writer.writeAttribute(HTML.id_ATTRIBUTE, (isAjaxMode) ? clientId
17 years
JBoss Rich Faces SVN: r13851 - in trunk/docs/realworld_app_guide/en/src/main/docbook: includes and 1 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: artdaw
Date: 2009-04-25 07:26:25 -0400 (Sat, 25 Apr 2009)
New Revision: 13851
Added:
trunk/docs/realworld_app_guide/en/src/main/docbook/includes/
trunk/docs/realworld_app_guide/en/src/main/docbook/includes/hiw.xml
trunk/docs/realworld_app_guide/en/src/main/docbook/includes/navigationPanel.xml
trunk/docs/realworld_app_guide/en/src/main/docbook/includes/usedComponents.xml
trunk/docs/realworld_app_guide/en/src/main/docbook/modules/overview.xml
Removed:
trunk/docs/realworld_app_guide/en/src/main/docbook/modules/hiw.xml
Modified:
trunk/docs/realworld_app_guide/en/src/main/docbook/master.xml
trunk/docs/realworld_app_guide/en/src/main/docbook/modules/intro.xml
Log:
https://jira.jboss.org/jira/browse/RF-5768 - Photo Album review
Added: trunk/docs/realworld_app_guide/en/src/main/docbook/includes/hiw.xml
===================================================================
--- trunk/docs/realworld_app_guide/en/src/main/docbook/includes/hiw.xml (rev 0)
+++ trunk/docs/realworld_app_guide/en/src/main/docbook/includes/hiw.xml 2009-04-25 11:26:25 UTC (rev 13851)
@@ -0,0 +1,480 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<section>
+ <title>Upload images</title>
+ <para>The implementation of <emphasis role="bold"><property><rich:fileUpload></property></emphasis> in the Photo Album Demo uses the embedded Flash module that adds extra functionality to the component.
+ Here are the additional features that the Flash module provides:
+ </para>
+ <itemizedlist>
+ <listitem><para>Multiple files choosing;</para></listitem>
+ <listitem><para>Specification of permitted file types in the "Open File" dialog window;</para></listitem>
+ <listitem><para>A number of additional entry object properties.</para></listitem>
+ </itemizedlist>
+
+ <para>
+ The photos uploading functionality is based on the <code>/includes/fileUpload/fileUploader.xhtml page</code>. Let's have a look at this page to find out how the uploader is implemented:
+ </para>
+
+ <programlisting role="XML"><![CDATA[<rich:fileUpload style="margin : 0px 0px 20px 0px; width : 504px; height : 200px; background : #f1f1f1; border : 1px solid #A1A1A1"
+ id="fileUpload"
+ allowFlash="true"
+ immediateUpload="false"
+ acceptedTypes="jpg,jpeg"
+ maxFilesQuantity="100"
+ autoclear="true"
+ fileUploadListener="#{fileUploadManager.listener}" >
+ <a4j:support event="onuploadcomplete" reRender="filesPanel, tree" />
+ <a4j:support event="onfileuploadcomplete" />
+ </rich:fileUpload>]]></programlisting>
+
+ <para>
+ The "<emphasis><property>FileUploadListener</property></emphasis>" attribute is binded with <code>fileUploadManager.listener</code> method which makes the main job on the upload.
+ Below is the <code>fileUploadManager.listener</code> method:
+ </para>
+ <programlisting role="JAVA"><![CDATA[public void listener(UploadEvent event) throws Exception {
+ UploadItem item = event.getUploadItem();
+ Image image = constructImage(item);
+ try {
+ extractMetadata(item, image);
+ } catch (Exception e1) {
+ addError(item, image, Constants.FILE_PROCESSING_ERROR);
+ return;
+ }
+ image.setAlbum(model.getSelectedAlbum());
+ if(image.getAlbum() == null){
+ addError(item, image, Constants.NO_ALBUM_TO_DOWNLOAD_ERROR);
+ return;
+ }
+ try{
+ if(imageAction.isImageWithThisPathExist(image)){
+ image.setPath(generateNewPath(image.getPath()));
+ }
+ imageAction.addImage(image);
+ }catch(Exception e){
+ addError(item, image, Constants.IMAGE_SAVING_ERROR);
+ return;
+ }
+ if(!fileManager.addImage(image.getFullPath(), item.getFile().getPath())){
+ addError(item, image, Constants.FILE_SAVE_ERROR);
+ return;
+ }
+ fileWrapper.getFiles().add(image);
+ Events.instance().raiseEvent(Constants.IMAGE_ADDED_EVENT, image);
+ item.getFile().delete();
+}]]></programlisting>
+
+<para>
+ When a photo is added into the uploader, the first thing it does is saving this photo in the file system.
+ The uploaded files are stored in the temporary folder in the computer file system.
+ For this purpose the value of the <code>createTempFile</code> parameter in <code>Ajax4jsf Filter</code> section should be set to <code>true</code>.
+ Below in the <code>Web.xml</code> file Ajax filter section:
+</para>
+
+ <programlisting role="XML"><![CDATA[...
+<init-param>
+ <param-name>createTempFiles</param-name>
+ <param-value>true</param-value>
+</init-param>
+...]]></programlisting>
+
+ <para>
+ Then the uploader creates an <code>Image</code> object and extracts all image metadata such as Camera name, Image size etc.
+ Then it sets an album and generates a new path to it.
+ The system should save six different sizes of the photo.
+ After the photo was added into the database the system removes a temporary file created for storage.
+ </para>
+
+
+ </section>
+
+ <section>
+ <title>Slide show</title>
+
+ <para>The slide-show feature in the Photo Album Demo can be enabled by clicking "Start Slideshow" link from two different places in the application:
+ 1) from user's album preview (<code>/web/src/main/webapp/image/albumInfo.xhtml</code>) and 2) from a particular photo preview (<code>src/main/webapp/image/imageInfo.xhtml</code>).
+ Both of two mentioned XHTML files include slideshow with the help of Facelets <<emphasis role="bold"><property>ui:include</property></emphasis> tag
+ (for more information about <<emphasis role="bold"><property>ui:include</property></emphasis> see Facelets Reference Guide —
+ <ulink url="http://www.jsftoolbox.com/documentation/facelets/01-Introduction/index.jsf">http://www.jsftoolbox.com/documentation/facelets/01-Introduction/index.jsf</ulink>).
+ </para>
+
+ <para>
+ The <code>startSlideshow()</code> method of <code>SlideshowManager.java</code> has two implementations.
+ The first implementation is designed to activate the slide-show from an album preview (<code>/image/albumInfo.xhtml</code>) when no photo is selected in the current image list.
+ The method iterates over all photos of a particular album starting from the first one in the list. Look at the <code>SlideshowManager.java</code> listing below:
+ </para>
+ <programlisting role="JAVA"><![CDATA[...
+public void startSlideshow(){
+ active = true;
+ this.slideshowIndex = 0;
+ if(model.getImages() == null || model.getImages().size() < 1){
+ stopSlideshow();
+ Events.instance().raiseEvent(Constants.ADD_ERROR_EVENT, "No images for slideshow!");
+ return;
+ }
+ this.selectedImage = model.getImages().get(this.slideshowIndex);
+ this.selectedImage.getAlbum().visitImage(selectedImage, true);
+}
+...]]></programlisting>
+
+ <para>
+ The second implementation of the <code>startSlideshow()</code> method is activated when a link to slide-show is clicked from a particular photo preview.
+ This method iterates over the rest of photos starting from the current selected one:
+ </para>
+ <programlisting role="JAVA"><![CDATA[...
+public void startSlideshow(Image selectedImage){
+ active = true;
+ if(model.getImages() == null || model.getImages().size() < 1){
+ stopSlideshow();
+ Events.instance().raiseEvent(Constants.ADD_ERROR_EVENT, "No images for slideshow!");
+ return;
+ }
+ this.slideshowIndex = model.getImages().indexOf(selectedImage);
+ this.selectedImage = selectedImage;
+ this.selectedImage.getAlbum().visitImage(selectedImage, true);
+}
+...]]></programlisting>
+
+ <para>
+ Both implementations of <code>startSlideshow()</code> method set active property to true.
+ This <code>true</code> makes two important slide-show parts (slide-show modal panel and slide-show poller) render.
+ </para>
+ <para>
+ The slide-show modal panel is kept in the <code>web/src/main/webapp/includes/image/slideshow.xhtml</code> file and referred from the corresponding pages with the help of <emphasis role="bold"><property><ui:include></property></emphasis> Facelets tag:
+ </para>
+
+ <programlisting role="XML"><![CDATA[...
+<ui:include src="/includes/image/slideshow.xhtml"/>
+...]]></programlisting>
+
+ <para>
+ Have a look at <code>web/src/main/webapp/includes/image/slideshow.xhtml</code> file:
+ </para>
+
+ <programlisting role="XML"><![CDATA[...
+<ui:composition xmlns="http://www.w3.org/1999/xhtml"...>
+ <rich:modalPanel showWhenRendered="#{slideshow.active}"
+ domElementAttachment="parent"
+ id="slideShowModalPanel"
+ width="650"
+ onshow="showPictureEffect();"
+ height="650">
+ <f:facet name="controls">
+ <h:panelGroup>
+ <h:graphicImage value="/img/modal/close.png" style="cursor:pointer" id="hidelink">
+ <a4j:support event="onclick" actionListener="#{slideshow.stopSlideshow}" reRender="slideShowForm, mainArea, tree" />
+ </h:graphicImage>
+ </h:panelGroup>
+ </f:facet>
+ ...
+ </rich:modalPanel>
+</ui:composition>
+...]]></programlisting>
+
+ <para>
+ The modal panel is always rendered on the page in a hidden state.
+ Activating the slide-show renders the main area, so the slide-show modal panel appears in the closest to an observer layer.
+ </para>
+
+ <programlisting role="XML"><![CDATA[...
+<a4j:commandLink styleClass="slideshow-link"
+ actionListener="#{slideshow.startSlideshow()}"
+ reRender="slideShowForm, mainArea">
+ ...
+</a4j:commandLink>
+...]]></programlisting>
+ <para>
+ Slide-show poller is enabled if the slide-show is activated:
+ </para>
+ <programlisting role="XML"><![CDATA[...
+<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<ui:composition xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:s="http://jboss.com/products/seam/taglib"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:rich="http://richfaces.org/rich"
+ xmlns:a4j="http://richfaces.org/a4j"
+ xmlns:richx="http://richfaces.org/richx">
+ <a4j:form id="slideShowForm">
+ <a4j:poll reRender="slideshowImage"
+ actionListener="#{slideshow.showNextImage()}"
+ interval="#{slideshow.interval}"
+ enabled="#{slideshow.active}"
+ onsubmit="hidePictureEffect()"
+ oncomplete="showPictureEffect();"/>
+ </a4j:form>
+</ui:composition>
+...]]></programlisting>
+ <para>
+ The slide-show poller sends the request for the next image (<code>showNextImage()</code> method) each four seconds.
+ The interval is defined in the interval property of the <code>SlideshowManager.java</code> and refers to a <code>INITIAL.DELAY</code> constant (<code>constants.java</code>).
+ When the <emphasis role="bold"><property><a4j:poll></property></emphasis> component receives a new image it renders the slideShowImage area (<code>/web/src/main/webapp/image/slideshow.xhtml</code>):
+ </para>
+ <programlisting role="XML"><![CDATA[...
+<h:panelGroup id="slideshowImage">
+ <a4j:mediaOutput id="imgSlideShow"
+ element="img"
+ styleClass="main-image"
+ createContent="#{imageLoader.paintImage}"
+ style="opacity: 0.1"
+ value="#{slideshow.selectedImage != null? fileManager.transformPath(slideshow.selectedImage.path, '_medium'):null}">
+ <rich:toolTip followMouse="true"
+ direction="top-right"
+ showDelay="500"
+ styleClass="tooltip">
+ <span style="white-space: nowrap"> #{slideshow.selectedImage.description} </span>
+ </rich:toolTip>
+ </a4j:mediaOutput>
+</h:panelGroup>
+...]]></programlisting>
+
+ <para>
+ The <emphasis role="bold"><property>a4j:mediaOtuput</property></emphasis> component has a value attribute that takes a path to photos as a value and renders photos with the help of a <emphasis><property>createContent</property></emphasis> attribute. The showNextImage works cyclically.
+ </para>
+
+ <para>
+ There is <emphasis role="bold"><property>rich:effect</property></emphasis> that makes rendering process look more effective (<code>web/src/main/webapp/includes/image/slideshow.xhtml</code>):
+ </para>
+ <programlisting role="XML"><![CDATA[...
+<rich:effect name="hidePictureEffect" type="Opacity" params="duration:0.4, from:1.0, to:0.0" for="imgSlideShow" />
+<rich:effect name="showPictureEffect" type="Opacity" params="duration:0.4, from:0.1, to:1.0" for="imgSlideShow" />
+...]]></programlisting>
+
+ <para>
+ The described above example implements a modal panel with photos that change each other in order they store in an album.
+ </para>
+ <figure>
+ <title>Slide show</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/slide_show.png"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>
+ To quit the slide-show user clicks "Close window" button on the slide-show panel and <code>stopSlideshow()</code> method is activated.
+ </para>
+ <programlisting role="JAVA"><![CDATA[...
+@Observer("stopSlideshow")
+ public void stopSlideshow(){
+ active = false;
+ this.selectedImage = null;
+ this.slideshowIndex = 0;
+ }
+...]]></programlisting>
+
+ </section>
+
+ <section>
+ <title>Image Size control</title>
+
+ <section>
+ <title>Building the control with <rich:inputNumberSlider></title>
+ <para>
+ The <emphasis role="bold"><property>rich:inputNumberSlider</property></emphasis> component in the Photo Album Demo is used as a control that helps a user to change photos size while previewing an album.
+ A handler position on the slider track corresponds to a particular value of image size.
+ The component is included into the page with the help of <emphasis role="bold"><property>ui:include</property></emphasis>:
+ </para>
+ <programlisting role="XML"><![CDATA[...
+<ui:include src="/includes/misc/inputNumberSlider.xhtml"/>
+...]]></programlisting>
+
+ <para>
+ Now let's have a look at <code>src/main/webapp/includes/misc/inputNumberSlider.xhtml</code> file:
+ </para>
+ <programlisting role="XML"><![CDATA[...
+<ui:composition ...>
+ <div>
+ <rich:inputNumberSlider value="#{imageSizeHelper.value}"
+ minValue="80"
+ maxValue="200"
+ step="40"
+ enableManualInput="false"
+ showArrows="false"
+ showBoundaryValues="true"
+ showInput="false">
+ <a4j:support event="onchange" reRender="userAlbumImages"/>
+ </rich:inputNumberSlider>
+ </div>
+</ui:composition>
+...]]></programlisting>
+ <para>
+ On each slider position change the <emphasis role="bold"><property>a4j:support</property></emphasis> component invokes an Ajax request that passes a new set value into the <code>ImageSizeHelper.java</code> class.
+ This class saves new photo dimensions, processes and assigns new values to photo related attributes (a CSS class for new photo size, postfix for a new file name, image background):
+ </para>
+ <programlisting role="JAVA"><![CDATA[...
+ public static enum ImageDimension {
+
+ SIZE_80(80), SIZE_120(120), SIZE_160(160), SIZE_200(200);
+
+ final static String CSS_CLASS = "preview_box_photo_";
+ final static String FILE_POSTFIX = "_small";
+ final static String IMAGE_BG = "/img/shell/frame_photo_%1$d.png";
+ final static String IMAGE_BG_STYLE = "width: %1$dpx; height: %1$dpx";
+
+ int x;
+ String bgStyle;
+ String cssClass;
+ String imageBgSrc;
+ String filePostfix;
+
+ private ImageDimension(int x) {
+ this.x = x;
+ this.bgStyle = String.format(IMAGE_BG_STYLE, x + 20);
+ cssClass = CSS_CLASS + x;
+ imageBgSrc = String.format(IMAGE_BG, (x == 160) ? 200 : x);
+ filePostfix = FILE_POSTFIX + x;
+ }
+ ...]]></programlisting>
+
+ <para>
+ After the <code>ImageSizeHelper.java</code> is worked out the <emphasis role="bold"><property>a4j:support</property></emphasis> component renders user photos
+ (more exactly, the <emphasis role="bold"><property>h:panelGroup</property></emphasis> with <code>userAlbumImages</code> id that contains user photos)
+ correspondingly to a new set value. Here is <code>web/src/main/webapp/includes/image/imageList.xhtml</code>:
+ </para>
+ <programlisting role="XML"><![CDATA[...
+<h:panelGroup id="userAlbumImages">
+ <a4j:repeat id="imageList" value="#{model.images}" var="image" rows="20">
+ <h:panelGroup layout="block" styleClass="#{imageSizeHelper.currentDimension.cssClass}">
+ <h:graphicImage styleClass="pr_photo_bg" style="#{imageSizeHelper.currentDimension.imageBgStyle}" value="#{imageSizeHelper.currentDimension.imageBg}" />
+ <h:panelGrid cellpadding="0">
+ <h:panelGroup>
+ <a4j:commandLink actionListener="#{controller.showImage(image)}" reRender="mainArea, tree">
+ <a4j:mediaOutput id="img" element="img"
+ createContent="#{imageLoader.paintImage}"
+ style="border : 1px solid #FFFFFF;"
+ value="#{fileManager.transformPath(image.fullPath, imageSizeHelper.currentDimension.filePostfix)}">
+ <f:param value="#{imageSizeHelper.currentDimension.x}" name="x" />
+ <rich:dragSupport rendered="#{controller.isUserImage(image)}" reRender="mainArea, tree" id="dragSource" dragIndicator="dragIndicator"
+ dragType="image" dragValue="#{image}">
+ <rich:dndParam id="dragParam" name="label" value="#{image.name}" />
+ </rich:dragSupport>
+ <ui:include src="/includes/contextMenu/CMForImage.xhtml" >
+ <ui:param name="image" value="#{image}" />
+ </ui:include>
+ </a4j:mediaOutput>
+ </a4j:commandLink>
+ <br/>
+ </h:panelGroup>
+ </h:panelGrid>
+ <h:panelGroup layout="block" styleClass="photo_name">#{image.name} </h:panelGroup>
+ <h:panelGroup layout="block" styleClass="photo_data">
+ <h:outputText value="#{image.created}">
+ <f:convertDateTime />
+ </h:outputText>
+ </h:panelGroup>
+ </h:panelGroup>
+ </a4j:repeat>
+</h:panelGroup>
+...]]></programlisting>
+
+ <para>
+ When the <emphasis role="bold"><property><rich:inputNumberSlider<</property></emphasis> is rendered at first its default value for image size is 120 px.
+ </para>
+
+ <figure>
+ <title>Image size control</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/image_size.png"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ </section>
+
+ <section>
+ <title>Links in Photo Album Demo. Using the <a4j:commandLink></title>
+ <para>
+ The main difference between <emphasis role="bold"><property><h:commandLink></property></emphasis> component is a) Ajax request that is generated on a click and b) dynamic rerendering of the page after a response comes back.
+ It's not necessary to plug any support into the component, as Ajax support is already built-in.
+ </para>
+ <para>
+ The <emphasis role="bold"><property><a4j:commandLink></property></emphasis> component is used widely in the application.
+ In the following example clicking on the <Edit> link will rerender the main ares (watching area) of the application and open an album edit form.
+ Each album has its owner and only owner can edit the album contents.
+ The link <Edit> will be rendered only if the current logged-in user is the owner of this album: the <emphasis><property>"rendered"</property></emphasis> attribute refers to the owner id and compares it with the current user id:
+ </para>
+ <programlisting role="XML"><![CDATA[...
+<a4j:commandLink rendered="#{model.selectedAlbum.owner.id == user.id}"
+ value="#{messages['album.edit']} "
+ actionListener="#{controller.startEditAlbum(model.selectedAlbum)}"
+ reRender="mainArea">
+</a4j:commandLink>
+...]]></programlisting>
+ <para>
+ The <emphasis><property><value></property></emphasis> attribute (text that will appear on the link) is picked up from the <code>messages_en.properties</code> file.
+ Such property files are very useful e.g. for multi language applications.
+ Each property is saved in the format "name—value".
+ Let's have a look at this file in the JBDS:
+ </para>
+ <figure>
+ <title>Image size control</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/messages_en_property.png"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+ </section>
+
+ <section>
+ <title>Error Reports in the Real World Demo</title>
+ <para>The main page of the application <code>web/src/main/webapp/index.xhtml</code> includes <code>web/src/main/webapp/includes/misc/errorPanel.xhtml</code>.
+ The error panel itself is always rendered but hidden if no error appears. The listing below shows the part of <code>errorPanel.xhtml</code> page:
+ </para>
+ <programlisting role="XML"><![CDATA[...
+<a4j:outputPanel id="errors" ajaxRendered="true">
+ <h:panelGroup rendered="#{errorHandlerBean.errorExist}">
+ <rich:modalPanel id="errorPanel"
+ showWhenRendered="true"
+ minWidth="300"
+ minHeight="200"
+ autosized="true">
+ ...
+ </rich:modalPanel>
+ </h:panelGroup>
+</a4j:outputPanel>
+...]]></programlisting>
+ <para>
+ Error checking happens each time the Ajax request is invoked by user activity.
+ The <emphasis role="bold"><property>rich:modalPanel</property></emphasis> which wrapped with <emphasis role="bold"><property><h:panelGroup></property></emphasis> is rendered in case an error occurs,
+ its <emphasis><property>"rendered"</property></emphasis> attribute is binded with <code>isErrorExist</code> boolean method of <code>errorHandlerBean</code> class.
+ </para>
+ <programlisting role="XML"><![CDATA[...
+package org.richfaces.realworld.ui;
+...
+@Name("errorHandlerBean")
+(a)Scope(ScopeType.EVENT)
+@AutoCreate
+public class ErrorHandlerBean {
+ private List<String> errors = new ArrayList<String>();
+
+ public List<String> getErrors() {
+ return errors;
+ }
+
+ public boolean isErrorExist(){
+ return errors.size() > 0 ;
+ }
+
+ @Observer(Constants.ADD_ERROR_EVENT)
+ public void addToErrors(String e){
+ errors.add(e);
+ }
+}
+...]]></programlisting>
+
+ <para>
+ The <code>addToErrors</code> method is annotated with <code>@Observer</code> annotation which observes all methods in the application with <code>ADD_ERROR_EVENT</code> annotation.
+ </para>
+
+ </section>
+
+
+
+ </section>
+ <section id="contextMenu">
+ <title>Context Menu</title>
+ <para>Work in progress...</para>
+ </section>
Property changes on: trunk/docs/realworld_app_guide/en/src/main/docbook/includes/hiw.xml
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/realworld_app_guide/en/src/main/docbook/includes/navigationPanel.xml
===================================================================
--- trunk/docs/realworld_app_guide/en/src/main/docbook/includes/navigationPanel.xml (rev 0)
+++ trunk/docs/realworld_app_guide/en/src/main/docbook/includes/navigationPanel.xml 2009-04-25 11:26:25 UTC (rev 13851)
@@ -0,0 +1,350 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<section id="navigationPanel" xreflabel="navigationPanel">
+ <?dbhtml filename="navigationPanel.html"?>
+ <title>Navigation panel represented by <rich:tree></title>
+ <para>
+ The <emphasis role="bold"><property><rich:tree></property></emphasis> component takes one of the main places
+ in the <property>Photo Album</property> and is tightly bounded with the application logic.
+ It helps to represent
+ and implement inherently the "Shelves - Albums" hierarchy.
+ Shelf is the highest possible level in the tree hierarchy, that
+ is used to group thematic albums and may contain as many albums as needed.
+ </para>
+ <para>
+ There are two types of navigation panel in the application: for a registered user and for a guest.
+ The difference between them is that the first one has a context menu and drag-and-drop possibility.
+ </para>
+ <section>
+ <title>Navigation panel for a guest</title>
+
+ <!--para>
+ The <emphasis role="bold"><property><rich:tree></property></emphasis> component is designed for
+ hierarchical data presentation and is used to build a tree structure.
+ The component also supports built-in drag-and-drop functionality.
+ </para-->
+ <para>
+ Navigation panel for a guest is represented as a simple
+ <emphasis role="bold"><property><rich:tree></property></emphasis> component.
+ </para>
+ <para>
+ There are several ways to implement the <emphasis role="bold"><property><rich:tree></property></emphasis> on a page.
+ In the current application the <emphasis role="bold"><property><rich:tree></property></emphasis> is designed
+ using a model tag <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis>.
+ </para>
+ <para>
+ The <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> component
+ has a <emphasis><property>"nodes"</property></emphasis> attribute that accepts
+ a collection of elements, so <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis>
+ iterates over the collection and renders hierarchical tree structure on a page.
+ </para>
+ <para>
+ According to the "Shelves - Albums" hierarchy we need two nested
+ <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> components.
+ The first one iterates through the Shelves collection
+ that is returned from the <code>getPredefinedShelves()</code> method:
+ </para>
+ <programlisting role="JAVA"><![CDATA[...
+public List<Shelf> getPredefinedShelves() {
+ if (shelves == null) {
+ shelves = shelfAction.getPredefinedShelves();
+ }
+ return shelves;
+ }
+}
+...]]></programlisting>
+ <para>
+ The second <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> component
+ iterates through the Albums collection of the current Shelf which is available via
+ <emphasis><property>"var"</property></emphasis> attribute.
+ The <emphasis><property>"var"</property></emphasis> attribute
+ is used to get access to the data object of the current collection element Shelf,
+ so it is possible to output any necessary data:
+ </para>
+ <!--
+ The <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> component accepts
+ a collection of elements, which are allowed to include lists, arrays, maps, XML NodeList or NamedNodeMap, and iterate over it.
+ The <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> component repeats a hierarchical tree structure on a <code>xhtml</code> or <code>jsp</code> page in a component tree and can be nested without any limitations.
+ The code snippet below schematically shows the idea of how a tree can be built on a page with the help of adaptors:
+
+
+
+ <programlisting role="XML"><![CDATA[<rich:tree>
+ <rich:treeNodesAdaptor>
+ <rich:treeNode />
+
+ <rich:treeNodesAdaptor>
+ <rich:treeNode />
+
+ <rich:treeNodesAdaptor>
+ <rich:treeNode />
+ ...
+ </rich:treeNodesAdaptor>
+ </rich:treeNodesAdaptor>
+ </rich:treeNodesAdaptor>
+</rich:tree>]]></programlisting>
+
+ <para>
+ When using <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> component
+ there is no need to specify
+ the <emphasis><property>"value"</property></emphasis> and
+ <emphasis><property>"var"</property></emphasis> attributes
+ for the <emphasis role="bold"><property><rich:tree></property></emphasis>.
+ The values for nodes to render are passed directly into the corresponding adaptor
+ and the component performs all the necessary iterative work
+ (vizit the <ulink url="http://livedemo.exadel.com/richfaces-demo/richfaces/treeNodesAdaptor.jsf?..."><rich:treeNodesAdaptor> page</ulink> on the RichFacesLiveDemo for more details).
+ </para>
+
+ <para>
+ Implementation of the <emphasis role="bold"><property><rich:tree></property></emphasis> in the application
+ is very similar to the model shown above.
+ The top <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis>
+ in the <emphasis role="bold"><property><rich:tree></property></emphasis> in the Photo Album
+ application is responsible for shelves rendering.
+ Its <emphasis><property>"nodes"</property></emphasis> attribute refers
+ to <emphasis><property>getShelves()</property></emphasis> method of the <code>ShelfManager</code> class
+ and gets the collection of shelves associated with the current user including all shared shelves in the system.
+ Take a look at this method:
+ </para-->
+
+ <!-- para>
+ When the <emphasis><property>"nodes"</property></emphasis> attribute of the <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis>, which is responsible for shelves rendering, receives the collection of shelves,
+ the iteration process switches to the nested <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis>, which is responsible for albums.
+ The "albums" <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> <emphasis><property>"nodes"</property></emphasis> attribute refers in its turn to the <code>albums</code> field of the <code>Shelf</code> class
+ and takes a collection of all albums associated with the current shelf.
+ The "albums" <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> renders all albums that belong to the current iterating shelf and then switches back to the "shelf" <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> to render and iterate the next shelf in the shelves collection received earlier.
+ Here is how it looks in the <code>webapp/includes/index/tree.xhtml</code> file:
+ </para-->
+
+ <programlisting role="XML"><![CDATA[...
+<rich:tree
+ adviseNodeOpened="#{treeManager.adviseNodeSelected}"
+ adviseNodeSelected="#{treeManager.adviseNodeSelected}"
+ ajaxSubmitSelection="false" id="PreDefinedTree"
+ treeNodeVar="treeNode" switchType="client"
+ iconCollapsed="/img/shell/tree_icon_plus.png"
+ iconExpanded="/img/shell/tree_icon_minus.png"
+ showConnectingLines="false">
+ <rich:treeNodesAdaptor nodes="#{shelfManager.getPredefinedShelves()}" var="shelf">
+ <rich:treeNode style="cursor:pointer" reRender="treeform,mainArea"
+ selectedClass="tree-selected-node">
+ <f:facet name="icon">
+ <h:graphicImage style="border: none" value="/img/shell/tree_icon_shelf.png">
+ <a4j:support reRender="treeform,mainArea" event="onclick" actionListener="#{controller.showShelf(shelf)}" similarityGroupingId="sel" />
+ </h:graphicImage>
+ </f:facet>
+ <a4j:outputPanel >
+ <h:outputText style="cursor:pointer" value="#{shelf.name}" />
+ <h:outputText value=" :: " />
+ <strong>#{shelf.unvisitedImages.size()}</strong> new
+ <a4j:support reRender="treeform,mainArea" event="onclick" actionListener="#{controller.showShelf(shelf)}" similarityGroupingId="sel" />
+ </a4j:outputPanel>
+ </rich:treeNode>
+ <rich:treeNodesAdaptor var="album"
+ nodes="#{shelf.albums}">
+ <rich:treeNode style="cursor:pointer" reRender="treeform,mainArea"
+ selectedClass="tree-selected-node"
+ icon="img/shell/tree_icon_album.png">
+ <f:facet name="iconLeaf">
+ <h:graphicImage style="border: none" value="img/shell/tree_icon_album.png">
+ <a4j:support reRender="treeform,mainArea" event="onclick" actionListener="#{controller.showAlbum(album)}" similarityGroupingId="sel" />
+ </h:graphicImage>
+ </f:facet>
+ <a4j:outputPanel>
+ <h:outputText style="cursor:pointer" value="#{album.name}" />
+ <h:outputText value=" :: " />
+ <strong>#{album.unvisitedImages.size()}</strong> new
+ <a4j:support reRender="treeform,mainArea" event="onclick" actionListener="#{controller.showAlbum(album)}" similarityGroupingId="sel" />
+ </a4j:outputPanel>
+ </rich:treeNode>
+ </rich:treeNodesAdaptor>
+ </rich:treeNodesAdaptor>
+ </rich:tree>
+...]]></programlisting>
+
+ <para>
+ The illustration below shows how the navigation panel for a guest is rendered on the page.
+ </para>
+
+ <figure>
+ <title>Shelves and albums nodes rendered with the help of the <rich:treeNodesAdaptor></title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/tree.png"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+</section>
+
+ <section>
+ <title>Navigation panel for a registered user</title>
+ <para>
+ As it was mentioned before a navigation panel for a registered user has
+ two main features: drag-and-drop and context menu. Context menu is described
+ in the <link linkend="contextMenu">"Context menu"</link> chapter.
+ </para>
+ <para>
+ Drag-and-drop feature supported in the Photo Album application is not so complicated
+ as it may seem from the first view.
+ In this application we can mark out two types of drag-and-drop:
+ one type takes place only inside the tree (between tree nodes)
+ and another one - between the watching area and the tree.
+ The difference is not considerable enough to describe two types separately,
+ but also not at all insignificant to be omitted here.
+ </para>
+
+ <para>
+ The tree related components
+ (<emphasis role="bold"><property><rich:tree></property></emphasis> and <emphasis role="bold"><property><rich:treeNode></property></emphasis>)
+ have their own attributes that provide drag-and-drop functionality.
+ These attributes can be divided into two groups:
+ those which provide drag (dragValue, dragListener, dragIndicator, dragType attributes)
+ and those which provide drop operations (dropValue, dropListener, acceptedTypes, typeMapping).
+ </para>
+ <note>
+ <title>
+ Note:
+ </title>
+ <para>
+ Due to "Shelves - Albums - Photos" hierarchy we can say that photos could be moved between albums,
+ albums could be moved between shelves.
+ To avoid a mishmash, it's not allowed to place photos directly in shelves as well as nesting shelves
+ inside shelves or albums inside albums.
+ </para>
+ </note>
+ <para>
+ Let's explore how drag-and-drop works for albums.
+ </para>
+ <para>
+ All albums, that are represented as TreeNodes, must be marked somehow for dragging.
+ For this purpose we use previously mentioned
+ <emphasis><property>"dragValue"</property></emphasis>,
+ <emphasis><property>"dragType"</property></emphasis>
+ attributes:
+ </para>
+ <programlisting role="XML"><![CDATA[<rich:treeNodesAdaptor var="album" nodes="#{shelf.albums}">
+ <rich:treeNode dragType="album" dragValue="#{album}" reRender="mainArea, treeform">
+ ...
+ </rich:treeNode>
+</rich:treeNodesAdaptor>
+]]></programlisting>
+ <para>
+ To provide drop functionality for the marked albums we should mark Shelves as drop zones in the application code too.
+ For this purpose we add the <emphasis><property>"dropValue"</property></emphasis> and
+ <emphasis><property>"acceptedTypes"</property></emphasis> attributes to the "Shelf" node:
+ </para>
+ <programlisting role="XML"><![CDATA[<rich:treeNodesAdaptor nodes="#{shelfManager.getUserShelves()}" var="shelf">
+ <rich:treeNode acceptedTypes="album" dropValue="#{shelf}" reRender="mainArea, treeform">
+ ...
+ </rich:treeNode>
+</rich:treeNodeAdaptor>]]></programlisting>
+ <para>
+ The <emphasis><property>"acceptedTypes"</property></emphasis> attribute tells the "Shelf" node
+ what types of dragged zones (albums in this case) it can accept.
+ We have specified "Album" node
+ <emphasis><property>"dragType"</property></emphasis> as "album",
+ so the "Shelf" node can accept it.
+ </para>
+ <para>
+ Finally we need to specify listener in the <emphasis><property>"dropListener"</property></emphasis>
+ attribute in order to process drop on the server side:
+ </para>
+ <programlisting role="XML"><![CDATA[<rich:tree dragIndicator="dragIndicator" dropListener="#{dndManager.processDrop}">
+ ...
+</rich:tree>]]></programlisting>
+ <para>
+ The <code>processDrop()</code> method is shown in the listing below:
+ </para>
+ <programlisting role="JAVA"><![CDATA[...
+public void processDrop(DropEvent dropEvent) {
+ Dropzone dropzone = (Dropzone) dropEvent.getComponent();
+ Object dragValue = dropEvent.getDragValue();
+ Object dropValue = dropzone.getDropValue();
+ if(dragValue instanceof Image){
+ if(!((Album)dropValue).getOwner().getLogin().equals(user.getLogin())){
+ Events.instance().raiseEvent(Constants.ADD_ERROR_EVENT, Constants.DND_PHOTO_ERROR);
+ return;
+ }
+ handleImage((Image)dragValue, (Album)dropValue);
+ }else if(dragValue instanceof Album){
+ if(!((Shelf)dropValue).getOwner().getLogin().equals(user.getLogin())){
+ Events.instance().raiseEvent(Constants.ADD_ERROR_EVENT, Constants.DND_ALBUM_ERROR);
+ return;
+ }
+ handleAlbum((Album)dragValue, (Shelf)dropValue);
+ }
+}
+...]]></programlisting>
+ <para>
+ Here is the whole example of the "Navigation panel for a registered user":
+ </para>
+<programlisting role="XML"><![CDATA[<rich:tree
+ ajaxSubmitSelection="false" dragIndicator="dragIndicator"
+ treeNodeVar="treeNode" switchType="client"
+ iconCollapsed="/img/shell/tree_icon_plus.png"
+ iconExpanded="/img/shell/tree_icon_minus.png"
+ dropListener="#{dndManager.processDrop}"
+ showConnectingLines="false">
+ <rich:treeNodesAdaptor nodes="#{shelfManager.getUserShelves()}"
+ var="shelf">
+ <rich:treeNode style="cursor:pointer" acceptedTypes="album" dropValue="#{shelf}"
+ reRender="mainArea, treeform"
+ selectedClass="tree-selected-node">
+ <f:facet name="icon">
+ <h:graphicImage style="border: none" value="/img/shell/tree_icon_shelf.png">
+ <a4j:support reRender="treeform, mainArea" event="onclick" actionListener="#{controller.showShelf(shelf)}" similarityGroupingId="sel" />
+ </h:graphicImage>
+ </f:facet>
+ <ui:include src="/includes/contextMenu/CMForShelf.xhtml" >
+ <ui:param name="shelf" value="#{shelf}" />
+ </ui:include>
+ <a4j:outputPanel>
+ <h:outputText style="cursor:pointer" value="#{shelf.name}" />
+ <h:outputText value=" :: " />
+ <strong>#{shelf.unvisitedImages.size()}</strong> new
+ <a4j:support reRender="treeform, mainArea" event="onclick" actionListener="#{controller.showShelf(shelf)}" similarityGroupingId="sel" />
+ </a4j:outputPanel>
+ </rich:treeNode>
+
+ <rich:treeNodesAdaptor var="album"
+ nodes="#{shelf.albums}">
+ <rich:treeNode style="cursor:pointer" reRender="mainArea, treeform" dragType="album"
+ dragValue="#{album}" dropValue="#{album}"
+ acceptedTypes="image"
+ selectedClass="tree-selected-node"
+ icon="img/shell/tree_icon_album.png">
+ <f:facet name="iconLeaf">
+ <h:graphicImage style="border: none" value="img/shell/tree_icon_album.png">
+ <a4j:support reRender="treeform, mainArea" event="onclick" actionListener="#{controller.showAlbum(album)}" similarityGroupingId="sel" />
+ </h:graphicImage>
+ </f:facet>
+ <ui:include src="/includes/contextMenu/CMForAlbum.xhtml" >
+ <ui:param name="album" value="#{album}" />
+ </ui:include>
+ <rich:dndParam name="label" type="drag" value="#{album.name}" />
+ <a4j:outputPanel >
+ <h:outputText style="cursor:pointer" value="#{album.name}" />
+ <h:outputText value=" :: " />
+ <strong>#{album.unvisitedImages.size()}</strong> new
+ <a4j:support reRender="treeform, mainArea" event="onclick" actionListener="#{controller.showAlbum(album)}" similarityGroupingId="sel" />
+ </a4j:outputPanel>
+ </rich:treeNode>
+
+ </rich:treeNodesAdaptor>
+ </rich:treeNodesAdaptor>
+
+</rich:tree>]]></programlisting>
+ <para>
+ The illustration below shows how the described above drag-and-drop features are rendered in the Photo Album.
+ </para>
+ <figure>
+ <title>Dragging the "Flora" album from "Sport" shelf into the "Nature" (left) and the tree after drag-and-drop (right).</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/dnd.png"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+ </section>
+</section>
+
Property changes on: trunk/docs/realworld_app_guide/en/src/main/docbook/includes/navigationPanel.xml
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/docs/realworld_app_guide/en/src/main/docbook/includes/usedComponents.xml
===================================================================
--- trunk/docs/realworld_app_guide/en/src/main/docbook/includes/usedComponents.xml (rev 0)
+++ trunk/docs/realworld_app_guide/en/src/main/docbook/includes/usedComponents.xml 2009-04-25 11:26:25 UTC (rev 13851)
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<section id="usedComponents" xreflabel="usedComponents">
+<?dbhtml filename="usedComponents.html"?>
+ <title>Used Components</title>
+ <para>
+ Below there is a list of components used in <property>Photo Album</property>.
+ </para>
+ <table>
+ <title>Components used in "Photo Album Demo"</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Value</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><a4j:commandLink></entry>
+ <entry>The component is very similar to the <h:commandLink> component, the only difference is that an Ajax form submit is generated on a click and it allows dynamic rerendering after a response comes back. It's not necessary to plug any support into the component, as Ajax support is already built in.</entry>
+ </row>
+ <row>
+ <entry><a4j:commandButton></entry>
+ <entry>The component is very similar to the <h:commandButton> component, the only difference is that an Ajax form submit is generated on a click and it allows dynamic rerendering after a response comes back. It's not necessary to plug any support into the component, as Ajax support is already built in.</entry>
+ </row>
+ <!-- row>
+ <entry>a4j:push</entry>
+ <entry>The component periodically perform Ajax request to the server, to simulate 'push' data.</entry>
+ </row-->
+ <row>
+ <entry><a4j:poll></entry>
+ <entry>The component allows periodical sending of Ajax requests to the server and is used for a page updating according to a specified time interval.</entry>
+ </row>
+ <row>
+ <entry><rich:calendar></entry>
+ <entry>The component is used for creating monthly calendar elements on a page.</entry>
+ </row>
+ <row>
+ <entry><rich:contextMenu></entry>
+ <entry>The component is used for creation of multileveled context menus that are activated after a user defines an event ("onmouseover", "onclick", etc.) on any element on the page.</entry>
+ </row>
+ <row>
+ <entry><rich:dataGrid></entry>
+ <entry>The component to render data as a grid that allows choosing data from a model and obtains built-in support of Ajax updates.</entry>
+ </row>
+ <row>
+ <entry><rich:datascroller></entry>
+ <entry>The component is designed for providing the functionality of tables scrolling using Ajax requests.</entry>
+ </row>
+ <row>
+ <entry><rich:fileUpload></entry>
+ <entry>The component is designed to perform Ajax-ed files upload to the server.</entry>
+ </row>
+ <row>
+ <entry><rich:inplaceInput></entry>
+ <entry>The component is an input component used for displaying and editing data inputted. </entry>
+ </row>
+ <row>
+ <entry><rich:inplaceSelect></entry>
+ <entry>The component is used to create select based inputs: it shows the value as text in one state and enables editing the value, providing a list of options in another state.</entry>
+ </row>
+ <row>
+ <entry><rich:mediaOutput></entry>
+ <entry>The component implements one of the basic features specified in the framework. The component is a facility for generating images, video, sounds and other binary resources defined by you on-the-fly.</entry>
+ </row>
+ <row>
+ <entry><rich:modalPanel></entry>
+ <entry>The component implements a modal dialog window. All operations in the main application window are locked out while this window is active. Opening and closing the window is done with client JavaScript code.</entry>
+ </row>
+ <row>
+ <entry><rich:progressBar></entry>
+ <entry>The component is designed for displaying a progress bar which shows the current status of the process. </entry>
+ </row>
+ <row>
+ <entry><rich:tree></entry>
+ <entry>The component is designed for hierarchical data presentation and is applied for building a tree structure with a drag-and-drop capability. The component also uses built-in drag and drop.</entry>
+ </row>
+
+
+ </tbody>
+ </tgroup>
+ </table>
+</section>
Property changes on: trunk/docs/realworld_app_guide/en/src/main/docbook/includes/usedComponents.xml
___________________________________________________________________
Name: svn:executable
+ *
Modified: trunk/docs/realworld_app_guide/en/src/main/docbook/master.xml
===================================================================
--- trunk/docs/realworld_app_guide/en/src/main/docbook/master.xml 2009-04-25 10:41:47 UTC (rev 13850)
+++ trunk/docs/realworld_app_guide/en/src/main/docbook/master.xml 2009-04-25 11:26:25 UTC (rev 13851)
@@ -1,12 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3CR3//EN"
"http://www.docbook.org/xml/4.3CR3/docbookx.dtd" [
- <!ENTITY intro SYSTEM "modules/intro.xml">
- <!ENTITY application_overview SYSTEM "modules/application_overview.xml">
- <!ENTITY getting_started SYSTEM "modules/getting_started.xml">
- <!ENTITY hiw SYSTEM "modules/hiw.xml">
-
+ <!ENTITY intro SYSTEM "modules/intro.xml">
+ <!ENTITY application_overview SYSTEM "modules/application_overview.xml">
+ <!ENTITY overview SYSTEM "modules/overview.xml">
+ <!ENTITY getting_started SYSTEM "modules/getting_started.xml">
+
+ <!ENTITY usedComponents SYSTEM "includes/usedComponents.xml">
+ <!ENTITY navigationPanel SYSTEM "includes/navigationPanel.xml">
+ <!ENTITY hiw SYSTEM "includes/hiw.xml">
]>
<book>
@@ -44,8 +47,24 @@
<toc/>
&intro;
&getting_started;
+ &overview;
<!-- &application_overview; -->
+ <chapter id="patterns" xreflabel="patterns">
+ <?dbhtml filename="patterns.html"?>
+ <chapterinfo>
+ <keywordset>
+ <keyword>RichFaces</keyword>
+ </keywordset>
+ </chapterinfo>
+ <title>How it works</title>
+ <para>
+ In this chapter we explain how the Photo Album works.
+ </para>
+ <?forseChanks?>
+ &usedComponents;
+ &navigationPanel;
&hiw;
+ </chapter>
</book>
Deleted: trunk/docs/realworld_app_guide/en/src/main/docbook/modules/hiw.xml
===================================================================
--- trunk/docs/realworld_app_guide/en/src/main/docbook/modules/hiw.xml 2009-04-25 10:41:47 UTC (rev 13850)
+++ trunk/docs/realworld_app_guide/en/src/main/docbook/modules/hiw.xml 2009-04-25 11:26:25 UTC (rev 13851)
@@ -1,853 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<chapter id="patterns" xreflabel="patterns">
- <?dbhtml filename="patterns.html"?>
- <chapterinfo>
- <keywordset>
- <keyword>RichFaces</keyword>
-
- </keywordset>
- </chapterinfo>
- <title>How it works</title>
-
- <section>
- <title>Used Components</title>
-
- <para>Below there is a list of components used in <property>Photo Album</property>.</para>
- <table>
- <title>Components used in "Photo Album Demo"</title>
- <tgroup cols="2">
- <thead>
- <row>
- <entry>Name</entry>
- <entry>Value</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>a4j:commandLink</entry>
- <entry>The component is very similar to the <h:commandLink> component, the only difference is that an Ajax form submit is generated on a click and it allows dynamic rerendering after a response comes back. It's not necessary to plug any support into the component, as Ajax support is already built in.</entry>
- </row>
- <row>
- <entry>a4j:commandButton</entry>
- <entry>The component is very similar to the <h:commandButton> component, the only difference is that an Ajax form submit is generated on a click and it allows dynamic rerendering after a response comes back. It's not necessary to plug any support into the component, as Ajax support is already built in.</entry>
- </row>
- <!-- row>
- <entry>a4j:push</entry>
- <entry>The component periodically perform Ajax request to the server, to simulate 'push' data.</entry>
- </row-->
- <row>
- <entry>a4j:poll</entry>
- <entry>The component allows periodical sending of Ajax requests to the server and is used for a page updating according to a specified time interval.</entry>
- </row>
- <row>
- <entry>rich:calendar</entry>
- <entry>The component is used for creating monthly calendar elements on a page.</entry>
- </row>
- <row>
- <entry>rich:contextMenu</entry>
- <entry>The component is used for creation of multileveled context menus that are activated after a user defines an event ("onmouseover", "onclick", etc.) on any element on the page.</entry>
- </row>
- <row>
- <entry>rich:dataGrid</entry>
- <entry>The component to render data as a grid that allows choosing data from a model and obtains built-in support of Ajax updates.</entry>
- </row>
- <row>
- <entry>rich:datascroller</entry>
- <entry>The component is designed for providing the functionality of tables scrolling using Ajax requests.</entry>
- </row>
- <row>
- <entry>rich:fileUpload</entry>
- <entry>The component is designed to perform Ajax-ed files upload to the server.</entry>
- </row>
- <row>
- <entry>rich:inplaceInput</entry>
- <entry>The component is an input component used for displaying and editing data inputted. </entry>
- </row>
- <row>
- <entry>rich:inplaceSelect</entry>
- <entry>The component is used to create select based inputs: it shows the value as text in one state and enables editing the value, providing a list of options in another state.</entry>
- </row>
- <row>
- <entry>rich:mediaOutput</entry>
- <entry>The component implements one of the basic features specified in the framework. The component is a facility for generating images, video, sounds and other binary resources defined by you on-the-fly.</entry>
- </row>
- <row>
- <entry>rich:modalPanel</entry>
- <entry>The component implements a modal dialog window. All operations in the main application window are locked out while this window is active. Opening and closing the window is done with client JavaScript code.</entry>
- </row>
- <row>
- <entry>rich:progressBar</entry>
- <entry>The component is designed for displaying a progress bar which shows the current status of the process. </entry>
- </row>
- <row>
- <entry>rich:tree</entry>
- <entry>The component is designed for hierarchical data presentation and is applied for building a tree structure with a drag-and-drop capability. The component also uses built-in drag and drop.</entry>
- </row>
-
-
- </tbody>
- </tgroup>
- </table>
- </section>
-
- <section>
- <title>Navigation panel represented by <rich:tree></title>
- <para>
- The <emphasis role="bold"><property><rich:tree></property></emphasis> component takes one of the main places
- in the <property>Photo Album</property> and is tightly bounded with the application logic.
- It helps to represent
- and implement inherently the "Shelves - Albums" hierarchy.
- Shelf is the highest possible level in the tree hierarchy, that
- is used to group thematic albums and may contain as many albums as needed.
- </para>
- <para>
- There are two types of navigation panel in the application: for a registered user and for a guest.
- The difference between them is that the first one has a context menu and drag-and-drop possibility.
- </para>
- <section>
- <title>Navigation panel for a guest</title>
-
- <!--para>
- The <emphasis role="bold"><property><rich:tree></property></emphasis> component is designed for
- hierarchical data presentation and is used to build a tree structure.
- The component also supports built-in drag-and-drop functionality.
- </para-->
- <para>
- Navigation panel for a guest is represented as a simple
- <emphasis role="bold"><property><rich:tree></property></emphasis> component.
- </para>
- <para>
- There are several ways to implement the <emphasis role="bold"><property><rich:tree></property></emphasis> on a page.
- In the current application the <emphasis role="bold"><property><rich:tree></property></emphasis> is designed
- using a model tag <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis>.
- </para>
- <para>
- The <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> component
- has a <emphasis><property>"nodes"</property></emphasis> attribute that accepts
- a collection of elements, so <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis>
- iterates over the collection and renders hierarchical tree structure on a page.
- </para>
- <para>
- According to the "Shelves - Albums" hierarchy we need two nested
- <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> components.
- The first one iterates through the Shelves collection
- that is returned from the <code>getPredefinedShelves()</code> method:
- </para>
- <programlisting role="JAVA"><![CDATA[...
-public List<Shelf> getPredefinedShelves() {
- if (shelves == null) {
- shelves = shelfAction.getPredefinedShelves();
- }
- return shelves;
- }
-}
-...]]></programlisting>
- <para>
- The second <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> component
- iterates through the Albums collection of the current Shelf which is available via
- <emphasis><property>"var"</property></emphasis> attribute.
- The <emphasis><property>"var"</property></emphasis> attribute
- is used to get access to the data object of the current collection element Shelf,
- so it is possible to output any necessary data:
- </para>
- <!--
- The <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> component accepts
- a collection of elements, which are allowed to include lists, arrays, maps, XML NodeList or NamedNodeMap, and iterate over it.
- The <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> component repeats a hierarchical tree structure on a <code>xhtml</code> or <code>jsp</code> page in a component tree and can be nested without any limitations.
- The code snippet below schematically shows the idea of how a tree can be built on a page with the help of adaptors:
-
-
-
- <programlisting role="XML"><![CDATA[<rich:tree>
- <rich:treeNodesAdaptor>
- <rich:treeNode />
-
- <rich:treeNodesAdaptor>
- <rich:treeNode />
-
- <rich:treeNodesAdaptor>
- <rich:treeNode />
- ...
- </rich:treeNodesAdaptor>
- </rich:treeNodesAdaptor>
- </rich:treeNodesAdaptor>
-</rich:tree>]]></programlisting>
-
- <para>
- When using <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> component
- there is no need to specify
- the <emphasis><property>"value"</property></emphasis> and
- <emphasis><property>"var"</property></emphasis> attributes
- for the <emphasis role="bold"><property><rich:tree></property></emphasis>.
- The values for nodes to render are passed directly into the corresponding adaptor
- and the component performs all the necessary iterative work
- (vizit the <ulink url="http://livedemo.exadel.com/richfaces-demo/richfaces/treeNodesAdaptor.jsf?..."><rich:treeNodesAdaptor> page</ulink> on the RichFacesLiveDemo for more details).
- </para>
-
- <para>
- Implementation of the <emphasis role="bold"><property><rich:tree></property></emphasis> in the application
- is very similar to the model shown above.
- The top <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis>
- in the <emphasis role="bold"><property><rich:tree></property></emphasis> in the Photo Album
- application is responsible for shelves rendering.
- Its <emphasis><property>"nodes"</property></emphasis> attribute refers
- to <emphasis><property>getShelves()</property></emphasis> method of the <code>ShelfManager</code> class
- and gets the collection of shelves associated with the current user including all shared shelves in the system.
- Take a look at this method:
- </para-->
-
- <!-- para>
- When the <emphasis><property>"nodes"</property></emphasis> attribute of the <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis>, which is responsible for shelves rendering, receives the collection of shelves,
- the iteration process switches to the nested <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis>, which is responsible for albums.
- The "albums" <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> <emphasis><property>"nodes"</property></emphasis> attribute refers in its turn to the <code>albums</code> field of the <code>Shelf</code> class
- and takes a collection of all albums associated with the current shelf.
- The "albums" <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> renders all albums that belong to the current iterating shelf and then switches back to the "shelf" <emphasis role="bold"><property><rich:treeNodesAdaptor></property></emphasis> to render and iterate the next shelf in the shelves collection received earlier.
- Here is how it looks in the <code>webapp/includes/index/tree.xhtml</code> file:
- </para-->
-
- <programlisting role="XML"><![CDATA[...
-<rich:tree
- adviseNodeOpened="#{treeManager.adviseNodeSelected}"
- adviseNodeSelected="#{treeManager.adviseNodeSelected}"
- ajaxSubmitSelection="false" id="PreDefinedTree"
- treeNodeVar="treeNode" switchType="client"
- iconCollapsed="/img/shell/tree_icon_plus.png"
- iconExpanded="/img/shell/tree_icon_minus.png"
- showConnectingLines="false">
- <rich:treeNodesAdaptor nodes="#{shelfManager.getPredefinedShelves()}" var="shelf">
- <rich:treeNode style="cursor:pointer" reRender="treeform,mainArea"
- selectedClass="tree-selected-node">
- <f:facet name="icon">
- <h:graphicImage style="border: none" value="/img/shell/tree_icon_shelf.png">
- <a4j:support reRender="treeform,mainArea" event="onclick" actionListener="#{controller.showShelf(shelf)}" similarityGroupingId="sel" />
- </h:graphicImage>
- </f:facet>
- <a4j:outputPanel >
- <h:outputText style="cursor:pointer" value="#{shelf.name}" />
- <h:outputText value=" :: " />
- <strong>#{shelf.unvisitedImages.size()}</strong> new
- <a4j:support reRender="treeform,mainArea" event="onclick" actionListener="#{controller.showShelf(shelf)}" similarityGroupingId="sel" />
- </a4j:outputPanel>
- </rich:treeNode>
- <rich:treeNodesAdaptor var="album"
- nodes="#{shelf.albums}">
- <rich:treeNode style="cursor:pointer" reRender="treeform,mainArea"
- selectedClass="tree-selected-node"
- icon="img/shell/tree_icon_album.png">
- <f:facet name="iconLeaf">
- <h:graphicImage style="border: none" value="img/shell/tree_icon_album.png">
- <a4j:support reRender="treeform,mainArea" event="onclick" actionListener="#{controller.showAlbum(album)}" similarityGroupingId="sel" />
- </h:graphicImage>
- </f:facet>
- <a4j:outputPanel>
- <h:outputText style="cursor:pointer" value="#{album.name}" />
- <h:outputText value=" :: " />
- <strong>#{album.unvisitedImages.size()}</strong> new
- <a4j:support reRender="treeform,mainArea" event="onclick" actionListener="#{controller.showAlbum(album)}" similarityGroupingId="sel" />
- </a4j:outputPanel>
- </rich:treeNode>
- </rich:treeNodesAdaptor>
- </rich:treeNodesAdaptor>
- </rich:tree>
-...]]></programlisting>
-
- <para>
- The illustration below shows how the navigation panel for a guest is rendered on the page.
- </para>
-
- <figure>
- <title>Shelves and albums nodes rendered with the help of the <rich:treeNodesAdaptor></title>
- <mediaobject>
- <imageobject>
- <imagedata fileref="images/tree.png"/>
- </imageobject>
- </mediaobject>
- </figure>
-
-</section>
-
- <section>
- <title>Navigation panel for a registered user</title>
- <para>
- As it was mentioned before a navigation panel for a registered user has
- two main features: drag-and-drop and context menu. Context menu is described
- in the <link linkend="contextMenu">"Context menu"</link> chapter.
- </para>
- <para>
- Drag-and-drop feature supported in the Photo Album application is not so complicated
- as it may seem from the first view.
- In this application we can mark out two types of drag-and-drop:
- one type takes place only inside the tree (between tree nodes)
- and another one - between the watching area and the tree.
- The difference is not considerable enough to describe two types separately,
- but also not at all insignificant to be omitted here.
- </para>
-
- <para>
- Let's examine drag-and-drop inside tree.
- The tree related components
- (<emphasis role="bold"><property><rich:tree></property></emphasis> and <emphasis role="bold"><property><rich:treeNode></property></emphasis>)
- have their own attributes that provide drag-and-drop functionality.
- These attributes can be divided into two groups:
- those which provide drag (dragValue, dragListener, dragIndicator, dragType attributes)
- and those which provide drop operations (dropValue, dropListener, acceptedTypes, typeMapping).
- </para>
- <note>
- <title>
- Note:
- </title>
- <para>
- Due to "Shelves - Albums - Photos" hierarchy we can say that photos could be moved between albums,
- albums could be moved between shelves.
- To avoid a mishmash, it's not allowed to place photos directly in shelves as well as nesting shelves
- inside shelves or albums inside albums.
- </para>
- </note>
-
- <para>
- All albums or images, which are assumed to be dragged, must be marked somehow in the application code.
- For albums that are represented as tree nodes we will use previously mentioned
- <property>drag group</property> attributes:
- </para>
- <programlisting role="XML"><![CDATA[<rich:treeNodesAdaptor var="album" nodes="#{shelf.albums}">
- <rich:treeNode dropListener="#{dndManager.processDrop}" dragType="album" dragValue="#{album}" dropValue="#{album}" acceptedTypes="image" reRender="mainArea, treeform">
- ...
- </rich:treeNode>
-</rich:treeNodesAdaptor>
-]]></programlisting>
-
- <para>
- To provide drop functionality for the marked albums we should mark shelves as drop zones in the application code too.
- For this purpose we add the <emphasis role="bold"><property>rich:dropSupport</property></emphasis> component to the "shelf" node:
- </para>
- <programlisting role="XML"><![CDATA[<rich:treeNodesAdaptor nodes="#{shelfManager.getShelves()}" var="shelf">
- <rich:treeNode>
- <rich:dropSupport id="shelfDND" acceptedTypes="album" dropValue="#{album}" dropListener="#{dndManager.processDrop}" reRender="mainArea">
- </rich:dropSupport>
- ...
- </rich:treeNode>
-</rich:treeNodeAdaptor>]]></programlisting>
-
- <para>
- The <emphasis><property>"acceptedType"</property></emphasis> attribute tells the "shelf" node what types of dragged zones (albums in this case) it can accept.
- The value for the <emphasis><property>"acceptedType"</property></emphasis> attribute corresponds the album <emphasis><property>"dragType"</property></emphasis> attribute.
- The method binding that will process drag-and-drop operation should be pointed via <emphasis><property>"dropListener"</property></emphasis> attribute of the <emphasis role="bold"><property>rich:tree</property></emphasis>.
- This method is shown in the listing below:
- </para>
- <programlisting role="JAVA"><![CDATA[...
-public void processDrop(DropEvent dropEvent) {
- Dropzone dropzone = (Dropzone) dropEvent.getComponent();
- Object dragValue = dropEvent.getDragValue();
- Object dropValue = dropzone.getDropValue();
- if(dragValue instanceof Image){
- if(!((Album)dropValue).getOwner().getLogin().equals(user.getLogin())){
- Events.instance().raiseEvent(Constants.ADD_ERROR_EVENT, Constants.DND_PHOTO_ERROR);
- return;
- }
- handleImage((Image)dragValue, (Album)dropValue);
- }else if(dragValue instanceof Album){
- if(!((Shelf)dropValue).getOwner().getLogin().equals(user.getLogin())){
- Events.instance().raiseEvent(Constants.ADD_ERROR_EVENT, Constants.DND_ALBUM_ERROR);
- return;
- }
- handleAlbum((Album)dragValue, (Shelf)dropValue);
- }
-}
-...]]></programlisting>
- <para>
- The illustration below shows how the described above drag-and-drop features are rendered in the Photo Album Demo.
- </para>
- <figure>
- <title>Dragging the "Flora" album from "Sport" shelf into the "Nature" (left) and the tree after drag-and-drop (right).</title>
- <mediaobject>
- <imageobject>
- <imagedata fileref="images/dnd.png"/>
- </imageobject>
- </mediaobject>
- </figure>
-
- </section>
-
- </section>
-
- <section>
- <title>Upload images</title>
- <para>The implementation of <emphasis role="bold"><property><rich:fileUpload></property></emphasis> in the Photo Album Demo uses the embedded Flash module that adds extra functionality to the component.
- Here are the additional features that the Flash module provides:
- </para>
- <itemizedlist>
- <listitem><para>Multiple files choosing;</para></listitem>
- <listitem><para>Specification of permitted file types in the "Open File" dialog window;</para></listitem>
- <listitem><para>A number of additional entry object properties.</para></listitem>
- </itemizedlist>
-
- <para>
- The photos uploading functionality is based on the <code>/includes/fileUpload/fileUploader.xhtml page</code>. Let's have a look at this page to find out how the uploader is implemented:
- </para>
-
- <programlisting role="XML"><![CDATA[<rich:fileUpload style="margin : 0px 0px 20px 0px; width : 504px; height : 200px; background : #f1f1f1; border : 1px solid #A1A1A1"
- id="fileUpload"
- allowFlash="true"
- immediateUpload="false"
- acceptedTypes="jpg,jpeg"
- maxFilesQuantity="100"
- autoclear="true"
- fileUploadListener="#{fileUploadManager.listener}" >
- <a4j:support event="onuploadcomplete" reRender="filesPanel, tree" />
- <a4j:support event="onfileuploadcomplete" />
- </rich:fileUpload>]]></programlisting>
-
- <para>
- The "<emphasis><property>FileUploadListener</property></emphasis>" attribute is binded with <code>fileUploadManager.listener</code> method which makes the main job on the upload.
- Below is the <code>fileUploadManager.listener</code> method:
- </para>
- <programlisting role="JAVA"><![CDATA[public void listener(UploadEvent event) throws Exception {
- UploadItem item = event.getUploadItem();
- Image image = constructImage(item);
- try {
- extractMetadata(item, image);
- } catch (Exception e1) {
- addError(item, image, Constants.FILE_PROCESSING_ERROR);
- return;
- }
- image.setAlbum(model.getSelectedAlbum());
- if(image.getAlbum() == null){
- addError(item, image, Constants.NO_ALBUM_TO_DOWNLOAD_ERROR);
- return;
- }
- try{
- if(imageAction.isImageWithThisPathExist(image)){
- image.setPath(generateNewPath(image.getPath()));
- }
- imageAction.addImage(image);
- }catch(Exception e){
- addError(item, image, Constants.IMAGE_SAVING_ERROR);
- return;
- }
- if(!fileManager.addImage(image.getFullPath(), item.getFile().getPath())){
- addError(item, image, Constants.FILE_SAVE_ERROR);
- return;
- }
- fileWrapper.getFiles().add(image);
- Events.instance().raiseEvent(Constants.IMAGE_ADDED_EVENT, image);
- item.getFile().delete();
-}]]></programlisting>
-
-<para>
- When a photo is added into the uploader, the first thing it does is saving this photo in the file system.
- The uploaded files are stored in the temporary folder in the computer file system.
- For this purpose the value of the <code>createTempFile</code> parameter in <code>Ajax4jsf Filter</code> section should be set to <code>true</code>.
- Below in the <code>Web.xml</code> file Ajax filter section:
-</para>
-
- <programlisting role="XML"><![CDATA[...
-<init-param>
- <param-name>createTempFiles</param-name>
- <param-value>true</param-value>
-</init-param>
-...]]></programlisting>
-
- <para>
- Then the uploader creates an <code>Image</code> object and extracts all image metadata such as Camera name, Image size etc.
- Then it sets an album and generates a new path to it.
- The system should save six different sizes of the photo.
- After the photo was added into the database the system removes a temporary file created for storage.
- </para>
-
-
- </section>
-
- <section>
- <title>Slide show</title>
-
- <para>The slide-show feature in the Photo Album Demo can be enabled by clicking "Start Slideshow" link from two different places in the application:
- 1) from user's album preview (<code>/web/src/main/webapp/image/albumInfo.xhtml</code>) and 2) from a particular photo preview (<code>src/main/webapp/image/imageInfo.xhtml</code>).
- Both of two mentioned XHTML files include slideshow with the help of Facelets <<emphasis role="bold"><property>ui:include</property></emphasis> tag
- (for more information about <<emphasis role="bold"><property>ui:include</property></emphasis> see Facelets Reference Guide —
- <ulink url="http://www.jsftoolbox.com/documentation/facelets/01-Introduction/index.jsf">http://www.jsftoolbox.com/documentation/facelets/01-Introduction/index.jsf</ulink>).
- </para>
-
- <para>
- The <code>startSlideshow()</code> method of <code>SlideshowManager.java</code> has two implementations.
- The first implementation is designed to activate the slide-show from an album preview (<code>/image/albumInfo.xhtml</code>) when no photo is selected in the current image list.
- The method iterates over all photos of a particular album starting from the first one in the list. Look at the <code>SlideshowManager.java</code> listing below:
- </para>
- <programlisting role="JAVA"><![CDATA[...
-public void startSlideshow(){
- active = true;
- this.slideshowIndex = 0;
- if(model.getImages() == null || model.getImages().size() < 1){
- stopSlideshow();
- Events.instance().raiseEvent(Constants.ADD_ERROR_EVENT, "No images for slideshow!");
- return;
- }
- this.selectedImage = model.getImages().get(this.slideshowIndex);
- this.selectedImage.getAlbum().visitImage(selectedImage, true);
-}
-...]]></programlisting>
-
- <para>
- The second implementation of the <code>startSlideshow()</code> method is activated when a link to slide-show is clicked from a particular photo preview.
- This method iterates over the rest of photos starting from the current selected one:
- </para>
- <programlisting role="JAVA"><![CDATA[...
-public void startSlideshow(Image selectedImage){
- active = true;
- if(model.getImages() == null || model.getImages().size() < 1){
- stopSlideshow();
- Events.instance().raiseEvent(Constants.ADD_ERROR_EVENT, "No images for slideshow!");
- return;
- }
- this.slideshowIndex = model.getImages().indexOf(selectedImage);
- this.selectedImage = selectedImage;
- this.selectedImage.getAlbum().visitImage(selectedImage, true);
-}
-...]]></programlisting>
-
- <para>
- Both implementations of <code>startSlideshow()</code> method set active property to true.
- This <code>true</code> makes two important slide-show parts (slide-show modal panel and slide-show poller) render.
- </para>
- <para>
- The slide-show modal panel is kept in the <code>web/src/main/webapp/includes/image/slideshow.xhtml</code> file and referred from the corresponding pages with the help of <emphasis role="bold"><property><ui:include></property></emphasis> Facelets tag:
- </para>
-
- <programlisting role="XML"><![CDATA[...
-<ui:include src="/includes/image/slideshow.xhtml"/>
-...]]></programlisting>
-
- <para>
- Have a look at <code>web/src/main/webapp/includes/image/slideshow.xhtml</code> file:
- </para>
-
- <programlisting role="XML"><![CDATA[...
-<ui:composition xmlns="http://www.w3.org/1999/xhtml"...>
- <rich:modalPanel showWhenRendered="#{slideshow.active}"
- domElementAttachment="parent"
- id="slideShowModalPanel"
- width="650"
- onshow="showPictureEffect();"
- height="650">
- <f:facet name="controls">
- <h:panelGroup>
- <h:graphicImage value="/img/modal/close.png" style="cursor:pointer" id="hidelink">
- <a4j:support event="onclick" actionListener="#{slideshow.stopSlideshow}" reRender="slideShowForm, mainArea, tree" />
- </h:graphicImage>
- </h:panelGroup>
- </f:facet>
- ...
- </rich:modalPanel>
-</ui:composition>
-...]]></programlisting>
-
- <para>
- The modal panel is always rendered on the page in a hidden state.
- Activating the slide-show renders the main area, so the slide-show modal panel appears in the closest to an observer layer.
- </para>
-
- <programlisting role="XML"><![CDATA[...
-<a4j:commandLink styleClass="slideshow-link"
- actionListener="#{slideshow.startSlideshow()}"
- reRender="slideShowForm, mainArea">
- ...
-</a4j:commandLink>
-...]]></programlisting>
- <para>
- Slide-show poller is enabled if the slide-show is activated:
- </para>
- <programlisting role="XML"><![CDATA[...
-<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<ui:composition xmlns="http://www.w3.org/1999/xhtml"
- xmlns:s="http://jboss.com/products/seam/taglib"
- xmlns:ui="http://java.sun.com/jsf/facelets"
- xmlns:f="http://java.sun.com/jsf/core"
- xmlns:h="http://java.sun.com/jsf/html"
- xmlns:rich="http://richfaces.org/rich"
- xmlns:a4j="http://richfaces.org/a4j"
- xmlns:richx="http://richfaces.org/richx">
- <a4j:form id="slideShowForm">
- <a4j:poll reRender="slideshowImage"
- actionListener="#{slideshow.showNextImage()}"
- interval="#{slideshow.interval}"
- enabled="#{slideshow.active}"
- onsubmit="hidePictureEffect()"
- oncomplete="showPictureEffect();"/>
- </a4j:form>
-</ui:composition>
-...]]></programlisting>
- <para>
- The slide-show poller sends the request for the next image (<code>showNextImage()</code> method) each four seconds.
- The interval is defined in the interval property of the <code>SlideshowManager.java</code> and refers to a <code>INITIAL.DELAY</code> constant (<code>constants.java</code>).
- When the <emphasis role="bold"><property><a4j:poll></property></emphasis> component receives a new image it renders the slideShowImage area (<code>/web/src/main/webapp/image/slideshow.xhtml</code>):
- </para>
- <programlisting role="XML"><![CDATA[...
-<h:panelGroup id="slideshowImage">
- <a4j:mediaOutput id="imgSlideShow"
- element="img"
- styleClass="main-image"
- createContent="#{imageLoader.paintImage}"
- style="opacity: 0.1"
- value="#{slideshow.selectedImage != null? fileManager.transformPath(slideshow.selectedImage.path, '_medium'):null}">
- <rich:toolTip followMouse="true"
- direction="top-right"
- showDelay="500"
- styleClass="tooltip">
- <span style="white-space: nowrap"> #{slideshow.selectedImage.description} </span>
- </rich:toolTip>
- </a4j:mediaOutput>
-</h:panelGroup>
-...]]></programlisting>
-
- <para>
- The <emphasis role="bold"><property>a4j:mediaOtuput</property></emphasis> component has a value attribute that takes a path to photos as a value and renders photos with the help of a <emphasis><property>createContent</property></emphasis> attribute. The showNextImage works cyclically.
- </para>
-
- <para>
- There is <emphasis role="bold"><property>rich:effect</property></emphasis> that makes rendering process look more effective (<code>web/src/main/webapp/includes/image/slideshow.xhtml</code>):
- </para>
- <programlisting role="XML"><![CDATA[...
-<rich:effect name="hidePictureEffect" type="Opacity" params="duration:0.4, from:1.0, to:0.0" for="imgSlideShow" />
-<rich:effect name="showPictureEffect" type="Opacity" params="duration:0.4, from:0.1, to:1.0" for="imgSlideShow" />
-...]]></programlisting>
-
- <para>
- The described above example implements a modal panel with photos that change each other in order they store in an album.
- </para>
- <figure>
- <title>Slide show</title>
- <mediaobject>
- <imageobject>
- <imagedata fileref="images/slide_show.png"/>
- </imageobject>
- </mediaobject>
- </figure>
-
- <para>
- To quit the slide-show user clicks "Close window" button on the slide-show panel and <code>stopSlideshow()</code> method is activated.
- </para>
- <programlisting role="JAVA"><![CDATA[...
-@Observer("stopSlideshow")
- public void stopSlideshow(){
- active = false;
- this.selectedImage = null;
- this.slideshowIndex = 0;
- }
-...]]></programlisting>
-
- </section>
-
- <section>
- <title>Image Size control</title>
-
- <section>
- <title>Building the control with <rich:inputNumberSlider></title>
- <para>
- The <emphasis role="bold"><property>rich:inputNumberSlider</property></emphasis> component in the Photo Album Demo is used as a control that helps a user to change photos size while previewing an album.
- A handler position on the slider track corresponds to a particular value of image size.
- The component is included into the page with the help of <emphasis role="bold"><property>ui:include</property></emphasis>:
- </para>
- <programlisting role="XML"><![CDATA[...
-<ui:include src="/includes/misc/inputNumberSlider.xhtml"/>
-...]]></programlisting>
-
- <para>
- Now let's have a look at <code>src/main/webapp/includes/misc/inputNumberSlider.xhtml</code> file:
- </para>
- <programlisting role="XML"><![CDATA[...
-<ui:composition ...>
- <div>
- <rich:inputNumberSlider value="#{imageSizeHelper.value}"
- minValue="80"
- maxValue="200"
- step="40"
- enableManualInput="false"
- showArrows="false"
- showBoundaryValues="true"
- showInput="false">
- <a4j:support event="onchange" reRender="userAlbumImages"/>
- </rich:inputNumberSlider>
- </div>
-</ui:composition>
-...]]></programlisting>
- <para>
- On each slider position change the <emphasis role="bold"><property>a4j:support</property></emphasis> component invokes an Ajax request that passes a new set value into the <code>ImageSizeHelper.java</code> class.
- This class saves new photo dimensions, processes and assigns new values to photo related attributes (a CSS class for new photo size, postfix for a new file name, image background):
- </para>
- <programlisting role="JAVA"><![CDATA[...
- public static enum ImageDimension {
-
- SIZE_80(80), SIZE_120(120), SIZE_160(160), SIZE_200(200);
-
- final static String CSS_CLASS = "preview_box_photo_";
- final static String FILE_POSTFIX = "_small";
- final static String IMAGE_BG = "/img/shell/frame_photo_%1$d.png";
- final static String IMAGE_BG_STYLE = "width: %1$dpx; height: %1$dpx";
-
- int x;
- String bgStyle;
- String cssClass;
- String imageBgSrc;
- String filePostfix;
-
- private ImageDimension(int x) {
- this.x = x;
- this.bgStyle = String.format(IMAGE_BG_STYLE, x + 20);
- cssClass = CSS_CLASS + x;
- imageBgSrc = String.format(IMAGE_BG, (x == 160) ? 200 : x);
- filePostfix = FILE_POSTFIX + x;
- }
- ...]]></programlisting>
-
- <para>
- After the <code>ImageSizeHelper.java</code> is worked out the <emphasis role="bold"><property>a4j:support</property></emphasis> component renders user photos
- (more exactly, the <emphasis role="bold"><property>h:panelGroup</property></emphasis> with <code>userAlbumImages</code> id that contains user photos)
- correspondingly to a new set value. Here is <code>web/src/main/webapp/includes/image/imageList.xhtml</code>:
- </para>
- <programlisting role="XML"><![CDATA[...
-<h:panelGroup id="userAlbumImages">
- <a4j:repeat id="imageList" value="#{model.images}" var="image" rows="20">
- <h:panelGroup layout="block" styleClass="#{imageSizeHelper.currentDimension.cssClass}">
- <h:graphicImage styleClass="pr_photo_bg" style="#{imageSizeHelper.currentDimension.imageBgStyle}" value="#{imageSizeHelper.currentDimension.imageBg}" />
- <h:panelGrid cellpadding="0">
- <h:panelGroup>
- <a4j:commandLink actionListener="#{controller.showImage(image)}" reRender="mainArea, tree">
- <a4j:mediaOutput id="img" element="img"
- createContent="#{imageLoader.paintImage}"
- style="border : 1px solid #FFFFFF;"
- value="#{fileManager.transformPath(image.fullPath, imageSizeHelper.currentDimension.filePostfix)}">
- <f:param value="#{imageSizeHelper.currentDimension.x}" name="x" />
- <rich:dragSupport rendered="#{controller.isUserImage(image)}" reRender="mainArea, tree" id="dragSource" dragIndicator="dragIndicator"
- dragType="image" dragValue="#{image}">
- <rich:dndParam id="dragParam" name="label" value="#{image.name}" />
- </rich:dragSupport>
- <ui:include src="/includes/contextMenu/CMForImage.xhtml" >
- <ui:param name="image" value="#{image}" />
- </ui:include>
- </a4j:mediaOutput>
- </a4j:commandLink>
- <br/>
- </h:panelGroup>
- </h:panelGrid>
- <h:panelGroup layout="block" styleClass="photo_name">#{image.name} </h:panelGroup>
- <h:panelGroup layout="block" styleClass="photo_data">
- <h:outputText value="#{image.created}">
- <f:convertDateTime />
- </h:outputText>
- </h:panelGroup>
- </h:panelGroup>
- </a4j:repeat>
-</h:panelGroup>
-...]]></programlisting>
-
- <para>
- When the <emphasis role="bold"><property><rich:inputNumberSlider<</property></emphasis> is rendered at first its default value for image size is 120 px.
- </para>
-
- <figure>
- <title>Image size control</title>
- <mediaobject>
- <imageobject>
- <imagedata fileref="images/image_size.png"/>
- </imageobject>
- </mediaobject>
- </figure>
-
- </section>
-
- <section>
- <title>Links in Photo Album Demo. Using the <a4j:commandLink></title>
- <para>
- The main difference between <emphasis role="bold"><property><h:commandLink></property></emphasis> component is a) Ajax request that is generated on a click and b) dynamic rerendering of the page after a response comes back.
- It's not necessary to plug any support into the component, as Ajax support is already built-in.
- </para>
- <para>
- The <emphasis role="bold"><property><a4j:commandLink></property></emphasis> component is used widely in the application.
- In the following example clicking on the <Edit> link will rerender the main ares (watching area) of the application and open an album edit form.
- Each album has its owner and only owner can edit the album contents.
- The link <Edit> will be rendered only if the current logged-in user is the owner of this album: the <emphasis><property>"rendered"</property></emphasis> attribute refers to the owner id and compares it with the current user id:
- </para>
- <programlisting role="XML"><![CDATA[...
-<a4j:commandLink rendered="#{model.selectedAlbum.owner.id == user.id}"
- value="#{messages['album.edit']} "
- actionListener="#{controller.startEditAlbum(model.selectedAlbum)}"
- reRender="mainArea">
-</a4j:commandLink>
-...]]></programlisting>
- <para>
- The <emphasis><property><value></property></emphasis> attribute (text that will appear on the link) is picked up from the <code>messages_en.properties</code> file.
- Such property files are very useful e.g. for multi language applications.
- Each property is saved in the format "name—value".
- Let's have a look at this file in the JBDS:
- </para>
- <figure>
- <title>Image size control</title>
- <mediaobject>
- <imageobject>
- <imagedata fileref="images/messages_en_property.png"/>
- </imageobject>
- </mediaobject>
- </figure>
- </section>
-
- <section>
- <title>Error Reports in the Real World Demo</title>
- <para>The main page of the application <code>web/src/main/webapp/index.xhtml</code> includes <code>web/src/main/webapp/includes/misc/errorPanel.xhtml</code>.
- The error panel itself is always rendered but hidden if no error appears. The listing below shows the part of <code>errorPanel.xhtml</code> page:
- </para>
- <programlisting role="XML"><![CDATA[...
-<a4j:outputPanel id="errors" ajaxRendered="true">
- <h:panelGroup rendered="#{errorHandlerBean.errorExist}">
- <rich:modalPanel id="errorPanel"
- showWhenRendered="true"
- minWidth="300"
- minHeight="200"
- autosized="true">
- ...
- </rich:modalPanel>
- </h:panelGroup>
-</a4j:outputPanel>
-...]]></programlisting>
- <para>
- Error checking happens each time the Ajax request is invoked by user activity.
- The <emphasis role="bold"><property>rich:modalPanel</property></emphasis> which wrapped with <emphasis role="bold"><property><h:panelGroup></property></emphasis> is rendered in case an error occurs,
- its <emphasis><property>"rendered"</property></emphasis> attribute is binded with <code>isErrorExist</code> boolean method of <code>errorHandlerBean</code> class.
- </para>
- <programlisting role="XML"><![CDATA[...
-package org.richfaces.realworld.ui;
-...
-@Name("errorHandlerBean")
-(a)Scope(ScopeType.EVENT)
-@AutoCreate
-public class ErrorHandlerBean {
- private List<String> errors = new ArrayList<String>();
-
- public List<String> getErrors() {
- return errors;
- }
-
- public boolean isErrorExist(){
- return errors.size() > 0 ;
- }
-
- @Observer(Constants.ADD_ERROR_EVENT)
- public void addToErrors(String e){
- errors.add(e);
- }
-}
-...]]></programlisting>
-
- <para>
- The <code>addToErrors</code> method is annotated with <code>@Observer</code> annotation which observes all methods in the application with <code>ADD_ERROR_EVENT</code> annotation.
- </para>
-
- </section>
-
-
-
- </section>
- <section id="contextMenu">
- <title>Context Menu</title>
- <para>Work in progress...</para>
- </section>
-
-</chapter>
Modified: trunk/docs/realworld_app_guide/en/src/main/docbook/modules/intro.xml
===================================================================
--- trunk/docs/realworld_app_guide/en/src/main/docbook/modules/intro.xml 2009-04-25 10:41:47 UTC (rev 13850)
+++ trunk/docs/realworld_app_guide/en/src/main/docbook/modules/intro.xml 2009-04-25 11:26:25 UTC (rev 13851)
@@ -23,19 +23,19 @@
<itemizedlist>
<listitem>
<para>
- <emphasis>wide variety of UI components</emphasis> — the <property>RichFaces</property> provides
+ <emphasis>wide variety of UI components</emphasis> - the <property>RichFaces</property> provides
a Lego-like way of building user interfaces for web applications;
</para>
</listitem>
<listitem>
<para>
- <emphasis>built-in Ajax capability</emphasis> — the <property>RichFaces</property> offers
+ <emphasis>built-in Ajax capability</emphasis> - the <property>RichFaces</property> offers
both component-wide and very flexible page-wide Ajax support with no need to write any JavaScript code;
</para>
</listitem>
<listitem>
<para>
- <emphasis>highly customizable look-and-feel</emphasis> — the <property>RichFaces</property> have special feature called
+ <emphasis>highly customizable look-and-feel</emphasis> - the <property>RichFaces</property> have special feature called
<ulink url="http://www.jboss.org/file-access/default/members/jbossrichfaces/freezone/...">Skinnability</ulink>.
</para>
</listitem>
Added: trunk/docs/realworld_app_guide/en/src/main/docbook/modules/overview.xml
===================================================================
--- trunk/docs/realworld_app_guide/en/src/main/docbook/modules/overview.xml (rev 0)
+++ trunk/docs/realworld_app_guide/en/src/main/docbook/modules/overview.xml 2009-04-25 11:26:25 UTC (rev 13851)
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter id="overview" xreflabel="overview">
+ <?dbhtml filename="overview.html"?>
+ <chapterinfo>
+ <keywordset>
+ <keyword>RichFaces</keyword>
+
+ </keywordset>
+ </chapterinfo>
+ <title>Application Overview</title>
+ <section id="pageFlows">
+ <title>Page flows</title>
+ <para>
+ Work in progress...
+ </para>
+ </section>
+ <section id="dataModel">
+ <title>Data Model</title>
+ <para>
+ Work in progress...
+ </para>
+ </section>
+ <section id="setUp">
+ <title>Project Set Up</title>
+ <para>
+ Work in progress...
+ </para>
+ </section>
+</chapter>
+
Property changes on: trunk/docs/realworld_app_guide/en/src/main/docbook/modules/overview.xml
___________________________________________________________________
Name: svn:executable
+ *
17 years
JBoss Rich Faces SVN: r13850 - in trunk/samples/extendedDataTable-sample/src/main: resources/i18n and 2 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: pkawiak
Date: 2009-04-25 06:41:47 -0400 (Sat, 25 Apr 2009)
New Revision: 13850
Added:
trunk/samples/extendedDataTable-sample/src/main/webapp/pages/index.xhtml
trunk/samples/extendedDataTable-sample/src/main/webapp/pages/stateTestPage.xhtml
Removed:
trunk/samples/extendedDataTable-sample/src/main/webapp/pages/index.jsp
trunk/samples/extendedDataTable-sample/src/main/webapp/pages/stateTestPage.jsp
Modified:
trunk/samples/extendedDataTable-sample/src/main/java/org/richfaces/samples/extdt/beans/ExtendedDataTableBB.java
trunk/samples/extendedDataTable-sample/src/main/resources/i18n/messages.properties
trunk/samples/extendedDataTable-sample/src/main/resources/i18n/messages_en.properties
trunk/samples/extendedDataTable-sample/src/main/resources/i18n/messages_pl.properties
trunk/samples/extendedDataTable-sample/src/main/webapp/WEB-INF/.faces-config.xml.jsfdia
trunk/samples/extendedDataTable-sample/src/main/webapp/WEB-INF/web.xml
Log:
RF-6151: updated demo of extendedTableDataModel. Facelets introduced, serializing/deserializing dataModel is now available in demo.
Modified: trunk/samples/extendedDataTable-sample/src/main/java/org/richfaces/samples/extdt/beans/ExtendedDataTableBB.java
===================================================================
--- trunk/samples/extendedDataTable-sample/src/main/java/org/richfaces/samples/extdt/beans/ExtendedDataTableBB.java 2009-04-25 10:32:22 UTC (rev 13849)
+++ trunk/samples/extendedDataTable-sample/src/main/java/org/richfaces/samples/extdt/beans/ExtendedDataTableBB.java 2009-04-25 10:41:47 UTC (rev 13850)
@@ -1,11 +1,17 @@
package org.richfaces.samples.extdt.beans;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import javax.faces.context.FacesContext;
+import javax.faces.event.ActionEvent;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -17,102 +23,156 @@
/**
* @author pkawiak
- *
+ *
*/
public class ExtendedDataTableBB {
-
- private SimpleSelection selection = new SimpleSelection();
- private List<DemoPatient> selectedItems;
- private Comparator<DemoPatient> dateComparator;
- private String tableState = null;
- private ExtendedTableDataModel<DemoPatient> dataModel;
- private Integer patientsNumber = 100;
- public ExtendedDataTableBB() {
- }
-
- public ExtendedTableDataModel<DemoPatient> getDataModel(){
- if (dataModel == null){
- dataModel = new ExtendedTableDataModel<DemoPatient>(new DemoPatientProvider(patientsNumber));
- }
- return dataModel;
- }
-
- public SimpleSelection getSelection() {
- return selection;
- }
+ private SimpleSelection selection = new SimpleSelection();
+ private List<DemoPatient> selectedItems;
+ private Comparator<DemoPatient> dateComparator;
+ private String tableState = null;
+ private ExtendedTableDataModel<DemoPatient> dataModel;
+ private Integer patientsNumber = 100;
- public void setSelection(SimpleSelection selection) {
- this.selection = selection;
- }
-
- public String takeSelection() {
- getSelectedItems().clear();
- Iterator<Object> iterator = getSelection().getKeys();
- while (iterator.hasNext()){
- Object key = iterator.next();
- selectedItems.add(getDataModel().getObjectByKey(key));
- }
- return null;
- }
-
- public Integer getPatientsNumber() {
- return patientsNumber;
- }
+ private ByteArrayOutputStream byteOutputStream;
+ private ObjectOutputStream objectOutputStream;
- public void setPatientsNumber(Integer patientsNumber) {
- if (patientsNumber != this.patientsNumber) {
- dataModel = new ExtendedTableDataModel<DemoPatient>(new DemoPatientProvider(patientsNumber));
- }
- this.patientsNumber = patientsNumber;
- }
+ public ExtendedDataTableBB() {
+ }
- public List<DemoPatient> getSelectedItems() {
- if (selectedItems == null){
- selectedItems = new ArrayList<DemoPatient>();
- }
- return selectedItems;
- }
+ public ExtendedTableDataModel<DemoPatient> getDataModel() {
+ if (dataModel == null) {
+ dataModel = new ExtendedTableDataModel<DemoPatient>(
+ new DemoPatientProvider(patientsNumber));
+ }
+ return dataModel;
+ }
- public void setSelectedItems(List<DemoPatient> selectedItems) {
- this.selectedItems = selectedItems;
- }
+ public SimpleSelection getSelection() {
+ return selection;
+ }
- public String getTableState() {
- if (tableState == null){
- //try to get state from cookies
- Cookie[] cookies = ((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getCookies();
- if (cookies != null){
- for (Cookie c : cookies){
- if (c.getName().equals("extdtSampleTabelState")){
- tableState = c.getValue();
- break;
- }
- }
- }
- }
- return tableState;
- }
+ public void setSelection(SimpleSelection selection) {
+ this.selection = selection;
+ }
- public void setTableState(String tableState) {
- this.tableState = tableState;
- //save state in cookies
- Cookie stateCookie = new Cookie("extdtSampleTabelState", this.tableState);
+ public String takeSelection() {
+ getSelectedItems().clear();
+ Iterator<Object> iterator = getSelection().getKeys();
+ while (iterator.hasNext()) {
+ Object key = iterator.next();
+ selectedItems.add(getDataModel().getObjectByKey(key));
+ }
+ return null;
+ }
+
+ public Integer getPatientsNumber() {
+ return patientsNumber;
+ }
+
+ public void setPatientsNumber(Integer patientsNumber) {
+ if (patientsNumber != this.patientsNumber) {
+ dataModel = new ExtendedTableDataModel<DemoPatient>(
+ new DemoPatientProvider(patientsNumber));
+ }
+ this.patientsNumber = patientsNumber;
+ }
+
+ public List<DemoPatient> getSelectedItems() {
+ if (selectedItems == null) {
+ selectedItems = new ArrayList<DemoPatient>();
+ }
+ return selectedItems;
+ }
+
+ public void setSelectedItems(List<DemoPatient> selectedItems) {
+ this.selectedItems = selectedItems;
+ }
+
+ public String getTableState() {
+ if (tableState == null) {
+ // try to get state from cookies
+ Cookie[] cookies = ((HttpServletRequest) FacesContext
+ .getCurrentInstance().getExternalContext().getRequest())
+ .getCookies();
+ if (cookies != null) {
+ for (Cookie c : cookies) {
+ if (c.getName().equals("extdtSampleTabelState")) {
+ tableState = c.getValue();
+ break;
+ }
+ }
+ }
+ }
+ return tableState;
+ }
+
+ public void setTableState(String tableState) {
+ this.tableState = tableState;
+ // save state in cookies
+ Cookie stateCookie = new Cookie("extdtSampleTabelState",
+ this.tableState);
stateCookie.setMaxAge(30 * 24 * 60 * 60);
- ((HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse()).addCookie(stateCookie);
+ ((HttpServletResponse) FacesContext.getCurrentInstance()
+ .getExternalContext().getResponse()).addCookie(stateCookie);
+ }
+
+ public void serializeModel(ActionEvent event) {
+ try {
+ byteOutputStream = new ByteArrayOutputStream();
+ objectOutputStream = new ObjectOutputStream(byteOutputStream);
+ objectOutputStream.writeObject(dataModel);
+ System.out.println("Data Model serialized");
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ objectOutputStream.flush();
+ objectOutputStream.close();
+ byteOutputStream.close();
+ } catch (IOException e1) {
+ e1.printStackTrace();
+ }
+ }
+ }
+
+ public void deserializeModel(ActionEvent event) {
+ ByteArrayInputStream fIn=null;
+ ObjectInputStream oIn=null;
+
+ try{
+ fIn= new ByteArrayInputStream(byteOutputStream.toByteArray());
+ oIn = new ObjectInputStream(fIn);
+ // de-serializing dataModel
+ dataModel = (ExtendedTableDataModel<DemoPatient>) oIn.readObject();
+ System.out.println("Data Model deserialized");
+ patientsNumber = dataModel.getRowCount();
+ } catch(IOException e) {
+ e.printStackTrace();
+ } catch(ClassNotFoundException e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ oIn.close();
+ fIn.close();
+ } catch (IOException e1) {
+ e1.printStackTrace();
+ }
+ }
}
-
- public Comparator<DemoPatient> getDateComparator(){
- if (dateComparator == null){
- dateComparator = new Comparator<DemoPatient>(){
- public int compare(DemoPatient o1, DemoPatient o2) {
- return o1.getAdmissionDate().compareTo(o2.getAdmissionDate());
- }
-
- };
- }
- return dateComparator;
- }
-
+ public Comparator<DemoPatient> getDateComparator() {
+ if (dateComparator == null) {
+ dateComparator = new Comparator<DemoPatient>() {
+
+ public int compare(DemoPatient o1, DemoPatient o2) {
+ return o1.getAdmissionDate().compareTo(
+ o2.getAdmissionDate());
+ }
+
+ };
+ }
+ return dateComparator;
+ }
+
}
Modified: trunk/samples/extendedDataTable-sample/src/main/resources/i18n/messages.properties
===================================================================
--- trunk/samples/extendedDataTable-sample/src/main/resources/i18n/messages.properties 2009-04-25 10:32:22 UTC (rev 13849)
+++ trunk/samples/extendedDataTable-sample/src/main/resources/i18n/messages.properties 2009-04-25 10:41:47 UTC (rev 13850)
@@ -10,6 +10,8 @@
table.selectionMode=Selection mode
table.patientsNumber=Number of patients
table.testComponentState=Test component state
+table.serializeDataModel=Serialize data model
+table.deserializeDataModel=Deserialize data model
table.back=Back
demo.testPageTitle=Component state test page
table.paginated=Enable paginator
@@ -17,3 +19,6 @@
table.selectedPatients=Selected patients
select=Select
table.enableContextMenu=Enable context menu
+component.test=Component test
+dataModel.test=ExtendedTableDataModel test
+
Modified: trunk/samples/extendedDataTable-sample/src/main/resources/i18n/messages_en.properties
===================================================================
--- trunk/samples/extendedDataTable-sample/src/main/resources/i18n/messages_en.properties 2009-04-25 10:32:22 UTC (rev 13849)
+++ trunk/samples/extendedDataTable-sample/src/main/resources/i18n/messages_en.properties 2009-04-25 10:41:47 UTC (rev 13850)
@@ -15,5 +15,9 @@
table.paginated=Enable paginator
table.rowsNumber=Number of rows
table.selectedPatients=Selected patients
+table.serializeDataModel=Serialize data model
+table.deserializeDataModel=Deserialize data model
select=Select
table.enableContextMenu=Enable context menu
+component.test=Component test
+dataModel.test=ExtendedTableDataModel test
Modified: trunk/samples/extendedDataTable-sample/src/main/resources/i18n/messages_pl.properties
===================================================================
--- trunk/samples/extendedDataTable-sample/src/main/resources/i18n/messages_pl.properties 2009-04-25 10:32:22 UTC (rev 13849)
+++ trunk/samples/extendedDataTable-sample/src/main/resources/i18n/messages_pl.properties 2009-04-25 10:41:47 UTC (rev 13850)
@@ -10,6 +10,8 @@
table.selectionMode=Selection mode
table.patientsNumber=Number of patients
table.testComponentState=Test component state
+table.serializeDataModel=Serialize data model
+table.deserializeDataModel=Deserialize data model
table.back=Back
demo.testPageTitle=Component state test page
table.paginated=Enable paginator
@@ -17,3 +19,5 @@
table.selectedPatients=Selected patients
select=Selekt
table.enableContextMenu=Enable context menu
+component.test=Component test
+dataModel.test=ExtendedTableDataModel test
Modified: trunk/samples/extendedDataTable-sample/src/main/webapp/WEB-INF/.faces-config.xml.jsfdia
===================================================================
--- trunk/samples/extendedDataTable-sample/src/main/webapp/WEB-INF/.faces-config.xml.jsfdia 2009-04-25 10:32:22 UTC (rev 13849)
+++ trunk/samples/extendedDataTable-sample/src/main/webapp/WEB-INF/.faces-config.xml.jsfdia 2009-04-25 10:41:47 UTC (rev 13850)
@@ -1,17 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
-<PROCESS model-entity="JSFProcess">
- <PROCESS-ITEM NAME="rules:*" PATH="*" SHAPE="32,17,0,0" model-entity="JSFProcessGroup">
- <PROCESS-ITEM ID="rules:*:0" NAME="item" PATH="*" model-entity="JSFProcessItem">
- <PROCESS-ITEM-OUTPUT ID="stateTest::#pages#stateTestPage.jsp"
- NAME="output" PATH="/pages/stateTestPage.jsp"
- TARGET="rules:#pages#stateTestPage.jsp" TITLE="stateTest" model-entity="JSFProcessItemOutput"/>
- <PROCESS-ITEM-OUTPUT ID="index::#pages#index.jsp" NAME="output1"
- PATH="/pages/index.jsp" TARGET="rules:#pages#index.jsp"
- TITLE="index" model-entity="JSFProcessItemOutput"/>
+<PROCESS ENTITY="JSFProcess">
+ <PROCESS-ITEM ENTITY="JSFProcessGroup" NAME="rules:*" PATH="*" SHAPE="32,17,0,0">
+ <PROCESS-ITEM ENTITY="JSFProcessItem" ID="rules:*:0" NAME="item" PATH="*">
+ <PROCESS-ITEM-OUTPUT ENTITY="JSFProcessItemOutput"
+ ID="stateTest::#pages#stateTestPage.jsp" NAME="output"
+ PATH="/pages/stateTestPage.jsp"
+ TARGET="rules:#pages#stateTestPage.jsp" TITLE="stateTest"/>
+ <PROCESS-ITEM-OUTPUT ENTITY="JSFProcessItemOutput"
+ ID="index::#pages#index.jsp" NAME="output1" PATH="/pages/index.jsp"
+ TARGET="rules:#pages#index.jsp" TITLE="index"/>
</PROCESS-ITEM>
</PROCESS-ITEM>
- <PROCESS-ITEM NAME="rules:#pages#stateTestPage.jsp"
- PATH="/pages/stateTestPage.jsp" SHAPE="32,465,0,0" model-entity="JSFProcessGroup"/>
- <PROCESS-ITEM NAME="rules:#pages#index.jsp" PATH="/pages/index.jsp"
- SHAPE="32,577,0,0" model-entity="JSFProcessGroup"/>
+ <PROCESS-ITEM ENTITY="JSFProcessGroup"
+ NAME="rules:#pages#stateTestPage.jsp" PATH="/pages/stateTestPage.jsp" SHAPE="32,465,0,0"/>
+ <PROCESS-ITEM ENTITY="JSFProcessGroup" NAME="rules:#pages#index.jsp"
+ PATH="/pages/index.jsp" SHAPE="32,577,0,0"/>
</PROCESS>
Modified: trunk/samples/extendedDataTable-sample/src/main/webapp/WEB-INF/web.xml
===================================================================
--- trunk/samples/extendedDataTable-sample/src/main/webapp/WEB-INF/web.xml 2009-04-25 10:32:22 UTC (rev 13849)
+++ trunk/samples/extendedDataTable-sample/src/main/webapp/WEB-INF/web.xml 2009-04-25 10:41:47 UTC (rev 13850)
@@ -1,46 +1,60 @@
-<?xml version="1.0"?>
-<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
- <display-name>Archetype Created Web Application</display-name>
- <context-param>
- <param-name>javax.faces.CONFIG_FILES</param-name>
- <param-value>/WEB-INF/faces-config.xml</param-value>
- </context-param>
- <context-param>
- <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
- <param-value>server</param-value>
- </context-param>
- <context-param>
- <param-name>org.ajax4jsf.COMPRESS_SCRIPT</param-name>
- <param-value>false</param-value>
- </context-param>
-
- <filter>
- <display-name>Ajax4jsf Filter</display-name>
- <filter-name>ajax4jsf</filter-name>
- <filter-class>org.ajax4jsf.Filter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>ajax4jsf</filter-name>
- <servlet-name>Faces Servlet</servlet-name>
- <dispatcher>REQUEST</dispatcher>
- <dispatcher>FORWARD</dispatcher>
- <dispatcher>INCLUDE</dispatcher>
- </filter-mapping>
- <servlet>
- <servlet-name>Faces Servlet</servlet-name>
- <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>Faces Servlet</servlet-name>
- <url-pattern>/faces/*</url-pattern>
- </servlet-mapping>
- <servlet-mapping>
- <servlet-name>Faces Servlet</servlet-name>
- <url-pattern>*.jsf</url-pattern>
- </servlet-mapping>
- <login-config>
- <auth-method>BASIC</auth-method>
- </login-config>
-</web-app>
+<?xml version="1.0"?>
+<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
+ <display-name>Archetype Created Web Application</display-name>
+ <context-param>
+ <param-name>javax.faces.CONFIG_FILES</param-name>
+ <param-value>/WEB-INF/faces-config.xml</param-value>
+ </context-param>
+ <context-param>
+ <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
+ <param-value>server</param-value>
+ </context-param>
+ <context-param>
+ <param-name>org.ajax4jsf.COMPRESS_SCRIPT</param-name>
+ <param-value>false</param-value>
+ </context-param>
+ <context-param>
+ <param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
+ <param-value>com.sun.facelets.FaceletViewHandler</param-value>
+ </context-param>
+ <context-param>
+ <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
+ <param-value>.xhtml</param-value>
+ </context-param>
+ <context-param>
+ <param-name>facelets.VIEW_MAPPINGS</param-name>
+ <param-value>*xhtml</param-value>
+ </context-param>
+ <filter>
+ <display-name>Ajax4jsf Filter</display-name>
+ <filter-name>ajax4jsf</filter-name>
+ <filter-class>org.ajax4jsf.Filter</filter-class>
+ </filter>
+ <filter-mapping>
+ <filter-name>ajax4jsf</filter-name>
+ <servlet-name>Faces Servlet</servlet-name>
+ <dispatcher>REQUEST</dispatcher>
+ <dispatcher>FORWARD</dispatcher>
+ <dispatcher>INCLUDE</dispatcher>
+ </filter-mapping>
+ <servlet>
+ <servlet-name>Faces Servlet</servlet-name>
+ <servlet-class>
+ javax.faces.webapp.FacesServlet
+ </servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>Faces Servlet</servlet-name>
+ <url-pattern>/faces/*</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>Faces Servlet</servlet-name>
+ <url-pattern>*.jsf</url-pattern>
+ </servlet-mapping>
+ <login-config>
+ <auth-method>BASIC</auth-method>
+ </login-config>
+</web-app>
Deleted: trunk/samples/extendedDataTable-sample/src/main/webapp/pages/index.jsp
===================================================================
--- trunk/samples/extendedDataTable-sample/src/main/webapp/pages/index.jsp 2009-04-25 10:32:22 UTC (rev 13849)
+++ trunk/samples/extendedDataTable-sample/src/main/webapp/pages/index.jsp 2009-04-25 10:41:47 UTC (rev 13850)
@@ -1,188 +0,0 @@
-<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
-<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
-<%@ taglib uri="http://richfaces.org/rich" prefix="rich" %>
-<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j" %>
-<%@ taglib uri="http://labs.jboss.com/jbossrichfaces/ui/extendedDataTable" prefix="extdt" %>
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<f:view>
- <html>
- <head>
- <title>
- <h:outputText value="#{msg['demo.title']}">
- </h:outputText>
- </title>
- <style type="text/css">
-
- .leftColumn {
- width: 50%;
- height: 100%;
- }
-
- .rightColumn {
- width: 50%;
- height: 100%;
- }
-
- table {
- cell-padding: 10;
- cell-spacing: 10;
- }
-
- #mainPanel {
- width: 100%;
- height: 100%;
- }
-
- #leftPanel {
- width: 100%;
- height: 100%;
- }
-
- #rightPanel {
- width: 100%;
- height: 100%;
- }
- </style>
- </head>
-
-<body>
- <h:panelGrid style="table-layout: fixed;" columns="2" id="mainPanel" columnClasses="leftColumn, rightColumn">
- <rich:spacer></rich:spacer>
- <rich:spacer></rich:spacer>
- <rich:panel id="leftPanel">
- <h:form id="form1">
- <extdt:extendedDataTable id="demoTable"
- value="#{extendedDataTableBean.dataModel}" var="patient"
- style="margin: 0 auto;"
- rows="#{extendedDataTableControlBean.rowsNumber}"
- width="#{extendedDataTableControlBean.width}"
- height="#{extendedDataTableControlBean.height}"
- selectedClass="dataTableSelectedRow" footerClass="demo-footer"
- sortMode="#{extendedDataTableControlBean.sortMode}"
- selectionMode="#{extendedDataTableControlBean.selectionMode}"
- selection="#{extendedDataTableBean.selection}" rowKeyVar="rkvar"
- enableContextMenu="#{extendedDataTableControlBean.contextMenuEnabled}"
- tableState="#{extendedDataTableBean.tableState}">
- <rich:column id="firstName" headerClass="dataTableHeader"
- width="25%" label="#{msg['patient.firstName']}" sortable="true"
- sortBy="#{patient.firstName}" filterBy="#{patient.firstName}"
- filterEvent="onkeyup">
- <f:facet name="header">
- <h:outputText value="#{msg['patient.firstName']}" />
- </f:facet>
- <h:outputText id="text" value="#{patient.firstName}">
- <rich:toolTip for="text">
- <h:outputText value="sasasasasasa" />
- </rich:toolTip>
- </h:outputText>
- </rich:column>
- <rich:column id="lastName" headerClass="dataTableHeader"
- width="25%" label="#{msg['patient.lastName']}" sortable="true"
- sortBy="#{patient.lastName}" filterBy="#{patient.lastName}"
- filterEvent="onkeyup">
- <f:facet name="header">
- <h:outputText value="#{msg['patient.lastName']}" />
- </f:facet>
- <h:outputText value="#{patient.lastName}" />
- </rich:column>
- <rich:column id="admissionDate" headerClass="dataTableHeader"
- width="50%" label="#{msg['patient.admissionDate']}"
- sortable="true" sortBy="#{patient.admissionDate}">
- <f:facet name="header">
- <h:outputText value="#{msg['patient.admissionDate']}" />
- </f:facet>
- <h:outputText value="#{patient.admissionDate}" />
- </rich:column>
-
- <f:facet name="footer">
- <rich:datascroller
- style="width: #{extendedDataTableControlBean.width}"
- rendered="#{extendedDataTableControlBean.paginated}"
- for="demoTable">
- </rich:datascroller>
- </f:facet>
- <a4j:support event="onselectionchange"
- action="#{extendedDataTableBean.takeSelection}"
- reRender="selectedPatients" />
- </extdt:extendedDataTable>
- </h:form>
- </rich:panel>
- <rich:panel id="rightPanel">
- <h:form>
- <h:panelGrid columns="2">
- <h:outputLabel value="#{msg['table.width']}" for="tableWidthInput" />
- <h:inputText
- id="tableWidthInput"
- value="#{extendedDataTableControlBean.width}" />
- <h:outputLabel value="#{msg['table.height']}" for="tableHeightInput" />
- <h:inputText
- id="tableHeightInput"
- value="#{extendedDataTableControlBean.height}" />
- <h:outputLabel value="#{msg['table.patientsNumber']}" for="tablePatientsNumberInput" />
- <h:inputText
- id="tablePatientsNumberInput"
- value="#{extendedDataTableBean.patientsNumber}" />
- <h:outputLabel value="#{msg['table.enableContextMenu']}" for="tableEnableContextMenu" />
- <h:selectBooleanCheckbox
- id="tableEnableContextMenu"
- value="#{extendedDataTableControlBean.contextMenuEnabled}" />
- <h:outputLabel value="#{msg['table.sortMode']}" for="tableSortModeSelect" />
- <h:selectOneMenu
- id="tableSortModeSelect"
- value="#{extendedDataTableControlBean.sortMode}"
- >
- <f:selectItems value="#{extendedDataTableControlBean.sortModeSelectItems}"/>
- </h:selectOneMenu>
- <h:outputLabel value="#{msg['table.selectionMode']}" for="tableSelectionModeSelect" />
- <h:selectOneMenu
- id="tableSelectionModeSelect"
- value="#{extendedDataTableControlBean.selectionMode}"
- >
- <f:selectItems value="#{extendedDataTableControlBean.selectionModeSelectItems}"/>
- </h:selectOneMenu>
- <h:outputLabel value="#{msg['table.paginated']}" for="paginatedCheckbox" />
- <h:selectBooleanCheckbox
- id="paginatedCheckbox"
- value="#{extendedDataTableControlBean.paginated}" />
- <h:outputLabel value="#{msg['table.rowsNumber']}" for="tableRowsNumberInput" />
- <h:inputText
- id="tableRowsNumberInput"
- value="#{extendedDataTableControlBean.rowsNumber}" />
- </h:panelGrid>
- <a4j:commandButton value="#{msg['table.update']}" reRender="mainPanel">
- </a4j:commandButton>
- <a4j:commandButton value="#{msg['table.testComponentState']}"
- action="stateTest"
- >
- </a4j:commandButton>
- <rich:spacer height="5px" width="100%">
- </rich:spacer>
- <rich:dataTable id="selectedPatients" value="#{extendedDataTableBean.selectedItems}" var="selectedPatient">
- <f:facet name="header">
- <h:outputText value="#{msg['table.selectedPatients']}" />
- </f:facet>
- <rich:column id="selectedFirstName"
- headerClass="dataTableHeader"
- label="#{msg['patient.firstName']}">
- <f:facet name="header">
- <h:outputText value="#{msg['patient.firstName']}" />
- </f:facet>
- <h:outputText value="#{selectedPatient.firstName}" />
- </rich:column>
- <rich:column id="selectedLastName"
- headerClass="dataTableHeader"
- label="#{msg['patient.lastName']}">
- <f:facet name="header">
- <h:outputText value="#{msg['patient.lastName']}" />
- </f:facet>
- <h:outputText value="#{selectedPatient.lastName}" />
- </rich:column>
- </rich:dataTable>
- <rich:messages>
- </rich:messages>
- </h:form>
- </rich:panel>
- </h:panelGrid>
-</body>
-</html>
-</f:view>
\ No newline at end of file
Added: trunk/samples/extendedDataTable-sample/src/main/webapp/pages/index.xhtml
===================================================================
--- trunk/samples/extendedDataTable-sample/src/main/webapp/pages/index.xhtml (rev 0)
+++ trunk/samples/extendedDataTable-sample/src/main/webapp/pages/index.xhtml 2009-04-25 10:41:47 UTC (rev 13850)
@@ -0,0 +1,199 @@
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:rich="http://richfaces.org/rich"
+ xmlns:extdt="http://labs.jboss.com/jbossrichfaces/ui/extendedDataTable"
+ xmlns:a4j="http://richfaces.org/a4j">
+
+<head>
+<title><h:outputText value="#{msg['demo.title']}">
+</h:outputText></title>
+<style type="text/css">
+.leftColumn {
+ width: 50%;
+ height: 100%;
+}
+
+.rightColumn {
+ width: 50%;
+ height: 100%;
+}
+
+#mainPanel {
+ width: 100%;
+ height: 100%;
+}
+
+#leftPanel {
+ width: 100%;
+ height: 100%;
+}
+
+#rightPanel {
+ width: 100%;
+ height: 100%;
+}
+</style>
+</head>
+<body>
+<f:view>
+ <table style="width: 100%;">
+ <tr>
+ <td />
+ <td />
+ </tr>
+ <tr style="width: 100%;">
+ <td class="leftColumn"><rich:panel id="leftPanel">
+ <h:form id="form1">
+ <extdt:extendedDataTable id="demoTable"
+ value="#{extendedDataTableBean.dataModel}" var="patient"
+ style="margin: 0 auto;"
+ rows="#{extendedDataTableControlBean.rowsNumber}"
+ width="#{extendedDataTableControlBean.width}"
+ height="#{extendedDataTableControlBean.height}"
+ selectedClass="dataTableSelectedRow" footerClass="demo-footer"
+ sortMode="#{extendedDataTableControlBean.sortMode}"
+ selectionMode="#{extendedDataTableControlBean.selectionMode}"
+ selection="#{extendedDataTableBean.selection}" rowKeyVar="rkvar"
+ enableContextMenu="#{extendedDataTableControlBean.contextMenuEnabled}"
+ tableState="#{extendedDataTableBean.tableState}">
+ <rich:column id="firstName" headerClass="dataTableHeader"
+ width="25%" label="#{msg['patient.firstName']}" sortable="true"
+ sortBy="#{patient.firstName}" filterBy="#{patient.firstName}"
+ filterEvent="onkeyup">
+ <f:facet name="header">
+ <h:outputText value="#{msg['patient.firstName']}" />
+ </f:facet>
+ <h:outputText id="text" value="#{patient.firstName}">
+ <rich:toolTip for="text">
+ <h:outputText value="sasasasasasa" />
+ </rich:toolTip>
+ </h:outputText>
+ </rich:column>
+ <rich:column id="lastName" headerClass="dataTableHeader"
+ width="25%" label="#{msg['patient.lastName']}" sortable="true"
+ sortBy="#{patient.lastName}" filterBy="#{patient.lastName}"
+ filterEvent="onkeyup">
+ <f:facet name="header">
+ <h:outputText value="#{msg['patient.lastName']}" />
+ </f:facet>
+ <h:outputText value="#{patient.lastName}" />
+ </rich:column>
+ <rich:column id="admissionDate" headerClass="dataTableHeader"
+ width="50%" label="#{msg['patient.admissionDate']}"
+ sortable="true" sortBy="#{patient.admissionDate}">
+ <f:facet name="header">
+ <h:outputText value="#{msg['patient.admissionDate']}" />
+ </f:facet>
+ <h:outputText value="#{patient.admissionDate}" />
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:datascroller
+ style="width: #{extendedDataTableControlBean.width}"
+ rendered="#{extendedDataTableControlBean.paginated}"
+ for="demoTable">
+ </rich:datascroller>
+ </f:facet>
+ <a4j:support event="onselectionchange"
+ action="#{extendedDataTableBean.takeSelection}"
+ reRender="selectedPatients" />
+ </extdt:extendedDataTable>
+ </h:form>
+ </rich:panel></td>
+ <td class="rightColumn"><rich:panel id="rightPanel">
+ <rich:tabPanel switchType="ajax">
+ <rich:tab label="#{msg['component.test']}">
+ <h:form id="componentTestForm">
+ <h:panelGrid columns="2">
+ <h:outputLabel value="#{msg['table.width']}"
+ for="tableWidthInput" />
+ <h:inputText id="tableWidthInput"
+ value="#{extendedDataTableControlBean.width}" />
+ <h:outputLabel value="#{msg['table.height']}"
+ for="tableHeightInput" />
+ <h:inputText id="tableHeightInput"
+ value="#{extendedDataTableControlBean.height}" />
+ <h:outputLabel value="#{msg['table.patientsNumber']}"
+ for="tablePatientsNumberInput" />
+ <h:inputText id="tablePatientsNumberInput"
+ value="#{extendedDataTableBean.patientsNumber}" />
+ <h:outputLabel value="#{msg['table.enableContextMenu']}"
+ for="tableEnableContextMenu" />
+ <h:selectBooleanCheckbox id="tableEnableContextMenu"
+ value="#{extendedDataTableControlBean.contextMenuEnabled}" />
+ <h:outputLabel value="#{msg['table.sortMode']}"
+ for="tableSortModeSelect" />
+ <h:selectOneMenu id="tableSortModeSelect"
+ value="#{extendedDataTableControlBean.sortMode}">
+ <f:selectItems
+ value="#{extendedDataTableControlBean.sortModeSelectItems}" />
+ </h:selectOneMenu>
+ <h:outputLabel value="#{msg['table.selectionMode']}"
+ for="tableSelectionModeSelect" />
+ <h:selectOneMenu id="tableSelectionModeSelect"
+ value="#{extendedDataTableControlBean.selectionMode}">
+ <f:selectItems
+ value="#{extendedDataTableControlBean.selectionModeSelectItems}" />
+ </h:selectOneMenu>
+ <h:outputLabel value="#{msg['table.paginated']}"
+ for="paginatedCheckbox" />
+ <h:selectBooleanCheckbox id="paginatedCheckbox"
+ value="#{extendedDataTableControlBean.paginated}" />
+ <h:outputLabel value="#{msg['table.rowsNumber']}"
+ for="tableRowsNumberInput" />
+ <h:inputText id="tableRowsNumberInput"
+ value="#{extendedDataTableControlBean.rowsNumber}" />
+ </h:panelGrid>
+ <a4j:commandButton value="#{msg['table.update']}"
+ reRender="demoTable">
+ </a4j:commandButton>
+ <a4j:commandButton value="#{msg['table.testComponentState']}"
+ action="stateTest">
+ </a4j:commandButton>
+ <rich:spacer height="5px" width="100%">
+ </rich:spacer>
+ <rich:dataTable id="selectedPatients"
+ value="#{extendedDataTableBean.selectedItems}"
+ var="selectedPatient">
+ <f:facet name="header">
+ <h:outputText value="#{msg['table.selectedPatients']}" />
+ </f:facet>
+ <rich:column id="selectedFirstName"
+ headerClass="dataTableHeader"
+ label="#{msg['patient.firstName']}">
+ <f:facet name="header">
+ <h:outputText value="#{msg['patient.firstName']}" />
+ </f:facet>
+ <h:outputText value="#{selectedPatient.firstName}" />
+ </rich:column>
+ <rich:column id="selectedLastName" headerClass="dataTableHeader"
+ label="#{msg['patient.lastName']}">
+ <f:facet name="header">
+ <h:outputText value="#{msg['patient.lastName']}" />
+ </f:facet>
+ <h:outputText value="#{selectedPatient.lastName}" />
+ </rich:column>
+ </rich:dataTable>
+ </h:form>
+ </rich:tab>
+ <rich:tab label="#{msg['dataModel.test']}">
+ <h:form id="dataModelTestForm">
+ <a4j:commandButton value="#{msg['table.serializeDataModel']}"
+ actionListener="#{extendedDataTableBean.serializeModel}" />
+ <a4j:commandButton value="#{msg['table.deserializeDataModel']}"
+ reRender="demoTable"
+ actionListener="#{extendedDataTableBean.deserializeModel}" />
+ </h:form>
+ </rich:tab>
+ </rich:tabPanel>
+ <rich:messages>
+ </rich:messages>
+ </rich:panel></td>
+ </tr>
+ </table>
+</f:view>
+</body>
+</html>
\ No newline at end of file
Deleted: trunk/samples/extendedDataTable-sample/src/main/webapp/pages/stateTestPage.jsp
===================================================================
--- trunk/samples/extendedDataTable-sample/src/main/webapp/pages/stateTestPage.jsp 2009-04-25 10:32:22 UTC (rev 13849)
+++ trunk/samples/extendedDataTable-sample/src/main/webapp/pages/stateTestPage.jsp 2009-04-25 10:41:47 UTC (rev 13850)
@@ -1,24 +0,0 @@
-<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
-<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
-<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j" %>
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<f:view>
- <html>
- <head>
- <title>
- <h:outputText value="#{msg['demo.testPageTitle']}">
- </h:outputText>
- </title>
-
- </head>
-
-<body>
- <h:form>
- <a4j:commandButton value="#{msg['table.back']}"
- action="index"
- >
- </a4j:commandButton>
- </h:form>
-</body>
-</html>
-</f:view>
\ No newline at end of file
Copied: trunk/samples/extendedDataTable-sample/src/main/webapp/pages/stateTestPage.xhtml (from rev 13415, trunk/samples/extendedDataTable-sample/src/main/webapp/pages/stateTestPage.jsp)
===================================================================
--- trunk/samples/extendedDataTable-sample/src/main/webapp/pages/stateTestPage.xhtml (rev 0)
+++ trunk/samples/extendedDataTable-sample/src/main/webapp/pages/stateTestPage.xhtml 2009-04-25 10:41:47 UTC (rev 13850)
@@ -0,0 +1,23 @@
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:rich="http://richfaces.org/rich"
+ xmlns:extdt="http://labs.jboss.com/jbossrichfaces/ui/extendedDataTable"
+ xmlns:a4j="http://richfaces.org/a4j">
+
+<head>
+<title><h:outputText value="#{msg['demo.title']}">
+</h:outputText></title>
+
+</head>
+<body>
+<f:view>
+ <h:form>
+ <a4j:commandButton value="#{msg['table.back']}" action="index">
+ </a4j:commandButton>
+ </h:form>
+</f:view>
+</body>
+</html>
\ No newline at end of file
Property changes on: trunk/samples/extendedDataTable-sample/src/main/webapp/pages/stateTestPage.xhtml
___________________________________________________________________
Name: svn:mergeinfo
+
17 years
JBoss Rich Faces SVN: r13849 - trunk/framework/impl/src/main/java/org/richfaces/model.
by richfaces-svn-commits@lists.jboss.org
Author: pkawiak
Date: 2009-04-25 06:32:22 -0400 (Sat, 25 Apr 2009)
New Revision: 13849
Modified:
trunk/framework/impl/src/main/java/org/richfaces/model/ExtendedTableDataModel.java
Log:
RF-6151: extendedTableDataModel now implements Serializable interface
Modified: trunk/framework/impl/src/main/java/org/richfaces/model/ExtendedTableDataModel.java
===================================================================
--- trunk/framework/impl/src/main/java/org/richfaces/model/ExtendedTableDataModel.java 2009-04-25 08:03:04 UTC (rev 13848)
+++ trunk/framework/impl/src/main/java/org/richfaces/model/ExtendedTableDataModel.java 2009-04-25 10:32:22 UTC (rev 13849)
@@ -22,6 +22,7 @@
package org.richfaces.model;
import java.io.IOException;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -45,7 +46,7 @@
* @author pawelgo
*
*/
-public class ExtendedTableDataModel<T> extends ExtendedDataModel {
+public class ExtendedTableDataModel<T> extends ExtendedDataModel implements Serializable{
private static final long serialVersionUID = 7374505108088114161L;
17 years
JBoss Rich Faces SVN: r13848 - trunk/docs/userguide/en/src/main/docbook/included.
by richfaces-svn-commits@lists.jboss.org
Author: ochikvina
Date: 2009-04-25 04:03:04 -0400 (Sat, 25 Apr 2009)
New Revision: 13848
Modified:
trunk/docs/userguide/en/src/main/docbook/included/treeNode.xml
Log:
https://jira.jboss.org/jira/browse/RF-6720 - adding 'rich-tree-node-handle' CSS class;
Modified: trunk/docs/userguide/en/src/main/docbook/included/treeNode.xml
===================================================================
--- trunk/docs/userguide/en/src/main/docbook/included/treeNode.xml 2009-04-25 08:01:25 UTC (rev 13847)
+++ trunk/docs/userguide/en/src/main/docbook/included/treeNode.xml 2009-04-25 08:03:04 UTC (rev 13848)
@@ -321,12 +321,17 @@
<tbody>
<row>
<entry>rich-tree-node</entry>
- <entry> Defines styles for a tree node</entry>
+ <entry>Defines styles for a tree node</entry>
</row>
+
+ <row>
+ <entry>rich-tree-node-handle</entry>
+ <entry>Defines styles for a tree node handle</entry>
+ </row>
<row>
<entry>rich-tree-node-handleicon</entry>
- <entry>Defines styles for a tree node handleicon</entry>
+ <entry>Defines styles for a tree node handle icon</entry>
</row>
<row>
17 years
JBoss Rich Faces SVN: r13846 - in trunk/docs/userguide/en/src/main/docbook: modules and 1 other directory.
by richfaces-svn-commits@lists.jboss.org
Author: smukhina
Date: 2009-04-24 19:03:55 -0400 (Fri, 24 Apr 2009)
New Revision: 13846
Modified:
trunk/docs/userguide/en/src/main/docbook/included/dataTable.xml
trunk/docs/userguide/en/src/main/docbook/included/scrollableDataTable.xml
trunk/docs/userguide/en/src/main/docbook/modules/RFCGettingStarted.xml
Log:
https://jira.jboss.org/jira/browse/RF-4616
All Cookbook articles are looked through, links are created to them from dev guide where it's necessary
syntax of scrollableDataTable.xml is fixed
Modified: trunk/docs/userguide/en/src/main/docbook/included/dataTable.xml
===================================================================
--- trunk/docs/userguide/en/src/main/docbook/included/dataTable.xml 2009-04-24 19:25:07 UTC (rev 13845)
+++ trunk/docs/userguide/en/src/main/docbook/included/dataTable.xml 2009-04-24 23:03:55 UTC (rev 13846)
@@ -572,5 +572,8 @@
</emphasis> in a context of Extended Data Model see on the <ulink
url="http://www.jboss.com/index.html?module=bb&op=viewtopic&t=115636"
>RichFaces Users Forum</ulink>.</para>
+
+ <para>From <ulink url="http://www.jboss.org/community/docs/DOC-11861">"rich:dataTable border to 0px "</ulink> article you'll figure out how to set rich:dataTable border to 0px </para>
+ <para><ulink url="http://www.jboss.org/community/docs/DOC-11860">dataTable Background Out </ulink> tells you how to remove rich:dataTable header background</para>
</section>
</section>
Modified: trunk/docs/userguide/en/src/main/docbook/included/scrollableDataTable.xml
===================================================================
--- trunk/docs/userguide/en/src/main/docbook/included/scrollableDataTable.xml 2009-04-24 19:25:07 UTC (rev 13845)
+++ trunk/docs/userguide/en/src/main/docbook/included/scrollableDataTable.xml 2009-04-24 23:03:55 UTC (rev 13846)
@@ -90,7 +90,7 @@
<para> It's possible to select the whole row with onclick on the row or
some set of rows. Selection is optional and availability of such
feature is defined on the component. There are two ways to select a
- few rows: <itemizedlist>
+ few rows: </para> <itemizedlist>
<listitem>
<para>Just clicking the columns one by one.</para>
</listitem>
@@ -101,16 +101,17 @@
be selected.</para>
</listitem>
</itemizedlist>
- </para>
+
<para> The columns provides the possibility of expanding/collapsing on the
- client side through the next JS API: <itemizedlist>
+ client side through the next JS API:</para> <itemizedlist>
<listitem>
<para><code>collapse(columnId)</code> - Performs
the collapse action for the column with
the corresponding id</para>
</listitem>
- </itemizedlist> It's possible to sort the table content after
+ </itemizedlist>
+ <para> It's possible to sort the table content after
clicks on the header. The feature is optional. Every column should be
pointed to the comparator method that is used for sorting the table.
In case the <emphasis role="bold">
@@ -150,7 +151,7 @@
<para>This attribute is a reference to object to the instance of
<ulink url="http://www.jboss.org/file-access/default/members/jbossrichfaces/freezone/..."> <code>org.richfaces.model.selection.Selection</code></ulink>.
- interface</para>
+ interface
interface, containing current collection of objects selected by you.</para>
@@ -230,7 +231,7 @@
<para> The <emphasis role="bold">
<property><rich:scrollableDataTable></property>
</emphasis> component has the following extra attributes for event
- processing on the client: <itemizedlist>
+ processing on the client:</para> <itemizedlist>
<listitem>
<para>
<emphasis>
@@ -274,7 +275,7 @@
</para>
</listitem>
</itemizedlist>
- </para>
+
<para>Information about sorting and filtering you can find in RichFaces Developer guide section about<link linkend="sort"
>sorting</link>.</para>
<para> Information about the <emphasis>
@@ -284,7 +285,7 @@
<note>
<title>Note:</title>
<para>
- If you want to use specific features such as pagination on database level you should pass to the
+ If you want to use specific features such as pagination on database level you should pass to the
<emphasis><property>"value"</property></emphasis> of the
<emphasis role="bold"><property><rich:scrollableDataTable></property></emphasis> component
an object which class extends <code>org.richfaces.model.ScrollableTableDataModel</code>.
@@ -787,6 +788,9 @@
>On the component LiveDemo page</ulink> you can see the example of <emphasis
role="bold">
<property><rich:scrollableDataTable></property>
- </emphasis> usage. </para>
+ </emphasis> usage. </para>
+ <para>Cookbook article <ulink url="http://www.jboss.org/community/docs/DOC-11857">
+ Scrollable dataTable Selection Usage
+ </ulink> provides a simple example of how you can use the "selection" attribute in order to get row selection in rich:scrollableDataTable. </para>
</section>
</section>
Modified: trunk/docs/userguide/en/src/main/docbook/modules/RFCGettingStarted.xml
===================================================================
--- trunk/docs/userguide/en/src/main/docbook/modules/RFCGettingStarted.xml 2009-04-24 19:25:07 UTC (rev 13845)
+++ trunk/docs/userguide/en/src/main/docbook/modules/RFCGettingStarted.xml 2009-04-24 23:03:55 UTC (rev 13846)
@@ -535,11 +535,21 @@
"<ulink url="http://docs.jboss.org/tools/movies/demos/rich_faces_demo/rich_faces_demo.htm">How to Configure Maven for RichFaces</ulink>" article shortly discusses Maven configuration for RichFaces.
</para>
</listitem>
+ <listitem>
+ <para>
+ "<ulink url="http://www.jboss.org/community/docs/DOC-13446">
+ RichFaces Release Procedure
+ </ulink>" article describes how RichFaces release builds are made.
+ </para>
+ </listitem>
+
</itemizedlist>
<para>Read also the <ulink url="http://mkblog.exadel.com/?p=110">quick overview</ulink> to "Practical RichFaces " book by Max Katz at his blog.</para>
+
+
</section>
</chapter>
17 years
JBoss Rich Faces SVN: r13845 - trunk/framework/impl/src/main/javascript/ajaxjsf.
by richfaces-svn-commits@lists.jboss.org
Author: nbelaevski
Date: 2009-04-24 15:25:07 -0400 (Fri, 24 Apr 2009)
New Revision: 13845
Modified:
trunk/framework/impl/src/main/javascript/ajaxjsf/JSFAJAX.js
Log:
https://jira.jboss.org/jira/browse/RF-6929
Modified: trunk/framework/impl/src/main/javascript/ajaxjsf/JSFAJAX.js
===================================================================
--- trunk/framework/impl/src/main/javascript/ajaxjsf/JSFAJAX.js 2009-04-24 19:00:59 UTC (rev 13844)
+++ trunk/framework/impl/src/main/javascript/ajaxjsf/JSFAJAX.js 2009-04-24 19:25:07 UTC (rev 13845)
@@ -1721,7 +1721,7 @@
var xmlString = "<html xmlns='http://www.w3.org/1999/xhtml'><sc"+"ript>A4J.AJAX._scriptEvaluated=true;</scr"+"ipt></html>";
oDomDoc = (new DOMParser()).parseFromString(xmlString, "text/xml");
var _script=oDomDoc.getElementsByTagName("script")[0];
- if(!window.opera && _span.outerHTML){
+ if (!window.opera && !A4J.AJAX.isWebkitBreakingAmps() && _span.outerHTML) {
_span.outerHTML = new XMLSerializer().serializeToString(_script);
} else {
var importednode ;
17 years