Commit 1a44c66c22a60d980c0d30f3156c2c48f633ff09

Authored by bernard
1 parent a7422da3

Restructuring repo to match branches/tags/trunk.

Showing 60 changed files with 4782 additions and 0 deletions

Too many changes to show.

To preserve performance only 60 of 60+ files are displayed.

  1 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  3 + <modelVersion>4.0.0</modelVersion>
  4 + <parent>
  5 + <groupId>org.richfaces.sandbox</groupId>
  6 + <artifactId>ui</artifactId>
  7 + <version>3.3.4-SNAPSHOT</version>
  8 + </parent>
  9 + <groupId>org.richfaces.sandbox.ui</groupId>
  10 + <artifactId>richfaces-assembly</artifactId>
  11 + <name>assembly</name>
  12 + <packaging>jar</packaging>
  13 +
  14 + <build>
  15 + <plugins>
  16 + <plugin>
  17 + <groupId>org.richfaces.cdk</groupId>
  18 + <artifactId>maven-cdk-plugin</artifactId>
  19 + <version>3.3.4-SNAPSHOT</version>
  20 + <configuration>
  21 + <library>
  22 + <prefix>org.richfaces</prefix>
  23 + <description>RichFaces Sandbox Components</description>
  24 + <taglibs>
  25 + <taglib>
  26 + <shortName>sandbox</shortName>
  27 + <taglib>sandbox</taglib>
  28 + <uri>http://richfaces.org/sandbox</uri>
  29 + <displayName>richfaces-sandbox</displayName>
  30 + <excludeModules>assembly</excludeModules>
  31 + </taglib>
  32 + </taglibs>
  33 + </library>
  34 + <excludeXcss>**/basic.xcss, **/basic_classes.xcss, **/basic_both.xcss, **/extended.xcss, **/extended_classes.xcss, **/extended_both.xcss, **/skin*.xcss, **/tiny_mce/**, **/org/richfaces/renderkit/html/css/simple.xcss, **/org/richfaces/renderkit/html/css/violetRays.xcss</excludeXcss>
  35 + <commonStyle>org/richfaces/skin.xcss</commonStyle>
  36 + <includeProjectDependencies>true</includeProjectDependencies>
  37 + </configuration>
  38 + <executions>
  39 + <execution>
  40 + <goals>
  41 + <goal>assembly</goal>
  42 + </goals>
  43 + </execution>
  44 + </executions>
  45 + </plugin>
  46 + <plugin>
  47 + <artifactId>maven-jar-plugin</artifactId>
  48 + <version>2.3.2</version>
  49 + <configuration>
  50 + <outputDirectory>
  51 + ${project.build.directory}/dist
  52 + </outputDirectory>
  53 + </configuration>
  54 + </plugin>
  55 + </plugins>
  56 + </build>
  57 +
  58 + <dependencies />
  59 +</project>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
  3 + <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5" inherit-compiler-output="false">
  4 + <output url="file://$MODULE_DIR$/target/classes" />
  5 + <output-test url="file://$MODULE_DIR$/target/test-classes" />
  6 + <content url="file://$MODULE_DIR$">
  7 + <sourceFolder url="file://$MODULE_DIR$/target/generated-component/java" isTestSource="false" />
  8 + <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
  9 + <sourceFolder url="file://$MODULE_DIR$/src/main/resources" isTestSource="false" />
  10 + <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
  11 + <excludeFolder url="file://$MODULE_DIR$/target/classes" />
  12 + </content>
  13 + <orderEntry type="inheritedJdk" />
  14 + <orderEntry type="sourceFolder" forTests="false" />
  15 + <orderEntry type="library" name="Maven: org.richfaces.framework:richfaces-impl:3.3.3.Final" level="project" />
  16 + <orderEntry type="library" name="Maven: commons-digester:commons-digester:1.8.1" level="project" />
  17 + <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.8.0" level="project" />
  18 + <orderEntry type="library" name="Maven: org.richfaces.framework:richfaces-api:3.3.3.Final" level="project" />
  19 + <orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2" level="project" />
  20 + <orderEntry type="library" scope="PROVIDED" name="Maven: commons-logging:commons-logging:1.0.4" level="project" />
  21 + <orderEntry type="library" name="Maven: opensymphony:oscache:2.3" level="project" />
  22 + <orderEntry type="library" name="Maven: nekohtml:nekohtml:1.9.6" level="project" />
  23 + <orderEntry type="library" name="Maven: xerces:xercesImpl:2.9.1" level="project" />
  24 + <orderEntry type="library" scope="TEST" name="Maven: org.richfaces.framework:richfaces-test:3.3.3.Final" level="project" />
  25 + <orderEntry type="library" scope="TEST" name="Maven: junit:junit:3.8.1" level="project" />
  26 + <orderEntry type="library" scope="TEST" name="Maven: org.apache.shale:shale-test:1.0.4" level="project" />
  27 + <orderEntry type="library" scope="TEST" name="Maven: net.sourceforge.htmlunit:htmlunit:1.14" level="project" />
  28 + <orderEntry type="library" scope="TEST" name="Maven: jaxen:jaxen:1.1.1" level="project" />
  29 + <orderEntry type="library" scope="TEST" name="Maven: commons-lang:commons-lang:2.3" level="project" />
  30 + <orderEntry type="library" scope="TEST" name="Maven: commons-httpclient:commons-httpclient:3.1" level="project" />
  31 + <orderEntry type="library" scope="TEST" name="Maven: commons-codec:commons-codec:1.3" level="project" />
  32 + <orderEntry type="library" scope="TEST" name="Maven: rhino:js:1.6R7" level="project" />
  33 + <orderEntry type="library" scope="TEST" name="Maven: xerces:xmlParserAPIs:2.6.2" level="project" />
  34 + <orderEntry type="library" scope="TEST" name="Maven: net.sourceforge.cssparser:cssparser:0.9.4" level="project" />
  35 + <orderEntry type="library" scope="TEST" name="Maven: commons-io:commons-io:1.3.1" level="project" />
  36 + <orderEntry type="library" scope="TEST" name="Maven: org.easymock:easymock:2.2" level="project" />
  37 + <orderEntry type="library" scope="TEST" name="Maven: org.easymock:easymockclassextension:2.2.1" level="project" />
  38 + <orderEntry type="library" scope="TEST" name="Maven: cglib:cglib-nodep:2.1_3" level="project" />
  39 + <orderEntry type="library" name="Maven: com.sun.facelets:jsf-facelets:1.1.15.B1" level="project" />
  40 + <orderEntry type="library" scope="PROVIDED" name="Maven: javax.el:el-api:1.0" level="project" />
  41 + <orderEntry type="library" scope="PROVIDED" name="Maven: javax.servlet:servlet-api:2.5" level="project" />
  42 + <orderEntry type="library" scope="PROVIDED" name="Maven: javax.servlet.jsp:jsp-api:2.1" level="project" />
  43 + <orderEntry type="library" scope="PROVIDED" name="Maven: javax.servlet:jstl:1.1.2" level="project" />
  44 + <orderEntry type="library" scope="PROVIDED" name="Maven: javax.faces:jsf-api:1.2_12" level="project" />
  45 + <orderEntry type="library" scope="PROVIDED" name="Maven: javax.faces:jsf-impl:1.2_12" level="project" />
  46 + </component>
  47 +</module>
  48 +
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
  3 + xmlns="http://maven.apache.org/POM/4.0.0"
  4 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  5 + <modelVersion>4.0.0</modelVersion>
  6 + <parent>
  7 + <groupId>org.richfaces.sandbox</groupId>
  8 + <artifactId>ui</artifactId>
  9 + <version>3.3.4-SNAPSHOT</version>
  10 + </parent>
  11 + <groupId>org.richfaces.sandbox.ui</groupId>
  12 + <artifactId>coordinatesGrid-sm</artifactId>
  13 + <name>coordinatesGrid-sm</name>
  14 + <build>
  15 + <plugins>
  16 + <plugin>
  17 + <groupId>org.richfaces.cdk</groupId>
  18 + <artifactId>maven-cdk-plugin</artifactId>
  19 + <version>${project.version}</version>
  20 + <executions>
  21 + <execution>
  22 + <phase>generate-sources</phase>
  23 + <goals>
  24 + <goal>generate</goal>
  25 + </goals>
  26 + </execution>
  27 + </executions>
  28 + <configuration>
  29 + <library>
  30 + <prefix>org.richfaces.sandbox.ui</prefix>
  31 + <taglib>
  32 + <shortName>coordinatesGrid</shortName>
  33 + <uri>http://richfaces.org/coordinatesGrid</uri>
  34 + </taglib>
  35 + </library>
  36 + </configuration>
  37 + </plugin>
  38 + <plugin>
  39 + <artifactId>maven-compiler-plugin</artifactId>
  40 + <inherited>true</inherited>
  41 + <configuration>
  42 + <source>1.5</source>
  43 + <target>1.5</target>
  44 + <encoding>${project.build.sourceEncoding}</encoding>
  45 + </configuration>
  46 + </plugin>
  47 + <plugin>
  48 + <groupId>org.apache.maven.plugins</groupId>
  49 + <artifactId>maven-resources-plugin</artifactId>
  50 + <version>2.2</version>
  51 + <configuration>
  52 + <encoding>${project.build.sourceEncoding}</encoding>
  53 + </configuration>
  54 + </plugin>
  55 + </plugins>
  56 + </build>
  57 + <dependencies>
  58 + <dependency>
  59 + <groupId>org.richfaces.framework</groupId>
  60 + <artifactId>richfaces-impl</artifactId>
  61 + <version>${project.version}</version>
  62 + </dependency>
  63 + </dependencies>
  64 + <properties>
  65 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  66 + </properties>
  67 + <distributionManagement>
  68 + <snapshotRepository>
  69 + <id>bernard.labno.pl</id>
  70 + <name>MyCo Internal Repository</name>
  71 + <url>http://bernard.labno.pl/artifactory/libs-snapshot-local</url>
  72 + </snapshotRepository>
  73 + </distributionManagement>
  74 +</project>
  75 +
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE components PUBLIC "-//AJAX4JSF//CDK Generator config/EN"
  3 + "http://labs.jboss.com/jbossrichfaces/component-config.dtd"[
  4 + <!ENTITY listeners SYSTEM "listeners.ent">
  5 + ]>
  6 +
  7 +<components>
  8 + <component>
  9 + <name>org.richfaces.CoordinatesGrid</name>
  10 + <family>org.richfaces.CoordinatesGrid</family>
  11 + <classname>org.richfaces.component.html.HtmlCoordinatesGrid</classname>
  12 + <superclass>org.richfaces.component.UICoordinatesGrid</superclass>
  13 + <description>
  14 + <![CDATA[
  15 + ]]>
  16 + </description>
  17 + <renderer generate="true" override="true">
  18 + <name>org.richfaces.component.renderkit.html.CoordinatesGridRenderer</name>
  19 + <template>htmlCoordinatesGrid.jspx</template>
  20 + </renderer>
  21 + <tag>
  22 + <name>coordinatesGrid</name>
  23 + <classname>org.richfaces.taglib.CoordinatesGridTag</classname>
  24 + <superclass>
  25 + org.ajax4jsf.webapp.taglib.HtmlComponentTagBase
  26 + </superclass>
  27 + </tag>
  28 + <taghandler generate="true">
  29 + <classname>org.richfaces.taglib.CoordinatesGridTagHandler</classname>
  30 + <superclass>com.sun.facelets.tag.jsf.ComponentHandler</superclass>
  31 + </taghandler>
  32 + &ui_output_attributes;
  33 + &ajax_component_attributes;
  34 + &html_style_attributes;
  35 + <property>
  36 + <name>switchType</name>
  37 + <classname>java.lang.String</classname>
  38 + <description></description>
  39 + <defaultvalue>null</defaultvalue>
  40 + </property>
  41 + <property>
  42 + <name>widgetVar</name>
  43 + <classname>java.lang.String</classname>
  44 + <description></description>
  45 + <defaultvalue>null</defaultvalue>
  46 + </property>
  47 + <property>
  48 + <name>rows</name>
  49 + <classname>java.lang.Integer</classname>
  50 + <description></description>
  51 + <defaultvalue>null</defaultvalue>
  52 + </property>
  53 + <property>
  54 + <name>cols</name>
  55 + <classname>java.lang.Integer</classname>
  56 + <description></description>
  57 + <defaultvalue>null</defaultvalue>
  58 + </property>
  59 + <property>
  60 + <name>rowIndexVar</name>
  61 + <classname>java.lang.String</classname>
  62 + <description></description>
  63 + <defaultvalue>null</defaultvalue>
  64 + </property>
  65 + <property>
  66 + <name>colIndexVar</name>
  67 + <classname>java.lang.String</classname>
  68 + <description></description>
  69 + <defaultvalue>null</defaultvalue>
  70 + </property>
  71 + <property>
  72 + <name>rowHeaderText</name>
  73 + <classname>java.lang.String</classname>
  74 + <description></description>
  75 + <defaultvalue>null</defaultvalue>
  76 + </property>
  77 + <property>
  78 + <name>colHeaderText</name>
  79 + <classname>java.lang.String</classname>
  80 + <description></description>
  81 + <defaultvalue>null</defaultvalue>
  82 + </property>
  83 + <property>
  84 + <name>rowHeaderPosition</name>
  85 + <classname>java.lang.String</classname>
  86 + <description></description>
  87 + <defaultvalue>null</defaultvalue>
  88 + </property>
  89 + <property>
  90 + <name>colHeaderPosition</name>
  91 + <classname>java.lang.String</classname>
  92 + <description></description>
  93 + <defaultvalue>null</defaultvalue>
  94 + </property>
  95 + <property>
  96 + <name>selectable</name>
  97 + <classname>boolean</classname>
  98 + <description></description>
  99 + <defaultvalue>false</defaultvalue>
  100 + </property>
  101 + <property>
  102 + <name>onselect</name>
  103 + <classname>java.lang.String</classname>
  104 + <description>
  105 + </description>
  106 + <defaultvalue>null</defaultvalue>
  107 + </property>
  108 + <property>
  109 + <name>onbeforeselect</name>
  110 + <classname>java.lang.String</classname>
  111 + <description>
  112 + </description>
  113 + <defaultvalue>null</defaultvalue>
  114 + </property>
  115 + <property>
  116 + <name>onclick</name>
  117 + <classname>java.lang.String</classname>
  118 + <description>
  119 + </description>
  120 + <defaultvalue>null</defaultvalue>
  121 + </property>
  122 +
  123 + <property elonly="true" attachedstate="true">
  124 + <name>selectionListener</name>
  125 + <classname>javax.faces.el.MethodBinding</classname>
  126 + <methodargs>org.richfaces.component.event.CoordinatesSelectionEvent</methodargs>
  127 + </property>
  128 + </component>
  129 +</components>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE components PUBLIC "-//AJAX4JSF//CDK Generator config/EN"
  3 + "http://labs.jboss.com/jbossrichfaces/component-config.dtd">
  4 +
  5 +<components>
  6 + <component>
  7 + <name>org.richfaces.CoordinatesGridItem</name>
  8 + <family>org.richfaces.Schedule</family>
  9 + <classname>org.richfaces.component.html.HtmlCoordinatesGridItem</classname>
  10 + <superclass>org.richfaces.component.UICoordinatesGridItem</superclass>
  11 + <description>
  12 + <![CDATA[
  13 + ]]>
  14 + </description>
  15 + <tag>
  16 + <name>coordinatesGridItem</name>
  17 + <classname>org.richfaces.taglib.CoordinatesGridItemTag</classname>
  18 + <superclass>
  19 + org.ajax4jsf.webapp.taglib.HtmlComponentTagBase
  20 + </superclass>
  21 + </tag>
  22 + <!--
  23 + <taghandler>
  24 + <classname>org.ajax4jsf.tag.TestHandler</classname>
  25 + </taghandler>
  26 + -->
  27 + &ui_component_attributes;
  28 + <!--
  29 + -->
  30 + <property>
  31 + <name>styleClass</name>
  32 + <classname>java.lang.String</classname>
  33 + <description>
  34 + </description>
  35 + <defaultvalue>null</defaultvalue>
  36 + </property>
  37 +
  38 + <property>
  39 + <name>text</name>
  40 + <classname>java.lang.String</classname>
  41 + <description>
  42 + </description>
  43 + </property>
  44 + <property required="true">
  45 + <name>x</name>
  46 + <classname>int</classname>
  47 + <description>
  48 + </description>
  49 + </property>
  50 + <property required="true">
  51 + <name>y</name>
  52 + <classname>int</classname>
  53 + <description>
  54 + </description>
  55 + </property>
  56 +
  57 + </component>
  58 +</components>
  1 +<listener>
  2 + <name>selectionListener</name>
  3 + <property existintag="true" exist="true" el="true" elonly="true">
  4 + <name>binding</name>
  5 + <classname>org.richfaces.coordinatesGridSelectionListener</classname>
  6 + <description>The attribute takes a value-binding expression for a component property of
  7 + a backing bean
  8 + </description>
  9 + </property>
  10 + <listenerclass>
  11 + org.richfaces.component.event.CoordinatesSelectionListener
  12 + </listenerclass>
  13 + <componentclass>
  14 + org.richfaces.component.event.CoordinatesGridEventsProducer
  15 + </componentclass>
  16 + <eventclass>
  17 + org.richfaces.component.event.CoordinatesSelectionEvent
  18 + </eventclass>
  19 + <taghandler generate="true">
  20 + <classname>
  21 + org.richfaces.taglib.CoordinatesSelectionListenerTagHandler
  22 + </classname>
  23 + </taghandler>
  24 + <tag generate="true">
  25 + <classname>
  26 + org.richfaces.taglib.CoordinatesSelectionListenerTag
  27 + </classname>
  28 + </tag>
  29 +
  30 + <property existintag="true" exist="true" el="false">
  31 + <name>type</name>
  32 + <classname>java.lang.String</classname>
  33 + <description>The fully qualified Java class name for the listener</description>
  34 + </property>
  35 +</listener>
  1 +package org.richfaces.component;
  2 +
  3 +import org.ajax4jsf.component.AjaxActionComponent;
  4 +import org.ajax4jsf.component.AjaxComponent;
  5 +import org.ajax4jsf.context.AjaxContext;
  6 +import org.ajax4jsf.event.AjaxEvent;
  7 +import org.ajax4jsf.model.DataVisitor;
  8 +import org.ajax4jsf.model.ExtendedDataModel;
  9 +import org.ajax4jsf.renderkit.RendererUtils;
  10 +import org.richfaces.component.event.CoordinatesGridEventsProducer;
  11 +import org.richfaces.component.event.CoordinatesRefreshEvent;
  12 +import org.richfaces.component.event.CoordinatesSelectionEvent;
  13 +import org.richfaces.component.event.CoordinatesSelectionListener;
  14 +import org.richfaces.component.model.SquareRange;
  15 +
  16 +import javax.el.ELContext;
  17 +import javax.el.ValueExpression;
  18 +import javax.faces.component.UIComponent;
  19 +import javax.faces.component.UIComponentBase;
  20 +import javax.faces.context.FacesContext;
  21 +import javax.faces.el.MethodBinding;
  22 +import javax.faces.event.AbortProcessingException;
  23 +import javax.faces.event.FacesEvent;
  24 +import javax.faces.model.ArrayDataModel;
  25 +import javax.faces.model.DataModel;
  26 +import javax.faces.model.ListDataModel;
  27 +import javax.faces.model.ResultDataModel;
  28 +import javax.faces.model.ResultSetDataModel;
  29 +import javax.faces.model.ScalarDataModel;
  30 +import javax.servlet.jsp.jstl.sql.Result;
  31 +import java.io.IOException;
  32 +import java.sql.ResultSet;
  33 +import java.util.ArrayList;
  34 +import java.util.Collections;
  35 +import java.util.HashMap;
  36 +import java.util.List;
  37 +import java.util.Map;
  38 +
  39 +public abstract class UICoordinatesGrid extends UIComponentBase implements CoordinatesGridEventsProducer, AjaxComponent {
  40 +
  41 + public static final String COMPONENT_TYPE = "org.richfaces.CoordinatesGrid";
  42 + public static final String COMPONENT_FAMILY = "org.richfaces.CoordinatesGrid";
  43 + private DataModel model;
  44 +
  45 + public abstract Object getValue();
  46 +
  47 + public abstract void setValue(Object value);
  48 +
  49 + public abstract String getVar();
  50 +
  51 + public abstract void setVar(String var);
  52 +
  53 + public abstract String getRowIndexVar();
  54 +
  55 + public abstract void setRowIndexVar(String rowIndexVar);
  56 +
  57 + public abstract String getColIndexVar();
  58 +
  59 + public abstract void setColIndexVar(String var);
  60 +
  61 + public abstract String getRowHeaderText();
  62 +
  63 + public abstract void setRowHeaderText(String rowHeaderText);
  64 +
  65 + public abstract String getColHeaderText();
  66 +
  67 + public abstract void setColHeaderText(String colHeaderText);
  68 +
  69 + public abstract String getColHeaderPosition();
  70 +
  71 + public abstract void setColHeaderPosition(String colHeaderPosition);
  72 +
  73 + public abstract String getRowHeaderPosition();
  74 +
  75 + public abstract void setRowHeaderPosition(String rowHeaderPosition);
  76 +
  77 + public abstract String getSwitchType();
  78 +
  79 + public abstract void setSwitchType(String switchType);
  80 +
  81 + public abstract String getWidgetVar();
  82 +
  83 + public abstract void setWidgetVar(String widgetVar);
  84 +
  85 + public abstract String getOnclick();
  86 +
  87 + public abstract void setOnclick(String onclick);
  88 +
  89 + public abstract String getOnbeforeselect();
  90 +
  91 + public abstract void setOnbeforeselect(String onbeforeselect);
  92 +
  93 + public abstract String getOnselect();
  94 +
  95 + public abstract void setOnselect(String onselect);
  96 +
  97 + public abstract Integer getRows();
  98 +
  99 + public abstract void setRows(Integer rows);
  100 +
  101 + public abstract Integer getCols();
  102 +
  103 + public abstract void setCols(Integer cols);
  104 +
  105 + public abstract boolean isSelectable();
  106 +
  107 + public abstract void setSelectable(boolean selectable);
  108 +
  109 + public abstract MethodBinding getSelectionListener();
  110 +
  111 + public abstract void setSelectionListener(MethodBinding listener);
  112 +
  113 + @Override
  114 + public void broadcast(FacesEvent event) throws AbortProcessingException {
  115 + if (event instanceof CoordinatesSelectionEvent) {
  116 + super.broadcast(event);
  117 + new AjaxEvent(this).queue();
  118 + CoordinatesSelectionEvent selectionEvent = (CoordinatesSelectionEvent) event;
  119 + FacesContext facesContext = getFacesContext();
  120 + AjaxContext ajaxContext = AjaxContext.getCurrentInstance(facesContext);
  121 + MethodBinding expression = getSelectionListener();
  122 + if (expression != null) {
  123 + expression.invoke(facesContext, new Object[]{event});
  124 + }
  125 + try {
  126 + ajaxContext.getResponseDataMap().put("_ajax:coordinatesGridData", getData(selectionEvent.getStartX(), selectionEvent.getStartY(), selectionEvent.getEndX(), selectionEvent.getEndY(), false));
  127 + } catch (IOException ex) {
  128 + getFacesContext().getExternalContext().log("Cannot get coordinates grid data", ex);
  129 + }
  130 +
  131 + } else if (event instanceof CoordinatesRefreshEvent) {
  132 + super.broadcast(event);
  133 + new AjaxEvent(this).queue();
  134 + CoordinatesRefreshEvent refreshEvent = (CoordinatesRefreshEvent) event;
  135 + FacesContext facesContext = getFacesContext();
  136 + AjaxContext ajaxContext = AjaxContext.getCurrentInstance(facesContext);
  137 + try {
  138 + ajaxContext.getResponseDataMap().put("_ajax:coordinatesGridData", getData(refreshEvent.getStartX(), refreshEvent.getStartY(), refreshEvent.getEndX(), refreshEvent.getEndY(), true));
  139 + } catch (IOException ex) {
  140 + getFacesContext().getExternalContext().log("Cannot get coordinates grid data", ex);
  141 + }
  142 +
  143 + } else if (event instanceof AjaxEvent) {
  144 + FacesContext context = getFacesContext();
  145 + // complete re-Render fields. AjaxEvent deliver before render
  146 + // response.
  147 + AjaxContext.getCurrentInstance(context).addRegionsFromComponent(this);
  148 + // Put data for send in response
  149 + Object data = getData();
  150 + AjaxContext ajaxContext = AjaxContext.getCurrentInstance(context);
  151 + if (null != data) {
  152 + ajaxContext.setResponseData(data);
  153 + }
  154 + String focus = getFocus();
  155 + if (null != focus) {
  156 + // search for component in tree.
  157 + // XXX - use more pourful search, as in h:outputLabel
  158 + // component.
  159 + UIComponent focusComponent = RendererUtils.getInstance().
  160 + findComponentFor(this, focus);
  161 + if (null != focusComponent) {
  162 + focus = focusComponent.getClientId(context);
  163 + }
  164 + ajaxContext.getResponseDataMap().put(AjaxActionComponent.FOCUS_DATA_ID, focus);
  165 + }
  166 + ajaxContext.setOncomplete(getOncomplete());
  167 + }
  168 + }
  169 +
  170 + public void addCoordinatesSelectionListener(CoordinatesSelectionListener listener) {
  171 + addFacesListener(listener);
  172 + }
  173 +
  174 + public void removeCoordinatesSelectionListener(CoordinatesSelectionListener listener) {
  175 + removeFacesListener(listener);
  176 + }
  177 +
  178 + public CoordinatesSelectionListener[] getCoordinatesSelectionListeners() {
  179 + return (CoordinatesSelectionListener[]) getFacesListeners(CoordinatesSelectionListener.class);
  180 + }
  181 +
  182 + protected DataModel getDataModel() {
  183 + // Return any previously cached DataModel instance
  184 + if (this.model != null) {
  185 + return (model);
  186 + }
  187 +
  188 + // Synthesize a DataModel around our current value if possible
  189 + Object current = getValue();
  190 + if (current == null) {
  191 + setDataModel(new ListDataModel(Collections.EMPTY_LIST));
  192 + } else if (current instanceof DataModel) {
  193 + setDataModel((DataModel) current);
  194 + } else if (current instanceof List) {
  195 + setDataModel(new ListDataModel((List) current));
  196 + } else if (Object[].class.isAssignableFrom(current.getClass())) {
  197 + setDataModel(new ArrayDataModel((Object[]) current));
  198 + } else if (current instanceof ResultSet) {
  199 + setDataModel(new ResultSetDataModel((ResultSet) current));
  200 + } else if (current instanceof Result) {
  201 + setDataModel(new ResultDataModel((Result) current));
  202 + } else {
  203 + setDataModel(new ScalarDataModel(current));
  204 + }
  205 + return (model);
  206 +
  207 + }
  208 +
  209 + public void setDataModel(DataModel model) {
  210 + this.model = model;
  211 + }
  212 +
  213 + public Map<String, Object> getData(int startX, int startY, int endX, int endY, boolean includeHeaders) throws IOException {
  214 + Map<String, Object> responseData = new HashMap<String, Object>();
  215 + if (includeHeaders) {
  216 + responseData.put("rowHeaders", getRowHeadersData());
  217 + responseData.put("colHeaders", getColHeadersData());
  218 + }
  219 + ELContext elContext = getFacesContext().getELContext();
  220 + ValueExpression valueExpression = getFacesContext().getApplication().getExpressionFactory().createValueExpression(getFacesContext().getELContext(), "#{" + getVar() + "}", Object.class);
  221 + List<List<Object>> data = new ArrayList<List<Object>>();
  222 + responseData.put("data", data);
  223 + DataModel dataModel = getDataModel();
  224 + List<Object> elements = new ArrayList<Object>();
  225 + if (dataModel instanceof ExtendedDataModel) {
  226 + final List<Object> keys = new ArrayList<Object>();
  227 + DataVisitor visitor = new DataVisitor() {
  228 +
  229 + public void process(FacesContext context, Object rowKey, Object argument) throws IOException {
  230 + keys.add(rowKey);
  231 + }
  232 + };
  233 + ((ExtendedDataModel) dataModel).walk(getFacesContext(), visitor, new SquareRange(startX, startY, endX, endY), null);
  234 + for (Object key : keys) {
  235 + ((ExtendedDataModel) dataModel).setRowKey(key);
  236 + if (dataModel.isRowAvailable()) {
  237 + elements.add(dataModel.getRowData());
  238 + }
  239 + }
  240 + } else {
  241 + for (int i = 0; i < dataModel.getRowCount(); i++) {
  242 + dataModel.setRowIndex(i);
  243 + if (dataModel.isRowAvailable()) {
  244 + elements.add(dataModel.getRowData());
  245 + }
  246 + }
  247 + }
  248 +
  249 + for (Object element : elements) {
  250 + valueExpression.setValue(elContext, element);
  251 + List<Object> firstDataElement = new ArrayList<Object>();
  252 + for (UIComponent child : getChildren()) {
  253 + if (child instanceof UICoordinatesGridItem) {
  254 + UICoordinatesGridItem item = (UICoordinatesGridItem) child;
  255 + if (!item.isRendered()) {
  256 + continue;
  257 + }
  258 + firstDataElement.add(item.getX());
  259 + firstDataElement.add(item.getY());
  260 + String text = item.getText();
  261 + if (text == null) {
  262 + text = "";
  263 + }
  264 + firstDataElement.add(text.trim());
  265 + String styleClass = item.getStyleClass();
  266 + if (styleClass == null) {
  267 + styleClass = "";
  268 + }
  269 + firstDataElement.add(styleClass.trim());
  270 + data.add(firstDataElement);
  271 + }
  272 + }
  273 + }
  274 + valueExpression.setValue(elContext, null);
  275 + return responseData;
  276 + }
  277 +
  278 + public List<Map<String, Object>> getRowHeadersData() throws IOException {
  279 + ELContext elContext = getFacesContext().getELContext();
  280 + ValueExpression valueExpression = getFacesContext().getApplication().getExpressionFactory().createValueExpression(getFacesContext().getELContext(), "#{" + getRowIndexVar() + "}", Object.class);
  281 + List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
  282 + for (int i = 0; i < getRows(); i++) {
  283 + if (getRowIndexVar() != null) {
  284 + valueExpression.setValue(elContext, i);
  285 + }
  286 + Map<String, Object> row = new HashMap<String, Object>();
  287 + data.add(row);
  288 + row.put("text", getRowHeaderText());
  289 + }
  290 + if (getRowIndexVar() != null) {
  291 + valueExpression.setValue(elContext, null);
  292 + }
  293 + return data;
  294 + }
  295 +
  296 + public List<Map<String, Object>> getColHeadersData() throws IOException {
  297 + ELContext elContext = getFacesContext().getELContext();
  298 + ValueExpression valueExpression = getFacesContext().getApplication().getExpressionFactory().createValueExpression(getFacesContext().getELContext(), "#{" + getColIndexVar() + "}", Object.class);
  299 + List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
  300 + for (int i = 0; i < getCols(); i++) {
  301 + if (getColIndexVar() != null) {
  302 + valueExpression.setValue(elContext, i);
  303 + }
  304 + Map<String, Object> col = new HashMap<String, Object>();
  305 + data.add(col);
  306 + col.put("text", getColHeaderText());
  307 + }
  308 + if (getColIndexVar() != null) {
  309 + valueExpression.setValue(elContext, null);
  310 + }
  311 + return data;
  312 + }
  313 +}
  1 +package org.richfaces.component;
  2 +
  3 +import javax.faces.component.UIComponentBase;
  4 +
  5 +public abstract class UICoordinatesGridItem extends UIComponentBase {
  6 +
  7 + public static final String COMPONENT_TYPE = "org.richfaces.CoordinatesGridItem";
  8 + public static final String COMPONENT_FAMILY = "org.richfaces.CoordinatesGrid";
  9 +
  10 + public abstract String getStyleClass();
  11 +
  12 + public abstract void setStyleClass(String styleClass);
  13 +
  14 + public abstract String getText();
  15 +
  16 + public abstract void setText(String text);
  17 +
  18 + public abstract int getX();
  19 +
  20 + public abstract void setX(int x);
  21 +
  22 + public abstract int getY();
  23 +
  24 + public abstract void setY(int y);
  25 +}
  1 +package org.richfaces.component.event;
  2 +
  3 +public interface CoordinatesGridEventsProducer {
  4 +
  5 + void addCoordinatesSelectionListener(CoordinatesSelectionListener listener);
  6 +
  7 + void removeCoordinatesSelectionListener(CoordinatesSelectionListener listener);
  8 +
  9 + CoordinatesSelectionListener[] getCoordinatesSelectionListeners();
  10 +}
  1 +package org.richfaces.component.event;
  2 +
  3 +import javax.faces.component.UIComponent;
  4 +import javax.faces.event.FacesEvent;
  5 +import javax.faces.event.FacesListener;
  6 +
  7 +/**
  8 + * Created by IntelliJ IDEA.
  9 + * User: bernard
  10 + * Date: Oct 18, 2010
  11 + * Time: 6:55:06 PM
  12 + */
  13 +public class CoordinatesRefreshEvent extends FacesEvent {
  14 +
  15 + private int startX;
  16 + private int startY;
  17 + private int endX;
  18 + private int endY;
  19 +
  20 + public CoordinatesRefreshEvent(int startX, int startY, int endX, int endY, UIComponent component) {
  21 + super(component);
  22 + this.startX = startX;
  23 + this.startY = startY;
  24 + this.endX = endX;
  25 + this.endY = endY;
  26 + }
  27 +
  28 + @Override
  29 + public boolean isAppropriateListener(FacesListener listener) {
  30 + return false;
  31 + }
  32 +
  33 + @Override
  34 + public void processListener(FacesListener listener) {
  35 + throw new UnsupportedOperationException();
  36 + }
  37 +
  38 + public int getStartX() {
  39 + return startX;
  40 + }
  41 +
  42 + public int getStartY() {
  43 + return startY;
  44 + }
  45 +
  46 + public int getEndX() {
  47 + return endX;
  48 + }
  49 +
  50 + public int getEndY() {
  51 + return endY;
  52 + }
  53 +
  54 + @Override
  55 + public String toString() {
  56 + return "CoordinatesRefreshEvent{" +
  57 + "startX=" + startX +
  58 + ", startY=" + startY +
  59 + ", endX=" + endX +
  60 + ", endY=" + endY +
  61 + '}';
  62 + }
  63 +}
  1 +package org.richfaces.component.event;
  2 +
  3 +import javax.faces.component.UIComponent;
  4 +import javax.faces.event.FacesEvent;
  5 +import javax.faces.event.FacesListener;
  6 +
  7 +/**
  8 + * Created by IntelliJ IDEA.
  9 + * User: bernard
  10 + * Date: Aug 17, 2010
  11 + * Time: 2:59:13 PM
  12 + */
  13 +public class CoordinatesSelectionEvent extends FacesEvent {
  14 +
  15 + private int startX;
  16 + private int startY;
  17 + private int endX;
  18 + private int endY;
  19 +
  20 + public CoordinatesSelectionEvent(int startX, int startY, int endX, int endY, UIComponent component) {
  21 + super(component);
  22 + this.startX = startX;
  23 + this.startY = startY;
  24 + this.endX = endX;
  25 + this.endY = endY;
  26 + }
  27 +
  28 + @Override
  29 + public boolean isAppropriateListener(FacesListener listener) {
  30 + return listener instanceof CoordinatesSelectionListener;
  31 + }
  32 +
  33 + @Override
  34 + public void processListener(FacesListener listener) {
  35 + ((CoordinatesSelectionListener) listener).coordinatesSelected(this);
  36 + }
  37 +
  38 + public int getStartX() {
  39 + return startX;
  40 + }
  41 +
  42 + public int getStartY() {
  43 + return startY;
  44 + }
  45 +
  46 + public int getEndX() {
  47 + return endX;
  48 + }
  49 +
  50 + public int getEndY() {
  51 + return endY;
  52 + }
  53 +
  54 + @Override
  55 + public String toString() {
  56 + return "CoordinatesSelectionEvent{" +
  57 + "startX=" + startX +
  58 + ", startY=" + startY +
  59 + ", endX=" + endX +
  60 + ", endY=" + endY +
  61 + '}';
  62 + }
  63 +}
  1 +package org.richfaces.component.event;
  2 +
  3 +import javax.faces.event.FacesListener;
  4 +
  5 +/**
  6 + * Created by IntelliJ IDEA.
  7 + * User: bernard
  8 + * Date: Aug 17, 2010
  9 + * Time: 3:01:08 PM
  10 + */
  11 +public interface CoordinatesSelectionListener extends FacesListener {
  12 +
  13 + void coordinatesSelected(CoordinatesSelectionEvent event);
  14 +
  15 +}
  1 +package org.richfaces.component.model;
  2 +
  3 +import org.ajax4jsf.model.Range;
  4 +
  5 +public class SquareRange implements Range {
  6 +
  7 + private int startX;
  8 + private int startY;
  9 + private int endX;
  10 + private int endY;
  11 +
  12 + public SquareRange() {
  13 + }
  14 +
  15 + public SquareRange(int startX, int startY, int endX, int endY) {
  16 + this.startX = startX;
  17 + this.startY = startY;
  18 + this.endX = endX;
  19 + this.endY = endY;
  20 + }
  21 +
  22 + public int getStartX() {
  23 + return startX;
  24 + }
  25 +
  26 + public void setStartX(int startX) {
  27 + this.startX = startX;
  28 + }
  29 +
  30 + public int getStartY() {
  31 + return startY;
  32 + }
  33 +
  34 + public void setStartY(int startY) {
  35 + this.startY = startY;
  36 + }
  37 +
  38 + public int getEndX() {
  39 + return endX;
  40 + }
  41 +
  42 + public void setEndX(int endX) {
  43 + this.endX = endX;
  44 + }
  45 +
  46 + public int getEndY() {
  47 + return endY;
  48 + }
  49 +
  50 + public void setEndY(int endY) {
  51 + this.endY = endY;
  52 + }
  53 +}
  1 +package org.richfaces.renderkit.html;
  2 +
  3 +import org.ajax4jsf.javascript.JSFunction;
  4 +import org.ajax4jsf.javascript.JSFunctionDefinition;
  5 +import org.ajax4jsf.javascript.JSObject;
  6 +import org.ajax4jsf.javascript.JSReference;
  7 +import org.ajax4jsf.renderkit.AjaxRendererUtils;
  8 +import org.ajax4jsf.renderkit.HeaderResourcesRendererBase;
  9 +import org.apache.commons.logging.Log;
  10 +import org.apache.commons.logging.LogFactory;
  11 +import org.richfaces.component.UICoordinatesGrid;
  12 +import org.richfaces.component.event.CoordinatesRefreshEvent;
  13 +import org.richfaces.component.event.CoordinatesSelectionEvent;
  14 +
  15 +import javax.faces.component.NamingContainer;
  16 +import javax.faces.component.UIComponent;
  17 +import javax.faces.context.FacesContext;
  18 +import javax.faces.context.ResponseWriter;
  19 +import java.io.IOException;
  20 +import java.util.HashMap;
  21 +import java.util.Map;
  22 +
  23 +public class CoordinatesGridRendererBase extends HeaderResourcesRendererBase {
  24 +
  25 + private static Log logger = LogFactory.getLog(CoordinatesGridRendererBase.class);
  26 + private static final String EVENT_TYPE_PARAM = "eventType";
  27 + private static final String START_X_PARAM = "startX";
  28 + private static final String END_X_PARAM = "endX";
  29 + private static final String START_Y_PARAM = "startY";
  30 + private static final String END_Y_PARAM = "endY";
  31 + private static final String CALLBACK = "callback";
  32 + private static final String SELECT_EVENT = "select";
  33 + private static final String REFRESH_EVENT = "refresh";
  34 + public static final String AJAX_MODE = "ajax";
  35 + public static final String SERVER_MODE = "server";
  36 + public static final String CLIENT_MODE = "client";
  37 +
  38 + protected Class<? extends UIComponent> getComponentClass() {
  39 + return UICoordinatesGrid.class;
  40 + }
  41 +
  42 + @Override
  43 + protected void doDecode(FacesContext context, UIComponent component) {
  44 + super.doDecode(context, component);
  45 + UICoordinatesGrid uiCoordinatesGrid;
  46 +
  47 + if (component instanceof UICoordinatesGrid) {
  48 + uiCoordinatesGrid = (UICoordinatesGrid) component;
  49 + } else {
  50 + if (logger.isDebugEnabled()) {
  51 + logger.debug("No decoding necessary since the component " + component.getId() +
  52 + " is not an instance or a sub class of UIInplaceInput");
  53 + }
  54 + return;
  55 + }
  56 + String startXParam = getFieldId(context, uiCoordinatesGrid, START_X_PARAM);
  57 + String startYParam = getFieldId(context, uiCoordinatesGrid, START_Y_PARAM);
  58 + String endXParam = getFieldId(context, uiCoordinatesGrid, END_X_PARAM);
  59 + String endYParam = getFieldId(context, uiCoordinatesGrid, END_Y_PARAM);
  60 + String eventTypeParam = getFieldId(context, uiCoordinatesGrid, EVENT_TYPE_PARAM);
  61 +
  62 + Map<String, String> request = context.getExternalContext().getRequestParameterMap();
  63 +
  64 + String startXString = request.get(startXParam);
  65 + String endXString = request.get(endXParam);
  66 + String startYString = request.get(startYParam);
  67 + String endYString = request.get(endYParam);
  68 + String eventType = request.get(eventTypeParam);
  69 + if ((uiCoordinatesGrid.isSelectable() && SELECT_EVENT.equals(eventType)) || REFRESH_EVENT.equals(eventType) && startXString != null && !"".equals(startXString)) {
  70 + try {
  71 + int startX = Integer.parseInt(startXString);
  72 + int startY = Integer.parseInt(startYString);
  73 + int endX = Integer.parseInt(endXString);
  74 + int endY = Integer.parseInt(endYString);
  75 + if (SELECT_EVENT.equals(eventType)) {
  76 + new CoordinatesSelectionEvent(startX, startY, endX, endY, uiCoordinatesGrid).queue();
  77 + } else {
  78 + uiCoordinatesGrid.queueEvent(new CoordinatesRefreshEvent(startX, startY, endX, endY, uiCoordinatesGrid));
  79 + }
  80 + } catch (Exception e) {
  81 + logger.error("Problem during decoding event for component " + component.getId() + " (params: " + startXParam + "=" + startXString + ";" + startYParam + "=" + startYString + ";" + endXParam + "=" + endXString + ";" + endYParam + "=" + endYString + ")");
  82 + }
  83 + }
  84 + }
  85 +
  86 + protected String getFieldId(FacesContext context, UIComponent component, String attribute) {
  87 + return getUtils().clientId(context, component) + NamingContainer.SEPARATOR_CHAR + attribute;
  88 + }
  89 +
  90 + public void writeInitFunction(FacesContext context, UICoordinatesGrid component) throws IOException {
  91 + ResponseWriter writer = context.getResponseWriter();
  92 + if (component.getWidgetVar() != null) {
  93 + writer.write("var " + component.getWidgetVar() + "=");
  94 + }
  95 + Map<String, Object> options = new HashMap<String, Object>();
  96 + addOptionIfSet("onclick", component.getOnclick(), options);
  97 + addOptionIfSet("onbeforeselect", component.getOnbeforeselect(), options);
  98 + addOptionIfSet("onselect", component.getOnselect(), options);
  99 + addOptionIfSet("rows", component.getRows(), options);
  100 + addOptionIfSet("cols", component.getCols(), options);
  101 + addOptionIfSet("selectable", component.isSelectable(), options);
  102 + addOptionIfSet("colHeaderPosition", component.getColHeaderPosition(), options);
  103 + addOptionIfSet("rowHeaderPosition", component.getRowHeaderPosition(), options);
  104 + addOptionIfSet("data", component.getData(0, 0, component.getCols() - 1, component.getRows() - 1, true), options);
  105 +
  106 + writer.writeText(new JSObject("RichFaces.CoordinatesGrid",
  107 + component.getClientId(context),
  108 + options,
  109 + createSubmitEventFunction(context, component)).toScript(), null);
  110 + }
  111 +
  112 + protected Object createSubmitEventFunction(FacesContext context, UICoordinatesGrid component) {
  113 + JSFunction jsFunction;
  114 + Map<String, Object> params = new HashMap<String, Object>();
  115 + params.put(getFieldId(context, component, EVENT_TYPE_PARAM), new JSReference(EVENT_TYPE_PARAM));
  116 + params.put(getFieldId(context, component, START_X_PARAM), new JSReference(START_X_PARAM));
  117 + params.put(getFieldId(context, component, START_Y_PARAM), new JSReference(START_Y_PARAM));
  118 + params.put(getFieldId(context, component, END_X_PARAM), new JSReference(END_X_PARAM));
  119 + params.put(getFieldId(context, component, END_Y_PARAM), new JSReference(END_Y_PARAM));
  120 + if (isAjaxMode(component)) {
  121 + jsFunction = AjaxRendererUtils.buildAjaxFunction(component, context);
  122 + Map<String, Object> eventOptions = AjaxRendererUtils.buildEventOptions(context, component, params);
  123 + eventOptions.put("oncomplete", new JSReference(CALLBACK));
  124 + jsFunction.addParameter(eventOptions);
  125 + } else if (SERVER_MODE.equals(component.getSwitchType())) {
  126 + jsFunction = new JSFunction("Richfaces.jsFormSubmit",
  127 + component.getClientId(context),
  128 + getUtils().getNestingForm(context, component).getClientId(context),
  129 + null,
  130 + params);
  131 + } else {
  132 + return null;
  133 + }
  134 + return new JSFunctionDefinition("event", EVENT_TYPE_PARAM, START_X_PARAM, START_Y_PARAM, END_X_PARAM, END_Y_PARAM, CALLBACK).addToBody(jsFunction);
  135 + }
  136 +
  137 + private void addOptionIfSet(String optionName, Object value, Map<String, Object> options) {
  138 + if (value != null && value != "") {
  139 + options.put(optionName, value);
  140 + }
  141 + }
  142 +
  143 + private boolean isAjaxMode(UICoordinatesGrid component) {
  144 + String mode = component.getSwitchType();
  145 + return AJAX_MODE.equals(mode) || "".equals(mode) || null == mode;
  146 + }
  147 +}
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<f:template
  3 + xmlns:f="http://jsf.exadel.com/template"
  4 + xmlns:u="http://jsf.exadel.com/template/util"
  5 + xmlns="http://www.w3.org/1999/xhtml">
  6 +
  7 + <u:selector name=".rf-cg td">
  8 + <u:style name="width" value="20px"/>
  9 + <u:style name="height" value="20px"/>
  10 + <u:style name="border-width" value="1px"/>
  11 + <u:style name="border-style" value="solid"/>
  12 + <u:style name="border-color" skin="panelBorderColor"/>
  13 + </u:selector>
  14 + <u:selector name=".rf-cg td.highlight">
  15 + <u:style name="background-color" skin="headerBackgroundColor"/>
  16 + <u:style name="color" skin="headTextColor"/>
  17 + </u:selector>
  18 +</f:template>
  1 +if (window.RichFaces == null) {
  2 + window.RichFaces = {};
  3 +}
  4 +RichFaces.CoordinatesGrid = function(targetId, options, submitEventFunction) {
  5 +
  6 + var startX;
  7 + var startY;
  8 + var endX;
  9 + var endY;
  10 + var selecting = false;
  11 + this.target = document.getElementById(targetId);
  12 + var _this = this;
  13 + this.options = jQuery.extend({}, this.options, options);
  14 + if (this.target.component != null && this.target.component.destroy != null) {
  15 + this.target.component.destroy();
  16 + }
  17 + this.target.component = this;
  18 +
  19 + var getY = function(o) {
  20 + if (o == null || o.parentNode == null || o.parentNode.rowIndex == null) {
  21 + throw "HTMLTableCellElement expected";
  22 + }
  23 + return o.parentNode.rowIndex - 1;
  24 + };
  25 + var getX = function(o) {
  26 + if (o == null || o.cellIndex == null) {
  27 + throw "HTMLTableCellElement expected";
  28 + }
  29 + return o.cellIndex;
  30 + };
  31 + /**
  32 + * Updates element on the grid with data from initial or ajax request.
  33 + * @param data array of data where: 0: x, 1: y, 2: text, 3: css class
  34 + */
  35 + var updateElementFromData = function(data) {
  36 + var element = _this.getElementAt(data[0], data[1]);
  37 + if (element != null) {
  38 + _this.updateElement(element, {innerHTML:data[2],className:data[3]});
  39 + }
  40 + return element;
  41 + };
  42 + var updateRowHeaders = function(headers) {
  43 + jQuery.each(headers, function(index) {
  44 + var text = this.text;
  45 + delete this.text;
  46 + if (text != null) {
  47 + this.innerHTML = text;
  48 + }
  49 + if (_this.isLeftRowHeadersVisible()) {
  50 + _this.updateElement(_this.getElementAt(-1, index), this);
  51 + }
  52 + if (_this.isRightRowHeadersVisible()) {
  53 + _this.updateElement(_this.getElementAt(_this.options.cols, index), this);
  54 + }
  55 + });
  56 + };
  57 + var updateColHeaders = function(headers) {
  58 + jQuery.each(headers, function(index) {
  59 + var text = this.text;
  60 + delete this.text;
  61 + if (text != null) {
  62 + this.innerHTML = text;
  63 + }
  64 + if (_this.isTopColHeadersVisible()) {
  65 + _this.updateElement(_this.getElementAt(index, -1), this);
  66 + }
  67 + if (_this.isBottomColHeadersVisible()) {
  68 + _this.updateElement(_this.getElementAt(index, _this.options.rows), this);
  69 + }
  70 + });
  71 + };
  72 + var updateElementsWithRequestData = function(request, _startX, _startY, _endX, _endY) {
  73 + /** Server component should respond with data of elements matching selection */
  74 + var data = request.getJSON('_ajax:coordinatesGridData');
  75 + if (data != undefined) {
  76 + var elementsFromUpdate = [];
  77 + jQuery.each(data.data, function() {
  78 + var element = updateElementFromData(this);
  79 + if (element != null) {
  80 + elementsFromUpdate.push(element);
  81 + }
  82 + });
  83 + if (data.rowHeaders != null) {
  84 + updateRowHeaders(data.rowHeaders);
  85 + }
  86 + if (data.colHeaders != null) {
  87 + updateColHeaders(data.colHeaders);
  88 + }
  89 + jQuery.each(_this.getElements(_startX, _startY, _endX, _endY), function() {
  90 + var visitedCell = this;
  91 + var exists = false;
  92 + jQuery.each(elementsFromUpdate, function() {
  93 + if (this == visitedCell) {
  94 + exists = true;
  95 + }
  96 + });
  97 + if (!exists) {
  98 + this.className = "";
  99 + this.innerHTML = "";
  100 + }
  101 + });
  102 + }
  103 + };
  104 + var mouseDownHanlder = function() {
  105 + if (selecting) {
  106 + mouseUpHanlder.apply(this);
  107 + } else if (options.selectable) {
  108 + startX = getX(this);
  109 + startY = getY(this);
  110 + selecting = true;
  111 + }
  112 + };
  113 + var mouseUpHanlder = function() {
  114 + if (!selecting) {
  115 + return;
  116 + }
  117 + endX = getX(this);
  118 + endY = getY(this);
  119 + selecting = false;
  120 + highlightSelection();
  121 + if (_this.options.onbeforeselect != null) {
  122 + var result;
  123 + if (typeof _this.options.onbeforeselect == "function") {
  124 + result = _this.options.onbeforeselect(_this, _startX, _startY, _endX, _endY);
  125 + } else {
  126 + result = RichFaces.CoordinatesGrid.eval("(function(){" + _this.options.onbeforeselect + "})()", {
  127 + 'startX':startX,
  128 + 'startY':startY,
  129 + 'endX':endX,
  130 + 'endY':endY,
  131 + 'component':_this
  132 + });
  133 + }
  134 + if (result === false) {
  135 + return;
  136 + }
  137 + }
  138 + /**
  139 + * endX and endY will be reset before ajax response comes.
  140 + */
  141 + var _endX = endX;
  142 + var _endY = endY;
  143 + var _startX = startX;
  144 + var _startY = startY;
  145 + /** Notify server side */
  146 + if (submitEventFunction != null) {
  147 + submitEventFunction({}, "select", _this.indexToCoordX(startX), _this.indexToCoordY(startY), _this.indexToCoordX(endX), _this.indexToCoordY(endY),
  148 + function(request, event, data) {
  149 + updateElementsWithRequestData(request, _startX, _startY, _endX, _endY);
  150 +
  151 + if (_this.options.onselect != null) {
  152 + if (typeof _this.options.onselect == "function") {
  153 + _this.options.onselect(_this, _startX, _startY, _endX, _endY);
  154 + } else {
  155 + RichFaces.CoordinatesGrid.eval("(function(){" + _this.options.onselect + "})()", {
  156 + 'startX':_startX,
  157 + 'startY':_startY,
  158 + 'endX':_endX,
  159 + 'endY':_endY,
  160 + 'component':_this
  161 + });
  162 + }
  163 + }
  164 + delete _endX,_endY,_startX,_startY;
  165 + });
  166 + }
  167 + endX = -1;
  168 + endY = -1;
  169 + highlightSelection();
  170 + };
  171 + var mouseOverHandler = function() {
  172 + if (!selecting) {
  173 + return;
  174 + }
  175 + endX = getX(this);
  176 + endY = getY(this);
  177 + highlightSelection();
  178 + };
  179 + var highlightSelection = function() {
  180 + jQuery("td", _this.target).each(function() {
  181 + var x = getX(this);
  182 + var y = getY(this);
  183 + if (startX <= x && x <= endX && startY <= y && y <= endY) {
  184 + jQuery(this).addClass(_this.options.highlightClass);
  185 + } else {
  186 + jQuery(this).removeClass(_this.options.highlightClass);
  187 + }
  188 + });
  189 + };
  190 + var clickHandler = function() {
  191 + if (_this.options.onclick != null) {
  192 + if (typeof _this.options.onclick == "function") {
  193 + _this.options.onclick(_this, getX(this), getY(this));
  194 + } else {
  195 + RichFaces.CoordinatesGrid.eval("(function(){" + _this.options.onclick + "})()", {
  196 + 'x':getX(this),
  197 + 'y':getY(this),
  198 + 'component':_this
  199 + });
  200 + }
  201 + }
  202 + };
  203 + this.getElements = function(startX, startY, endX, endY) {
  204 + var elements = [];
  205 + jQuery("td", _this.target).each(function() {
  206 + var x = getX(this);
  207 + var y = getY(this);
  208 + if (startX <= x && x <= endX && startY <= y && y <= endY) {
  209 + elements.push(this);
  210 + }
  211 + });
  212 + return elements;
  213 + };
  214 + this.refresh = function(_startX, _startY, _endX, _endY) {
  215 + if (_startX == null && _startY == null && _endX == null && _endY == null) {
  216 + _startX = 0;
  217 + _startY = 0;
  218 + _endX = this.options.cols;
  219 + _endY = this.options.rows;
  220 + }
  221 + submitEventFunction({}, "refresh", _startX, _startY, _endX, _endY, function(request, event, data) {
  222 + updateElementsWithRequestData(request, _startX, _startY, _endX, _endY);
  223 + delete _endX,_endY,_startX,_startY;
  224 + });
  225 + };
  226 + /**
  227 + * @param element HTMLTableCellElement
  228 + * @param options options used to extend element, i.e. {className:'important'}
  229 + **/
  230 + this.updateElement = function(element, options) {
  231 + if (options.className) {
  232 + options.className = "rich-table-cell " + options.className;
  233 + }
  234 + jQuery.extend(element, options);
  235 + };
  236 + this.getElementAt = function(x, y) {
  237 + return table[0].rows[y + 1 + (_this.isTopColHeadersVisible() ? 1 : 0)].cells[x + (y > -1 && _this.isLeftRowHeadersVisible() ? 1 : 0)];
  238 + };
  239 + /**
  240 + * Create grid.
  241 + */
  242 + var table = jQuery("<table></table>");
  243 + (function() {
  244 + table.appendTo(_this.target);
  245 + var cell;
  246 + /**
  247 + * Function used for appending headers without filling them with text
  248 + */
  249 + var appendHeaders = function(targetElement) {
  250 + var row = jQuery("<tr class='rich-table-subheader'></tr>");
  251 + row.appendTo(targetElement);
  252 + row.addClass(_this.options.colHeaderClass);
  253 + if (_this.options.data.rowHeaders != null) {
  254 + if (targetElement[0].tagName != 'THEAD' && (_this.options.rowHeaderPosition == 'both' || _this.options.rowHeaderPosition == 'left')) {
  255 + cell = jQuery("<th class='rich-table-subheadercell'></th>");
  256 + cell.appendTo(row);
  257 + }
  258 + for (var x = 0; x < _this.options.cols; x++) {
  259 + cell = jQuery("<th class='rich-table-subheadercell'></th>");
  260 + cell.appendTo(row);
  261 + }
  262 + if (_this.options.rowHeaderPosition == 'both' || _this.options.rowHeaderPosition == 'right') {
  263 + cell = jQuery("<th class='rich-table-subheadercell'></th>");
  264 + cell.appendTo(row);
  265 + }
  266 + }
  267 + };
  268 + var thead = jQuery("<thead></thead>");
  269 + thead.appendTo(table);
  270 + /** Append custom SailMedia headers */
  271 + row = jQuery("<tr class='rich-table-subheader'></tr>");
  272 + row.appendTo(thead);
  273 + row.addClass(_this.options.colHeaderClass);
  274 + cell = jQuery("<th class='th1' rowspan='2'></th>");
  275 + cell.appendTo(row);
  276 + cell = jQuery("<th class='nav' colspan='" + _this.options.cols + "'></th>");
  277 + cell.appendTo(row);
  278 + /** Append top column headers */
  279 + if (_this.isTopColHeadersVisible()) {
  280 + appendHeaders(thead);
  281 + }
  282 + for (var y = 0; y < _this.options.rows; y++) {
  283 + var row = jQuery("<tr class='rich-table-row'></tr>");
  284 + row.appendTo(table);
  285 + /** Append left row headers */
  286 + if (_this.isLeftRowHeadersVisible()) {
  287 + cell = jQuery("<th class='rich-table-cell'></th>");
  288 + cell.appendTo(row);
  289 + cell.addClass(_this.options.rowHeaderClass);
  290 + }
  291 + /** Append regular cells */
  292 + for (var x = 0; x < _this.options.cols; x++) {
  293 + cell = jQuery("<td class='rich-table-cell'></td>");
  294 + cell.appendTo(row);
  295 + cell.mouseup(mouseUpHanlder);
  296 + cell.mousedown(mouseDownHanlder);
  297 + cell.mouseover(mouseOverHandler);
  298 + cell.click(clickHandler);
  299 + }
  300 + /** Append right row headers */
  301 + if (_this.isRightRowHeadersVisible()) {
  302 + cell = jQuery("<th class='rich-table-cell'></th>");
  303 + cell.appendTo(row);
  304 + cell.addClass(_this.options.rowHeaderClass);
  305 + }
  306 + }
  307 + var tfoot = jQuery("<tfoot></tfoot>");
  308 + tfoot.appendTo(table);
  309 + /** Append bottom column headers */
  310 + if (_this.isBottomColHeadersVisible()) {
  311 + appendHeaders(tfoot);
  312 + }
  313 + /** Append custom SailMedia footer */
  314 + row = jQuery("<tr class='rich-table-subheader'></tr>");
  315 + row.appendTo(tfoot);
  316 + row.addClass(_this.options.colHeaderClass);
  317 + cell = jQuery("<th class='ft1'></th>");
  318 + cell.appendTo(row);
  319 + cell = jQuery("<th class='nav' colspan='" + _this.options.cols + "'></th>");
  320 + cell.appendTo(row);
  321 + /** Customize headers - className and text */
  322 + updateRowHeaders(_this.options.data.rowHeaders);
  323 + updateColHeaders(_this.options.data.colHeaders);
  324 +
  325 + /** Customize regular cell */
  326 + if (_this.options.data.data != null) {
  327 + jQuery.each(_this.options.data.data, function() {
  328 + updateElementFromData(this)
  329 + });
  330 + }
  331 + /** Disable text selection */
  332 + if (options.selectable) {
  333 + table.attr('unselectable', 'on').css('MozUserSelect', 'none').bind('selectstart.ui', function() {
  334 + return false;
  335 + });
  336 + }
  337 + })();
  338 +}
  339 + ;
  340 +RichFaces.CoordinatesGrid.prototype.options = {
  341 + rows: 10,
  342 + cols: 10,
  343 + highlightClass: 'highlight',
  344 + colHeaderPosition: 'bottom',
  345 + rowHeaderPosition: 'left'
  346 +};
  347 +RichFaces.CoordinatesGrid.prototype.select = function(func) {
  348 + this.options.onselect = func;
  349 +};
  350 +RichFaces.CoordinatesGrid.prototype.destroy = function() {
  351 + jQuery("table", this.target).remove();
  352 + delete this.target.component;
  353 +};
  354 +RichFaces.CoordinatesGrid.prototype.isLeftRowHeadersVisible = function() {
  355 + return this.options.data.rowHeaders != null && (this.options.rowHeaderPosition == 'both' || this.options.rowHeaderPosition == 'left');
  356 +};
  357 +RichFaces.CoordinatesGrid.prototype.isRightRowHeadersVisible = function() {
  358 + return this.options.data.rowHeaders != null && (this.options.rowHeaderPosition == 'both' || this.options.rowHeaderPosition == 'right');
  359 +};
  360 +RichFaces.CoordinatesGrid.prototype.isTopColHeadersVisible = function() {
  361 + return this.options.data.colHeaders != null && (this.options.colHeaderPosition == 'both' || this.options.colHeaderPosition == 'top');
  362 +};
  363 +RichFaces.CoordinatesGrid.prototype.isBottomColHeadersVisible = function() {
  364 + return this.options.data.colHeaders != null && (this.options.colHeaderPosition == 'both' || this.options.colHeaderPosition == 'bottom');
  365 +};
  366 +RichFaces.CoordinatesGrid.prototype.indexToCoordX = function(index) {
  367 + return index - (this.isLeftRowHeadersVisible() ? 1 : 0);
  368 +};
  369 +RichFaces.CoordinatesGrid.prototype.indexToCoordY = function(index) {
  370 + return index - (this.isTopColHeadersVisible() ? 1 : 0);
  371 +};
  372 +/**
  373 + * This function evaluates code in template with object in ScopeChain.
  374 + * This is usefull if you need to evaluate code that uses member names
  375 + * that colide with external names that the code refers to.
  376 + * There is almost exact method in utils.js called Richfaces.eval,
  377 + * but it swallows exception thrown during evaluation, which makes debugging
  378 + * hard.
  379 + */
  380 +RichFaces.CoordinatesGrid.eval = function(template, object) {
  381 + var value = '';
  382 + with (object) {
  383 + value = eval(template);
  384 + }
  385 + return value;
  386 +};
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<f:root
  3 + xmlns:f="http://ajax4jsf.org/cdk/template"
  4 + xmlns:c="http://java.sun.com/jsf/core"
  5 + xmlns:ui="http://ajax4jsf.org/cdk/ui"
  6 + xmlns:u="http://ajax4jsf.org/cdk/u"
  7 + xmlns:x="http://ajax4jsf.org/cdk/x"
  8 + xmlns:jsp="http://ajax4jsf.org/cdk/jsp"
  9 + class="org.richfaces.renderkit.html.CoordinatesGridRenderer"
  10 + baseclass="org.richfaces.renderkit.html.CoordinatesGridRendererBase"
  11 + component="org.richfaces.component.UICoordinatesGrid"
  12 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://ajax4jsf.org/cdk/template ">
  13 +
  14 + <h:styles>/org/richfaces/renderkit/html/css/richfaces.coordinatesGrid.xcss</h:styles>
  15 + <h:scripts>
  16 + new org.ajax4jsf.javascript.PrototypeScript(),
  17 + new org.ajax4jsf.javascript.AjaxScript(),
  18 + /org/richfaces/renderkit/html/scripts/jquery/jquery.js,
  19 + /org/richfaces/renderkit/html/scripts/richfaces.coordinatesGrid.js
  20 + </h:scripts>
  21 +
  22 +
  23 + <f:clientid var="clientId"/>
  24 +
  25 + <jsp:scriptlet>
  26 + <![CDATA[
  27 + org.richfaces.component.util.FormUtil.throwEnclFormReqExceptionIfNeed(context, component);
  28 + variables.setVariable("selectableStyleClass",((Boolean)component.getAttributes().get("selectable"))?" rf-cg-se":"");
  29 + ]]>
  30 + </jsp:scriptlet>
  31 + <div id="#{clientId}" class="rf-cg#{selectableStyleClass} #{component.attributes['styleClass']}" style="#{component.attributes['style']}">
  32 + <script type="text/javascript">
  33 + <f:call name="writeInitFunction"/>
  34 + </script>
  35 + </div>
  36 +</f:root>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
  3 + xmlns="http://maven.apache.org/POM/4.0.0"
  4 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  5 + <modelVersion>4.0.0</modelVersion>
  6 + <parent>
  7 + <groupId>org.richfaces.sandbox</groupId>
  8 + <artifactId>ui</artifactId>
  9 + <version>3.3.4-SNAPSHOT</version>
  10 + </parent>
  11 + <groupId>org.richfaces.sandbox.ui</groupId>
  12 + <artifactId>coordinatesGrid</artifactId>
  13 + <name>coordinatesGrid</name>
  14 + <build>
  15 + <plugins>
  16 + <plugin>
  17 + <groupId>org.richfaces.cdk</groupId>
  18 + <artifactId>maven-cdk-plugin</artifactId>
  19 + <version>${project.version}</version>
  20 + <executions>
  21 + <execution>
  22 + <phase>generate-sources</phase>
  23 + <goals>
  24 + <goal>generate</goal>
  25 + </goals>
  26 + </execution>
  27 + </executions>
  28 + <configuration>
  29 + <library>
  30 + <prefix>org.richfaces.sandbox.ui</prefix>
  31 + <taglib>
  32 + <shortName>coordinatesGrid</shortName>
  33 + <uri>http://richfaces.org/sandbox/coordinatesGrid</uri>
  34 + </taglib>
  35 + </library>
  36 + </configuration>
  37 + </plugin>
  38 + <plugin>
  39 + <artifactId>maven-compiler-plugin</artifactId>
  40 + <inherited>true</inherited>
  41 + <configuration>
  42 + <source>1.5</source>
  43 + <target>1.5</target>
  44 + <encoding>${project.build.sourceEncoding}</encoding>
  45 + </configuration>
  46 + </plugin>
  47 + <plugin>
  48 + <groupId>org.apache.maven.plugins</groupId>
  49 + <artifactId>maven-resources-plugin</artifactId>
  50 + <version>2.2</version>
  51 + <configuration>
  52 + <encoding>${project.build.sourceEncoding}</encoding>
  53 + </configuration>
  54 + </plugin>
  55 + </plugins>
  56 + </build>
  57 + <dependencies>
  58 + <dependency>
  59 + <groupId>org.richfaces.framework</groupId>
  60 + <artifactId>richfaces-impl</artifactId>
  61 + <version>${project.version}</version>
  62 + </dependency>
  63 + </dependencies>
  64 + <properties>
  65 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  66 + </properties>
  67 + <distributionManagement>
  68 + <snapshotRepository>
  69 + <id>bernard.labno.pl</id>
  70 + <name>MyCo Internal Repository</name>
  71 + <url>http://bernard.labno.pl/artifactory/libs-snapshot-local</url>
  72 + </snapshotRepository>
  73 + </distributionManagement>
  74 +
  75 +</project>
  76 +
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE components PUBLIC "-//AJAX4JSF//CDK Generator config/EN"
  3 + "http://labs.jboss.com/jbossrichfaces/component-config.dtd"[
  4 + <!ENTITY listeners SYSTEM "listeners.ent">
  5 + ]>
  6 +
  7 +<components>
  8 + <component>
  9 + <name>org.richfaces.CoordinatesGrid</name>
  10 + <family>org.richfaces.CoordinatesGrid</family>
  11 + <classname>org.richfaces.component.html.HtmlCoordinatesGrid</classname>
  12 + <superclass>org.richfaces.component.UICoordinatesGrid</superclass>
  13 + <description>
  14 + <![CDATA[
  15 + ]]>
  16 + </description>
  17 + <renderer generate="true" override="true">
  18 + <name>org.richfaces.component.renderkit.html.CoordinatesGridRenderer</name>
  19 + <template>htmlCoordinatesGrid.jspx</template>
  20 + </renderer>
  21 + <tag>
  22 + <name>coordinatesGrid</name>
  23 + <classname>org.richfaces.taglib.CoordinatesGridTag</classname>
  24 + <superclass>
  25 + org.ajax4jsf.webapp.taglib.HtmlComponentTagBase
  26 + </superclass>
  27 + </tag>
  28 + <taghandler generate="true">
  29 + <classname>org.richfaces.taglib.CoordinatesGridTagHandler</classname>
  30 + <superclass>com.sun.facelets.tag.jsf.ComponentHandler</superclass>
  31 + </taghandler>
  32 + &ui_output_attributes;
  33 + &ajax_component_attributes;
  34 + &html_style_attributes;
  35 + <property>
  36 + <name>switchType</name>
  37 + <classname>java.lang.String</classname>
  38 + <description></description>
  39 + <defaultvalue>null</defaultvalue>
  40 + </property>
  41 + <property>
  42 + <name>widgetVar</name>
  43 + <classname>java.lang.String</classname>
  44 + <description></description>
  45 + <defaultvalue>null</defaultvalue>
  46 + </property>
  47 + <property>
  48 + <name>rows</name>
  49 + <classname>java.lang.Integer</classname>
  50 + <description></description>
  51 + <defaultvalue>null</defaultvalue>
  52 + </property>
  53 + <property>
  54 + <name>cols</name>
  55 + <classname>java.lang.Integer</classname>
  56 + <description></description>
  57 + <defaultvalue>null</defaultvalue>
  58 + </property>
  59 + <property>
  60 + <name>rowIndexVar</name>
  61 + <classname>java.lang.String</classname>
  62 + <description></description>
  63 + <defaultvalue>null</defaultvalue>
  64 + </property>
  65 + <property>
  66 + <name>colIndexVar</name>
  67 + <classname>java.lang.String</classname>
  68 + <description></description>
  69 + <defaultvalue>null</defaultvalue>
  70 + </property>
  71 + <property>
  72 + <name>rowHeaderText</name>
  73 + <classname>java.lang.String</classname>
  74 + <description></description>
  75 + <defaultvalue>null</defaultvalue>
  76 + </property>
  77 + <property>
  78 + <name>colHeaderText</name>
  79 + <classname>java.lang.String</classname>
  80 + <description></description>
  81 + <defaultvalue>null</defaultvalue>
  82 + </property>
  83 + <property>
  84 + <name>rowHeaderPosition</name>
  85 + <classname>java.lang.String</classname>
  86 + <description></description>
  87 + <defaultvalue>null</defaultvalue>
  88 + </property>
  89 + <property>
  90 + <name>colHeaderPosition</name>
  91 + <classname>java.lang.String</classname>
  92 + <description></description>
  93 + <defaultvalue>null</defaultvalue>
  94 + </property>
  95 + <property>
  96 + <name>selectable</name>
  97 + <classname>boolean</classname>
  98 + <description></description>
  99 + <defaultvalue>false</defaultvalue>
  100 + </property>
  101 + <property>
  102 + <name>onselect</name>
  103 + <classname>java.lang.String</classname>
  104 + <description>
  105 + </description>
  106 + <defaultvalue>null</defaultvalue>
  107 + </property>
  108 + <property>
  109 + <name>onbeforeselect</name>
  110 + <classname>java.lang.String</classname>
  111 + <description>
  112 + </description>
  113 + <defaultvalue>null</defaultvalue>
  114 + </property>
  115 + <property>
  116 + <name>onclick</name>
  117 + <classname>java.lang.String</classname>
  118 + <description>
  119 + </description>
  120 + <defaultvalue>null</defaultvalue>
  121 + </property>
  122 +
  123 + <property elonly="true" attachedstate="true">
  124 + <name>selectionListener</name>
  125 + <classname>javax.faces.el.MethodBinding</classname>
  126 + <methodargs>org.richfaces.component.event.CoordinatesSelectionEvent</methodargs>
  127 + </property>
  128 + </component>
  129 +</components>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE components PUBLIC "-//AJAX4JSF//CDK Generator config/EN"
  3 + "http://labs.jboss.com/jbossrichfaces/component-config.dtd">
  4 +
  5 +<components>
  6 + <component>
  7 + <name>org.richfaces.CoordinatesGridItem</name>
  8 + <family>org.richfaces.Schedule</family>
  9 + <classname>org.richfaces.component.html.HtmlCoordinatesGridItem</classname>
  10 + <superclass>org.richfaces.component.UICoordinatesGridItem</superclass>
  11 + <description>
  12 + <![CDATA[
  13 + ]]>
  14 + </description>
  15 + <tag>
  16 + <name>coordinatesGridItem</name>
  17 + <classname>org.richfaces.taglib.CoordinatesGridItemTag</classname>
  18 + <superclass>
  19 + org.ajax4jsf.webapp.taglib.HtmlComponentTagBase
  20 + </superclass>
  21 + </tag>
  22 + <!--
  23 + <taghandler>
  24 + <classname>org.ajax4jsf.tag.TestHandler</classname>
  25 + </taghandler>
  26 + -->
  27 + &ui_component_attributes;
  28 + <!--
  29 + -->
  30 + <property>
  31 + <name>styleClass</name>
  32 + <classname>java.lang.String</classname>
  33 + <description>
  34 + </description>
  35 + <defaultvalue>null</defaultvalue>
  36 + </property>
  37 +
  38 + <property>
  39 + <name>text</name>
  40 + <classname>java.lang.String</classname>
  41 + <description>
  42 + </description>
  43 + </property>
  44 + <property required="true">
  45 + <name>x</name>
  46 + <classname>int</classname>
  47 + <description>
  48 + </description>
  49 + </property>
  50 + <property required="true">
  51 + <name>y</name>
  52 + <classname>int</classname>
  53 + <description>
  54 + </description>
  55 + </property>
  56 +
  57 + </component>
  58 +</components>
  1 +<listener>
  2 + <name>selectionListener</name>
  3 + <property existintag="true" exist="true" el="true" elonly="true">
  4 + <name>binding</name>
  5 + <classname>org.richfaces.coordinatesGridSelectionListener</classname>
  6 + <description>The attribute takes a value-binding expression for a component property of
  7 + a backing bean
  8 + </description>
  9 + </property>
  10 + <listenerclass>
  11 + org.richfaces.component.event.CoordinatesSelectionListener
  12 + </listenerclass>
  13 + <componentclass>
  14 + org.richfaces.component.event.CoordinatesGridEventsProducer
  15 + </componentclass>
  16 + <eventclass>
  17 + org.richfaces.component.event.CoordinatesSelectionEvent
  18 + </eventclass>
  19 + <taghandler generate="true">
  20 + <classname>
  21 + org.richfaces.taglib.CoordinatesSelectionListenerTagHandler
  22 + </classname>
  23 + </taghandler>
  24 + <tag generate="true">
  25 + <classname>
  26 + org.richfaces.taglib.CoordinatesSelectionListenerTag
  27 + </classname>
  28 + </tag>
  29 +
  30 + <property existintag="true" exist="true" el="false">
  31 + <name>type</name>
  32 + <classname>java.lang.String</classname>
  33 + <description>The fully qualified Java class name for the listener</description>
  34 + </property>
  35 +</listener>
  1 +package org.richfaces.component;
  2 +
  3 +import org.ajax4jsf.component.AjaxActionComponent;
  4 +import org.ajax4jsf.component.AjaxComponent;
  5 +import org.ajax4jsf.context.AjaxContext;
  6 +import org.ajax4jsf.event.AjaxEvent;
  7 +import org.ajax4jsf.model.DataVisitor;
  8 +import org.ajax4jsf.model.ExtendedDataModel;
  9 +import org.ajax4jsf.renderkit.RendererUtils;
  10 +import org.richfaces.component.event.CoordinatesGridEventsProducer;
  11 +import org.richfaces.component.event.CoordinatesRefreshEvent;
  12 +import org.richfaces.component.event.CoordinatesSelectionEvent;
  13 +import org.richfaces.component.event.CoordinatesSelectionListener;
  14 +import org.richfaces.component.model.SquareRange;
  15 +
  16 +import javax.el.ELContext;
  17 +import javax.el.ValueExpression;
  18 +import javax.faces.component.UIComponent;
  19 +import javax.faces.component.UIComponentBase;
  20 +import javax.faces.context.FacesContext;
  21 +import javax.faces.el.MethodBinding;
  22 +import javax.faces.event.AbortProcessingException;
  23 +import javax.faces.event.FacesEvent;
  24 +import javax.faces.model.ArrayDataModel;
  25 +import javax.faces.model.DataModel;
  26 +import javax.faces.model.ListDataModel;
  27 +import javax.faces.model.ResultDataModel;
  28 +import javax.faces.model.ResultSetDataModel;
  29 +import javax.faces.model.ScalarDataModel;
  30 +import javax.servlet.jsp.jstl.sql.Result;
  31 +import java.io.IOException;
  32 +import java.sql.ResultSet;
  33 +import java.util.ArrayList;
  34 +import java.util.Collections;
  35 +import java.util.HashMap;
  36 +import java.util.List;
  37 +import java.util.Map;
  38 +
  39 +public abstract class UICoordinatesGrid extends UIComponentBase implements CoordinatesGridEventsProducer, AjaxComponent {
  40 +
  41 + public static final String COMPONENT_TYPE = "org.richfaces.CoordinatesGrid";
  42 + public static final String COMPONENT_FAMILY = "org.richfaces.CoordinatesGrid";
  43 + private DataModel model;
  44 +
  45 + public abstract Object getValue();
  46 +
  47 + public abstract void setValue(Object value);
  48 +
  49 + public abstract String getVar();
  50 +
  51 + public abstract void setVar(String var);
  52 +
  53 + public abstract String getRowIndexVar();
  54 +
  55 + public abstract void setRowIndexVar(String rowIndexVar);
  56 +
  57 + public abstract String getColIndexVar();
  58 +
  59 + public abstract void setColIndexVar(String var);
  60 +
  61 + public abstract String getRowHeaderText();
  62 +
  63 + public abstract void setRowHeaderText(String rowHeaderText);
  64 +
  65 + public abstract String getColHeaderText();
  66 +
  67 + public abstract void setColHeaderText(String colHeaderText);
  68 +
  69 + public abstract String getColHeaderPosition();
  70 +
  71 + public abstract void setColHeaderPosition(String colHeaderPosition);
  72 +
  73 + public abstract String getRowHeaderPosition();
  74 +
  75 + public abstract void setRowHeaderPosition(String rowHeaderPosition);
  76 +
  77 + public abstract String getSwitchType();
  78 +
  79 + public abstract void setSwitchType(String switchType);
  80 +
  81 + public abstract String getWidgetVar();
  82 +
  83 + public abstract void setWidgetVar(String widgetVar);
  84 +
  85 + public abstract String getOnclick();
  86 +
  87 + public abstract void setOnclick(String onclick);
  88 +
  89 + public abstract String getOnbeforeselect();
  90 +
  91 + public abstract void setOnbeforeselect(String onbeforeselect);
  92 +
  93 + public abstract String getOnselect();
  94 +
  95 + public abstract void setOnselect(String onselect);
  96 +
  97 + public abstract Integer getRows();
  98 +
  99 + public abstract void setRows(Integer rows);
  100 +
  101 + public abstract Integer getCols();
  102 +
  103 + public abstract void setCols(Integer cols);
  104 +
  105 + public abstract boolean isSelectable();
  106 +
  107 + public abstract void setSelectable(boolean selectable);
  108 +
  109 + public abstract MethodBinding getSelectionListener();
  110 +
  111 + public abstract void setSelectionListener(MethodBinding listener);
  112 +
  113 + @Override
  114 + public void broadcast(FacesEvent event) throws AbortProcessingException {
  115 + if (event instanceof CoordinatesSelectionEvent) {
  116 + super.broadcast(event);
  117 + new AjaxEvent(this).queue();
  118 + CoordinatesSelectionEvent selectionEvent = (CoordinatesSelectionEvent) event;
  119 + FacesContext facesContext = getFacesContext();
  120 + AjaxContext ajaxContext = AjaxContext.getCurrentInstance(facesContext);
  121 + MethodBinding expression = getSelectionListener();
  122 + if (expression != null) {
  123 + expression.invoke(facesContext, new Object[]{event});
  124 + }
  125 + try {
  126 + ajaxContext.getResponseDataMap().put("_ajax:coordinatesGridData", getData(selectionEvent.getStartX(), selectionEvent.getStartY(), selectionEvent.getEndX(), selectionEvent.getEndY()));
  127 + } catch (IOException ex) {
  128 + getFacesContext().getExternalContext().log("Cannot get coordinates grid data", ex);
  129 + }
  130 +
  131 + } else if (event instanceof CoordinatesRefreshEvent) {
  132 + super.broadcast(event);
  133 + new AjaxEvent(this).queue();
  134 + CoordinatesRefreshEvent refreshEvent = (CoordinatesRefreshEvent) event;
  135 + FacesContext facesContext = getFacesContext();
  136 + AjaxContext ajaxContext = AjaxContext.getCurrentInstance(facesContext);
  137 + try {
  138 + ajaxContext.getResponseDataMap().put("_ajax:coordinatesGridData", getData(refreshEvent.getStartX(), refreshEvent.getStartY(), refreshEvent.getEndX(), refreshEvent.getEndY()));
  139 + } catch (IOException ex) {
  140 + getFacesContext().getExternalContext().log("Cannot get coordinates grid data", ex);
  141 + }
  142 +
  143 + } else if (event instanceof AjaxEvent) {
  144 + FacesContext context = getFacesContext();
  145 + // complete re-Render fields. AjaxEvent deliver before render
  146 + // response.
  147 + AjaxContext.getCurrentInstance(context).addRegionsFromComponent(this);
  148 + // Put data for send in response
  149 + Object data = getData();
  150 + AjaxContext ajaxContext = AjaxContext.getCurrentInstance(context);
  151 + if (null != data) {
  152 + ajaxContext.setResponseData(data);
  153 + }
  154 + String focus = getFocus();
  155 + if (null != focus) {
  156 + // search for component in tree.
  157 + // XXX - use more pourful search, as in h:outputLabel
  158 + // component.
  159 + UIComponent focusComponent = RendererUtils.getInstance().
  160 + findComponentFor(this, focus);
  161 + if (null != focusComponent) {
  162 + focus = focusComponent.getClientId(context);
  163 + }
  164 + ajaxContext.getResponseDataMap().put(AjaxActionComponent.FOCUS_DATA_ID, focus);
  165 + }
  166 + ajaxContext.setOncomplete(getOncomplete());
  167 + }
  168 + }
  169 +
  170 + public void addCoordinatesSelectionListener(CoordinatesSelectionListener listener) {
  171 + addFacesListener(listener);
  172 + }
  173 +
  174 + public void removeCoordinatesSelectionListener(CoordinatesSelectionListener listener) {
  175 + removeFacesListener(listener);
  176 + }
  177 +
  178 + public CoordinatesSelectionListener[] getCoordinatesSelectionListeners() {
  179 + return (CoordinatesSelectionListener[]) getFacesListeners(CoordinatesSelectionListener.class);
  180 + }
  181 +
  182 + protected DataModel getDataModel() {
  183 + // Return any previously cached DataModel instance
  184 + if (this.model != null) {
  185 + return (model);
  186 + }
  187 +
  188 + // Synthesize a DataModel around our current value if possible
  189 + Object current = getValue();
  190 + if (current == null) {
  191 + setDataModel(new ListDataModel(Collections.EMPTY_LIST));
  192 + } else if (current instanceof DataModel) {
  193 + setDataModel((DataModel) current);
  194 + } else if (current instanceof List) {
  195 + setDataModel(new ListDataModel((List) current));
  196 + } else if (Object[].class.isAssignableFrom(current.getClass())) {
  197 + setDataModel(new ArrayDataModel((Object[]) current));
  198 + } else if (current instanceof ResultSet) {
  199 + setDataModel(new ResultSetDataModel((ResultSet) current));
  200 + } else if (current instanceof Result) {
  201 + setDataModel(new ResultDataModel((Result) current));
  202 + } else {
  203 + setDataModel(new ScalarDataModel(current));
  204 + }
  205 + return (model);
  206 +
  207 + }
  208 +
  209 + public void setDataModel(DataModel model) {
  210 + this.model = model;
  211 + }
  212 +
  213 + public List<List<Object>> getData(int startX, int startY, int endX, int endY) throws IOException {
  214 + ELContext elContext = getFacesContext().getELContext();
  215 + ValueExpression valueExpression = getFacesContext().getApplication().getExpressionFactory().createValueExpression(getFacesContext().getELContext(), "#{" + getVar() + "}", Object.class);
  216 + List<List<Object>> data = new ArrayList<List<Object>>();
  217 + DataModel dataModel = getDataModel();
  218 + List<Object> elements = new ArrayList<Object>();
  219 + if (dataModel instanceof ExtendedDataModel) {
  220 + final List<Object> keys = new ArrayList<Object>();
  221 + DataVisitor visitor = new DataVisitor() {
  222 +
  223 + public void process(FacesContext context, Object rowKey, Object argument) throws IOException {
  224 + keys.add(rowKey);
  225 + }
  226 + };
  227 + ((ExtendedDataModel) dataModel).walk(getFacesContext(), visitor, new SquareRange(startX, startY, endX, endY), null);
  228 + for (Object key : keys) {
  229 + ((ExtendedDataModel) dataModel).setRowKey(key);
  230 + if (dataModel.isRowAvailable()) {
  231 + elements.add(dataModel.getRowData());
  232 + }
  233 + }
  234 + } else {
  235 + for (int i = 0; i < dataModel.getRowCount(); i++) {
  236 + dataModel.setRowIndex(i);
  237 + if (dataModel.isRowAvailable()) {
  238 + elements.add(dataModel.getRowData());
  239 + }
  240 + }
  241 + }
  242 +
  243 + for (Object element : elements) {
  244 + valueExpression.setValue(elContext, element);
  245 + List<Object> firstDataElement = new ArrayList<Object>();
  246 + for (UIComponent child : getChildren()) {
  247 + if (child instanceof UICoordinatesGridItem) {
  248 + UICoordinatesGridItem item = (UICoordinatesGridItem) child;
  249 + if (!item.isRendered()) {
  250 + continue;
  251 + }
  252 + firstDataElement.add(item.getX());
  253 + firstDataElement.add(item.getY());
  254 + String text = item.getText();
  255 + if (text == null) {
  256 + text = "";
  257 + }
  258 + firstDataElement.add(text.trim());
  259 + String styleClass = item.getStyleClass();
  260 + if (styleClass == null) {
  261 + styleClass = "";
  262 + }
  263 + firstDataElement.add(styleClass.trim());
  264 + data.add(firstDataElement);
  265 + }
  266 + }
  267 + }
  268 + valueExpression.setValue(elContext, null);
  269 + return data;
  270 + }
  271 +
  272 + public List<Map<String, Object>> getRowHeadersData() throws IOException {
  273 + ELContext elContext = getFacesContext().getELContext();
  274 + ValueExpression valueExpression = getFacesContext().getApplication().getExpressionFactory().createValueExpression(getFacesContext().getELContext(), "#{" + getRowIndexVar() + "}", Object.class);
  275 + List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
  276 + for (int i = 0; i < getRows(); i++) {
  277 + if (getRowIndexVar() != null) {
  278 + valueExpression.setValue(elContext, i);
  279 + }
  280 + Map<String, Object> row = new HashMap<String, Object>();
  281 + data.add(row);
  282 + row.put("text", getRowHeaderText());
  283 + }
  284 + if (getRowIndexVar() != null) {
  285 + valueExpression.setValue(elContext, null);
  286 + }
  287 + return data;
  288 + }
  289 +
  290 + public List<Map<String, Object>> getColHeadersData() throws IOException {
  291 + ELContext elContext = getFacesContext().getELContext();
  292 + ValueExpression valueExpression = getFacesContext().getApplication().getExpressionFactory().createValueExpression(getFacesContext().getELContext(), "#{" + getColIndexVar() + "}", Object.class);
  293 + List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
  294 + for (int i = 0; i < getCols(); i++) {
  295 + if (getColIndexVar() != null) {
  296 + valueExpression.setValue(elContext, i);
  297 + }
  298 + Map<String, Object> col = new HashMap<String, Object>();
  299 + data.add(col);
  300 + col.put("text", getColHeaderText());
  301 + }
  302 + if (getColIndexVar() != null) {
  303 + valueExpression.setValue(elContext, null);
  304 + }
  305 + return data;
  306 + }
  307 +}
  1 +package org.richfaces.component;
  2 +
  3 +import javax.faces.component.UIComponentBase;
  4 +
  5 +public abstract class UICoordinatesGridItem extends UIComponentBase {
  6 +
  7 + public static final String COMPONENT_TYPE = "org.richfaces.CoordinatesGridItem";
  8 + public static final String COMPONENT_FAMILY = "org.richfaces.CoordinatesGrid";
  9 +
  10 + public abstract String getStyleClass();
  11 +
  12 + public abstract void setStyleClass(String styleClass);
  13 +
  14 + public abstract String getText();
  15 +
  16 + public abstract void setText(String text);
  17 +
  18 + public abstract int getX();
  19 +
  20 + public abstract void setX(int x);
  21 +
  22 + public abstract int getY();
  23 +
  24 + public abstract void setY(int y);
  25 +}
  1 +package org.richfaces.component.event;
  2 +
  3 +public interface CoordinatesGridEventsProducer {
  4 +
  5 + void addCoordinatesSelectionListener(CoordinatesSelectionListener listener);
  6 +
  7 + void removeCoordinatesSelectionListener(CoordinatesSelectionListener listener);
  8 +
  9 + CoordinatesSelectionListener[] getCoordinatesSelectionListeners();
  10 +}
  1 +package org.richfaces.component.event;
  2 +
  3 +import javax.faces.component.UIComponent;
  4 +import javax.faces.event.FacesEvent;
  5 +import javax.faces.event.FacesListener;
  6 +
  7 +/**
  8 + * Created by IntelliJ IDEA.
  9 + * User: bernard
  10 + * Date: Oct 18, 2010
  11 + * Time: 6:55:06 PM
  12 + */
  13 +public class CoordinatesRefreshEvent extends FacesEvent {
  14 +
  15 + private int startX;
  16 + private int startY;
  17 + private int endX;
  18 + private int endY;
  19 +
  20 + public CoordinatesRefreshEvent(int startX, int startY, int endX, int endY, UIComponent component) {
  21 + super(component);
  22 + this.startX = startX;
  23 + this.startY = startY;
  24 + this.endX = endX;
  25 + this.endY = endY;
  26 + }
  27 +
  28 + @Override
  29 + public boolean isAppropriateListener(FacesListener listener) {
  30 + return false;
  31 + }
  32 +
  33 + @Override
  34 + public void processListener(FacesListener listener) {
  35 + throw new UnsupportedOperationException();
  36 + }
  37 +
  38 + public int getStartX() {
  39 + return startX;
  40 + }
  41 +
  42 + public int getStartY() {
  43 + return startY;
  44 + }
  45 +
  46 + public int getEndX() {
  47 + return endX;
  48 + }
  49 +
  50 + public int getEndY() {
  51 + return endY;
  52 + }
  53 +}
  1 +package org.richfaces.component.event;
  2 +
  3 +import javax.faces.component.UIComponent;
  4 +import javax.faces.event.FacesEvent;
  5 +import javax.faces.event.FacesListener;
  6 +
  7 +/**
  8 + * Created by IntelliJ IDEA.
  9 + * User: bernard
  10 + * Date: Aug 17, 2010
  11 + * Time: 2:59:13 PM
  12 + */
  13 +public class CoordinatesSelectionEvent extends FacesEvent {
  14 +
  15 + private int startX;
  16 + private int startY;
  17 + private int endX;
  18 + private int endY;
  19 +
  20 + public CoordinatesSelectionEvent(int startX, int startY, int endX, int endY, UIComponent component) {
  21 + super(component);
  22 + this.startX = startX;
  23 + this.startY = startY;
  24 + this.endX = endX;
  25 + this.endY = endY;
  26 + }
  27 +
  28 + @Override
  29 + public boolean isAppropriateListener(FacesListener listener) {
  30 + return listener instanceof CoordinatesSelectionListener;
  31 + }
  32 +
  33 + @Override
  34 + public void processListener(FacesListener listener) {
  35 + ((CoordinatesSelectionListener) listener).coordinatesSelected(this);
  36 + }
  37 +
  38 + public int getStartX() {
  39 + return startX;
  40 + }
  41 +
  42 + public int getStartY() {
  43 + return startY;
  44 + }
  45 +
  46 + public int getEndX() {
  47 + return endX;
  48 + }
  49 +
  50 + public int getEndY() {
  51 + return endY;
  52 + }
  53 +}
  1 +package org.richfaces.component.event;
  2 +
  3 +import javax.faces.event.FacesListener;
  4 +
  5 +/**
  6 + * Created by IntelliJ IDEA.
  7 + * User: bernard
  8 + * Date: Aug 17, 2010
  9 + * Time: 3:01:08 PM
  10 + */
  11 +public interface CoordinatesSelectionListener extends FacesListener {
  12 +
  13 + void coordinatesSelected(CoordinatesSelectionEvent event);
  14 +
  15 +}
  1 +package org.richfaces.component.model;
  2 +
  3 +import org.ajax4jsf.model.Range;
  4 +
  5 +public class SquareRange implements Range {
  6 +
  7 + private int startX;
  8 + private int startY;
  9 + private int endX;
  10 + private int endY;
  11 +
  12 + public SquareRange() {
  13 + }
  14 +
  15 + public SquareRange(int startX, int startY, int endX, int endY) {
  16 + this.startX = startX;
  17 + this.startY = startY;
  18 + this.endX = endX;
  19 + this.endY = endY;
  20 + }
  21 +
  22 + public int getStartX() {
  23 + return startX;
  24 + }
  25 +
  26 + public void setStartX(int startX) {
  27 + this.startX = startX;
  28 + }
  29 +
  30 + public int getStartY() {
  31 + return startY;
  32 + }
  33 +
  34 + public void setStartY(int startY) {
  35 + this.startY = startY;
  36 + }
  37 +
  38 + public int getEndX() {
  39 + return endX;
  40 + }
  41 +
  42 + public void setEndX(int endX) {
  43 + this.endX = endX;
  44 + }
  45 +
  46 + public int getEndY() {
  47 + return endY;
  48 + }
  49 +
  50 + public void setEndY(int endY) {
  51 + this.endY = endY;
  52 + }
  53 +}
  1 +package org.richfaces.renderkit.html;
  2 +
  3 +import org.ajax4jsf.javascript.JSFunction;
  4 +import org.ajax4jsf.javascript.JSFunctionDefinition;
  5 +import org.ajax4jsf.javascript.JSObject;
  6 +import org.ajax4jsf.javascript.JSReference;
  7 +import org.ajax4jsf.renderkit.AjaxRendererUtils;
  8 +import org.ajax4jsf.renderkit.HeaderResourcesRendererBase;
  9 +import org.apache.commons.logging.Log;
  10 +import org.apache.commons.logging.LogFactory;
  11 +import org.richfaces.component.UICoordinatesGrid;
  12 +import org.richfaces.component.event.CoordinatesRefreshEvent;
  13 +import org.richfaces.component.event.CoordinatesSelectionEvent;
  14 +
  15 +import javax.faces.component.NamingContainer;
  16 +import javax.faces.component.UIComponent;
  17 +import javax.faces.context.FacesContext;
  18 +import javax.faces.context.ResponseWriter;
  19 +import java.io.IOException;
  20 +import java.util.HashMap;
  21 +import java.util.Map;
  22 +
  23 +public class CoordinatesGridRendererBase extends HeaderResourcesRendererBase {
  24 +
  25 + private static Log logger = LogFactory.getLog(CoordinatesGridRendererBase.class);
  26 + private static final String EVENT_TYPE_PARAM = "eventType";
  27 + private static final String START_X_PARAM = "startX";
  28 + private static final String END_X_PARAM = "endX";
  29 + private static final String START_Y_PARAM = "startY";
  30 + private static final String END_Y_PARAM = "endY";
  31 + private static final String CALLBACK = "callback";
  32 + private static final String SELECT_EVENT = "select";
  33 + private static final String REFRESH_EVENT = "refresh";
  34 + public static final String AJAX_MODE = "ajax";
  35 + public static final String SERVER_MODE = "server";
  36 + public static final String CLIENT_MODE = "client";
  37 +
  38 + protected Class<? extends UIComponent> getComponentClass() {
  39 + return UICoordinatesGrid.class;
  40 + }
  41 +
  42 + @Override
  43 + protected void doDecode(FacesContext context, UIComponent component) {
  44 + super.doDecode(context, component);
  45 + UICoordinatesGrid uiCoordinatesGrid;
  46 +
  47 + if (component instanceof UICoordinatesGrid) {
  48 + uiCoordinatesGrid = (UICoordinatesGrid) component;
  49 + } else {
  50 + if (logger.isDebugEnabled()) {
  51 + logger.debug("No decoding necessary since the component " + component.getId() +
  52 + " is not an instance or a sub class of UIInplaceInput");
  53 + }
  54 + return;
  55 + }
  56 + String startXParam = getFieldId(context, uiCoordinatesGrid, START_X_PARAM);
  57 + String startYParam = getFieldId(context, uiCoordinatesGrid, START_Y_PARAM);
  58 + String endXParam = getFieldId(context, uiCoordinatesGrid, END_X_PARAM);
  59 + String endYParam = getFieldId(context, uiCoordinatesGrid, END_Y_PARAM);
  60 + String eventTypeParam = getFieldId(context, uiCoordinatesGrid, EVENT_TYPE_PARAM);
  61 +
  62 + Map<String, String> request = context.getExternalContext().getRequestParameterMap();
  63 +
  64 + String startXString = request.get(startXParam);
  65 + String endXString = request.get(endXParam);
  66 + String startYString = request.get(startYParam);
  67 + String endYString = request.get(endYParam);
  68 + String eventType = request.get(eventTypeParam);
  69 + if (uiCoordinatesGrid.isSelectable() && (SELECT_EVENT.equals(eventType) || REFRESH_EVENT.equals(eventType)) && startXString != null && !"".equals(startXString)) {
  70 + try {
  71 + int startX = Integer.parseInt(startXString);
  72 + int startY = Integer.parseInt(startYString);
  73 + int endX = Integer.parseInt(endXString);
  74 + int endY = Integer.parseInt(endYString);
  75 + if (SELECT_EVENT.equals(eventType)) {
  76 + new CoordinatesSelectionEvent(startX, startY, endX, endY, uiCoordinatesGrid).queue();
  77 + } else {
  78 + uiCoordinatesGrid.queueEvent(new CoordinatesRefreshEvent(startX, startY, endX, endY, uiCoordinatesGrid));
  79 + }
  80 + } catch (Exception e) {
  81 + logger.error("Problem during decoding event for component " + component.getId() + " (params: " + startXParam + "=" + startXString + ";" + startYParam + "=" + startYString + ";" + endXParam + "=" + endXString + ";" + endYParam + "=" + endYString + ")");
  82 + }
  83 + }
  84 + }
  85 +
  86 + protected String getFieldId(FacesContext context, UIComponent component, String attribute) {
  87 + return getUtils().clientId(context, component) + NamingContainer.SEPARATOR_CHAR + attribute;
  88 + }
  89 +
  90 + public void writeInitFunction(FacesContext context, UICoordinatesGrid component) throws IOException {
  91 + ResponseWriter writer = context.getResponseWriter();
  92 + if (component.getWidgetVar() != null) {
  93 + writer.write("var " + component.getWidgetVar() + "=");
  94 + }
  95 + Map<String, Object> options = new HashMap<String, Object>();
  96 + addOptionIfSet("onclick", component.getOnclick(), options);
  97 + addOptionIfSet("onbeforeselect", component.getOnbeforeselect(), options);
  98 + addOptionIfSet("onselect", component.getOnselect(), options);
  99 + addOptionIfSet("rows", component.getRows(), options);
  100 + addOptionIfSet("cols", component.getCols(), options);
  101 + addOptionIfSet("selectable", component.isSelectable(), options);
  102 + addOptionIfSet("colHeaderPosition", component.getColHeaderPosition(), options);
  103 + addOptionIfSet("rowHeaderPosition", component.getRowHeaderPosition(), options);
  104 + addOptionIfSet("rowHeaders", component.getRowHeadersData(), options);
  105 + addOptionIfSet("colHeaders", component.getColHeadersData(), options);
  106 + addOptionIfSet("elements", component.getData(0, 0, component.getCols() - 1, component.getRows() - 1), options);
  107 +
  108 + writer.writeText(new JSObject("RichFaces.CoordinatesGrid",
  109 + component.getClientId(context),
  110 + options,
  111 + createSubmitEventFunction(context, component)).toScript(), null);
  112 + }
  113 +
  114 + protected Object createSubmitEventFunction(FacesContext context, UICoordinatesGrid component) {
  115 + JSFunction jsFunction;
  116 + Map<String, Object> params = new HashMap<String, Object>();
  117 + params.put(getFieldId(context, component, EVENT_TYPE_PARAM), new JSReference(EVENT_TYPE_PARAM));
  118 + params.put(getFieldId(context, component, START_X_PARAM), new JSReference(START_X_PARAM));
  119 + params.put(getFieldId(context, component, START_Y_PARAM), new JSReference(START_Y_PARAM));
  120 + params.put(getFieldId(context, component, END_X_PARAM), new JSReference(END_X_PARAM));
  121 + params.put(getFieldId(context, component, END_Y_PARAM), new JSReference(END_Y_PARAM));
  122 + if (isAjaxMode(component)) {
  123 + jsFunction = AjaxRendererUtils.buildAjaxFunction(component, context);
  124 + Map<String, Object> eventOptions = AjaxRendererUtils.buildEventOptions(context, component, params);
  125 + eventOptions.put("oncomplete", new JSReference(CALLBACK));
  126 + jsFunction.addParameter(eventOptions);
  127 + } else if (SERVER_MODE.equals(component.getSwitchType())) {
  128 + jsFunction = new JSFunction("Richfaces.jsFormSubmit",
  129 + component.getClientId(context),
  130 + getUtils().getNestingForm(context, component).getClientId(context),
  131 + null,
  132 + params);
  133 + } else {
  134 + return null;
  135 + }
  136 + return new JSFunctionDefinition("event", EVENT_TYPE_PARAM, START_X_PARAM, START_Y_PARAM, END_X_PARAM, END_Y_PARAM, CALLBACK).addToBody(jsFunction);
  137 + }
  138 +
  139 + private void addOptionIfSet(String optionName, Object value, Map<String, Object> options) {
  140 + if (value != null && value != "") {
  141 + options.put(optionName, value);
  142 + }
  143 + }
  144 +
  145 + private boolean isAjaxMode(UICoordinatesGrid component) {
  146 + String mode = component.getSwitchType();
  147 + return AJAX_MODE.equals(mode) || "".equals(mode) || null == mode;
  148 + }
  149 +}
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<f:template
  3 + xmlns:f="http://jsf.exadel.com/template"
  4 + xmlns:u="http://jsf.exadel.com/template/util"
  5 + xmlns="http://www.w3.org/1999/xhtml">
  6 +
  7 + <u:selector name=".rf-cg td">
  8 + <u:style name="width" value="20px"/>
  9 + <u:style name="height" value="20px"/>
  10 + <u:style name="border-width" value="1px"/>
  11 + <u:style name="border-style" value="solid"/>
  12 + <u:style name="border-color" skin="panelBorderColor"/>
  13 + </u:selector>
  14 + <u:selector name=".rf-cg td.highlight">
  15 + <u:style name="background-color" skin="headerBackgroundColor"/>
  16 + <u:style name="color" skin="headTextColor"/>
  17 + </u:selector>
  18 +</f:template>
  1 +if (window.RichFaces == null) {
  2 + window.RichFaces = {};
  3 +}
  4 +RichFaces.CoordinatesGrid = function(targetId, options, submitEventFunction) {
  5 +
  6 + var startX;
  7 + var startY;
  8 + var endX;
  9 + var endY;
  10 + var selecting = false;
  11 + this.target = document.getElementById(targetId);
  12 + var _this = this;
  13 + this.options = jQuery.extend({}, this.options, options);
  14 + if (this.target.component != null && this.target.component.destroy != null) {
  15 + this.target.component.destroy();
  16 + }
  17 + this.target.component = this;
  18 +
  19 + var getY = function(o) {
  20 + if (o == null || o.parentNode == null || o.parentNode.rowIndex == null) {
  21 + throw "HTMLTableCellElement expected";
  22 + }
  23 + return o.parentNode.rowIndex;
  24 + };
  25 + var getX = function(o) {
  26 + if (o == null || o.cellIndex == null) {
  27 + throw "HTMLTableCellElement expected";
  28 + }
  29 + return o.cellIndex;
  30 + };
  31 + /**
  32 + * Updates element on the grid with data from initial or ajax request.
  33 + * @param data array of data where: 0: x, 1: y, 2: text, 3: css class
  34 + */
  35 + var updateElementFromData = function(data) {
  36 + var element = _this.getElementAt(data[0], data[1]);
  37 + if (element != null) {
  38 + _this.updateElement(element, {innerHTML:data[2],className:data[3]});
  39 + }
  40 + return element;
  41 + };
  42 + var updateElementsWithRequestData = function(request, _startX, _startY, _endX, _endY) {
  43 + /** Server component should respond with data of elements matching selection */
  44 + var elements = request.getJSON('_ajax:coordinatesGridData');
  45 + if (elements != undefined) {
  46 + var elementsFromUpdate = [];
  47 + jQuery.each(elements, function() {
  48 + var element = updateElementFromData(this);
  49 + if (element != null) {
  50 + elementsFromUpdate.push(element);
  51 + }
  52 + });
  53 + jQuery.each(_this.getElements(_startX, _startY, _endX, _endY), function() {
  54 + var visitedCell = this;
  55 + var exists = false;
  56 + jQuery.each(elementsFromUpdate, function() {
  57 + if (this == visitedCell) {
  58 + exists = true;
  59 + }
  60 + });
  61 + if (!exists) {
  62 + this.className = "";
  63 + this.innerHTML = "";
  64 + }
  65 + });
  66 + }
  67 + };
  68 + var mouseDownHanlder = function() {
  69 + if (selecting) {
  70 + mouseUpHanlder.apply(this);
  71 + } else if (options.selectable) {
  72 + startX = getX(this);
  73 + startY = getY(this);
  74 + selecting = true;
  75 + }
  76 + };
  77 + var mouseUpHanlder = function() {
  78 + if (!selecting) {
  79 + return;
  80 + }
  81 + endX = getX(this);
  82 + endY = getY(this);
  83 + selecting = false;
  84 + highlightSelection();
  85 + if (_this.options.onbeforeselect != null) {
  86 + var result;
  87 + if (typeof _this.options.onbeforeselect == "function") {
  88 + result = _this.options.onbeforeselect(_this, _startX, _startY, _endX, _endY);
  89 + } else {
  90 + result = RichFaces.CoordinatesGrid.eval("(function(){" + _this.options.onbeforeselect + "})()", {
  91 + 'startX':startX,
  92 + 'startY':startY,
  93 + 'endX':endX,
  94 + 'endY':endY,
  95 + 'component':_this
  96 + });
  97 + }
  98 + if (result === false) {
  99 + return;
  100 + }
  101 + }
  102 + /**
  103 + * endX and endY will be reset before ajax response comes.
  104 + */
  105 + var _endX = endX;
  106 + var _endY = endY;
  107 + var _startX = startX;
  108 + var _startY = startY;
  109 + /** Notify server side */
  110 + if (submitEventFunction != null) {
  111 + submitEventFunction({}, "select",
  112 + _this.indexToCoordX(startX), _this.indexToCoordY(startY), _this.indexToCoordX(endX), _this.indexToCoordY(endY),
  113 + function(request, event, data) {
  114 + updateElementsWithRequestData(request, _startX, _startY, _endX, _endY);
  115 +
  116 + if (_this.options.onselect != null) {
  117 + if (typeof _this.options.onselect == "function") {
  118 + _this.options.onselect(_this, _startX, _startY, _endX, _endY);
  119 + } else {
  120 + RichFaces.CoordinatesGrid.eval("(function(){" + _this.options.onselect + "})()", {
  121 + 'startX':_startX,
  122 + 'startY':_startY,
  123 + 'endX':_endX,
  124 + 'endY':_endY,
  125 + 'component':_this
  126 + });
  127 + }
  128 + }
  129 + delete _endX,_endY,_startX,_startY;
  130 + });
  131 + }
  132 + endX = -1;
  133 + endY = -1;
  134 + highlightSelection();
  135 + };
  136 + var mouseOverHandler = function() {
  137 + if (!selecting) {
  138 + return;
  139 + }
  140 + endX = getX(this);
  141 + endY = getY(this);
  142 + highlightSelection();
  143 + };
  144 + var highlightSelection = function() {
  145 + jQuery("td", _this.target).each(function() {
  146 + var x = getX(this);
  147 + var y = getY(this);
  148 + if (startX <= x && x <= endX && startY <= y && y <= endY) {
  149 + jQuery(this).addClass(_this.options.highlightClass);
  150 + } else {
  151 + jQuery(this).removeClass(_this.options.highlightClass);
  152 + }
  153 + });
  154 + };
  155 + var clickHandler = function() {
  156 + if (_this.options.onclick != null) {
  157 + if (typeof _this.options.onclick == "function") {
  158 + _this.options.onclick(_this, getX(this), getY(this));
  159 + } else {
  160 + RichFaces.CoordinatesGrid.eval("(function(){" + _this.options.onclick + "})()", {
  161 + 'x':getX(this),
  162 + 'y':getY(this),
  163 + 'component':_this
  164 + });
  165 + }
  166 + }
  167 + };
  168 + this.getElements = function(startX, startY, endX, endY) {
  169 + var elements = [];
  170 + jQuery("td", _this.target).each(function() {
  171 + var x = getX(this);
  172 + var y = getY(this);
  173 + if (startX <= x && x <= endX && startY <= y && y <= endY) {
  174 + elements.push(this);
  175 + }
  176 + });
  177 + return elements;
  178 + };
  179 + this.refresh = function(_startX, _startY, _endX, _endY) {
  180 + if (_startX == null && _startY == null && _endX == null && _endY == null) {
  181 + _startX = 0;
  182 + _startY = 0;
  183 + _endX = this.options.cols;
  184 + _endY = this.options.rows;
  185 + }
  186 + submitEventFunction({}, "refresh", _startX, _startY, _endX, _endY, function(request, event, data) {
  187 + updateElementsWithRequestData(request, _startX, _startY, _endX, _endY);
  188 + delete _endX,_endY,_startX,_startY;
  189 + });
  190 + };
  191 + /**
  192 + * @param element HTMLTableCellElement
  193 + * @param options options used to extend element, i.e. {className:'important'}
  194 + **/
  195 + this.updateElement = function(element, options) {
  196 + if (options.className) {
  197 + options.className = "rich-table-cell " + options.className;
  198 + }
  199 + jQuery.extend(element, options);
  200 + };
  201 + this.getElementAt = function(x, y) {
  202 + return table[0].rows[y + (_this.isTopColHeadersVisible() ? 1 : 0)].cells[x + (_this.isLeftRowHeadersVisible() ? 1 : 0)];
  203 + };
  204 + /**
  205 + * Create grid.
  206 + */
  207 + var table = jQuery("<table></table>");
  208 + (function() {
  209 + table.appendTo(_this.target);
  210 + var cell;
  211 + /**
  212 + * Function used for appending headers without filling them with text
  213 + */
  214 + var appendHeaders = function() {
  215 + var row = jQuery("<tr class='rich-table-subheader'></tr>");
  216 + row.appendTo(table);
  217 + row.addClass(_this.options.colHeaderClass);
  218 + if (_this.options.rowHeaders != null) {
  219 +
  220 + if (_this.options.rowHeaderPosition == 'both' || _this.options.rowHeaderPosition == 'left') {
  221 + var cell = jQuery("<th class='rich-table-subheadercell'></th>");
  222 + cell.appendTo(row);
  223 + }
  224 + for (var x = 0; x < _this.options.cols; x++) {
  225 + cell = jQuery("<th class='rich-table-subheadercell'></th>");
  226 + cell.appendTo(row);
  227 + }
  228 + if (_this.options.rowHeaderPosition == 'both' || _this.options.rowHeaderPosition == 'right') {
  229 + cell = jQuery("<th class='rich-table-subheadercell'></th>");
  230 + cell.appendTo(row);
  231 + }
  232 + }
  233 + };
  234 + /** Append top column headers */
  235 + if (_this.isTopColHeadersVisible()) {
  236 + appendHeaders()
  237 + }
  238 + for (var y = 0; y < _this.options.rows; y++) {
  239 + var row = jQuery("<tr class='rich-table-row'></tr>");
  240 + row.appendTo(table);
  241 + /** Append left row headers */
  242 + if (_this.isLeftRowHeadersVisible()) {
  243 + cell = jQuery("<th class='rich-table-cell'></th>");
  244 + cell.appendTo(row);
  245 + cell.addClass(_this.options.rowHeaderClass);
  246 + }
  247 + /** Append regular cells */
  248 + for (var x = 0; x < _this.options.cols; x++) {
  249 + cell = jQuery("<td class='rich-table-cell'></td>");
  250 + cell.appendTo(row);
  251 + cell.mouseup(mouseUpHanlder);
  252 + cell.mousedown(mouseDownHanlder);
  253 + cell.mouseover(mouseOverHandler);
  254 + cell.click(clickHandler);
  255 + }
  256 + /** Append right row headers */
  257 + if (_this.isRightRowHeadersVisible()) {
  258 + cell = jQuery("<th class='rich-table-cell'></th>");
  259 + cell.appendTo(row);
  260 + cell.addClass(_this.options.rowHeaderClass);
  261 + }
  262 + }
  263 + /** Append bottom column headers */
  264 + if (_this.isBottomColHeadersVisible()) {
  265 + appendHeaders()
  266 + }
  267 + /** Customize headers - className and text */
  268 + jQuery.each(_this.options.rowHeaders, function(index) {
  269 + var text = this.text;
  270 + delete this.text;
  271 + if (text != null) {
  272 + this.innerHTML = text;
  273 + }
  274 + if (_this.isLeftRowHeadersVisible()) {
  275 + _this.updateElement(_this.getElementAt(-1, index), this);
  276 + }
  277 + if (_this.isRightRowHeadersVisible()) {
  278 + _this.updateElement(_this.getElementAt(_this.options.cols, index), this);
  279 + }
  280 + });
  281 + jQuery.each(_this.options.colHeaders, function(index) {
  282 + var text = this.text;
  283 + delete this.text;
  284 + if (text != null) {
  285 + this.innerHTML = text;
  286 + }
  287 + if (_this.isTopColHeadersVisible()) {
  288 + _this.updateElement(_this.getElementAt(index, -1), this);
  289 + }
  290 + if (_this.isBottomColHeadersVisible()) {
  291 + _this.updateElement(_this.getElementAt(index, _this.options.rows), this);
  292 + }
  293 + });
  294 + /** Customize regular cell */
  295 + if (_this.options.elements != null) {
  296 + jQuery.each(_this.options.elements, function() {
  297 + updateElementFromData(this)
  298 + });
  299 + }
  300 + /** Disable text selection */
  301 + if (options.selectable) {
  302 + table.attr('unselectable', 'on').css('MozUserSelect', 'none').bind('selectstart.ui', function() {
  303 + return false;
  304 + });
  305 + }
  306 + })();
  307 +}
  308 + ;
  309 +RichFaces.CoordinatesGrid.prototype.options = {
  310 + rows: 10,
  311 + cols: 10,
  312 + highlightClass: 'highlight',
  313 + colHeaderPosition: 'bottom',
  314 + rowHeaderPosition: 'left'
  315 +};
  316 +RichFaces.CoordinatesGrid.prototype.select = function(func) {
  317 + this.options.onselect = func;
  318 +};
  319 +RichFaces.CoordinatesGrid.prototype.destroy = function() {
  320 + jQuery("table", this.target).remove();
  321 + delete this.target.component;
  322 +};
  323 +RichFaces.CoordinatesGrid.prototype.isLeftRowHeadersVisible = function() {
  324 + return this.options.rowHeaders != null && (this.options.rowHeaderPosition == 'both' || this.options.rowHeaderPosition == 'left');
  325 +};
  326 +RichFaces.CoordinatesGrid.prototype.isRightRowHeadersVisible = function() {
  327 + return this.options.rowHeaders != null && (this.options.rowHeaderPosition == 'both' || this.options.rowHeaderPosition == 'right');
  328 +};
  329 +RichFaces.CoordinatesGrid.prototype.isTopColHeadersVisible = function() {
  330 + return this.options.colHeaders != null && (this.options.colHeaderPosition == 'both' || this.options.colHeaderPosition == 'top');
  331 +};
  332 +RichFaces.CoordinatesGrid.prototype.isBottomColHeadersVisible = function() {
  333 + return this.options.colHeaders != null && (this.options.colHeaderPosition == 'both' || this.options.colHeaderPosition == 'bottom');
  334 +};
  335 +RichFaces.CoordinatesGrid.prototype.indexToCoordX = function(index) {
  336 + return index - (this.isLeftRowHeadersVisible() ? 1 : 0);
  337 +};
  338 +RichFaces.CoordinatesGrid.prototype.indexToCoordY = function(index) {
  339 + return index - (this.isTopColHeadersVisible() ? 1 : 0);
  340 +};
  341 +/**
  342 + * This function evaluates code in template with object in ScopeChain.
  343 + * This is usefull if you need to evaluate code that uses member names
  344 + * that colide with external names that the code refers to.
  345 + * There is almost exact method in utils.js called Richfaces.eval,
  346 + * but it swallows exception thrown during evaluation, which makes debugging
  347 + * hard.
  348 + */
  349 +RichFaces.CoordinatesGrid.eval = function(template, object) {
  350 + var value = '';
  351 + with (object) {
  352 + value = eval(template);
  353 + }
  354 + return value;
  355 +};
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<f:root
  3 + xmlns:f="http://ajax4jsf.org/cdk/template"
  4 + xmlns:c="http://java.sun.com/jsf/core"
  5 + xmlns:ui="http://ajax4jsf.org/cdk/ui"
  6 + xmlns:u="http://ajax4jsf.org/cdk/u"
  7 + xmlns:x="http://ajax4jsf.org/cdk/x"
  8 + xmlns:jsp="http://ajax4jsf.org/cdk/jsp"
  9 + class="org.richfaces.renderkit.html.CoordinatesGridRenderer"
  10 + baseclass="org.richfaces.renderkit.html.CoordinatesGridRendererBase"
  11 + component="org.richfaces.component.UICoordinatesGrid"
  12 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://ajax4jsf.org/cdk/template ">
  13 +
  14 + <h:styles>/org/richfaces/renderkit/html/css/richfaces.coordinatesGrid.xcss</h:styles>
  15 + <h:scripts>
  16 + new org.ajax4jsf.javascript.PrototypeScript(),
  17 + new org.ajax4jsf.javascript.AjaxScript(),
  18 + /org/richfaces/renderkit/html/scripts/jquery/jquery.js,
  19 + /org/richfaces/renderkit/html/scripts/richfaces.coordinatesGrid.js
  20 + </h:scripts>
  21 +
  22 +
  23 + <f:clientid var="clientId"/>
  24 +
  25 + <jsp:scriptlet>
  26 + <![CDATA[
  27 + org.richfaces.component.util.FormUtil.throwEnclFormReqExceptionIfNeed(context, component);
  28 + variables.setVariable("selectableStyleClass",((Boolean)component.getAttributes().get("selectable"))?" rf-cg-se":"");
  29 + ]]>
  30 + </jsp:scriptlet>
  31 + <div id="#{clientId}" class="rf-cg#{selectableStyleClass} #{component.attributes['styleClass']}" style="#{component.attributes['style']}">
  32 + <script type="text/javascript">
  33 + <f:call name="writeInitFunction"/>
  34 + </script>
  35 + </div>
  36 +</f:root>
  1 +<?xml version="1.0"?>
  2 +<project>
  3 + <parent>
  4 + <groupId>org.richfaces.sandbox</groupId>
  5 + <artifactId>ui</artifactId>
  6 + <version>3.3.4-SNAPSHOT</version>
  7 + </parent>
  8 + <modelVersion>4.0.0</modelVersion>
  9 + <groupId>org.richfaces.sandbox.ui</groupId>
  10 + <artifactId>dock</artifactId>
  11 + <name>dock</name>
  12 + <build>
  13 + <plugins>
  14 + <plugin>
  15 + <groupId>org.richfaces.cdk</groupId>
  16 + <artifactId>maven-cdk-plugin</artifactId>
  17 + <version>${project.version}</version>
  18 + <executions>
  19 + <execution>
  20 + <phase>generate-sources</phase>
  21 + <goals>
  22 + <goal>generate</goal>
  23 + </goals>
  24 + </execution>
  25 + </executions>
  26 + <configuration>
  27 + <library>
  28 + <prefix>org.richfaces.sandbox.ui</prefix>
  29 + <taglib>
  30 + <shortName>dock</shortName>
  31 + <uri>http://richfaces.org/sandbox/dock</uri>
  32 + </taglib>
  33 + </library>
  34 + </configuration>
  35 + </plugin>
  36 + <plugin>
  37 + <artifactId>maven-compiler-plugin</artifactId>
  38 + <inherited>true</inherited>
  39 + <configuration>
  40 + <source>1.5</source>
  41 + <target>1.5</target>
  42 + <encoding>${project.build.sourceEncoding}</encoding>
  43 + </configuration>
  44 + </plugin>
  45 + <plugin>
  46 + <groupId>org.apache.maven.plugins</groupId>
  47 + <artifactId>maven-resources-plugin</artifactId>
  48 + <version>2.2</version>
  49 + <configuration>
  50 + <encoding>${project.build.sourceEncoding}</encoding>
  51 + </configuration>
  52 + </plugin>
  53 + </plugins>
  54 + </build>
  55 + <dependencies>
  56 + <dependency>
  57 + <groupId>org.richfaces.framework</groupId>
  58 + <artifactId>richfaces-impl</artifactId>
  59 + <version>${project.version}</version>
  60 + </dependency>
  61 + </dependencies>
  62 + <properties>
  63 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  64 + </properties>
  65 + <distributionManagement>
  66 + <snapshotRepository>
  67 + <id>bernard.labno.pl</id>
  68 + <name>MyCo Internal Repository</name>
  69 + <url>http://bernard.labno.pl/artifactory/libs-snapshot-local</url>
  70 + </snapshotRepository>
  71 + </distributionManagement>
  72 +
  73 +</project>
  1 +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE components PUBLIC "-//AJAX4JSF//CDK Generator config/EN"
  2 + "http://labs.jboss.com/jbossrichfaces/component-config.dtd"
  3 + >
  4 +<components>
  5 + <component>
  6 + <name>org.richfaces.Dock</name>
  7 + <family>org.richfaces.Dock</family>
  8 + <classname>org.richfaces.component.html.HtmlDock</classname>
  9 + <superclass>org.richfaces.component.UIDock</superclass>
  10 + <description>
  11 + The Dock - as anyone familiar with a Mac will know - is a set of iconic images that expand when rolled over
  12 + with the cursor, and usually perform some action when clicked. This plugin mimics that behaviour by
  13 + transforming a contiguous set of HTML images into an expanding Dock, vertical or horizontal, with or without
  14 + labels.
  15 +
  16 + Note that this component will not work if it's children render anything else except "&lt;script>", "&lt;a>"
  17 + or "&lt;img>".
  18 + </description>
  19 + <renderer generate="false" override="true">
  20 + <name>org.richfaces.DockRenderer</name>
  21 + <classname>org.richfaces.renderkit.html.DockRenderer</classname>
  22 + </renderer>
  23 + <tag>
  24 + <name>dock</name>
  25 + <classname>org.richfaces.taglib.DockTag</classname>
  26 + <superclass>
  27 + org.ajax4jsf.webapp.taglib.HtmlComponentTagBase
  28 + </superclass>
  29 + <!--
  30 + <test>
  31 + <classname>org.richfaces.taglib.HtmlDockTagTest</classname>
  32 + <superclassname>org.ajax4jsf.tests.AbstractJspTestCase</superclassname>
  33 + </test>
  34 + -->
  35 +
  36 + </tag>
  37 +
  38 + &ui_component_attributes;
  39 + &html_style_attributes;
  40 +
  41 + <property>
  42 + <name>active</name>
  43 + <classname>int</classname>
  44 + <description>
  45 + This designates one of the menu's elements to be fully expanded when the dock is initialised. The option
  46 + takes a zero-based index of the position of the desired menu element (image) within the dock - so if you
  47 + want the 4th of 6 images to be expanded, set active : 3.
  48 +
  49 + Warning : There are consequences to using this option, which might possibly only become apparent when
  50 + you try it. I have provided it because it has specifically been requested, but ... if you set a mid-menu
  51 + image initially active, and the user then enters the dock at either end, it is quite likely that the
  52 + dock will simply collapse to its 'at rest' state because the resultant animation takes the mouse off the
  53 + dock!
  54 + </description>
  55 + <defaultvalue>-1</defaultvalue>
  56 + </property>
  57 +
  58 + <property>
  59 + <name>align</name>
  60 + <classname>java.lang.String</classname>
  61 + <description>
  62 + values = 'top', 'middle', 'bottom', left', center', 'right'
  63 +
  64 + Fixes the horizontal/vertical main axis, and direction of expansion.
  65 +
  66 + For a horizontal menu:
  67 + * 'top' : fixes the top edge of the dock, so that images expand down
  68 + * 'middle' : fixes the middle of the images, so that images expand up and down equally
  69 + * 'bottom' : fixes the bottom edge of the dock, so that images expand up
  70 +
  71 + For a vertical menu:
  72 + * 'left' : fixes the left edge of the dock, so that images expand right
  73 + * 'center' : fixes the center of the images, so that images expand left and right equally
  74 + * 'right' : fixes the right edge of the dock, so that images expand left
  75 + </description>
  76 + <defaultvalue>"bottom"</defaultvalue>
  77 + </property>
  78 +
  79 + <property>
  80 + <name>coefficient</name>
  81 + <classname>double</classname>
  82 + <description>
  83 + Attenuation coefficient. This controls the relationship between the distance from the cursor and the
  84 + amount of expansion of any affected image within that distance. A coefficient of 1 makes the expansion
  85 + linear with respect to distance from cursor; a larger coefficient gives a greater degree of expansion
  86 + the closer to the cursor the affected image is (within distance). # distance : integer, default = 72
  87 + Attenuation distance from cursor, ie the distance (in pixels) from the cursor that an image has to be
  88 + within in order to have any expansion applied.
  89 +
  90 + Note that attenuation is always calculated as if the Dock was 'at rest' (no images expanded), even
  91 + though there may be expanded images at the time.
  92 + </description>
  93 + <defaultvalue>1.5</defaultvalue>
  94 + </property>
  95 +
  96 + <property>
  97 + <name>duration</name>
  98 + <classname>int</classname>
  99 + <description>
  100 + The duration (in milliseconds) of the initial 'on-Dock' expansion, and the 'off-Dock' shrinkage.
  101 + </description>
  102 + <defaultvalue>300</defaultvalue>
  103 + </property>
  104 +
  105 + <property>
  106 + <name>fadeIn</name>
  107 + <classname>int</classname>
  108 + <description>
  109 + The amount of time (in milliseconds) for the initial fade-in of the Dock after initialisation. By
  110 + default this is set to 0 (zero), which means that the Dock is displayed in full as soon as it can be ( =
  111 + show() ). There may be occasions when a 'softer' presentation of the Dock is desirable, and setting
  112 + fadeIn to, for example, 400 would fade the Dock in over that period.
  113 + </description>
  114 + <defaultvalue>0</defaultvalue>
  115 + </property>
  116 +
  117 + <property>
  118 + <name>fadeLayer</name>
  119 + <classname>java.lang.String</classname>
  120 + <description>
  121 + By default the fade-in effect (see fadeIn above) is applied to the original target menu element. By
  122 + specifying either 'wrap' or 'dock' here, the fade-in element can be switched to the child or grand-child
  123 + (ie. div.jqDockWrap or div.jqDock, respectively) of the original target menu element. This option only
  124 + has any effect if fadeIn is set, and is really only useful for cases where, for example, background
  125 + colours have been styled on the original menu element or div.jqDock, and you don't want them to be faded
  126 + in.
  127 + </description>
  128 + <defaultvalue>null</defaultvalue>
  129 + </property>
  130 +
  131 + <property>
  132 + <name>flow</name>
  133 + <classname>boolean</classname>
  134 + <description>
  135 + If set, this alters the default dock behaviour such that the Dock is not auto-centered and the wrap
  136 + element (.jqDockWrap, which is relatively positioned) expands and collapses to precisely contain the
  137 + Dock (.jqDock); this allows elements positioned around the docked menu to adjust their own relative
  138 + position according to the current state of the docked menu.
  139 +
  140 + Warning : There are consequences to using this option, which might possibly only become apparent when
  141 + you try it. I have provided it because it has specifically been requested, but with flow enabled, if you
  142 + aim your mouse at a specific menu option you will probably find that quite often you don't stay on that
  143 + option without having to move the mouse again!
  144 + </description>
  145 + <defaultvalue>false</defaultvalue>
  146 + </property>
  147 +
  148 + <property>
  149 + <name>idle</name>
  150 + <classname>int</classname>
  151 + <description>
  152 + The period of time (in milliseconds) after the mouse has left the menu (without re-entering, obviously!)
  153 + before the Dock attempts to go to sleep.
  154 + </description>
  155 + <defaultvalue>0</defaultvalue>
  156 + </property>
  157 +
  158 + <property>
  159 + <name>inactivity</name>
  160 + <classname>int</classname>
  161 + <description>
  162 + The period of time (in milliseconds) after which the Dock will shrink if there has been no movement of
  163 + the mouse while it is over an expanded Dock.
  164 + </description>
  165 + <defaultvalue>0</defaultvalue>
  166 + </property>
  167 +
  168 + <property>
  169 + <name>labels</name>
  170 + <classname>java.lang.String</classname>
  171 + <description>
  172 + values = 'true', 'false', 'tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'
  173 +
  174 + This enables/disables display of a label on the current image. Allowed string values are 2 characters in
  175 + length: the first character indicates horizontal position (t=top, m=middle, b=bottom) and the second
  176 + indicates vertical position (l=left, c=center, r=right). So 'br' means bottom-right! If simply set to
  177 + true, jqDock will use its default positioning for the label, which is 'tl' (top-left) for any align
  178 + setting other than 'top' or 'left'. The defaults for 'top' and 'left' alignment are 'br' (bottom-right)
  179 + and 'tr' (top-right) respectively. To determine the text for the label, jqDock looks firstly for text in
  180 + the image's 'title' attribute; if not found, it will then look for text in the 'title' attribute of the
  181 + parent link - if there is one - and use that if found.
  182 +
  183 + Please be aware that enabling this option with one of the middle/center label positions (eg. 'ml', 'bc',
  184 + etc) may have a slight effect on the performance of the Dock, simply due to the additional processing
  185 + required to position the label correctly.
  186 + </description>
  187 + <defaultvalue>"false"</defaultvalue>
  188 + </property>
  189 +
  190 + <property>
  191 + <name>loader</name>
  192 + <classname>java.lang.String</classname>
  193 + <description>
  194 + values = 'image', 'jquery'
  195 +
  196 + This overrides the default image loader used by jqDock. Depending on the browser, jqDock uses an image
  197 + loader based on either "new Image()", or the jQuery HTML constructor "jQuery('&lt;img/>')...". If your
  198 + Dock is not being displayed, and you have triple checked all your image paths, try setting this option
  199 + to 'image' or 'jquery' to override the default loader.
  200 + </description>
  201 + <defaultvalue>null</defaultvalue>
  202 + </property>
  203 +
  204 + <property>
  205 + <name>noBuffer</name>
  206 + <classname>boolean</classname>
  207 + <description>
  208 + By default, while the dock is asleep the most recent mouse event is buffered, and when the dock is
  209 + nudged awake that buffered event is used and acted upon - before any other mouse event that might occur
  210 + subsequent to the 'nudge'. Setting the noBuffer option to true will prevent buffering of the mouse
  211 + events.
  212 + </description>
  213 + <defaultvalue>false</defaultvalue>
  214 + </property>
  215 +
  216 + <property>
  217 + <name>size</name>
  218 + <classname>int</classname>
  219 + <description>
  220 + This is the maximum value (in pixels) of the minor axis dimension for the 'at rest' images. For example,
  221 + an image of natural dimensions 90x120 (width x height), placed in a horizontal Dock (say, 'align' =
  222 + 'bottom') would, by default, be sized down to 36x48. This is because height is the minor axis in a
  223 + horizontal Dock, and to keep the presentation of the 'at rest' images neat and tidy it is the height
  224 + that is governed by the size option. Conversely, in a vertical Dock it would be the width that was
  225 + capped at the size value, with height being set proportionately.
  226 + </description>
  227 + <defaultvalue>48</defaultvalue>
  228 + </property>
  229 +
  230 + <property>
  231 + <name>step</name>
  232 + <classname>int</classname>
  233 + <description>
  234 + The timer interval (in milliseconds) between each animation step of the 'on-Dock' expansion, and the
  235 + 'off-Dock' shrinkage.
  236 + </description>
  237 + <defaultvalue>50</defaultvalue>
  238 + </property>
  239 +
  240 + </component>
  241 +</components>
  1 +package org.richfaces.component;
  2 +
  3 +import javax.faces.component.UIComponentBase;
  4 +
  5 +public abstract class UIDock extends UIComponentBase {
  6 +// ------------------------------ FIELDS ------------------------------
  7 +
  8 + public static final String COMPONENT_FAMILY = "org.richfaces.Dock";
  9 +
  10 + public static final String COMPONENT_TYPE = "org.richfaces.Dock";
  11 +
  12 + public static final boolean DEFAULT_ACTIVE = false;
  13 +
  14 +// -------------------------- OTHER METHODS --------------------------
  15 +
  16 + public abstract int getActive();
  17 +
  18 + public abstract String getAlign();
  19 +
  20 + public abstract double getCoefficient();
  21 +
  22 + public abstract int getDistance();
  23 +
  24 + public abstract int getDuration();
  25 +
  26 + public abstract int getFadeIn();
  27 +
  28 + public abstract String getFadeLayer();
  29 +
  30 + public abstract int getIdle();
  31 +
  32 + public abstract int getInactivity();
  33 +
  34 + public abstract String getLabels();
  35 +
  36 + public abstract String getLoader();
  37 +
  38 + public abstract int getSize();
  39 +
  40 + public abstract int getStep();
  41 +
  42 + public abstract String getStyle();
  43 +
  44 + public abstract String getStyleClass();
  45 +
  46 + public abstract boolean isFlow();
  47 +
  48 + public abstract boolean isNoBuffer();
  49 +
  50 + public abstract void setActive(int active);
  51 +
  52 + public abstract void setAlign(String align);
  53 +
  54 + public abstract void setCoefficient(double coefficient);
  55 +
  56 + public abstract void setDistance(int distance);
  57 +
  58 + public abstract void setDuration(int duration);
  59 +
  60 + public abstract void setFadeIn(int fadeIn);
  61 +
  62 + public abstract void setFadeLayer(String fadeLayer);
  63 +
  64 + public abstract void setFlow(boolean flow);
  65 +
  66 + public abstract void setIdle(int idle);
  67 +
  68 + public abstract void setInactivity(int inactivity);
  69 +
  70 + public abstract void setLabels(String labels);
  71 +
  72 + public abstract void setLoader(String loader);
  73 +
  74 + public abstract void setNoBuffer(boolean noBuffer);
  75 +
  76 + public abstract void setSize(int size);
  77 +
  78 + public abstract void setStep(int step);
  79 +
  80 + public abstract void setStyle(String style);
  81 +
  82 + public abstract void setStyleClass(String styleClass);
  83 +}
  1 +/*
  2 + * JBoss, Home of Professional Open Source
  3 + * Copyright , Red Hat, Inc. and individual contributors
  4 + * by the @authors tag. See the copyright.txt in the distribution for a
  5 + * full listing of individual contributors.
  6 + *
  7 + * This is free software; you can redistribute it and/or modify it
  8 + * under the terms of the GNU Lesser General Public License as
  9 + * published by the Free Software Foundation; either version 2.1 of
  10 + * the License, or (at your option) any later version.
  11 + *
  12 + * This software is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15 + * Lesser General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU Lesser General Public
  18 + * License along with this software; if not, write to the Free
  19 + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20 + * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21 + */
  22 +
  23 +package org.richfaces.renderkit.html;
  24 +
  25 +import org.ajax4jsf.javascript.JSFunction;
  26 +import org.ajax4jsf.renderkit.HeaderResourcesRendererBase;
  27 +import org.ajax4jsf.renderkit.RendererUtils.HTML;
  28 +import org.ajax4jsf.resource.InternetResource;
  29 +import org.richfaces.component.UIDock;
  30 +
  31 +import javax.faces.component.UIComponent;
  32 +import javax.faces.context.FacesContext;
  33 +import javax.faces.context.ResponseWriter;
  34 +import java.io.IOException;
  35 +import java.util.Collection;
  36 +import java.util.Collections;
  37 +import java.util.HashMap;
  38 +import java.util.Map;
  39 +
  40 +public class DockRenderer extends HeaderResourcesRendererBase {
  41 +// ------------------------------ FIELDS ------------------------------
  42 +
  43 + private static final Map<String, Object> DEFAULTS;
  44 +
  45 + private final InternetResource[] scripts = {
  46 + getResource("/org/richfaces/renderkit/html/scripts/jquery/jquery.js"),
  47 + getResource("/org/richfaces/renderkit/html/scripts/jquery.jdock.js"),
  48 + getResource("/org/richfaces/renderkit/html/scripts/richfaces.dock.js")
  49 + };
  50 + private final InternetResource[] styles = {
  51 + getResource("/org/richfaces/renderkit/html/css/dock.xcss")
  52 + };
  53 +
  54 +// -------------------------- STATIC METHODS --------------------------
  55 +
  56 + static {
  57 + Map<String, Object> defaults = new HashMap<String, Object>();
  58 + defaults.put("active", -1);
  59 + defaults.put("align", "bottom");
  60 + defaults.put("coefficient", 1.5);
  61 + defaults.put("duration", 300);
  62 + defaults.put("fadeIn", 0);
  63 + defaults.put("fadeLayer", "");
  64 + defaults.put("flow", false);
  65 + defaults.put("idle", 0);
  66 + defaults.put("inactivity", 0);
  67 + defaults.put("labels", "false");
  68 + defaults.put("loader", "");
  69 + defaults.put("noBuffer", false);
  70 + defaults.put("size", 48);
  71 + defaults.put("step", 50);
  72 + DEFAULTS = Collections.unmodifiableMap(defaults);
  73 + }
  74 +
  75 +// --------------------- GETTER / SETTER METHODS ---------------------
  76 +
  77 + protected Class<? extends UIComponent> getComponentClass() {
  78 + return UIDock.class;
  79 + }
  80 +
  81 + @Override
  82 + protected InternetResource[] getScripts() {
  83 + return scripts;
  84 + }
  85 +
  86 + @Override
  87 + protected InternetResource[] getStyles() {
  88 + return styles;
  89 + }
  90 +
  91 +// -------------------------- OTHER METHODS --------------------------
  92 +
  93 + @Override
  94 + protected void doEncodeBegin(ResponseWriter writer, FacesContext context, UIComponent component) throws IOException {
  95 + writer.startElement(HTML.DIV_ELEM, component);
  96 + final String clientId = getUtils().clientId(context, component);
  97 + writer.writeAttribute(HTML.id_ATTRIBUTE, clientId, HTML.id_ATTRIBUTE);
  98 + writer.startElement(HTML.DIV_ELEM, component);
  99 + writer.writeAttribute(HTML.id_ATTRIBUTE, getContainerClientId(context, component), HTML.id_ATTRIBUTE);
  100 + Object styleClass = component.getAttributes().get("styleClass");
  101 + styleClass = styleClass == null ? "" : " " + styleClass.toString();
  102 + writer.writeAttribute(HTML.class_ATTRIBUTE, "rf-dk" + styleClass, HTML.class_ATTRIBUTE);
  103 + Object style = component.getAttributes().get("style");
  104 + style = style == null ? "" : style.toString();
  105 + writer.writeAttribute(HTML.style_ATTRIBUTE, "display:none;" + style, HTML.style_ATTRIBUTE);
  106 + }
  107 +
  108 + @Override
  109 + protected void doEncodeEnd(ResponseWriter writer, FacesContext context, UIComponent component) throws IOException {
  110 + writer.endElement(HTML.DIV_ELEM);
  111 + writer.startElement(HTML.SCRIPT_ELEM, null);
  112 + writer.writeAttribute(HTML.TYPE_ATTR, "text/javascript", "type");
  113 + writer.writeText(new JSFunction("RichFaces.Dock", getContainerClientId(context, component),
  114 + getOptions((UIDock) component)), null);
  115 + writer.writeText(";", null);
  116 + writer.endElement(HTML.SCRIPT_ELEM);
  117 + writer.endElement(HTML.DIV_ELEM);
  118 + }
  119 +
  120 + private String getContainerClientId(FacesContext context, UIComponent component) {
  121 + return getUtils().clientId(context, component) + "Container";
  122 + }
  123 +
  124 + protected Map<String, Object> getOptions(UIDock dock) throws IOException {
  125 + /**
  126 + * Include only attributes that are actually set.
  127 + */
  128 + Map<String, Object> options = new HashMap<String, Object>();
  129 + addOptionIfSetAndNotDefault("active", dock.getActive(), options);
  130 + addOptionIfSetAndNotDefault("align", dock.getAlign(), options);
  131 + addOptionIfSetAndNotDefault("coefficient", dock.getCoefficient(), options);
  132 + addOptionIfSetAndNotDefault("duration", dock.getDuration(), options);
  133 + addOptionIfSetAndNotDefault("fadeIn", dock.getFadeIn(), options);
  134 + addOptionIfSetAndNotDefault("fadeLayer", dock.getFadeLayer(), options);
  135 + addOptionIfSetAndNotDefault("flow", dock.isFlow(), options);
  136 + addOptionIfSetAndNotDefault("idle", dock.getIdle(), options);
  137 + addOptionIfSetAndNotDefault("inactivity", dock.getInactivity(), options);
  138 + addOptionIfSetAndNotDefault("labels", dock.getLabels(), options);
  139 + addOptionIfSetAndNotDefault("loader", dock.getLoader(), options);
  140 + addOptionIfSetAndNotDefault("noBuffer", dock.isNoBuffer(), options);
  141 + addOptionIfSetAndNotDefault("size", dock.getSize(), options);
  142 + addOptionIfSetAndNotDefault("step", dock.getStep(), options);
  143 + return options;
  144 + }
  145 +
  146 + protected void addOptionIfSetAndNotDefault(String optionName, Object value, Map<String, Object> options) {
  147 + if (value != null && !"".equals(value)
  148 + && !value.equals(DEFAULTS.get(optionName))
  149 + && !(value instanceof Collection && ((Collection) value).size() == 0)
  150 + && !(value instanceof Map && ((Map) value).size() == 0)) {
  151 + options.put(optionName, value);
  152 + }
  153 + }
  154 +}
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<f:template xmlns:f='http:/jsf.exadel.com/template'
  3 +xmlns:u='http:/jsf.exadel.com/template/util'
  4 +xmlns="http://www.w3.org/1999/xhtml" >
  5 +
  6 + <f:verbatim>
  7 +.rf-dk a {
  8 + text-decoration:none;
  9 +}
  10 + </f:verbatim>
  11 +
  12 + <u:selector name=".rf-dk .jqDockLabelText">
  13 + <u:style name="color" skin="generalTextColor"/>
  14 + <u:style name="font-weight" value="bold"/>
  15 + <u:style name="font-size" skin="generalSizeFont"/>
  16 + <u:style name="font-family" skin="generalFamilyFont"/>
  17 + </u:selector>
  18 +
  19 +</f:template>
  1 +/*
  2 + jquery.jqDock.js v1.6
  3 +*/
  4 +(function(k,w){if(!k.jqDock){var v=["Top","Right","Bottom","Left"],N=["Major","Minor"],z=["mouseenter","mousemove","mouseleave"],x=["docknudge","dockidle","dockfreeze"],s=["Idler","Inactive","Indock","Overdock","Offdock"],E=['<div style="position:relative;padding:0;',"margin:0;border:0 none;background-color:transparent;",'">'],p={v:{wh:"height",xy:1,tl:"top",lead:0,trail:2,inv:"h"},h:{wh:"width",xy:0,tl:"left",lead:3,trail:1,inv:"v"}},m=[],F=[0,0],X=function(){},C=function(a){a=parseInt(a,10);return isNaN(a)?
  5 +0:a},t=function(a,d){for(var c=s[d]?d+1:s.length;d<c&&c--;)if(a[s[c]]){w.clearTimeout(a[s[c]]);a[s[c]]=null}},A=function(a){return a?1*((a.id||"").match(/^jqDock(\d+)$/)||[0,-1])[1]:-1},Y=function(){var a=m[A(k(".jqDockFilter",this).add(this).css({filter:""}).removeClass("jqDockFilter").filter(".jqDock")[0])];if(a){a.Asleep=false;a.Menu.trigger("dockshow",["ready"]).trigger(x[0])}},G=function(a,d){for(var c=true,e=m.length,b;a&&c&&e--&&m[e].Elem;)for(b=m[e].Elem.length;c&&b--;)c=m[e].Elem[b].Img[0]!==
  6 +a;return c?!c:d?[e,b]:m[e].Elem[b]},H=function(a){var d=(new Date).getTime();a=a?a.Stamp+a.Opts.duration:0;if(a>d)d-=a-d;return d},O=function(a){var d=m[a.data.id],c=d.Elem[a.data.idx];c.height=this.height;c.width=this.width;--d.Load<=0&&w.setTimeout(function(){k.jqDock.initDock(a.data.id)},0)},Z=function(a,d){for(var c;a&&a.ownerDocument&&a!==d;){if(c=a.className.toString().match(/jqDockMouse(\d+)/))return 1*c[1];a=a.parentNode}return-1},P=function(a,d,c){var e={},b=p[c].wh;c=p[p[c].inv].wh;e[b]=
  7 +d;e[c]=Math.round(d*a[c]/a[b]);return e},Q=function(){k(this).prev("img").trigger("click");return false},y=function(a,d){var c=a.Elem[a.Current];if(c&&a.Opts.labels)c.Label.el[d?"show":"hide"]()},R=function(a){var d=p[a.Opts.vh],c=a.Elem.length,e=-1,b=0,f,h,j,i=F[d.xy]-a.Elem[0].Wrap.parent().offset()[d.tl];if(i>=0)for(;e<0&&b<c;b++){f=a.Elem[b];h=f.Pad[d.lead]+f.Pad[d.trail];j=f.Major+h;if(i<j){if(b!=a.Current){y(a);a.Current=b}e=f.Offset+i*(f.Initial+h)/j}else i-=j}return e},S=function(a){for(var d=
  8 +a.childNodes.length,c;d;){c=a.childNodes[--d];if(c.childNodes&&c.childNodes.length)S(c);else c.nodeType==3&&a.removeChild(c)}},T=function(a){a.Menu.css({visibility:"visible"}).show()},D=function(a){var d=a.Opts.idle;if(d){t(a,0);a[s[0]]=w.setTimeout(function(){a.Menu.trigger("dockidle")},d)}},$=function(a,d,c){var e=a.Opts,b=e.labels,f=d.Label,h;f.el=k('<div class="jqDockLabel jqDockLabel'+d.Link+'" style="position:absolute;margin:0;"></div>').hide().insertAfter(d.Img);if(b){h=b.charAt(0)=="b";b=
  9 +b.charAt(1)=="r";f.el.css({top:h?"auto":0,left:b?"auto":0,bottom:h?0:"auto",right:b?0:"auto"}).click(Q)}a=e.setLabel.call(a.Menu[0],d.Title,c,f.el[0]);a!==false&&k('<div class="jqDockLabelText">'+a.toString()+"</div>").appendTo(f.el)},I=function(a,d){var c=m[a],e=c.Opts,b=p[e.vh].wh,f=c.Elem.length,h,j,i;for(d=d||d===0?d:R(c);f--;){h=c.Elem[f];i=h.Initial;if(d>=0){j=Math.abs(d-h.Centre);if(j<e.distance)i=h[b]-Math.round((h[b]-h.Initial)*Math.pow(j,e.coefficient)/e.attenuation);if(f==c.Current){j=
  10 +[F[p[e.vh].xy],c.Current,i].join(",");if(j===c.ToFro[0]&&i!==c.ToFro[2])i=c.ToFro[2];else c.ToFro=[c.ToFro[1],j,i]}}h.Final=i}},aa=function(a){return a},U=function(a,d,c,e){a=m[a];var b=a.Elem[d],f=a.Opts,h=a.Yard,j=p[f.vh],i=p[j.inv],n=b.src!=b.altsrc,o,g,l;if(e||b.Major!=c){o=k.boxModel||f.vh=="v"?0:a.Border[j.lead]+a.Border[j.trail];if(n&&!e&&b.Major==b.Initial)b.Img[0].src=b.altsrc;a.Spread+=c-b.Major;g=P(b,c,f.vh);l=f.size-g[i.wh];if({top:1,left:1}[f.align])g["margin"+v[i.trail]]=l;else if({middle:1,
  11 +center:1}[f.align]){g["margin"+v[i.lead]]=(l+l%2)/2;g["margin"+v[i.trail]]=(l-l%2)/2}else g["margin"+v[i.lead]]=l;if(c!=b.Major||e&&!d){f.flow&&h.parent()[j.wh](a.Spread+a.Border[j.lead]+a.Border[j.trail]);h[j.wh](a.Spread+o)}b.Wrap.css(g);f.flow||h.css(j.tl,Math.floor(Math.max(0,(a[j.wh]-a.Spread)/2)));if(a.OnDock){d=!a.Stamp;f=a.Opts.labels;h=p[a.Opts.vh];j=a.Elem[a.Current];var q,r;if(j&&f){o=j.Label;l=o.el;if(o.mc){o.mc=0;for(q in p){o[q]=l[p[q].wh]();for(r in{lead:1,trail:1})o[q]+=C(l.css("padding"+
  12 +v[p[q][r]]))}}f.charAt(0)=="m"&&l.css({top:Math.floor((j[N[p[h.inv].xy]]-o.v)/2)});f.charAt(1)=="c"&&l.css({left:Math.floor((j[N[h.xy]]-o.h)/2)})}d&&y(a,1)}b.Major=c;b.Minor=g[i.wh];if(n&&!e&&c==b.Initial)b.Img[0].src=b.src}},J=function(a){var d=m[a],c=d.Opts,e=p[c.vh],b=c.duration+c.step,f=0,h;if(d.Stamp){b=H()-d.Stamp;if(b>=c.duration)d.Stamp=0}if(b>=c.step){for(h=(c.duration-b)/c.step;f<d.Elem.length;f++){c=d.Elem[f];b=(b=c.Final-c.Major)&&h>1?c.Major+Math[b<0?"floor":"ceil"](b/h):c.Final;U(a,
  13 +f,b)}if(d.Spread>d[e.wh]){d.Yard.parent()[e.wh](d.Spread+d.Border[e.lead]+d.Border[e.trail]);d[e.wh]=d.Spread}}},K=function(a,d){var c=m[a],e=c.Elem,b=e.length;t(c,2);if(c.OnDock&&!c.Stamp){for(I(a,d);b--&&e[b].Major==e[b].Final;);if(b<0)y(c,1);else{J(a);c[s[2]]=w.setTimeout(function(){K(a,d)},c.Opts.step)}}},V=function(a,d){var c=m[a],e=c.Elem,b=e.length;if(!c.OnDock){for(;b--&&e[b].Major<=e[b].Initial;);R(c);if(b<0){c.Stamp=0;for(b=e.length;b--;)e[b].Major=e[b].Final=e[b].Initial;c.Current=-1;d||
  14 +D(c)}else{J(a);c[s[4]]=w.setTimeout(function(){V(a,d)},c.Opts.step)}}},W=function(a,d){var c=m[a],e=c.Elem,b=e.length;if(c.OnDock){for(I(a,d);b--&&e[b].Major==e[b].Final;);if(b<0||!c.Stamp){c.Stamp=0;K(a,d)}else{J(a);c[s[3]]=w.setTimeout(function(){W(a,d)},c.Opts.step)}}},B=function(a,d,c,e){var b=m[d],f=b.Elem,h=f.length;if(a===0){b.OnDock=1;b.Current>=0&&b.Current!==c&&y(b);b.Current=c;b.Stamp=e&&e>1?0:H(b);W(d,e?f[c].Centre:null)}if(a===1){if(c!==b.Current){y(b);b.Current=c}K(d)}if(a===2){t(b,
  15 +1);b.OnDock=0;y(b);for(b.Stamp=H(b);h--;)f[h].Final=f[h].Initial;V(d,!!e)}},L=function(a){var d=A(this),c=m[d],e=c?Z(a.target,this):-1,b=-1,f;if(c)if(c.Asleep){if(!c.Opts.noBuffer)c.Sleeper={target:a.target,type:a.type,pageX:a.pageX,pageY:a.pageY}}else{f=c.OnDock;t(c,0);F=[a.pageX,a.pageY];if(a.type==z[2])if(f)b=2;else D(c);else{if(c.Opts.inactivity){t(c,1);c[s[1]]=w.setTimeout(function(){B(2,d,e,1)},c.Opts.inactivity)}if(a.type==z[1])if(e<0){if(f&&c.Current>=0)b=2}else b=!f||c.Current<0?0:1;else if(e>=
  16 +0&&!f)b=0}c.Sleeper=null;b>=0&&B(b,d,e)}},M=function(a){var d=k(".jqDock",this).get(0),c=A(d),e=m[c],b=a.type==x[2],f=b?"freeze":"sleep";if(e)if(a.type==x[0]){f=e.Frozen?"thaw":"wake";if(e.Asleep&&!(e.Asleep=e.Opts.onWake.call(this,f)===false))e.Frozen=!k(this).trigger("dockwake",[f]);if(!e.Asleep){D(e);e.Sleeper&&L.call(d,e.Sleeper)}}else{t(e,0);a=!e.Asleep||b&&!e.Frozen;if(!a||e.Opts.onSleep.call(e.Menu[0],f)!==false){e.Asleep=!t(e,b?-1:1);e.Frozen=e.Frozen||b;a&&e.Menu.trigger("docksleep",[f]);
  17 +if(b)e.Stamp=e.OnDock=0;else B(2,c,0,1)}}};k.jqDock=function(){return{version:1.6,defaults:{size:48,distance:72,coefficient:1.5,duration:300,align:"bottom",labels:0,source:0,loader:0,inactivity:0,fadeIn:0,fadeLayer:"",step:50,setLabel:0,flow:0,idle:0,onReady:0,onSleep:0,onWake:0,noBuffer:0,active:-1},useJqLoader:k.browser.opera||k.browser.safari,initDock:function(a){var d=m[a],c=d.Opts,e=p[c.vh],b=p[e.inv],f=d.Border,h=d.Elem.length,j=E.join(""),i=0,n=0,o,g,l,q=c.fadeLayer;S(d.Menu[0]);for(d.Menu.children().each(function(r,
  18 +u){var ba=d.Elem[r].Wrap=k(u).wrap(j+j+"</div></div>").parent();c.vh=="h"&&ba.parent().css("float","left")}).find("img").andSelf().css({position:"relative",padding:0,margin:0,borderWidth:0,borderStyle:"none",verticalAlign:"top",display:"block",width:"100%",height:"100%"});n<h;){g=d.Elem[n++];l=P(g,c.size,e.inv);g.Major=g.Final=g.Initial=l[e.wh];g.Wrap.css(l);g.Img.attr({alt:""}).parent("a").andSelf().removeAttr("title");d[b.wh]=Math.max(d[b.wh],c.size+g.Pad[b.lead]+g.Pad[b.trail]);g.Offset=i;g.Centre=
  19 +i+g.Pad[e.lead]+g.Initial/2;i+=g.Initial+g.Pad[e.lead]+g.Pad[e.trail]}for(n=0;n<h;){g=d.Elem[n++];l=g.Pad[e.lead]+g.Pad[e.trail];d.Spread+=g.Initial+l;for(o in{Centre:1,Offset:1}){I(a,g[o]);i=0;for(b=h;b--;)i+=d.Elem[b].Final+l;if(i>d[e.wh])d[e.wh]=i}}for(;n;){g=d.Elem[--n];g.Final=g.Initial}e=[E[0],E[2],'<div id="jqDock',a,'" class="jqDock" style="position:absolute;top:0;left:0;padding:0;margin:0;overflow:visible;height:',d.height,"px;width:",d.width,'px;"></div></div>'].join("");d.Yard=k("div.jqDock",
  20 +d.Menu.wrapInner(e));for(b=4;b--;)f[b]=C(d.Yard.css("border"+v[b]+"Width"));for(d.Yard.parent().addClass("jqDockWrap").width(d.width+f[1]+f[3]).height(d.height+f[0]+f[2]);n<h;n++){g=d.Elem[n];l=g.Wrap.parent();for(b=4;b--;)g.Pad[b]&&l.css("padding"+v[b],g.Pad[b]);U(a,n,g.Final,true);l.add(g.Img).addClass("jqDockMouse"+n);$(d,g,n)}g=d.Menu.bind(x.join(" "),M);d.Yard.bind(z.join(" "),L).find("*").css({filter:"inherit"});d.Elem[c.active]&&B(0,a,c.active,2);if(!(d.Asleep=c.onReady.call(d.Menu[0],"ready")===
  21 +false))if(q){if(q!="menu"){g=d.Yard;if(q=="wrap")g=g.parent()}d.Asleep=!!k(".jqDock,.jqDockWrap",g).addClass("jqDockFilter").css({filter:"inherit"});g.css({opacity:0});T(d);g.animate({opacity:1},c.fadeIn,Y)}else{T(d);d.Menu.trigger("dockshow",["ready"]);D(d)}}}}();k.fn.jqDock=function(a){if(a==="nudge"||a==="idle"||a==="freeze")this.filter(".jqDocked").each(function(){M.call(this,{type:"dock"+a})});else if(a==="destroy")this.filter(".jqDocked").each(function(){var c=A(k(".jqDock",k(this).removeClass("jqDocked")).get(0)),
  22 +e=m[c],b=z.length,f,h,j;if(e){for(t(e,-1);b--;)e.Yard.unbind(z[b],L);for(b=x.length;b--;)e.Menu.unbind(x[b],M);for(b=0;b<e.Elem.length;b++){h=e.Elem[b];j=h.Img;h.Label.el.unbind("click",Q).remove();j.attr(h.Orig.i).removeClass("jqDockMouse"+b);h.Orig.i.style||j.removeAttr("style");if(h.Link=="Link"){j.parent().attr(h.Orig.a);h.Orig.a.style||j.parent().removeAttr("style")}e.Menu.append(h.Wrap.children());h.Label.el=h.Orig.i=h.Orig.a=null;for(f in h)h[f]=null}k(".jqDockWrap",e.Menu).remove();for(b in e)e[b]=
  23 +null;m[c]=null}for(c=m.length;c--&&m[c]===null;);if(c<0)m=[]});else if(a==="active"||a==="expand")this.each(function(){var c=G(this,1),e=c?m[c[0]]:0;if(e){t(e,-1);if(!e.Frozen)e.Frozen=e.Asleep=!!e.Menu.trigger("docksleep",["freeze"]);B(0,c[0],c[1],a=="active"?2:1)}});else if(a==="get"){var d=this.filter(".jqDocked");return(d=d.length?m[A(k(".jqDock",d).get(0))]:G(this.get(0)))?k.extend(true,{},d):null}else this.length&&!this.not("img").length?this.each(function(c,e){var b=G(e),f=0,h,j,i;a=a||{};
  24 +if(b){h=b.Major==b.Initial;for(i in{src:1,altsrc:1})if(a[i]){j=(k.isFunction(a[i])?a[i].call(e,b[i],i):a[i]).toString();if(b[i]!==j){b[i]=j;f=(i=="src"?h:!h)?i:f}}f&&k(e).attr("src",b[f])}}):this.not(".jqDocked").filter(function(){return!k(this).parents(".jqDocked").length&&!k(this).children().not("img").filter(function(){return k(this).filter("a").children("img").parent().children().length!==1}).length}).addClass("jqDocked").each(function(){var c=k(this),e=m.length,b,f,h,j,i;m[e]={Elem:[],Menu:c,
  25 +OnDock:0,Stamp:0,width:0,height:0,Spread:0,Border:[],Opts:k.extend({},k.jqDock.defaults,a||{},k.metadata?c.metadata():{}),Current:-1,Load:0,ToFro:["","",0]};b=m[e];f=b.Opts;h=!f.loader&&k.jqDock.useJqLoader||f.loader==="jquery";for(i in{size:1,distance:1,duration:1,inactivity:1,fadeIn:1,step:1,idle:1,active:1})f[i]=C(f[i]);i=f.coefficient*1;f.coefficient=isNaN(i)?1.5:i;f.labels=/^[tmb][lcr]$/.test(f.labels.toString())?f.labels:f.labels?{top:"br",left:"tr"}[f.align]||"tl":"";f.setLabel=f.setLabel?
  26 +f.setLabel:aa;f.fadeLayer=f.fadeIn?{dock:1,wrap:1}[f.fadeLayer]?f.fadeLayer:"menu":"";for(i in{onSleep:1,onWake:1,onReady:1,onFreeze:1})f[i]||(f[i]=X);j=/^m|c$/.test(f.labels);f.attenuation=Math.pow(f.distance,f.coefficient);f.vh={left:1,center:1,right:1}[f.align]?"v":"h";k("img",c).each(function(n,o){var g=k(o),l=g.parent("a"),q=l.attr("title")||"",r={},u;for(u in{src:1,alt:1,title:1,style:1})r[u]=g.attr(u)||"";++b.Load;b.Elem[n]={Img:g,src:r.src,altsrc:(f.source?f.source.call(o,n):"")||(/\.(gif|jpg|jpeg|png)$/i.test(r.alt||
  27 +"")?r.alt:"")||r.src,Title:r.title||q||"",Orig:{i:k.extend({},r),a:{title:q,style:l.attr("style")||""}},Label:{mc:j},Pad:[],Link:l.length?"Link":"Image"};for(u=4;u--;)b.Elem[n].Pad[u]=C(g.css("padding"+v[u]))});k.each(b.Elem,function(n,o){var g,l=o.altsrc;if(h)k("<img>").bind("load",{id:e,idx:n},O).attr({src:l});else{g=new Image;g.onload=function(){O.call(this,{data:{id:e,idx:n}});g.onload="";g=null};g.src=l}})});return this}}})(jQuery,window);
  1 +/*
  2 + * JBoss, Home of Professional Open Source
  3 + * Copyright , Red Hat, Inc. and individual contributors
  4 + * by the @authors tag. See the copyright.txt in the distribution for a
  5 + * full listing of individual contributors.
  6 + *
  7 + * This is free software; you can redistribute it and/or modify it
  8 + * under the terms of the GNU Lesser General Public License as
  9 + * published by the Free Software Foundation; either version 2.1 of
  10 + * the License, or (at your option) any later version.
  11 + *
  12 + * This software is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15 + * Lesser General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU Lesser General Public
  18 + * License along with this software; if not, write to the Free
  19 + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20 + * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21 + */
  22 +
  23 +window.RichFaces = window.RichFaces || {};
  24 +RichFaces.Dock = function(clientId, options) {
  25 + var container = jQuery(document.getElementById(clientId));
  26 + /**
  27 + * Move all scripts generated by children out of container (jDock requirement).
  28 + */
  29 + container.children().filter("script").appendTo(container.parent());
  30 + return container.jqDock(options);
  31 +};
  1 +<?xml version="1.0"?>
  2 +<project>
  3 + <parent>
  4 + <artifactId>ui</artifactId>
  5 + <groupId>org.richfaces.sandbox</groupId>
  6 + <version>3.3.4-SNAPSHOT</version>
  7 + </parent>
  8 + <modelVersion>4.0.0</modelVersion>
  9 + <groupId>org.richfaces.sandbox.ui</groupId>
  10 + <artifactId>focus</artifactId>
  11 + <name>focus</name>
  12 + <build>
  13 + <plugins>
  14 + <plugin>
  15 + <groupId>org.richfaces.cdk</groupId>
  16 + <artifactId>maven-cdk-plugin</artifactId>
  17 + <version>${project.version}</version>
  18 + <executions>
  19 + <execution>
  20 + <phase>generate-sources</phase>
  21 + <goals>
  22 + <goal>generate</goal>
  23 + </goals>
  24 + </execution>
  25 + </executions>
  26 + <configuration>
  27 + <library>
  28 + <prefix>org.richfaces</prefix>
  29 + <taglib>
  30 + <shortName>focus</shortName>
  31 + <uri>http://richfaces.org/sandbox/focus</uri>
  32 + </taglib>
  33 + </library>
  34 + </configuration>
  35 + </plugin>
  36 + <plugin>
  37 + <artifactId>maven-compiler-plugin</artifactId>
  38 + <inherited>true</inherited>
  39 + <configuration>
  40 + <source>1.5</source>
  41 + <target>1.5</target>
  42 + <encoding>${project.build.sourceEncoding}</encoding>
  43 + </configuration>
  44 + </plugin>
  45 + <plugin>
  46 + <groupId>org.apache.maven.plugins</groupId>
  47 + <artifactId>maven-resources-plugin</artifactId>
  48 + <version>2.2</version>
  49 + <configuration>
  50 + <encoding>${project.build.sourceEncoding}</encoding>
  51 + </configuration>
  52 + </plugin>
  53 + </plugins>
  54 + </build>
  55 + <dependencies>
  56 + <dependency>
  57 + <groupId>org.richfaces.framework</groupId>
  58 + <artifactId>richfaces-impl</artifactId>
  59 + <version>${project.version}</version>
  60 + </dependency>
  61 + </dependencies>
  62 + <properties>
  63 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  64 + </properties>
  65 + <distributionManagement>
  66 + <snapshotRepository>
  67 + <id>bernard.labno.pl</id>
  68 + <name>MyCo Internal Repository</name>
  69 + <url>http://bernard.labno.pl/artifactory/libs-snapshot-local</url>
  70 + </snapshotRepository>
  71 + </distributionManagement>
  72 +
  73 +</project>
  1 +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE components PUBLIC "-//AJAX4JSF//CDK Generator config/EN"
  2 + "http://labs.jboss.com/jbossrichfaces/component-config.dtd" >
  3 +<components>
  4 + <component>
  5 + <name>org.richfaces.Focus</name>
  6 + <family>org.richfaces.Focus</family>
  7 + <classname>org.richfaces.component.html.HtmlFocus</classname>
  8 + <superclass>org.richfaces.component.UIFocus</superclass>
  9 + <description>
  10 + <![CDATA[Puts focus on rendered field. In case of text inputs it's
  11 + content is selected. If you use it with i.e. radio use suffix
  12 + attribute.
  13 + ]]>
  14 + </description>
  15 + <renderer generate="false" override="false">
  16 + <name>org.richfaces.FocusRenderer</name>
  17 + <classname>org.richfaces.renderkit.html.HtmlFocusRenderer</classname>
  18 + </renderer>
  19 + <tag>
  20 + <name>focus</name>
  21 + <classname>org.richfaces.taglib.FocusTag</classname>
  22 + <superclass>
  23 + org.ajax4jsf.webapp.taglib.HtmlComponentTagBase
  24 + </superclass>
  25 + <test>
  26 + <classname>org.richfaces.taglib.HtmlFocusTagTest</classname>
  27 + <superclassname>org.ajax4jsf.tests.AbstractJspTestCase</superclassname>
  28 + </test>
  29 +
  30 + </tag> &ui_component_attributes;
  31 + <property>
  32 + <name>for</name>
  33 + <classname>java.lang.String</classname>
  34 + <description>
  35 + Id of component that should be focused
  36 + </description>
  37 + <defaultvalue>""</defaultvalue>
  38 + </property>
  39 + <property>
  40 + <name>priority</name>
  41 + <classname>java.lang.Integer</classname>
  42 + <description>
  43 + If there are more components requesting focus, then component with lowest priority will be focused.
  44 + </description>
  45 + </property>
  46 + <property>
  47 + <name>targetClientId</name>
  48 + <classname>java.lang.String</classname>
  49 + <description>
  50 + If some other element then the one matching clintId of target component should be focused and it cannot be achieved with suffix, use this
  51 + attribute.
  52 + </description>
  53 + <defaultvalue>""</defaultvalue>
  54 + </property>
  55 + <property>
  56 + <name>suffix</name>
  57 + <classname>java.lang.String</classname>
  58 + <description>
  59 + Suffix added to clientId. Useful for focusing radio elements. Example : suffix=":0" puts focus on first radio if target is radio.
  60 + </description>
  61 + <defaultvalue>""</defaultvalue>
  62 + </property>
  63 + <property>
  64 + <name>timing</name>
  65 + <classname>java.lang.String</classname>
  66 + <description>
  67 + Moment when focus should be put. The possible values are "onJScall" and "onload". If "onJScall" is used then you must manually call
  68 + Richfaces.FocusManager.focus(). The default value is "onload".
  69 + </description>
  70 + <defaultvalue>"onload"</defaultvalue>
  71 + </property>
  72 + <property>
  73 + <name>name</name>
  74 + <classname>java.lang.String</classname>
  75 + <description>
  76 + Name of JavaScript function generated to trigger focus. This is required if "timing" attribute is set to "onJScall".
  77 + </description>
  78 + <defaultvalue>null</defaultvalue>
  79 + </property>
  80 + </component>
  81 +</components>
  1 +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE components PUBLIC "-//AJAX4JSF//CDK Generator config/EN"
  2 + "http://labs.jboss.com/jbossrichfaces/component-config.dtd" >
  3 +<components>
  4 + <component>
  5 + <name>org.richfaces.FocusModifier</name>
  6 + <family>org.richfaces.FocusModifier</family>
  7 + <classname>org.richfaces.component.html.HtmlFocusModifier</classname>
  8 + <superclass>org.richfaces.component.UIFocusModifier</superclass>
  9 + <description>
  10 + <![CDATA[
  11 + Provides info for focus component used to modify clientId to focus.
  12 + ]]>
  13 + </description>
  14 + <renderer generate="false" override="false">
  15 + <name>org.richfaces.FocusModifierRenderer</name>
  16 + <classname>org.richfaces.renderkit.html.HtmlFocusModifierRenderer</classname>
  17 + </renderer>
  18 + <tag>
  19 + <name>focusModifier</name>
  20 + <classname>org.richfaces.taglib.FocusModifierTag</classname>
  21 + <superclass>
  22 + org.ajax4jsf.webapp.taglib.HtmlComponentTagBase
  23 + </superclass>
  24 + <test>
  25 + <classname>org.richfaces.taglib.HtmlFocusModifierTagTest</classname>
  26 + <superclassname>org.ajax4jsf.tests.AbstractJspTestCase</superclassname>
  27 + </test>
  28 + </tag> &ui_component_attributes;
  29 + <property>
  30 + <name>targetClientId</name>
  31 + <classname>java.lang.String</classname>
  32 + <description>
  33 + If some other element then the one matching clintId of target component should be focused and it cannot be achieved with suffix, use this
  34 + attribute.
  35 + </description>
  36 + <defaultvalue>""</defaultvalue>
  37 + </property>
  38 + <property>
  39 + <name>suffix</name>
  40 + <classname>java.lang.String</classname>
  41 + <description>
  42 + Suffix added to clientId. Useful for focusing radio elements. Example : suffix=":0" puts focu on first radio if target is radio.
  43 + </description>
  44 + <defaultvalue>""</defaultvalue>
  45 + </property>
  46 + <property>
  47 + <name>priority</name>
  48 + <classname>java.lang.Integer</classname>
  49 + <description>
  50 + If there are more components requesting focus, then component with lowest priority will be focused.
  51 + </description>
  52 + </property>
  53 + <property>
  54 + <name>skipped</name>
  55 + <classname>boolean</classname>
  56 + <description>
  57 + If set to true, component will not be concerned when calculating default focus.
  58 + </description>
  59 + <defaultvalue>false</defaultvalue>
  60 + </property>
  61 + </component>
  62 +</components>
  1 +package org.richfaces.component;
  2 +
  3 +import javax.faces.component.UIComponent;
  4 +import javax.faces.component.UIComponentBase;
  5 +import javax.faces.component.UIForm;
  6 +import javax.faces.component.UIInput;
  7 +import javax.faces.context.FacesContext;
  8 +import java.util.*;
  9 +
  10 +public abstract class UIFocus extends UIComponentBase {
  11 +// ------------------------------ FIELDS ------------------------------
  12 +
  13 + public static final String COMPONENT_FAMILY = "org.richfaces.Focus";
  14 +
  15 + public static final String COMPONENT_TYPE = "org.richfaces.Focus";
  16 +
  17 + public static final int DEFAULT_PRIORITY = Integer.MAX_VALUE;
  18 +
  19 + public static final String FOCUS_MODIFIER_FACET_NAME = "focusModifier";
  20 +
  21 + public static final String TIMING_ON_LOAD = "onload";
  22 +
  23 +// -------------------------- STATIC METHODS --------------------------
  24 +
  25 + public static UIFocusModifier findModifier(UIComponent component) {
  26 + if (component instanceof UIFocusModifier) {
  27 + return (UIFocusModifier) component;
  28 + }
  29 + UIFocusModifier modifier = (UIFocusModifier) component.getFacet(UIFocus.FOCUS_MODIFIER_FACET_NAME);
  30 + if (modifier == null) {
  31 + for (UIComponent child : component.getChildren()) {
  32 + modifier = findModifier(child);
  33 + if (modifier != null) {
  34 + break;
  35 + }
  36 + }
  37 + }
  38 + return modifier;
  39 + }
  40 +
  41 +// -------------------------- OTHER METHODS --------------------------
  42 +
  43 + public int calculatePriority(UIComponent component) {
  44 + final UIFocusModifier modifier = findModifier(component);
  45 + if (modifier != null && modifier.getPriority() != null) {
  46 + return modifier.getPriority();
  47 + }
  48 + UIComponent parentForm = component.getParent();
  49 + while (parentForm != null && !(parentForm instanceof UIForm)) {
  50 + parentForm = parentForm.getParent();
  51 + }
  52 + if (parentForm != null) {
  53 + return getUIInputChildrenCount(parentForm, component.getId());
  54 + } else {
  55 + return DEFAULT_PRIORITY;
  56 + }
  57 + }
  58 +
  59 + public abstract String getFor();
  60 +
  61 + public abstract String getName();
  62 +
  63 + public abstract Integer getPriority();
  64 +
  65 + public abstract String getSuffix();
  66 +
  67 + public abstract String getTargetClientId();
  68 +
  69 + public String getTargetComponentId(FacesContext context) {
  70 + String aFor = getFor();
  71 +
  72 + if (aFor != null && !"".equals(aFor)) {
  73 + return aFor;
  74 + } else {
  75 + if (!(getParent() instanceof UIInput)) {
  76 + Set<String> allowedClientIds = new HashSet<String>();
  77 + Iterator<String> clientIdsWithMessages = getFacesContext().getClientIdsWithMessages();
  78 + while (clientIdsWithMessages.hasNext()) {
  79 + final String clientId = clientIdsWithMessages.next();
  80 + if (clientId != null) {
  81 + allowedClientIds.add(clientId);
  82 + }
  83 + }
  84 + final List<UIInput> inputs = new ArrayList<UIInput>();
  85 + getInputs(getParentForm(this), allowedClientIds, inputs);
  86 + UIInput inputWithLowestPriority = null;
  87 + int lowestPriority = Integer.MAX_VALUE;
  88 + for (UIInput input : inputs) {
  89 + final int priority = calculatePriority(input);
  90 + if (priority < lowestPriority) {
  91 + inputWithLowestPriority = input;
  92 + lowestPriority = priority;
  93 + }
  94 + }
  95 + return inputWithLowestPriority == null ? null : inputWithLowestPriority.getClientId(context);
  96 + } else {
  97 + return getParent().getClientId(context);
  98 + }
  99 + }
  100 + }
  101 +
  102 + public abstract String getTiming();
  103 +
  104 + public abstract void setFor(String value);
  105 +
  106 + public abstract void setName(String name);
  107 +
  108 + public abstract void setPriority(Integer value);
  109 +
  110 + public abstract void setSuffix(String value);
  111 +
  112 + public abstract void setTargetClientId(String targetClientId);
  113 +
  114 + public abstract void setTiming(String timing);
  115 +
  116 + private void getInputs(UIComponent parent, Set<String> allowedClientIds, List<UIInput> inputs) {
  117 + FacesContext facesContext = getFacesContext();
  118 + for (UIComponent child : parent.getChildren()) {
  119 + if (child instanceof UIInput && (allowedClientIds.size() == 0 || allowedClientIds.contains(child.getClientId(facesContext)))) {
  120 + final UIFocusModifier modifier = findModifier(child);
  121 + if (modifier == null || !modifier.isSkipped()) {
  122 + inputs.add((UIInput) child);
  123 + }
  124 + }
  125 + getInputs(child, allowedClientIds, inputs);
  126 + }
  127 + }
  128 +
  129 + private UIForm getParentForm(UIComponent component) {
  130 + UIComponent parent = component.getParent();
  131 + if (parent == null) {
  132 + return null;
  133 + }
  134 + if (parent instanceof UIForm) {
  135 + return (UIForm) parent;
  136 + } else {
  137 + return getParentForm(parent);
  138 + }
  139 + }
  140 +
  141 + private int getUIInputChildrenCount(UIComponent component, String breakOnId) {
  142 + final Holder<Integer> childrenCount = new Holder<Integer>();
  143 + childrenCount.value = 0;
  144 + getUIInputChildrenCount(component, breakOnId, childrenCount);
  145 + return childrenCount.value;
  146 + }
  147 +
  148 + private boolean getUIInputChildrenCount(UIComponent component, String breakOnId, Holder<Integer> childrenCount) {
  149 + for (UIComponent child : component.getChildren()) {
  150 + if (child.getId().equals(breakOnId)) {
  151 + return true;
  152 + }
  153 + if (child instanceof UIInput) {
  154 + final UIFocusModifier modifier = findModifier(child);
  155 + if (modifier == null || !modifier.isSkipped()) {
  156 + childrenCount.value++;
  157 + }
  158 + } else {
  159 + if (getUIInputChildrenCount(child, breakOnId, childrenCount)) return true;
  160 + }
  161 + }
  162 + return false;
  163 + }
  164 +
  165 +// -------------------------- INNER CLASSES --------------------------
  166 +
  167 + private class Holder<T> {
  168 +// ------------------------------ FIELDS ------------------------------
  169 +
  170 + public T value;
  171 + }
  172 +}
  1 +package org.richfaces.component;
  2 +
  3 +import javax.faces.component.UIComponentBase;
  4 +
  5 +public abstract class UIFocusModifier extends UIComponentBase {
  6 +// ------------------------------ FIELDS ------------------------------
  7 +
  8 + public static final String COMPONENT_FAMILY = "org.richfaces.Focus";
  9 +
  10 + public static final String COMPONENT_TYPE = "org.richfaces.FocusModifier";
  11 +
  12 +// -------------------------- OTHER METHODS --------------------------
  13 +
  14 + public abstract Integer getPriority();
  15 +
  16 + public abstract String getSuffix();
  17 +
  18 + public abstract String getTargetClientId();
  19 +
  20 + public abstract boolean isSkipped();
  21 +
  22 + public abstract void setPriority(Integer priority);
  23 +
  24 + public abstract void setSkipped(boolean skipped);
  25 +
  26 + public abstract void setSuffix(String value);
  27 +
  28 + public abstract void setTargetClientId(String focusClientId);
  29 +}
  1 +/*
  2 + * JBoss, Home of Professional Open Source
  3 + * Copyright , Red Hat, Inc. and individual contributors
  4 + * by the @authors tag. See the copyright.txt in the distribution for a
  5 + * full listing of individual contributors.
  6 + *
  7 + * This is free software; you can redistribute it and/or modify it
  8 + * under the terms of the GNU Lesser General Public License as
  9 + * published by the Free Software Foundation; either version 2.1 of
  10 + * the License, or (at your option) any later version.
  11 + *
  12 + * This software is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15 + * Lesser General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU Lesser General Public
  18 + * License along with this software; if not, write to the Free
  19 + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20 + * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21 + */
  22 +
  23 +package org.richfaces.renderkit.html;
  24 +
  25 +import org.ajax4jsf.renderkit.RendererBase;
  26 +import org.richfaces.component.UIFocusModifier;
  27 +
  28 +import javax.faces.component.UIComponent;
  29 +
  30 +public class HtmlFocusModifierRenderer extends RendererBase {
  31 +
  32 + protected Class<? extends UIComponent> getComponentClass() {
  33 + return UIFocusModifier.class;
  34 + }
  35 +}
  1 +/*
  2 + * JBoss, Home of Professional Open Source
  3 + * Copyright , Red Hat, Inc. and individual contributors
  4 + * by the @authors tag. See the copyright.txt in the distribution for a
  5 + * full listing of individual contributors.
  6 + *
  7 + * This is free software; you can redistribute it and/or modify it
  8 + * under the terms of the GNU Lesser General Public License as
  9 + * published by the Free Software Foundation; either version 2.1 of
  10 + * the License, or (at your option) any later version.
  11 + *
  12 + * This software is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15 + * Lesser General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU Lesser General Public
  18 + * License along with this software; if not, write to the Free
  19 + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20 + * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21 + */
  22 +
  23 +package org.richfaces.renderkit.html;
  24 +
  25 +import org.ajax4jsf.javascript.JSFunction;
  26 +import org.ajax4jsf.javascript.JSFunctionDefinition;
  27 +import org.ajax4jsf.renderkit.HeaderResourcesRendererBase;
  28 +import org.ajax4jsf.renderkit.RendererUtils;
  29 +import org.ajax4jsf.resource.InternetResource;
  30 +import org.richfaces.component.UIFocus;
  31 +import org.richfaces.component.UIFocusModifier;
  32 +
  33 +import javax.faces.FacesException;
  34 +import javax.faces.component.UIComponent;
  35 +import javax.faces.component.UIInput;
  36 +import javax.faces.context.FacesContext;
  37 +import javax.faces.context.ResponseWriter;
  38 +import java.io.IOException;
  39 +
  40 +public class HtmlFocusRenderer extends HeaderResourcesRendererBase {
  41 +// ------------------------------ FIELDS ------------------------------
  42 +
  43 + private final InternetResource[] scripts = {
  44 + getResource("/org/ajax4jsf/javascript/scripts/prototype.js"),
  45 + getResource("/org/richfaces/renderkit/html/scripts/focus.js"),
  46 + };
  47 +
  48 + private final InternetResource[] styles = {};
  49 +
  50 +// --------------------- GETTER / SETTER METHODS ---------------------
  51 +
  52 + @Override
  53 + protected InternetResource[] getScripts() {
  54 + return scripts;
  55 + }
  56 +
  57 + @Override
  58 + protected InternetResource[] getStyles() {
  59 + return styles;
  60 + }
  61 +
  62 + private void checkValidity(FacesContext context, UIFocus component) {
  63 + String clientId = getUtils().clientId(context, component);
  64 + String name = component.getName();
  65 + String timing = component.getTiming();
  66 + String _for = component.getFor();
  67 + String targetClientId = component.getTargetClientId();
  68 + if ((name == null || "".equals(name.trim())) && "onJScall".equals(timing)) {
  69 + throw new FacesException(
  70 + "The name attribute of the focus component (id='" + clientId + "') must be specified when timing attribute equals to 'onJScall'");
  71 + }
  72 + if (name != null && !"".equals(name.trim()) && !"onJScall".equals(timing)) {
  73 + throw new FacesException(
  74 + "The timing attribute of the focus component (id='" + clientId + "') must be set to 'onJScall' when name attribute is specified");
  75 + }
  76 + if ((_for == null || "".equals(_for)) && (targetClientId == null || "".equals(targetClientId)) && !(component.getParent() instanceof UIInput)
  77 + && getUtils().getNestingForm(context, component) == null) {
  78 + throw new FacesException("Focus component must have either one of 'for' or 'targetClientId' attributes specified or be nested within UIForm or UIInput component");
  79 + }
  80 + }
  81 +
  82 + @Override
  83 + protected void doEncodeEnd(ResponseWriter writer, FacesContext context, UIComponent component)
  84 + throws IOException {
  85 + if (!(component instanceof UIFocus)) {
  86 + return;
  87 + }
  88 + UIFocus uiFocus = (UIFocus) component;
  89 + final String clientId = getUtils().clientId(context, component);
  90 + checkValidity(context, uiFocus);
  91 + Integer priority = uiFocus.getPriority();
  92 + String targetClientId = uiFocus.getTargetClientId();
  93 + if (targetClientId == null || "".equals(targetClientId)) {
  94 + String targetComponentId = uiFocus.getTargetComponentId(context);
  95 + String suffix = uiFocus.getSuffix();
  96 + if (targetComponentId == null || "".equals(targetComponentId)) {
  97 + return;
  98 + }
  99 + UIComponent forcomp = getUtils().findComponentFor(component, targetComponentId);
  100 + if (forcomp == null) {
  101 + throw new FacesException("No component with id=" + targetComponentId + " found!");
  102 + }
  103 + targetClientId = forcomp.getClientId(context);
  104 + UIFocusModifier modifier = UIFocus.findModifier(forcomp);
  105 + if (modifier != null) {
  106 + final String modifiedTargetClientId = modifier.getTargetClientId();
  107 + if (modifiedTargetClientId != null && !modifiedTargetClientId.equals("")) {
  108 + targetClientId = modifiedTargetClientId;
  109 + } else {
  110 + suffix = modifier.getSuffix();
  111 + }
  112 + }
  113 + if (priority == null) {
  114 + priority = uiFocus.calculatePriority(forcomp);
  115 + }
  116 + if (suffix != null && !"".equals(suffix)) {
  117 + targetClientId += suffix;
  118 + }
  119 + }
  120 + if (targetClientId == null || targetClientId.equals("")) {
  121 + return;
  122 + }
  123 + if (priority == null) {
  124 + priority = UIFocus.DEFAULT_PRIORITY;
  125 + }
  126 + writer.startElement(RendererUtils.HTML.SCRIPT_ELEM, null);
  127 + writer.writeAttribute(RendererUtils.HTML.TYPE_ATTR, "text/javascript", "type");
  128 + writer.writeAttribute(RendererUtils.HTML.id_ATTRIBUTE, clientId, RendererUtils.HTML.id_ATTRIBUTE);
  129 + if (UIFocus.TIMING_ON_LOAD.equals(uiFocus.getTiming())) {
  130 + writer.write(new JSFunction("Richfaces.FocusManager.setFocus", targetClientId, priority).toScript());
  131 + writer.write(";");
  132 + } else {
  133 + writer.write(new JSFunction("Richfaces.FocusManager.setFocus", targetClientId, priority, clientId,
  134 + uiFocus.getTiming()).toScript());
  135 + writer.write(";");
  136 + }
  137 + if (uiFocus.getName() != null && !uiFocus.getName().trim().equals("")) {
  138 + final JSFunctionDefinition definition = new JSFunctionDefinition().addToBody(new JSFunction("Richfaces.FocusManager.focusStored", clientId));
  139 + definition.setName(uiFocus.getName());
  140 + writer.write(definition.toScript());
  141 + writer.write(";");
  142 + }
  143 + writer.endElement(RendererUtils.HTML.SCRIPT_ELEM);
  144 + }
  145 +
  146 + protected Class<? extends UIComponent> getComponentClass() {
  147 + return UIFocus.class;
  148 + }
  149 +}
  1 +if (!window.Richfaces) window.Richfaces = {};
  2 +
  3 +Richfaces.FocusManager = (function() {
  4 +
  5 + var m_focus;
  6 + var m_priority = 999999;
  7 + var m_domLoaded = false;
  8 + var m_timing = false;
  9 + var m_focusStore = {};
  10 + /** Constants */
  11 + var TIMING_ON_JS_CALL = "onJScall";
  12 + var TIMING_ON_LOAD = "onload";
  13 +
  14 + var focus = function(element) {
  15 + try {
  16 + if (element == null) {
  17 + if (m_focus == null) {
  18 + return;
  19 + }
  20 + element = $(m_focus);
  21 + }
  22 + if (element != null) {
  23 + element.focus();
  24 + element.select(element);
  25 + }
  26 + } finally {
  27 + Richfaces.FocusManager.clearFocus();
  28 + }
  29 + };
  30 +
  31 + document.observe('dom:loaded', function() {
  32 + if (m_timing == TIMING_ON_LOAD) {
  33 + focus(null);
  34 + }
  35 + m_domLoaded = true;
  36 + });
  37 +
  38 + return {
  39 + focus: focus,
  40 + focusStored: function(focusComponentId) {
  41 + var element = $(m_focusStore[focusComponentId]);
  42 + if (element != null) {
  43 + focus(element);
  44 + }
  45 + },
  46 + getFocus : function() {
  47 + return m_focus;
  48 + },
  49 + setFocus : function(id, priority, focusComponentId, timing) {
  50 + if (priority == null) {
  51 + priority = 99999;
  52 + }
  53 + if (timing != TIMING_ON_JS_CALL) {
  54 + timing = TIMING_ON_LOAD;
  55 + }
  56 + if (focusComponentId != null) {
  57 + m_focusStore[focusComponentId] = id;
  58 + }
  59 + if (m_focus == null || priority < m_priority) {
  60 + m_focus = id;
  61 + m_priority = priority == null ? 0 : priority;
  62 + m_timing = timing;
  63 + if (m_domLoaded && timing == TIMING_ON_LOAD) {
  64 + focus();
  65 + }
  66 + }
  67 + },
  68 + clearFocus : function() {
  69 + m_focus = null;
  70 + m_priority = 999999;
  71 + m_timing = null;
  72 + }
  73 + };
  74 +})();
  1 +<?xml version="1.0"?>
  2 +<project>
  3 + <parent>
  4 + <artifactId>ui</artifactId>
  5 + <groupId>org.richfaces.sandbox</groupId>
  6 + <version>3.3.4-SNAPSHOT</version>
  7 + </parent>
  8 + <modelVersion>4.0.0</modelVersion>
  9 + <groupId>org.richfaces.sandbox.ui</groupId>
  10 + <artifactId>gmapMarker</artifactId>
  11 + <name>gmapMarker</name>
  12 + <build>
  13 + <plugins>
  14 + <plugin>
  15 + <groupId>org.richfaces.cdk</groupId>
  16 + <artifactId>maven-cdk-plugin</artifactId>
  17 + <version>${project.version}</version>
  18 + <executions>
  19 + <execution>
  20 + <phase>generate-sources</phase>
  21 + <goals>
  22 + <goal>generate</goal>
  23 + </goals>
  24 + </execution>
  25 + </executions>
  26 + <configuration>
  27 + <library>
  28 + <prefix>org.richfaces</prefix>
  29 + <taglib>
  30 + <shortName>gmapMarker</shortName>
  31 + <uri>http://richfaces.org/sandbox/gmapMarker</uri>
  32 + </taglib>
  33 + </library>
  34 + </configuration>
  35 + </plugin>
  36 + <plugin>
  37 + <artifactId>maven-compiler-plugin</artifactId>
  38 + <inherited>true</inherited>
  39 + <configuration>
  40 + <source>1.5</source>
  41 + <target>1.5</target>
  42 + <encoding>${project.build.sourceEncoding}</encoding>
  43 + </configuration>
  44 + </plugin>
  45 + <plugin>
  46 + <groupId>org.apache.maven.plugins</groupId>
  47 + <artifactId>maven-resources-plugin</artifactId>
  48 + <version>2.2</version>
  49 + <configuration>
  50 + <encoding>${project.build.sourceEncoding}</encoding>
  51 + </configuration>
  52 + </plugin>
  53 + </plugins>
  54 + </build>
  55 + <dependencies>
  56 + <dependency>
  57 + <groupId>org.richfaces.framework</groupId>
  58 + <artifactId>richfaces-impl</artifactId>
  59 + <version>${project.version}</version>
  60 + </dependency>
  61 + <dependency>
  62 + <groupId>org.richfaces.ui</groupId>
  63 + <artifactId>gmap</artifactId>
  64 + <version>${project.version}</version>
  65 + </dependency>
  66 + </dependencies>
  67 + <properties>
  68 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  69 + </properties>
  70 + <distributionManagement>
  71 + <snapshotRepository>
  72 + <id>bernard.labno.pl</id>
  73 + <name>MyCo Internal Repository</name>
  74 + <url>http://bernard.labno.pl/artifactory/libs-snapshot-local</url>
  75 + </snapshotRepository>
  76 + </distributionManagement>
  77 +</project>
  1 +<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE components PUBLIC "-//AJAX4JSF//CDK Generator config/EN"
  2 + "http://labs.jboss.com/jbossrichfaces/component-config.dtd" >
  3 +<components>
  4 + <component>
  5 + <name>org.richfaces.GmapMarker</name>
  6 + <family>org.richfaces.GmapMarker</family>
  7 + <classname>org.richfaces.component.html.HtmlGmapMarker</classname>
  8 + <superclass>org.richfaces.component.UIGmapMarker</superclass>
  9 + <description>
  10 + <![CDATA[
  11 + Renders Google Map marker. This component must be nested inside <rich:gmap/>.
  12 + ]]>
  13 + </description>
  14 + <renderer generate="true" override="false">
  15 + <name>org.richfaces.GmapMarkerRenderer</name>
  16 + <classname>org.richfaces.renderkit.html.GmapMarkerRenderer</classname>
  17 + </renderer>
  18 + <tag>
  19 + <name>gmapMarker</name>
  20 + <classname>org.richfaces.taglib.GmapMarkerTag</classname>
  21 + <superclass>
  22 + org.ajax4jsf.webapp.taglib.HtmlComponentTagBase
  23 + </superclass>
  24 + <test>
  25 + <classname>org.richfaces.taglib.HtmlGmapMarkerTagTest</classname>
  26 + <superclassname>org.ajax4jsf.tests.AbstractJspTestCase</superclassname>
  27 + </test>
  28 +
  29 + </tag>
  30 + &ui_component_attributes;
  31 + <property required="true">
  32 + <name>latitude</name>
  33 + <classname>java.lang.Double</classname>
  34 + <description>
  35 + The latitude coordinate in degrees, as a number between -90 and +90.
  36 + </description>
  37 + </property>
  38 + <property required="true">
  39 + <name>longitude</name>
  40 + <classname>java.lang.Double</classname>
  41 + <description>
  42 + The longitude coordinate in degrees, as a number between -180 and +180.
  43 + </description>
  44 + </property>
  45 + <property>
  46 + <name>autoPan</name>
  47 + <classname>boolean</classname>
  48 + <description>
  49 + Auto-pan the map as you drag the marker near the edge.
  50 + </description>
  51 + <defaultvalue>true</defaultvalue>
  52 + </property>
  53 + <property>
  54 + <name>bouncy</name>
  55 + <classname>boolean</classname>
  56 + <description>
  57 + Toggles whether or not the marker should bounce up and down after it finishes dragging.
  58 + </description>
  59 + <defaultvalue>false</defaultvalue>
  60 + </property>
  61 + <property>
  62 + <name>bounceGravity</name>
  63 + <classname>java.lang.Double</classname>
  64 + <description>
  65 + When finishing dragging, this number is used to define the acceleration rate of the marker during the
  66 + bounce down to earth.
  67 + </description>
  68 + <defaultvalue>1d</defaultvalue>
  69 + </property>
  70 + <property>
  71 + <name>clickable</name>
  72 + <classname>boolean</classname>
  73 + <description>
  74 + Toggles whether or not the marker is clickable. Markers that are not clickable or draggable are inert,
  75 + consume less resources and do not respond to any events.
  76 + </description>
  77 + <defaultvalue>false</defaultvalue>
  78 + </property>
  79 + <property>
  80 + <name>draggable</name>
  81 + <classname>boolean</classname>
  82 + <description>
  83 + Toggles whether or not the marker will be draggable by users. Markers set up to be dragged require more
  84 + resources to set up than markers that are clickable. Any marker that is draggable is also clickable,
  85 + bouncy and auto-pan enabled by default.
  86 + </description>
  87 + <defaultvalue>false</defaultvalue>
  88 + </property>
  89 + <property>
  90 + <name>dragCrossMove</name>
  91 + <classname>boolean</classname>
  92 + <description>
  93 + When dragging markers normally, the marker floats up and away from the cursor. Setting this value to
  94 + true keeps the marker underneath the cursor, and moves the cross downwards instead.
  95 + </description>
  96 + <defaultvalue>false</defaultvalue>
  97 + </property>
  98 + <property>
  99 + <name>hide</name>
  100 + <classname>boolean</classname>
  101 + <description>
  102 + When true, indicates that the map should not initially display the GMarker. To turn on the overlay, call
  103 + GMarker.show().
  104 + </description>
  105 + <defaultvalue>false</defaultvalue>
  106 + </property>
  107 + <property>
  108 + <name>icon</name>
  109 + <classname>java.lang.String</classname>
  110 + <description>
  111 + Chooses the Icon for this class. If not specified, G_DEFAULT_ICON is used.
  112 + </description>
  113 + <defaultvalue>null</defaultvalue>
  114 + </property>
  115 + <property>
  116 + <name>iconHeight</name>
  117 + <classname>java.lang.Integer</classname>
  118 + <description>
  119 + The height of the icon.
  120 + </description>
  121 + <defaultvalue>null</defaultvalue>
  122 + </property>
  123 + <property>
  124 + <name>iconWidth</name>
  125 + <classname>java.lang.Integer</classname>
  126 + <description>
  127 + The width of the icon.
  128 + </description>
  129 + <defaultvalue>null</defaultvalue>
  130 + </property>
  131 + <property>
  132 + <name>title</name>
  133 + <classname>java.lang.String</classname>
  134 + <description>
  135 + This string will appear as tooltip on the marker, i.e. it will work just as the title attribute on HTML
  136 + elements.
  137 + </description>
  138 + <defaultvalue>null</defaultvalue>
  139 + </property>
  140 + <property>
  141 + <name>onclick</name>
  142 + <classname>java.lang.String</classname>
  143 + <description>
  144 + This event is fired when the marker icon was clicked, passing in the current coordinate of the marker
  145 + within its latlng argument. Notice that
  146 + this event will also fire for the map, with the marker passed as the first argument to the event handler
  147 + there.
  148 + </description>
  149 + <defaultvalue>null</defaultvalue>
  150 + </property>
  151 + </component>
  152 +</components>
  1 +package org.richfaces.component;
  2 +
  3 +import javax.faces.FacesException;
  4 +import javax.faces.component.UIComponent;
  5 +import javax.faces.component.UIComponentBase;
  6 +
  7 +public abstract class UIGmapMarker extends UIComponentBase {
  8 +// ------------------------------ FIELDS ------------------------------
  9 +
  10 + public static final String COMPONENT_FAMILY = "org.richfaces.GmapMarker";
  11 +
  12 + public static final String COMPONENT_TYPE = "org.richfaces.GmapMarker";
  13 + public static final boolean DEFAULT_AUTO_PAN = true;
  14 + public static final Double DEFAULT_BOUNCE_GRAVITY = 1d;
  15 + public static final boolean DEFAULT_DRAG_CROSS_MOVE = false;
  16 + public static final boolean DEFAULT_HIDE = false;
  17 +
  18 +// -------------------------- OTHER METHODS --------------------------
  19 +
  20 + public abstract Double getBounceGravity();
  21 +
  22 + public abstract String getIcon();
  23 +
  24 + public abstract Integer getIconHeight();
  25 +
  26 + public abstract Integer getIconWidth();
  27 +
  28 + public abstract Double getLatitude();
  29 +
  30 + public abstract Double getLongitude();
  31 +
  32 + public abstract String getOnclick();
  33 +
  34 + public UIGmap getParentMap() {
  35 + UIComponent parent = getParent();
  36 + while (parent != null && !(parent instanceof UIGmap)) {
  37 + parent = parent.getParent();
  38 + }
  39 + if (parent == null) {
  40 + throw new FacesException("Component " + getId() + " must be nested within gmap component.");
  41 + }
  42 + return (UIGmap) parent;
  43 + }
  44 +
  45 + public abstract String getTitle();
  46 +
  47 + public abstract boolean isAutoPan();
  48 +
  49 + public abstract boolean isBouncy();
  50 +
  51 + public abstract boolean isClickable();
  52 +
  53 + public abstract boolean isDragCrossMove();
  54 +
  55 + public abstract boolean isDraggable();
  56 +
  57 + public abstract boolean isHide();
  58 +
  59 + public abstract void setAutoPan(boolean autoPan);
  60 +
  61 + public abstract void setBounceGravity(Double bounceGravity);
  62 +
  63 + public abstract void setBouncy(boolean bouncy);
  64 +
  65 + public abstract void setClickable(boolean clickable);
  66 +
  67 + public abstract void setDragCrossMove(boolean dragCrossMove);
  68 +
  69 + public abstract void setDraggable(boolean draggable);
  70 +
  71 + public abstract void setHide(boolean hide);
  72 +
  73 + public abstract void setIcon(String icon);
  74 +
  75 + public abstract void setIconHeight(Integer height);
  76 +
  77 + public abstract void setIconWidth(Integer width);
  78 +
  79 + public abstract void setLatitude(Double latitude);
  80 +
  81 + public abstract void setLongitude(Double longitude);
  82 +
  83 + public abstract void setOnclick(String onclick);
  84 +
  85 + public abstract void setTitle(String title);
  86 +}
  1 +package org.richfaces.renderkit.html;
  2 +
  3 +import org.ajax4jsf.javascript.JSFunction;
  4 +import org.ajax4jsf.javascript.JSLiteral;
  5 +import org.ajax4jsf.javascript.JSObject;
  6 +import org.ajax4jsf.renderkit.HeaderResourcesRendererBase;
  7 +import org.ajax4jsf.renderkit.RendererUtils;
  8 +import org.ajax4jsf.resource.InternetResource;
  9 +import org.richfaces.component.UIGmap;
  10 +import org.richfaces.component.UIGmapMarker;
  11 +
  12 +import javax.faces.FacesException;
  13 +import javax.faces.component.NamingContainer;
  14 +import javax.faces.component.UIComponent;
  15 +import javax.faces.context.FacesContext;
  16 +import javax.faces.context.ResponseWriter;
  17 +import java.io.IOException;
  18 +import java.util.Collections;
  19 +import java.util.HashMap;
  20 +import java.util.Map;
  21 +
  22 +public class GmapMarkerRenderer extends HeaderResourcesRendererBase {
  23 +
  24 + private static final Map<String, Object> DEFAULTS;
  25 +
  26 + /**
  27 + * Following defaults are be used by addOptionIfSetAndNotDefault
  28 + */
  29 + static {
  30 + Map<String, Object> defaults = new HashMap<String, Object>();
  31 + defaults.put("autoPan", UIGmapMarker.DEFAULT_AUTO_PAN);
  32 + defaults.put("hide", UIGmapMarker.DEFAULT_HIDE);
  33 + defaults.put("bounceGravity", UIGmapMarker.DEFAULT_BOUNCE_GRAVITY);
  34 + defaults.put("icon", "");
  35 + defaults.put("zIndexProcess", "");
  36 + defaults.put("title", "");
  37 + defaults.put("iconWidth", "");
  38 + defaults.put("iconHeight", "");
  39 + defaults.put("onclick", "");
  40 + defaults.put("dragCrossMove", UIGmapMarker.DEFAULT_DRAG_CROSS_MOVE);
  41 +
  42 + DEFAULTS = Collections.unmodifiableMap(defaults);
  43 + }
  44 +
  45 + private final InternetResource[] scripts = {
  46 + getResource("script/gmap.js"),
  47 + getResource("/org/richfaces/renderkit/html/scripts/richfaces.gmapmarker.js")
  48 + };
  49 +
  50 + @Override
  51 + protected InternetResource[] getScripts() {
  52 + return scripts;
  53 + }
  54 +
  55 + @Override
  56 + protected Class<? extends UIComponent> getComponentClass() {
  57 + return UIGmapMarker.class;
  58 + }
  59 +
  60 + @Override
  61 + protected void doEncodeEnd(ResponseWriter writer, FacesContext context, UIComponent component) throws IOException {
  62 + UIGmapMarker marker = (UIGmapMarker) component;
  63 + Map<String, Object> options = new HashMap<String, Object>();
  64 + if (marker.getIcon() != null) {
  65 + options.put("icon", new JSObject("GIcon", new JSLiteral("G_DEFAULT_ICON"), marker.getIcon()));
  66 + }
  67 + addOptionIfSetAndNotDefault("clickable", marker.isClickable(), options);
  68 + addOptionIfSetAndNotDefault("draggable", marker.isDraggable(), options);
  69 + addOptionIfSetAndNotDefault("bouncy", marker.isBouncy(), options);
  70 + addOptionIfSetAndNotDefault("autoPan", marker.isAutoPan(), options);
  71 + addOptionIfSetAndNotDefault("hide", marker.isHide(), options);
  72 + addOptionIfSetAndNotDefault("bounceGravity", marker.getBounceGravity(), options);
  73 + addOptionIfSetAndNotDefault("icon", marker.getIcon(), options);
  74 + addOptionIfSetAndNotDefault("title", marker.getTitle(), options);
  75 + addOptionIfSetAndNotDefault("dragCrossMove", marker.isDragCrossMove(), options);
  76 + addOptionIfSetAndNotDefault("iconWidth", marker.getIconWidth(), options);
  77 + addOptionIfSetAndNotDefault("iconHeight", marker.getIconHeight(), options);
  78 + addOptionIfSetAndNotDefault("onclick", marker.getOnclick(), options);
  79 + final UIGmap map = marker.getParentMap();
  80 + final Map<String, Object> mapAttributes = map.getAttributes();
  81 + final Object gmapVar = mapAttributes.get("gmapVar");
  82 + if (gmapVar == null) {
  83 + throw new FacesException("Component " + map.getId() + " must have gmapVar attribute set.");
  84 + }
  85 + final UIComponent infoWindow = marker.getFacet("infoWindow");
  86 + String infoWindowClientId = null;
  87 + if (infoWindow != null) {
  88 + writer.startElement(RendererUtils.HTML.DIV_ELEM, component);
  89 + writer.writeAttribute(RendererUtils.HTML.style_ATTRIBUTE, "display:none", null);
  90 + writer.startElement(RendererUtils.HTML.DIV_ELEM, component);
  91 + infoWindowClientId = marker.getClientId(context) + NamingContainer.SEPARATOR_CHAR + "iW";
  92 + writer.writeAttribute(RendererUtils.HTML.id_ATTRIBUTE, infoWindowClientId, "id");
  93 + infoWindow.encodeAll(context);
  94 + writer.endElement(RendererUtils.HTML.DIV_ELEM);
  95 + writer.endElement(RendererUtils.HTML.DIV_ELEM);
  96 + }
  97 + getUtils().writeScript(context, component,
  98 + new JSFunction("RichFaces.addGmapMarker", gmapVar, marker.getLatitude(), marker.getLongitude(), options, infoWindowClientId)
  99 + );
  100 + Object oninit = mapAttributes.get("oninit");
  101 + if (oninit == null) {
  102 + oninit = "";
  103 + }
  104 + if (!oninit.toString().contains("RichFaces.handleGmapInit")) {
  105 + mapAttributes.put("oninit", oninit + ";" + new JSFunction("RichFaces.handleGmapInit", gmapVar));
  106 + }
  107 +
  108 + }
  109 +
  110 + protected void addOptionIfSetAndNotDefault(String optionName, Object value, Map<String, Object> options) {
  111 + if (value != null && !"".equals(value) && !value.equals(DEFAULTS.get(optionName))) {
  112 + options.put(optionName, value);
  113 + }
  114 + }
  115 +}
  1 +/*
  2 + * JBoss, Home of Professional Open Source
  3 + * Copyright , Red Hat, Inc. and individual contributors
  4 + * by the @authors tag. See the copyright.txt in the distribution for a
  5 + * full listing of individual contributors.
  6 + *
  7 + * This is free software; you can redistribute it and/or modify it
  8 + * under the terms of the GNU Lesser General Public License as
  9 + * published by the Free Software Foundation; either version 2.1 of
  10 + * the License, or (at your option) any later version.
  11 + *
  12 + * This software is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15 + * Lesser General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU Lesser General Public
  18 + * License along with this software; if not, write to the Free
  19 + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20 + * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21 + */
  22 +
  23 +window.RichFaces = window.RichFaces || {};
  24 +RichFaces.GmapMarkers = [];
  25 +RichFaces.addGmapMarker = function(gmapVar, lat, lng, options, infoWindowId) {
  26 + RichFaces.GmapMarkers.push({gmapVar:gmapVar,lat:lat,lng:lng,options:options,infoWindowId:infoWindowId});
  27 + RichFaces.handleGmapInit(gmapVar)
  28 +};
  29 +RichFaces.handleGmapInit = function(gmapVar, event) {
  30 + var gmap = window[gmapVar];
  31 + if (gmap == null) {
  32 + return;
  33 + }
  34 + while (RichFaces.GmapMarkers.length > 0) {
  35 + var data = RichFaces.GmapMarkers.pop();
  36 + if (data.options.icon != null) {
  37 + data.options.icon = new GIcon(G_DEFAULT_ICON, data.options.icon);
  38 + if (data.options.iconWidth != null) {
  39 + data.options.icon.iconSize = new GSize(data.options.iconWidth, data.options.iconHeight);
  40 + }
  41 + }
  42 + var marker = new GMarker(new GLatLng(data.lat, data.lng, true), data.options);
  43 + if (data.options.onclick != null) {
  44 + GEvent.addListener(marker, "click", function(latlng) {
  45 + RichFaces.GmapMarkers.eval(data.options.onclick, {'marker':this,'latlng':latlng});
  46 + })
  47 + }
  48 + gmap.addOverlay(marker);
  49 + if (data.infoWindowId != null) {
  50 + marker.bindInfoWindow(document.getElementById(data.infoWindowId));
  51 + }
  52 + }
  53 +};
  54 +/**
  55 + * This function evaluates code in template with object in ScopeChain.
  56 + * This is usefull if you need to evaluate code that uses member names
  57 + * that colide with external names that the code refers to.
  58 + * There is almost exact method in utils.js called Richfaces.eval,
  59 + * but it swallows exception thrown during evaluation, which makes debugging
  60 + * hard.
  61 + */
  62 +RichFaces.GmapMarkers.eval = function(template, object) {
  63 + var value;
  64 + with (object) {
  65 + value = eval(template);
  66 + }
  67 + return value;
  68 +};
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
  3 + xmlns="http://maven.apache.org/POM/4.0.0"
  4 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  5 + <modelVersion>4.0.0</modelVersion>
  6 + <parent>
  7 + <groupId>org.richfaces.sandbox</groupId>
  8 + <artifactId>ui</artifactId>
  9 + <version>3.3.4-SNAPSHOT</version>
  10 + </parent>
  11 + <groupId>org.richfaces.sandbox.ui</groupId>
  12 + <artifactId>imageSelectTool</artifactId>
  13 + <name>imageSelectTool</name>
  14 + <build>
  15 + <plugins>
  16 + <plugin>
  17 + <groupId>org.richfaces.cdk</groupId>
  18 + <artifactId>maven-cdk-plugin</artifactId>
  19 + <version>${project.version}</version>
  20 + <executions>
  21 + <execution>
  22 + <phase>generate-sources</phase>
  23 + <goals>
  24 + <goal>generate</goal>
  25 + </goals>
  26 + </execution>
  27 + </executions>
  28 + <configuration>
  29 + <library>
  30 + <prefix>org.richfaces.sandbox.ui</prefix>
  31 + <taglib>
  32 + <shortName>imageSelectTool</shortName>
  33 + <uri>http://richfaces.org/sandbox/imageSelectTool</uri>
  34 + </taglib>
  35 + </library>
  36 + </configuration>
  37 + </plugin>
  38 + <plugin>
  39 + <artifactId>maven-compiler-plugin</artifactId>
  40 + <inherited>true</inherited>
  41 + <configuration>
  42 + <source>1.5</source>
  43 + <target>1.5</target>
  44 + <encoding>${project.build.sourceEncoding}</encoding>
  45 + </configuration>
  46 + </plugin>
  47 + <plugin>
  48 + <groupId>org.apache.maven.plugins</groupId>
  49 + <artifactId>maven-resources-plugin</artifactId>
  50 + <version>2.2</version>
  51 + <configuration>
  52 + <encoding>${project.build.sourceEncoding}</encoding>
  53 + </configuration>
  54 + </plugin>
  55 + </plugins>
  56 + </build>
  57 + <dependencies>
  58 + <dependency>
  59 + <groupId>org.richfaces.framework</groupId>
  60 + <artifactId>richfaces-impl</artifactId>
  61 + <version>${project.version}</version>
  62 + </dependency>
  63 + </dependencies>
  64 + <properties>
  65 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  66 + </properties>
  67 + <distributionManagement>
  68 + <snapshotRepository>
  69 + <id>bernard.labno.pl</id>
  70 + <name>MyCo Internal Repository</name>
  71 + <url>http://bernard.labno.pl/artifactory/libs-snapshot-local</url>
  72 + </snapshotRepository>
  73 + </distributionManagement>
  74 +
  75 +</project>
  76 +
Please register or login to post a comment