Commit 1a44c66c22a60d980c0d30f3156c2c48f633ff09
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.
ui/assembly/pom.xml
0 → 100644
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> |
ui/coordinatesGrid-sm/coordinatesGrid.iml
0 → 100755
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 | + |
ui/coordinatesGrid-sm/pom.xml
0 → 100755
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 | +} |
ui/coordinatesGrid-sm/src/main/java/org/richfaces/component/event/CoordinatesGridEventsProducer.java
0 → 100755
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 | +} |
ui/coordinatesGrid-sm/src/main/java/org/richfaces/component/event/CoordinatesRefreshEvent.java
0 → 100644
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 | +} |
ui/coordinatesGrid-sm/src/main/java/org/richfaces/component/event/CoordinatesSelectionEvent.java
0 → 100755
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 | +} |
ui/coordinatesGrid-sm/src/main/java/org/richfaces/component/event/CoordinatesSelectionListener.java
0 → 100755
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 | +} |
ui/coordinatesGrid-sm/src/main/java/org/richfaces/renderkit/html/CoordinatesGridRendererBase.java
0 → 100755
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> |
ui/coordinatesGrid/pom.xml
0 → 100755
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 | +} |
ui/coordinatesGrid/src/main/java/org/richfaces/component/event/CoordinatesGridEventsProducer.java
0 → 100755
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 | +} |
ui/coordinatesGrid/src/main/java/org/richfaces/component/event/CoordinatesRefreshEvent.java
0 → 100644
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 | +} |
ui/coordinatesGrid/src/main/java/org/richfaces/component/event/CoordinatesSelectionEvent.java
0 → 100755
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 | +} |
ui/coordinatesGrid/src/main/java/org/richfaces/component/event/CoordinatesSelectionListener.java
0 → 100755
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 | +} |
ui/coordinatesGrid/src/main/java/org/richfaces/renderkit/html/CoordinatesGridRendererBase.java
0 → 100755
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> |
ui/coordinatesGrid/src/main/templates/readme
0 → 100755
ui/dock/pom.xml
0 → 100644
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> |
ui/dock/src/main/config/component/dock.xml
0 → 100644
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 "<script>", "<a>" | ||
17 | + or "<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('<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 | +}; |
ui/focus/pom.xml
0 → 100644
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> |
ui/focus/src/main/config/component/focus.xml
0 → 100644
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 | +})(); |
ui/gmapMarker/pom.xml
0 → 100644
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 | +} |
ui/gmapMarker/src/main/resources/org/richfaces/renderkit/html/scripts/richfaces.gmapmarker.js
0 → 100644
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 | +}; |
ui/imageSelectTool/pom.xml
0 → 100644
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