Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

version 2.0.0

  • Loading branch information...
commit 2e1821b82ed631d40c7bba4596f0c36d1e9d5fad 1 parent 04c4222
@intercommit authored
Showing with 4,108 additions and 1,699 deletions.
  1. +9 −10 README.md
  2. BIN  binaries/weaves-1.0.0.jar
  3. BIN  binaries/weaves-2.0.0.jar
  4. +29 −5 pom.xml
  5. +0 −2  src/main/java/nl/intercommit/weaves/base/BasicClientElement.java
  6. +188 −0 src/main/java/nl/intercommit/weaves/components/DataTable.java
  7. +43 −35 src/main/java/nl/intercommit/weaves/components/DropDownMenu.java
  8. +3 −0  src/main/java/nl/intercommit/weaves/components/EditableSelectBox.java
  9. +15 −4 src/main/java/nl/intercommit/weaves/components/Grid.java
  10. +95 −0 src/main/java/nl/intercommit/weaves/components/Growler.java
  11. +0 −140 src/main/java/nl/intercommit/weaves/components/HoverLink.java
  12. +3 −2 src/main/java/nl/intercommit/weaves/components/ModalBox.java
  13. +144 −80 src/main/java/nl/intercommit/weaves/components/PagedGrid.java
  14. +14 −13 src/main/java/nl/intercommit/weaves/components/PagedGridPager.java
  15. +2 −1  src/main/java/nl/intercommit/weaves/components/PopupWindow.java
  16. +1 −0  src/main/java/nl/intercommit/weaves/components/Switch.java
  17. +81 −0 src/main/java/nl/intercommit/weaves/components/Tabs.java
  18. +1 −1  src/main/java/nl/intercommit/weaves/components/TextMarker.java
  19. +15 −0 src/main/java/nl/intercommit/weaves/grid/ChildrenFetcher.java
  20. +11 −1 src/main/java/nl/intercommit/weaves/grid/PagedGridDataSource.java
  21. +32 −11 ...tercommit/weaves/test/pages/HoverLinkPage.java → main/java/nl/intercommit/weaves/growler/Message.java}
  22. +49 −0 src/main/java/nl/intercommit/weaves/mixins/CallBack.java
  23. +81 −0 src/main/java/nl/intercommit/weaves/mixins/Opentip.java
  24. +10 −1 src/main/java/nl/intercommit/weaves/services/WeavesModule.java
  25. +46 −0 src/main/java/nl/intercommit/weaves/services/internal/JQueryJavaScriptStack.java
  26. +33 −13 ...st/java/nl/intercommit/weaves/TestHoverlink.java → main/java/nl/intercommit/weaves/tabs/TabPanel.java}
  27. +0 −76 src/main/java/nl/intercommit/weaves/util/HoverlinkStreamResponse.java
  28. +23 −0 src/main/resources/nl/intercommit/weaves/components/DataTable.tml
  29. +0 −6 src/main/resources/nl/intercommit/weaves/components/PagedGrid.css
  30. +39 −5 src/main/resources/nl/intercommit/weaves/components/PagedGrid.tml
  31. +2 −1  src/main/resources/nl/intercommit/weaves/components/PagedGridPager.properties
  32. +0 −88 src/main/resources/nl/intercommit/weaves/components/PagedGridScript.js
  33. +3 −1 src/main/resources/nl/intercommit/weaves/components/PopupWindow.tml
  34. +0 −1  src/main/resources/nl/intercommit/weaves/components/TextMarker.tml
  35. +156 −0 src/main/resources/nl/intercommit/weaves/components/datatable/dataTables.min.js
  36. +571 −0 src/main/resources/nl/intercommit/weaves/components/datatable/datatable.css
  37. +3 −0  src/main/resources/nl/intercommit/weaves/components/datatable/datatable.js
  38. BIN  src/main/resources/nl/intercommit/weaves/components/datatable/sort_asc.png
  39. BIN  src/main/resources/nl/intercommit/weaves/components/datatable/sort_asc_disabled.png
  40. BIN  src/main/resources/nl/intercommit/weaves/components/datatable/sort_both.png
  41. BIN  src/main/resources/nl/intercommit/weaves/components/datatable/sort_desc.png
  42. BIN  src/main/resources/nl/intercommit/weaves/components/datatable/sort_desc_disabled.png
  43. +28 −0 src/main/resources/nl/intercommit/weaves/components/growler/Growler.css
  44. +182 −0 src/main/resources/nl/intercommit/weaves/components/growler/Growler.js
  45. BIN  src/main/resources/nl/intercommit/weaves/components/growler/error.png
  46. BIN  src/main/resources/nl/intercommit/weaves/components/growler/info.png
  47. BIN  src/main/resources/nl/intercommit/weaves/components/growler/warn.png
  48. +0 −4 src/main/resources/nl/intercommit/weaves/components/hoverlink/HoverLink.css
  49. +0 −1,147 src/main/resources/nl/intercommit/weaves/components/hoverlink/Hoverlink.js
  50. BIN  src/main/resources/nl/intercommit/weaves/components/hoverlink/hover_close.jpg
  51. +0 −7 src/main/resources/nl/intercommit/weaves/components/hoverlink/hoverlink_css.properties
  52. +32 −0 src/main/resources/nl/intercommit/weaves/components/pagedgrid/PagedGrid.css
  53. +142 −0 src/main/resources/nl/intercommit/weaves/components/pagedgrid/PagedGridScript.js
  54. BIN  src/main/resources/nl/intercommit/weaves/components/pagedgrid/branch.png
  55. BIN  src/main/resources/nl/intercommit/weaves/components/pagedgrid/collapse.png
  56. BIN  src/main/resources/nl/intercommit/weaves/components/pagedgrid/expand.png
  57. +190 −0 src/main/resources/nl/intercommit/weaves/components/pagedgrid/jquery.chromatable.js
  58. +13 −0 src/main/resources/nl/intercommit/weaves/components/tabs.tml
  59. +56 −0 src/main/resources/nl/intercommit/weaves/components/tabs/tabs.css
  60. +82 −0 src/main/resources/nl/intercommit/weaves/components/tabs/tabs.js
  61. +5 −0 src/main/resources/nl/intercommit/weaves/jquery/jquery-1.9.1.min.js
  62. +1 −0  src/main/resources/nl/intercommit/weaves/jquery/jquery_init.js
  63. +1 −0  src/main/resources/nl/intercommit/weaves/mixins/Confirm_en.properties
  64. +1 −0  src/main/resources/nl/intercommit/weaves/mixins/Confirm_nl.properties
  65. BIN  src/main/resources/nl/intercommit/weaves/mixins/opentip/loading.gif
  66. +459 −0 src/main/resources/nl/intercommit/weaves/mixins/opentip/opentip.css
  67. +1,203 −0 src/main/resources/nl/intercommit/weaves/mixins/opentip/opentip.min.js
  68. +10 −0 src/main/resources/nl/intercommit/weaves/mixins/opentip/opentip_init.js
  69. +1 −1  src/test/java/nl/intercommit/weaves/TestDropDownMenu.java
  70. +0 −43 src/test/java/nl/intercommit/weaves/util/TestHoverlinkStreamResponse.java
View
19 README.md
@@ -1,7 +1,7 @@
Weaves
======
-A Tapestry 5.2 component module featuring new components and multiple database support.
+A Tapestry 5.3.x component module featuring new components and adds support for multiple hibernate sessions.
#### Provided components in this library: ####
@@ -10,15 +10,19 @@ A Tapestry 5.2 component module featuring new components and multiple database s
- Switch
- TextMarker
- ModalBox
-- Hoverlink
+- Datatable
- EditableSelectBox
- DropDownMenu
+- Growler
+- Tabs
#### Provided Mixins in this library: ####
* Confirm
- A javascript popup dialog to be used for confirming actions on urls
+ A javascript popup dialog to be used for confirming actions on hyperlinks.
+ * OpenTip
+ A tooltip based on opentip.org
#### Provided Services in this library: ####
@@ -26,9 +30,9 @@ A Tapestry 5.2 component module featuring new components and multiple database s
A multi session / multi database service
-### TODO ###
+### Binaries ###
-There are still some TODO's left in the code, but 95% is working fine.
+For those who cannot build the jar themselves, there is a binaries directory in which compiled and packaged jar files are available.
### Building ###
@@ -41,8 +45,3 @@ Currently at around 70% coverage. Still some work to do to increase coverage.
### DEMO ###
A working demo can be found at: http://intercommitweavesdemo.intercommit.cloudbees.net/
-There are 3 parts still not (correctly) working at the demo site:
-
- * TextMarker demo - Crashes with a internal Tapestry exception
- * ModalBox demo - Crashes with a internal Tapestry exception
- * Hibernate demo - Seems to ignore the Layout component
View
BIN  binaries/weaves-1.0.0.jar
Binary file not shown
View
BIN  binaries/weaves-2.0.0.jar
Binary file not shown
View
34 pom.xml
@@ -4,17 +4,17 @@
<groupId>nl.intercommit</groupId>
<artifactId>weaves</artifactId>
<name>Weaves</name>
- <version>1.0.0</version>
+ <version>2.0.0</version>
- <description>Weaves; a Tapestry 5.2 component module featuring new components and multiple database support.</description>
+ <description>Weaves; a Tapestry 5.3.x component module featuring new components and multiple database support.</description>
<organization>
<name>InterCommIT b.v.</name>
<url>http://www.intercommit.nl</url>
</organization>
-
+
<properties>
- <tapestry.version>5.2.6</tapestry.version>
+ <tapestry.version>5.3.6</tapestry.version>
</properties>
<dependencies>
@@ -42,6 +42,12 @@
<artifactId>hibernate-annotations</artifactId>
<version>3.5.6-Final</version>
<scope>provided</scope>
+ <exclusions>
+ <exclusion>
+ <artifactId>slf4j-api</artifactId>
+ <groupId>org.slf4j</groupId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
@@ -71,7 +77,7 @@
<dependency>
<groupId>org.chenillekit</groupId>
<artifactId>chenillekit-tapestry</artifactId>
- <version>1.3.2</version>
+ <version>1.3.3</version>
<exclusions>
<exclusion>
<artifactId>tapestry-core</artifactId>
@@ -101,6 +107,23 @@
</dependency>
</dependencies>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.8</version>
+ <configuration>
+ <taglet>org.apache.tapestry5.javadoc.TapestryDocTaglet</taglet>
+ <tagletArtifact>
+ <groupId>org.apache.tapestry</groupId>
+ <artifactId>tapestry-javadoc</artifactId>
+ <version>${tapestry.version}</version>
+ </tagletArtifact>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
<build>
<plugins>
<plugin>
@@ -118,6 +141,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
+ <version>2.4</version>
<configuration>
<archive>
<manifestEntries>
View
2  src/main/java/nl/intercommit/weaves/base/BasicClientElement.java
@@ -14,7 +14,6 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with Weaves. If not, see <http://www.gnu.org/licenses/>.
-*
*/
package nl.intercommit.weaves.base;
@@ -39,7 +38,6 @@ private void setupRender() {
assignedClientId = javascriptSupport.allocateClientId(clientId);
}
- @Override
public String getClientId() {
return assignedClientId;
}
View
188 src/main/java/nl/intercommit/weaves/components/DataTable.java
@@ -0,0 +1,188 @@
+/* Copyright 2011 InterCommIT b.v.
+*
+* This file is part of the "Weaves" project hosted on https://github.com/intercommit/Weaves
+*
+* Weaves is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* any later version.
+*
+* Weaves is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Weaves. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+package nl.intercommit.weaves.components;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tapestry5.BindingConstants;
+import org.apache.tapestry5.Block;
+import org.apache.tapestry5.MarkupWriter;
+import org.apache.tapestry5.PropertyOverrides;
+import org.apache.tapestry5.annotations.AfterRender;
+import org.apache.tapestry5.annotations.BeginRender;
+import org.apache.tapestry5.annotations.Import;
+import org.apache.tapestry5.annotations.Parameter;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.annotations.SupportsInformalParameters;
+import org.apache.tapestry5.beaneditor.BeanModel;
+import org.apache.tapestry5.beaneditor.PropertyModel;
+import org.apache.tapestry5.grid.GridDataSource;
+import org.apache.tapestry5.internal.beaneditor.BeanModelUtils;
+import org.apache.tapestry5.ioc.Messages;
+import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.json.JSONArray;
+import org.apache.tapestry5.json.JSONObject;
+import org.apache.tapestry5.services.BeanModelSource;
+import org.apache.tapestry5.services.javascript.InitializationPriority;
+import org.apache.tapestry5.services.javascript.JavaScriptSupport;
+/**
+ * A jquery DataTable : http://www.datatables.net
+ *
+ * Only client side rendering is supported, serverside needs to be implemented.
+ *
+ * @tapestrydoc
+ */
+@Import(library={"datatable/datatable.js","datatable/dataTables.min.js"},stylesheet="datatable/datatable.css",stack="jquery")
+@SupportsInformalParameters
+public class DataTable extends nl.intercommit.weaves.base.BasicClientElement {
+
+ @Parameter(allowNull=false,required=true,defaultPrefix=BindingConstants.PROP)
+ private GridDataSource source;
+
+ @Parameter(value = "this", allowNull = false)
+ @Property(write = false)
+ private PropertyOverrides overrides;
+
+ @Parameter(defaultPrefix = BindingConstants.LITERAL)
+ private String include;
+
+ @Parameter(defaultPrefix = BindingConstants.LITERAL)
+ private String add;
+
+ @Parameter(defaultPrefix = BindingConstants.LITERAL)
+ private String exclude;
+
+ @Parameter(defaultPrefix = BindingConstants.LITERAL)
+ private String reorder;
+
+ @Parameter(allowNull=true)
+ private JSONObject parameters;
+
+ @Parameter(allowNull=true,defaultPrefix=BindingConstants.LITERAL)
+ private String sortColumn;
+
+ @Parameter(value="literal:asc",defaultPrefix=BindingConstants.LITERAL,allowNull=false)
+ private String sortDirection;
+
+ @Property
+ @Parameter
+ private int rowIndex;
+
+ @Property
+ @Parameter()
+ private Object row;
+
+ @Inject
+ private BeanModelSource bms;
+
+ @Inject
+ private JavaScriptSupport scriptSupport;
+
+ @Inject
+ private Messages msgs;
+
+ @Property
+ private BeanModel<Object> model;
+
+ private String header;
+
+ @Property
+ private String propertyName;
+
+ @Inject
+ private Block empty;
+
+ private boolean renderBody;
+
+ Object setupRender() {
+ return source.getAvailableRows() == 0 ? empty : null;
+ }
+
+ @BeginRender
+ private boolean setupDataTable() {
+ renderBody = false;
+ if (source.getAvailableRows() == 0) return renderBody;
+
+ renderBody = true;
+ model = bms.createDisplayModel(source.getRowType(),msgs);
+
+ BeanModelUtils.modify(model, add, include, exclude, reorder);
+
+ if (parameters == null) {
+ parameters = new JSONObject();
+ parameters.put("bSort", true);
+ parameters.put("bFilter", false);
+ if (source.getAvailableRows() < 10) {
+ parameters.put("bPaginate", false);
+ parameters.put("sDom","<'top'i>");
+ } else {
+ parameters.put("sDom","<'top'lp>");
+ }
+ if (sortColumn != null) {
+ // add some sorting
+ int position = 0;
+ for (String prop : model.getPropertyNames()) {
+ if (prop.equalsIgnoreCase(sortColumn)) {
+ break;
+ }
+ position++;
+ }
+ JSONArray sort = new JSONArray();
+ sort.put(position);
+ sort.put(sortDirection);
+
+ parameters.put("aaSorting", new JSONArray(sort));
+ }
+
+ }
+ return renderBody;
+ }
+
+
+ @AfterRender
+ private void afterRender(MarkupWriter writer) {
+ if (renderBody) {
+ scriptSupport.addScript(InitializationPriority.LATE,"initializeTable('#"+getClientId()+"',"+parameters.toCompactString()+");");
+ }
+ }
+
+ public List<Object> getRows() {
+ List<Object> rows = new ArrayList<Object>();
+ for (int i=0;i<source.getAvailableRows();i++) {
+ rows.add(source.getRowValue(i));
+ }
+ return rows;
+ }
+
+ public PropertyModel getPropModel() {
+ return model.get(propertyName);
+ }
+
+ public String getHeader() {
+ if (msgs.contains(header+"-label")) {
+ return msgs.get(header+"-label");
+ }
+ return header;
+ }
+
+ public void setHeader(String header) {
+ this.header = header;
+ }
+}
View
78 src/main/java/nl/intercommit/weaves/components/DropDownMenu.java
@@ -21,23 +21,26 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
+import java.util.LinkedList;
import java.util.List;
import nl.intercommit.weaves.menu.MenuItem;
+import org.apache.tapestry5.ComponentResources;
+import org.apache.tapestry5.annotations.BeginRender;
import org.apache.tapestry5.annotations.Import;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.annotations.SetupRender;
import org.apache.tapestry5.ioc.annotations.Inject;
-import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.javascript.JavaScriptSupport;
+/**
+ * @tapestrydoc
+ */
@Import(library="DropDownMenu.js",stylesheet="DropDownMenu.css")
public class DropDownMenu {
- public final static String MENU_ITEM_SELECTED = "selectmenuitem";
-
// linkedhashmaps to preserve ordering!
@Parameter(required=true,allowNull=false)
private LinkedHashMap<MenuItem,LinkedHashMap<MenuItem, List<MenuItem>>> menu;
@@ -46,7 +49,7 @@
private JavaScriptSupport js;
@Inject
- private Request request;
+ private ComponentResources cr;
@Property
private MenuItem level1;
@@ -57,8 +60,8 @@
@Property
private MenuItem level3;
- private boolean matched = false;
-
+ private MenuItem selectedLevel;
+
@SetupRender
private void initJavaScript() {
js.addScript("initMenu();", "");
@@ -106,44 +109,49 @@ public boolean getHasLevel3() {
return false;
}
- public String getSelectedClass() {
- String className= "none";
- for (MenuItem topLevel: menu.keySet()) {
- if (matchesRequest(topLevel,topLevel)) {
- return "toplevelselected";
+ @BeginRender
+ public void determineSelectedLevel() {
+ if (menu.keySet().size() > 0) {
+ String reqPath = cr.getPage().getComponentResources().getPageName();
+ if (reqPath.endsWith("/Index")) {
+ // special case, default page reached (dont know where this is configured..) so it could break.
+ reqPath = reqPath.substring(0,reqPath.indexOf("/Index"));
}
- if (menu.get(topLevel) != null) {
- for (MenuItem level2: menu.get(topLevel).keySet()) {
- if (matchesRequest(level2,topLevel)) {
- return "toplevelselected";
+
+ selectedLevel = (MenuItem) menu.keySet().toArray()[0]; // select 1st menu
+
+ for (MenuItem rootLevel:menu.keySet()) {
+ List<MenuItem> allItems = new LinkedList<MenuItem>();
+
+ allItems.add(rootLevel); // me
+ if (menu.get(rootLevel) != null) {
+ allItems.addAll(menu.get(rootLevel).keySet()); // all level2's
+ for (MenuItem level3: menu.get(rootLevel).keySet()) {
+ final List<MenuItem> subs = menu.get(rootLevel).get(level3);
+ if (subs != null) {
+ allItems.addAll(subs);
+ }
}
- if (menu.get(topLevel).get(level2) !=null ) {
-
- for (Object level3: menu.get(topLevel).get(level2).toArray()) {
- if (matchesRequest((MenuItem)level3,topLevel)) {
- return "toplevelselected";
- }
+ }
+
+ for (MenuItem item: allItems) {
+ final String basePath = item.getUrl().getBasePath().substring(1);
+ if (basePath.length() > 0) {
+ if (basePath.contains(reqPath.toLowerCase())) {
+ selectedLevel = rootLevel;
+ break;
}
}
}
}
}
- return className;
}
-
- private boolean matchesRequest(final MenuItem menu,final MenuItem currentLevel) {
- if (matched) {
- return false;
- }
- String basePath = menu.getUrl().getBasePath();
- String reqPath = request.getPath();
- if (!request.getContextPath().equals("")) {
- basePath = basePath.substring(request.getContextPath().length());
+
+ public String getSelectedclass() {
+ if (level1.equals(selectedLevel)) {
+ return "toplevelselected";
}
- matched = (basePath.startsWith(reqPath) &&
- currentLevel == level1 &&
- reqPath.length() > 1) ;
- return matched;
+ return "none";
}
}
View
3  src/main/java/nl/intercommit/weaves/components/EditableSelectBox.java
@@ -53,6 +53,9 @@
import org.apache.tapestry5.services.javascript.JavaScriptSupport;
import org.apache.tapestry5.util.EnumSelectModel;
+/**
+ * @tapestrydoc
+ */
@Import(library="editableselect/EditableSelect.js",stylesheet="editableselect/EditableSelect.css")
public class EditableSelectBox extends AbstractField {
View
19 src/main/java/nl/intercommit/weaves/components/Grid.java
@@ -19,22 +19,26 @@
package nl.intercommit.weaves.components;
import org.apache.tapestry5.BindingConstants;
+import org.apache.tapestry5.ClientElement;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.SetupRender;
/**
* This class is needed because we needed to override the Pager component
*
* @see org.apache.tapestry5.corelib.components.Grid
- *
+ * @tapestrydoc
*/
-public class Grid extends org.apache.tapestry5.corelib.components.Grid {
+public class Grid extends org.apache.tapestry5.corelib.components.Grid implements ClientElement {
@Parameter(defaultPrefix = BindingConstants.LITERAL,allowNull=true)
private String nonSortable;
- @Parameter(required=true)
+ @Parameter(required=false)
private PagedGridPager pagedpager;
+ @Parameter(required=true,defaultPrefix=BindingConstants.LITERAL)
+ private String clientId;
+
public Object getPagerTop() {
Object o = super.getPagerTop();
if (o!=null) o= pagedpager;
@@ -52,9 +56,16 @@ private void updateSortingColumns() {
if (nonSortable != null) {
final String[] columns = nonSortable.split(",");
for (final String column: columns) {
- getDataModel().get(column).sortable(false);
+ if (getDataModel().getPropertyNames().contains(column)) {
+ getDataModel().get(column).sortable(false);
+ }
}
}
}
+ @Override
+ public String getClientId() {
+ return clientId;
+ }
+
}
View
95 src/main/java/nl/intercommit/weaves/components/Growler.java
@@ -0,0 +1,95 @@
+/* Copyright 2011 InterCommIT b.v.
+*
+* This file is part of the "Weaves" project hosted on https://github.com/intercommit/Weaves
+*
+* Weaves is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* any later version.
+*
+* Weaves is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Weaves. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+package nl.intercommit.weaves.components;
+
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.List;
+
+import nl.intercommit.weaves.growler.Message;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.tapestry5.Asset;
+import org.apache.tapestry5.BindingConstants;
+import org.apache.tapestry5.MarkupWriter;
+import org.apache.tapestry5.annotations.AfterRender;
+import org.apache.tapestry5.annotations.Import;
+import org.apache.tapestry5.annotations.Parameter;
+import org.apache.tapestry5.annotations.SessionState;
+import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.services.javascript.JavaScriptSupport;
+
+/**
+ * Growler-like user feedback based on: https://github.com/prtksxna/growl-prototype/
+ *
+ * TODO: Support for zone updates.
+ * @tapestrydoc
+ */
+@Import(stylesheet={"growler/Growler.css"},library={"growler/Growler.js"})
+public class Growler {
+
+ @SessionState(create=false)
+ private List<nl.intercommit.weaves.growler.Message> _msgs;
+
+ @Inject
+ private JavaScriptSupport js;
+
+ @Parameter(defaultPrefix = BindingConstants.ASSET, value = "growler/error.png")
+ private Asset errorimage;
+
+ @Parameter(defaultPrefix = BindingConstants.ASSET, value = "growler/info.png")
+ private Asset infoimage;
+
+ @Parameter(defaultPrefix = BindingConstants.ASSET, value = "growler/warn.png")
+ private Asset warnimage;
+
+ @AfterRender
+ private void displayUserMessages(final MarkupWriter writer) {
+ js.addScript("var growl = new k.Growler();", "");
+ String imageUrl = "";
+ if (_msgs !=null) {
+ for (Message msg: _msgs) {
+ switch(msg.getLevel()) {
+ case ERROR:{
+ imageUrl = errorimage.toClientURL();
+ break;
+ }
+ case INFO: {
+ imageUrl = infoimage.toClientURL();
+ break;
+ }
+ case WARN: {
+ imageUrl = warnimage.toClientURL();
+ break;
+ }
+ }
+ js.addScript("growl."+msg.getLevel().name().toLowerCase()+"('"+StringEscapeUtils.escapeJavaScript(URLDecoder.decode(msg.getMessage()))+"',{ className: 'atwork', image: '"+imageUrl+"', sticky: true,life: 3});", "");
+ }
+ _msgs.clear();
+ }
+ }
+
+ public void addMessage(final Message msg) {
+ if (_msgs == null) {
+ _msgs = new ArrayList<Message>();
+ }
+ _msgs.add(msg);
+ }
+
+}
View
140 src/main/java/nl/intercommit/weaves/components/HoverLink.java
@@ -1,140 +0,0 @@
-/* Copyright 2011 InterCommIT b.v.
-*
-* This file is part of the "Weaves" project hosted on https://github.com/intercommit/Weaves
-*
-* Weaves is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Lesser General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* any later version.
-*
-* Weaves is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public License
-* along with Weaves. If not, see <http://www.gnu.org/licenses/>.
-*
-*/
-package nl.intercommit.weaves.components;
-
-import java.io.InputStream;
-import java.util.Properties;
-
-import org.apache.tapestry5.Asset;
-import org.apache.tapestry5.BindingConstants;
-import org.apache.tapestry5.ClientElement;
-import org.apache.tapestry5.ComponentResources;
-import org.apache.tapestry5.MarkupWriter;
-import org.apache.tapestry5.annotations.Events;
-import org.apache.tapestry5.annotations.Import;
-import org.apache.tapestry5.annotations.Parameter;
-import org.apache.tapestry5.annotations.SetupRender;
-import org.apache.tapestry5.ioc.annotations.Inject;
-import org.apache.tapestry5.ioc.internal.util.TapestryException;
-import org.apache.tapestry5.json.JSONArray;
-import org.apache.tapestry5.json.JSONLiteral;
-import org.apache.tapestry5.json.JSONObject;
-import org.apache.tapestry5.services.javascript.JavaScriptSupport;
-
-@Events(value=HoverLink.RETRIEVE_CONTENT_EVENT)
-@Import(library = "hoverlink/Hoverlink.js",stylesheet="hoverlink/HoverLink.css")
-public class HoverLink implements ClientElement {
-
- public static final String RETRIEVE_CONTENT_EVENT = "retrieveContent";
-
- @Parameter(value="250")
- private Integer width;
-
- @Parameter(value="200")
- private Integer height;
-
- @Parameter(defaultPrefix = BindingConstants.ASSET, value = "hoverlink/hover_close.jpg")
- private Asset closeButton;
-
- @Parameter(defaultPrefix = BindingConstants.ASSET, value="hoverlink/hoverlink_css.properties")
- private Asset ballooncss;
-
- @Parameter(allowNull=true)
- private Object context;
-
-
- @Inject
- private ComponentResources resources;
-
- @Inject
- private JavaScriptSupport jsSupport;
-
- private JSONObject balloonStyle;
-
- private String clientId;
-
- @SetupRender
- void createBalloonStyle() {
- Properties props = new Properties();
- balloonStyle = new JSONObject();
- InputStream io = null;
- try {
- io = ballooncss.getResource().openStream();
- props.load(io);
-
- for (Object key: props.keySet()) {
- balloonStyle.put((String)key,new JSONLiteral((String)props.get(key)));
- }
- } catch (Exception e) {
- throw new TapestryException("Could not read " + ballooncss,this,e);
- } finally {
- if (io != null) {
- try {
- io.close();
- } catch(Exception e) {}
- }
- }
- clientId = null;
- }
-
- void beginRender(MarkupWriter writer) {
- writer.element("div","style","display:inline;");
- writer.element("a", "href","#","id",getClientId(),"class","ic_t5-hoverlink","onclick","return false;");
- }
-
- void afterRender(MarkupWriter writer) {
- writer.end(); // </a>
- writer.writeRaw("<script type=\"text/javascript\">var hb_"+getClientId()+" = new HelpBalloon("+getBalloonOptions().toCompactString() + ");");
- writer.writeRaw(" hb_"+getClientId()+".balloonDimensions = " + getBalloonDimensions().toCompactString() +";");
- writer.writeRaw("</script>");
- writer.end(); // </div>
- }
-
- private JSONObject getBalloonOptions() {
- final JSONObject params = new JSONObject();
- if (context != null) {
- params.put("dataURL",resources.createEventLink("retrieveContent",context).toAbsoluteURI());
- } else {
- params.put("dataURL",resources.createEventLink("retrieveContent").toAbsoluteURI());
- }
- params.put("cacheRemoteContent", false);
- params.put("icon",new JSONLiteral("$('"+getClientId()+"')"));
- params.put("button", closeButton.toClientURL());
- params.put("balloonStyle", balloonStyle);
- params.put("contentMargin", 5);
- params.put("autoHideTimeout",2000); // autohide in ms
- params.put("useEvent",new JSONArray().put("mouseover"));
- return params;
- }
-
- private JSONArray getBalloonDimensions() {
- final JSONArray dimensions = new JSONArray();
- dimensions.put(width);
- dimensions.put(height);
- return dimensions;
- }
-
- @Override
- public String getClientId() {
- if (clientId == null) {
- clientId = jsSupport.allocateClientId(resources);
- }
- return clientId;
- }
-}
View
5 src/main/java/nl/intercommit/weaves/components/ModalBox.java
@@ -37,9 +37,10 @@
* ModalBox support for Tapestry5 Check <a
* href='http://okonet.ru/projects/modalbox/index.html'>ModalBox</a> for details
* This component uses version 1.5.5
+ * <p/>
+ * copied from : http://tapestry.1045711.n5.nabble.com/Modalbox-Integration-Example-td4248936.html#a4257039
*
- * @notes copied from : http://tapestry.1045711.n5.nabble.com/Modalbox-Integration-Example-td4248936.html#a4257039
- *
+ * @tapestrydoc
*/
@Import(library = { "modal/builder.js","modal/modalbox.js", "modal/modalboxinit.js" }, stylesheet = "modal/modalbox.css")
@SupportsInformalParameters
View
224 src/main/java/nl/intercommit/weaves/components/PagedGrid.java
@@ -24,32 +24,40 @@
import java.util.List;
import java.util.Map;
+import nl.intercommit.weaves.base.BasicClientElement;
import nl.intercommit.weaves.grid.CollectionPagedGridDataSource;
import nl.intercommit.weaves.grid.HibernatePagedGridDataSource;
import nl.intercommit.weaves.grid.PagedGridDataSource;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.tapestry5.Asset2;
import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.Block;
import org.apache.tapestry5.ComponentResources;
+import org.apache.tapestry5.EventContext;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.PersistenceConstants;
import org.apache.tapestry5.PropertyOverrides;
import org.apache.tapestry5.annotations.AfterRender;
import org.apache.tapestry5.annotations.Component;
-import org.apache.tapestry5.annotations.Events;
import org.apache.tapestry5.annotations.Import;
import org.apache.tapestry5.annotations.OnEvent;
import org.apache.tapestry5.annotations.Parameter;
+import org.apache.tapestry5.annotations.Path;
import org.apache.tapestry5.annotations.Persist;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.annotations.SetupRender;
import org.apache.tapestry5.annotations.SupportsInformalParameters;
+import org.apache.tapestry5.beaneditor.BeanModel;
import org.apache.tapestry5.corelib.components.Grid;
+import org.apache.tapestry5.corelib.components.Zone;
import org.apache.tapestry5.ioc.Messages;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.internal.util.TapestryException;
import org.apache.tapestry5.ioc.services.TypeCoercer;
+import org.apache.tapestry5.services.javascript.InitializationPriority;
import org.apache.tapestry5.services.javascript.JavaScriptSupport;
+import org.chenillekit.tapestry.core.components.AjaxCheckbox;
/**
* Custom component PagedGrid, embeds the usual tapestry grid plus extra paging row and eventhandlers for paging
* Can also be extended with a checkable checkbox column !
@@ -58,7 +66,6 @@
*
* 1. Each row gets highlighted when clicked on
* 2. Does not query the database for all rows, only a subset with limit
- * 3. Emits a 'pagedgrid:selectrow' javascript event when a row has been selected
*
* Caution:
*
@@ -71,13 +78,16 @@
* of hibernate this will be a primary key so not a problem. But in case of a Collection the source may have been altered in
* the meantime and thus give back the wrong rows.
*
+ *
+ * @tapestrydoc
*/
-@Events(value=PagedGrid.ROW_SELECTED_EVENT)
-@Import(library={"PagedGridScript.js"},stylesheet="PagedGrid.css")
+@Import(library={"pagedgrid/PagedGridScript.js","pagedgrid/jquery.chromatable.js"},stylesheet={"pagedgrid/PagedGrid.css"},stack="jquery")
@SupportsInformalParameters
-public class PagedGrid {
+public class PagedGrid extends BasicClientElement {
+
- public final static String ROW_SELECTED_EVENT = "pagedgrid:selectrow";
+ @Component
+ private nl.intercommit.weaves.components.Grid childrenGrid;
@Parameter(required = true)
private PagedGridDataSource pagedsource;
@@ -97,14 +107,26 @@
@Parameter(value = "false", defaultPrefix = BindingConstants.LITERAL)
private boolean checkBoxes;
- @Property
- private boolean checkall;
+ /**
+ * Parameter that tells that the parent rows have children
+ */
+ @Parameter(value = "false", defaultPrefix = BindingConstants.LITERAL)
+ private boolean tree;
- @Property
- private boolean checked;
+ @Parameter(value="500",required=false,defaultPrefix=BindingConstants.LITERAL)
+ private String maxHeight;
+
+ @Parameter(value="false",defaultPrefix=BindingConstants.LITERAL)
+ private boolean hoverAnimation;
+
+ @Component
+ private AjaxCheckbox checkall;
+
+ @Component
+ private Zone expansionZone;
@Persist(PersistenceConstants.SESSION)
- private Class rowIdClass;
+ private Class<?> rowIdClass;
//session persistence because it lives over multiple AJAX requests.
@Persist(PersistenceConstants.SESSION)
@@ -114,6 +136,9 @@
@Persist(PersistenceConstants.SESSION)
private int overriddenRowsPerPage;
+ @Persist(PersistenceConstants.SESSION)
+ private boolean checkedAll;
+
private int rowIndex;
@Inject
@@ -122,22 +147,25 @@
@Inject
private JavaScriptSupport scriptSupport;
- @Inject
- private Block rowCell;
+ @Property
+ @Inject @Path("pagedgrid/expand.png")
+ private Asset2 expandImage;
- @Inject
- private Block checkboxCell;
+ @Property
+ @Inject @Path("pagedgrid/collapse.png")
+ private Asset2 collapseImage;
- @Inject
- private Block checkboxHeader;
+ @Property
+ @Inject @Path("pagedgrid/branch.png")
+ private Asset2 branchImage;
- @Inject
- private TypeCoercer coerer;
+ @Property
+ private List<?> children;
@Component(
inheritInformalParameters=true,
- publishParameters="row,exclude,pagerposition,include,columnIndex,model,sortModel,nonSortable",
- parameters = {
+ publishParameters="row,columnIndex,include,exclude,model,sortModel,nonSortable,pagerposition",
+ parameters = {
"source=pagedsource",
"add=prop:addedRow",
"rowsPerPage=prop:selectedrowsperpage",
@@ -145,8 +173,9 @@
"reorder=prop:ordering",
"overrides=customoverrides",
"rowclass=rowclass",
- "pagedpager=pagedpager"
- }
+ "pagedpager=pagedpager",
+ "pagerposition=literal:bottom",
+ "clientId=clientId"}
)
private nl.intercommit.weaves.components.Grid grid;
@@ -166,11 +195,20 @@ private void checkParameters() {
@AfterRender
private void afterRender(MarkupWriter writer) {
+ if (pagedsource.getAvailableRows() != 0) {
+ if (tree) {
+ scriptSupport.addScript("observeExpansionZone();");
+ }
+ scriptSupport.addScript("initializeGrid('"+getClientId()+"',"+maxHeight+");");
+ }
+ if (hoverAnimation) {
+ scriptSupport.addScript("enableHovering(true);");
+ }
if (checkBoxes) {
- scriptSupport.addScript("listenToCheckAllBox();");
+ scriptSupport.addScript(InitializationPriority.LATE,"listenToCheckAllBox('"+checkall.getClientId()+"');");
rowIdClass = pagedsource.getRowIdClass();
}
- scriptSupport.addScript("observeGrid();");
+ checkedAll = false;
}
public int getRowIndex() {
@@ -187,24 +225,27 @@ public String getRowClass() {
public String getOrdering() {
if (reorder != null) {
- return "row" +addCheckBoxRow() + ","+ reorder;
+ return addExtraRows() + ","+ reorder;
}
- return "row" +addCheckBoxRow();
+ return addExtraRows();
}
public String getAddedRow() {
if (add != null) {
- return "row" +addCheckBoxRow() + ","+ add;
+ return addExtraRows() + ","+ add;
}
- return "row" +addCheckBoxRow();
+ return addExtraRows();
}
- public String addCheckBoxRow() {
+ private String addExtraRows() {
+ String extraRows = "row";
if (checkBoxes) {
- return ",checkbox";
- } else {
- return "";
+ extraRows = extraRows + ",checkbox";
+ }
+ if (tree) {
+ extraRows = extraRows + ",expander";
}
+ return extraRows; // hmm ok, this works
}
public int getSelectedRowsPerPage() {
@@ -220,66 +261,48 @@ void onPageSizeFromPagedGrid(int rowsPerPage) {
grid.setCurrentPage(1); // reset to page1
}
+ @OnEvent(value="fetchChildren")
+ Block fetchChildren(long rowId) {
+ children = pagedsource.fetchChildren(rowId);
+ return expansionZone.getBody();
+ }
+
public PropertyOverrides getCustomOverrides() {
return new PagedGridOverrides();
}
- public class PagedGridOverrides implements PropertyOverrides {
-
- public Block getOverrideBlock(String name) {
- if ("rowCell".equals(name)){
- return rowCell;
- }
- if (checkBoxes) {
- if ("checkboxCell".equals(name)) {
- return checkboxCell;
- }
- if ("checkboxHeader".equals(name)) {
- return checkboxHeader;
- }
- }
- return resources.getBlockParameter(name);
- }
-
- public Messages getOverrideMessages() {
- return resources.getContainerMessages();
- }
+ public PropertyOverrides getChildOverrides() {
+ return new ChildGridOverrides();
}
-
-
@OnEvent(value = "checkboxclicked")
- private void clickme(String context) {
-
- if ("true".equalsIgnoreCase(context) ||"false".equalsIgnoreCase(context)) {
- if (Boolean.parseBoolean(context)) {
+ private void clickme(EventContext context) {
+ if (!(rowIdClass == null || checkedItems == null)) {
+ if (context.toStrings().length ==1) {
+ checkedAll = !checkedAll;
for (Object key: checkedItems.keySet()) {
- checkedItems.put(key, true);
+ checkedItems.put(key, checkedAll);
}
} else {
- for (Object key: checkedItems.keySet()) {
- checkedItems.put(key, false);
+ // rowObject is the actual(real) type and value of the selected item
+ final Object rowObject = context.get(rowIdClass, 0);
+ /*
+ * containsKey works with equal and equal does NOT work with Long, which is usually the class
+ * of a primary hibernate key!
+ */
+ boolean found = false;
+ for (Object key:checkedItems.keySet()) {
+ if ((""+key).equals(""+rowObject)) {
+ found = true;
+ break;
+ }
}
- }
- } else {
- // rowObject is the actual(real) type and value of the selected item
- final Object rowObject = coerer.coerce(context, rowIdClass);
- /*
- * containsKey works with equal and equal does NOT work with Long, which is usually the class
- * of a primary hibernate key!
- */
- boolean found = false;
- for (Object key:checkedItems.keySet()) {
- if ((""+key).equals(""+rowObject)) {
- found = true;
- break;
+ if (found) {
+ checkedItems.put(rowObject, !checkedItems.get(rowObject));
+ } else {
+ throw new TapestryException("Could not add selected row , because it is not in the grid.",this,null);
}
}
- if (found) {
- checkedItems.put(rowObject, !checkedItems.get(rowObject));
- } else {
- throw new TapestryException("Could not add selected row , because it is not in the grid.",this,null);
- }
}
}
@@ -342,4 +365,45 @@ public void reset() {
checkedItems = null;
}
+ public BeanModel<?> getChildModel() {
+ return grid.getDataModel();
+ }
+
+ /*
+ * Overrides for parent and child grid
+ */
+ private class PagedGridOverrides implements PropertyOverrides {
+
+ public Block getOverrideBlock(String name) {
+ try {
+ return resources.getBlock(name);
+ } catch (Exception e) {
+ return resources.getBlockParameter(name);
+ }
+ }
+
+ public Messages getOverrideMessages() {
+ return resources.getContainerMessages();
+ }
+ }
+
+ private class ChildGridOverrides implements PropertyOverrides {
+
+ public Block getOverrideBlock(String name) {
+ if (name.endsWith("Header")) {
+ return null; // child grid does not have headers.
+ }
+ try {
+ return resources.getBlock(name+"Child");
+ } catch (Exception e) {
+ return resources.getBlockParameter(name+"Child");
+ }
+ }
+
+ public Messages getOverrideMessages() {
+ return resources.getContainerMessages();
+ }
+ }
+
+
}
View
27 src/main/java/nl/intercommit/weaves/components/PagedGridPager.java
@@ -37,6 +37,8 @@
*
* TODO: support for zones
* TODO: should be able to remove the 'row' column ?
+ *
+ * @tapestrydoc
*/
@Events({InternalConstants.GRID_INPLACE_UPDATE + " (internal event)","pagesize"})
public class PagedGridPager
@@ -89,31 +91,30 @@ void beginRender(final MarkupWriter writer)
}
writePageLink(divElement,currentPage,"refresh");
-
-
writer.end();
-
final Element divPagerRows = writer.element("div", "class","paged_rows");
-
+ divPagerRows.raw(messages.get("records_per_page")+" : ");
+
+ final Link link = resources.getContainer().getComponentResources().createEventLink("pagesize","$pg$");
+ Element select = writer.element("select","class","t-data-grid-pageselect","onchange","changePageSize('"+link.toURI()+"',this);");
+
for (final Long size: pagination) {
/*
* Generate an eventlink for the container which normally is the org.apache.tapestry5.corelib.components.Grid component
* and generate an event for it, the PagedGrid for example catches this event..
*/
-
- final Link link = resources.getContainer().getComponentResources().createEventLink("pagesize", size.intValue());
-
- Element aElement = null;
if (size.intValue() == rowsPerPage) {
- aElement = divPagerRows.element("span","class","current");
+ select = select.element("option","value",""+size,"selected","selected");
} else {
- aElement = divPagerRows.element("a","href", link.toString());
+ select = select.element("option","value", ""+size);
}
- aElement.text(""+size);
+ select.text(""+size);
}
- writer.end();
- writer.end();
+ writer.end(); // selectbox
+
+ writer.end(); // paged_rows div
+ writer.end(); // t-data-grid-pager div
}
View
3  src/main/java/nl/intercommit/weaves/components/PopupWindow.java
@@ -38,6 +38,7 @@
*
* Must have a zoneName parameter, this will allow the window to listen to zone update events and show this window.
*
+ * @tapestrydoc
*/
@Import(library={"PopupWindow.js"})
@SupportsInformalParameters
@@ -49,7 +50,7 @@
@Parameter(required=true,defaultPrefix="literal")
private String height;
- @Parameter()
+ @Parameter
private String title;
@Parameter(value="true")
View
1  src/main/java/nl/intercommit/weaves/components/Switch.java
@@ -29,6 +29,7 @@
/**
* A switch component for enum types or anything based on a object array
* Items in the list should have a decent toString method
+ * @tapestrydoc
*/
@SupportsInformalParameters
public class Switch extends BasicClientElement {
View
81 src/main/java/nl/intercommit/weaves/components/Tabs.java
@@ -0,0 +1,81 @@
+/* Copyright 2011 InterCommIT b.v.
+*
+* This file is part of the "Weaves" project hosted on https://github.com/intercommit/Weaves
+*
+* Weaves is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* any later version.
+*
+* Weaves is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Weaves. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+package nl.intercommit.weaves.components;
+
+import java.util.List;
+
+import nl.intercommit.weaves.base.BasicClientElement;
+import nl.intercommit.weaves.tabs.TabPanel;
+
+import org.apache.tapestry5.Block;
+import org.apache.tapestry5.ComponentResources;
+import org.apache.tapestry5.annotations.AfterRender;
+import org.apache.tapestry5.annotations.Import;
+import org.apache.tapestry5.annotations.Parameter;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.services.javascript.JavaScriptSupport;
+
+/**
+ * @tapestrydoc
+ */
+@Import(library={"tabs/tabs.js"},stylesheet={"tabs/tabs.css"})
+public class Tabs extends BasicClientElement {
+
+ @Inject
+ private JavaScriptSupport scriptSupport;
+
+ @Inject
+ private ComponentResources resources;
+
+ @Property
+ @Parameter(required=true)
+ private List<TabPanel> tabs;
+
+ @Parameter
+ private String selected;
+
+ @Property
+ @Parameter(value="literal:panel")
+ private String panelClass;
+
+ private TabPanel currenttab;
+
+ @AfterRender
+ private void initialize() {
+ if (selected == null) {
+ selected = tabs.get(0).getId();
+ }
+ scriptSupport.addScript("initializeTabs('%s','%s')",new Object[] {getClientId(),selected});
+ }
+
+ public Block getPanelBlock() {
+ return resources.getContainer().getComponentResources().getBlock(currenttab.getBlockid());
+ }
+
+ public TabPanel getCurrenttab() {
+ return currenttab;
+ }
+
+ public void setCurrenttab(TabPanel currenttab) {
+ this.currenttab = currenttab;
+ }
+
+
+}
View
2  src/main/java/nl/intercommit/weaves/components/TextMarker.java
@@ -29,7 +29,7 @@
import org.apache.tapestry5.annotations.SetupRender;
/**
* Marks specific keywords in a text with a yellow background.
- *
+ * @tapestrydoc
*/
@Import(stylesheet="TextMarker.css")
public class TextMarker extends BasicClientElement {
View
15 src/main/java/nl/intercommit/weaves/grid/ChildrenFetcher.java
@@ -0,0 +1,15 @@
+package nl.intercommit.weaves.grid;
+
+import java.util.List;
+/**
+ * An interface used by PagedGridDataSource for fetching children based on a row identifier.
+ * The implementation itself is responsible for returning a list of related children
+ *
+ * @author antalk
+ *
+ */
+public interface ChildrenFetcher {
+
+ public List<?> fetchChildren(long rowId);
+}
+
View
12 src/main/java/nl/intercommit/weaves/grid/PagedGridDataSource.java
@@ -23,6 +23,7 @@
import org.apache.tapestry5.annotations.Persist;
import org.apache.tapestry5.grid.GridDataSource;
import org.apache.tapestry5.grid.SortConstraint;
+import org.apache.tapestry5.ioc.internal.util.TapestryException;
/**
* Paged implementation of a GridDataSource,
@@ -33,6 +34,8 @@
*/
public abstract class PagedGridDataSource implements GridDataSource {
+ protected ChildrenFetcher fetcher;
+
@Persist
private int startIndex;
@@ -72,6 +75,13 @@ public void prepare(int startIndex, int endIndex,
public abstract List<?> fetchResult(int startIndex,int endIndexPlusOne,List<SortConstraint> sortConstraints);
+ public List<?> fetchChildren(final long rowId) {
+ if (fetcher != null) {
+ return fetcher.fetchChildren(rowId);
+ }
+ throw new TapestryException("Could not fetch children for 'PagedGridDataSource', no fetcher specified!",this,null);
+ }
+
/**
* Should return a value identifying the current checked row
*
@@ -83,6 +93,6 @@ public void prepare(int startIndex, int endIndex,
*/
public abstract Object getIdentifierForRowValue(final Object rowObject);
- public abstract Class getRowIdClass();
+ public abstract Class<?> getRowIdClass();
}
View
43 .../intercommit/weaves/test/pages/HoverLinkPage.java → ...n/java/nl/intercommit/weaves/growler/Message.java
@@ -16,18 +16,39 @@
* along with Weaves. If not, see <http://www.gnu.org/licenses/>.
*
*/
-package nl.intercommit.weaves.test.pages;
+package nl.intercommit.weaves.growler;
-import nl.intercommit.weaves.components.HoverLink;
-import nl.intercommit.weaves.util.HoverlinkStreamResponse;
+public class Message {
-import org.apache.tapestry5.StreamResponse;
-import org.apache.tapestry5.annotations.OnEvent;
-
-public class HoverLinkPage {
-
- @OnEvent(component="hoverlink",value=HoverLink.RETRIEVE_CONTENT_EVENT)
- private StreamResponse returnContent1() {
- return new HoverlinkStreamResponse("Popup Title","Popup test content");
+ public enum LEVEL {
+ INFO,
+ WARN,
+ ERROR;
+ }
+
+ private final LEVEL _level;
+ private final String _msg;
+
+ /**
+ * Default is {@link LEVEL.INFO} level
+ *
+ */
+ public Message(final String message) {
+ this._level = LEVEL.INFO;
+ this._msg = message;
+ }
+
+
+ public Message(final LEVEL level,final String message) {
+ this._level = level;
+ this._msg = message;
+ }
+
+ public String getMessage() {
+ return _msg;
+ }
+
+ public LEVEL getLevel() {
+ return _level;
}
}
View
49 src/main/java/nl/intercommit/weaves/mixins/CallBack.java
@@ -0,0 +1,49 @@
+/* Copyright 2011 InterCommIT b.v.
+*
+* This file is part of the "Weaves" project hosted on https://github.com/intercommit/Weaves
+*
+* Weaves is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* any later version.
+*
+* Weaves is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with Weaves. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+package nl.intercommit.weaves.mixins;
+
+import org.apache.tapestry5.BindingConstants;
+import org.apache.tapestry5.ClientElement;
+import org.apache.tapestry5.annotations.AfterRender;
+import org.apache.tapestry5.annotations.InjectContainer;
+import org.apache.tapestry5.annotations.Parameter;
+import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.services.javascript.JavaScriptSupport;
+
+public class CallBack {
+
+ @Parameter(allowNull=true)
+ private Object clickContext;
+
+ @Parameter(allowNull=false,defaultPrefix=BindingConstants.LITERAL,required=true)
+ private String callback;
+
+ @Inject
+ private JavaScriptSupport js;
+
+ @InjectContainer
+ private ClientElement element;
+
+ @AfterRender
+ public void afterRender() {
+ js.addScript(String.format("$('%s').observe('click', function(event) {"+
+ callback + "(event,"+clickContext+"); });",
+ element.getClientId()));
+ }
+}
View
81 src/main/java/nl/intercommit/weaves/mixins/Opentip.java
@@ -0,0 +1,81 @@
+package nl.intercommit.weaves.mixins;
+
+import org.apache.tapestry5.BindingConstants;
+import org.apache.tapestry5.ClientElement;
+import org.apache.tapestry5.ComponentResources;
+import org.apache.tapestry5.annotations.AfterRender;
+import org.apache.tapestry5.annotations.Import;
+import org.apache.tapestry5.annotations.InjectContainer;
+import org.apache.tapestry5.annotations.Parameter;
+import org.apache.tapestry5.annotations.SupportsInformalParameters;
+import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.json.JSONObject;
+import org.apache.tapestry5.services.javascript.JavaScriptSupport;
+
+
+@SupportsInformalParameters
+@Import(library = {"opentip/opentip.min.js", "opentip/opentip_init.js"}, stylesheet = "opentip/opentip.css")
+public class Opentip
+{
+ @Parameter(defaultPrefix = BindingConstants.LITERAL)
+ private String tip;
+
+ @Parameter(defaultPrefix = BindingConstants.LITERAL)
+ private String tipTitle;
+
+ @Parameter(defaultPrefix = BindingConstants.LITERAL)
+ private String tipEvent;
+
+ @Parameter(allowNull=true,defaultPrefix=BindingConstants.PROP)
+ private Object context;
+
+ @InjectContainer
+ private ClientElement element;
+
+ @Inject
+ private JavaScriptSupport javaScriptSupport;
+
+ @Inject
+ private ComponentResources resources;
+
+ @AfterRender
+ void addJavascript()
+ {
+ final JSONObject params = new JSONObject();
+
+ params.put("elementId", element.getClientId());
+ params.put("tipTitle", tipTitle);
+ params.put("tip", tip);
+
+ if(tipEvent != null)
+ {
+ params.put("url", createAjaxTipEvent());
+ }
+
+ params.put("options", createOptionsFromInformalParameters());
+
+ javaScriptSupport.addInitializerCall("setupOpentip", params);
+ }
+
+ private String createAjaxTipEvent() {
+ return resources.createEventLink(tipEvent,context).toURI();
+ }
+
+ private JSONObject createOptionsFromInformalParameters()
+ {
+ JSONObject options = new JSONObject();
+
+ for(String parameterName: resources.getInformalParameterNames())
+ {
+ options.put(parameterName,
+ resources.getInformalParameter(parameterName, String.class));
+ }
+
+ return options;
+ }
+
+}
+
+
+
+
View
11 src/main/java/nl/intercommit/weaves/services/WeavesModule.java
@@ -22,25 +22,34 @@
import nl.intercommit.weaves.hibernate.HibernateMultiSessionManagerImpl;
import nl.intercommit.weaves.hibernate.SessionFactorySource;
import nl.intercommit.weaves.hibernate.SessionFactorySourceImpl;
+import nl.intercommit.weaves.services.internal.JQueryJavaScriptStack;
import org.apache.tapestry5.ioc.Configuration;
+import org.apache.tapestry5.ioc.MappedConfiguration;
import org.apache.tapestry5.ioc.ScopeConstants;
import org.apache.tapestry5.ioc.ServiceBinder;
import org.apache.tapestry5.ioc.annotations.Scope;
import org.apache.tapestry5.ioc.services.PerthreadManager;
import org.apache.tapestry5.services.LibraryMapping;
+import org.apache.tapestry5.services.javascript.JavaScriptStack;
public class WeavesModule {
public static void contributeComponentClassResolver(
Configuration<LibraryMapping> configuration){
- configuration.add(new LibraryMapping("weave", "nl.intercommit.weaves"));
+ configuration.add(new LibraryMapping("weaves", "nl.intercommit.weaves"));
}
public static void bind(ServiceBinder binder) {
binder.bind(SessionFactorySource.class, SessionFactorySourceImpl.class);
}
+ public static void contributeJavaScriptStackSource(MappedConfiguration<String, JavaScriptStack>
+ configuration) {
+ configuration.addInstance("jquery", JQueryJavaScriptStack.class);
+ }
+
+
@Scope(ScopeConstants.PERTHREAD)
public static HibernateMultiSessionManager buildHibernateMultiSessionManager(
SessionFactorySource sessionFactorySource,
View
46 src/main/java/nl/intercommit/weaves/services/internal/JQueryJavaScriptStack.java
@@ -0,0 +1,46 @@
+package nl.intercommit.weaves.services.internal;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.tapestry5.Asset;
+import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.services.AssetSource;
+import org.apache.tapestry5.services.javascript.JavaScriptStack;
+import org.apache.tapestry5.services.javascript.StylesheetLink;
+/**
+ * Includes a minified JQuery 1.7.2 library and initializes it directly with:
+ *
+ * jQuery.noConflict();
+ *
+ */
+public class JQueryJavaScriptStack implements JavaScriptStack {
+
+ @Inject
+ private AssetSource as;
+
+ @Override
+ public String getInitialization() {
+ return null;
+ }
+
+ @Override
+ public List<Asset> getJavaScriptLibraries() {
+ List<Asset> assets = new ArrayList<Asset>();
+ assets.add(as.getUnlocalizedAsset("nl/intercommit/weaves/jquery/jquery-1.9.1.min.js"));
+ assets.add(as.getUnlocalizedAsset("nl/intercommit/weaves/jquery/jquery_init.js"));
+ return assets;
+ }
+
+ @Override
+ public List<String> getStacks() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<StylesheetLink> getStylesheets() {
+ return Collections.emptyList();
+ }
+
+}
View
46 ...est/java/nl/intercommit/weaves/TestHoverlink.java → ...ain/java/nl/intercommit/weaves/tabs/TabPanel.java
@@ -16,24 +16,44 @@
* along with Weaves. If not, see <http://www.gnu.org/licenses/>.
*
*/
-package nl.intercommit.weaves;
+package nl.intercommit.weaves.tabs;
-import util.WeaveTestCase;
-
-public class TestHoverlink extends WeaveTestCase {
+public class TabPanel {
+ private String id;
+ private String title;
+ private String blockid;
+ public TabPanel(String id,String title) {
+ this.id = id;
+ this.title = title;
+ this.blockid=id;
+ }
- public void testHoverLinkComponent() {
- org.apache.tapestry5.dom.Document dom = getTester().renderPage("HoverlinkPage");
-
- assertNotNull(dom);
- assertNotNull(dom.getElementById("hoverlink"));
-
- assertTrue(dom.getElementById("hoverlink").toString().equals("<a onclick=\"return false;\" class=\"ic_t5-hoverlink\" id=\"hoverlink\" href=\"#\">consectetur</a>"));
- assertTrue(dom.toString().contains("\"dataURL\":\"http://localhost/foo/hoverlinkpage.hoverlink:retrievecontent\""));
-
+ public String getId() {
+ return id;
+ }
+ public void setId(String id) {
+ this.id = id;
+ }
+ public String getTitle() {
+ return title;
}
+ public void setTitle(String title) {
+ this.title = title;
+ }
+ public String getBlockid() {
+ return blockid;
+ }
+ /**
+ * Override the to render blockid for this id
+ *
+ * @param blockid
+ */
+ public void setBlockid(String blockid) {
+ this.blockid = blockid;
+ }
+
}
View
76 src/main/java/nl/intercommit/weaves/util/HoverlinkStreamResponse.java
@@ -1,76 +0,0 @@
-/* Copyright 2011 InterCommIT b.v.
-*
-* This file is part of the "Weaves" project hosted on https://github.com/intercommit/Weaves
-*
-* Weaves is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Lesser General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* any later version.
-*
-* Weaves is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public License
-* along with Weaves. If not, see <http://www.gnu.org/licenses/>.
-*
-*/
-package nl.intercommit.weaves.util;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.apache.tapestry5.StreamResponse;
-import org.apache.tapestry5.services.Response;
-
-public class HoverlinkStreamResponse implements StreamResponse {
-
- private StringBuilder build;
-
- private final String title;
- private final String content;
-
- public HoverlinkStreamResponse(final String title, final String content) {
- this.title = title;
- this.content = content;
- build = new StringBuilder(1024);
- }
-
- @Override
- public String getContentType() {
- return "text/xml";
- }
-
- @Override
- public InputStream getStream() throws IOException {
- build.append("<HelpBalloon>");
- build.append("<title>").append(title);
- build.append("</title>");
- build.append("<content>").append(encodeHTML(content));
- build.append("</content>");
- build.append("</HelpBalloon>");
-
- return new ByteArrayInputStream(build.toString().getBytes("UTF-8"));
- }
-
- @Override
- public void prepareResponse(Response response) {
- }
-
- private String encodeHTML(String s)
- {
- StringBuffer out = new StringBuffer();
- for(int i=0; i<s.length(); i++) {
- char c = s.charAt(i);
- if(c > 127 || c=='"' || c=='<' || c=='>') {
- out.append("&#"+(int)c+";");
- } else {
- out.append(c);
- }
- }
- return out.toString();
- }
-}
-
View
23 src/main/resources/nl/intercommit/weaves/components/DataTable.tml
@@ -0,0 +1,23 @@
+<div xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">
+ <table id="${clientid}" cellpadding="0" cellspacing="0" border="0" width="100%" class="display">
+ <thead>
+ <tr>
+ <t:loop source="model.propertynames" value="header">
+ <th>${header}</th>
+ </t:loop>
+ </tr>
+ </thead>
+ <tbody>
+ <t:loop source="rows" value="row" index="rowindex">
+ <tr>
+ <t:loop source="model.propertynames" value="propertyName" formstate="none">
+ <td>
+ <t:gridcell model="propmodel" object="row" overrides="overrides"/>
+ </td>
+ </t:loop>
+ </tr>
+ </t:loop>
+ </tbody>
+ </table>
+ <t:block id="empty">${message:no_more_data}</t:block>
+</div>
View
6 src/main/resources/nl/intercommit/weaves/components/PagedGrid.css
@@ -1,6 +0,0 @@
-
-.ic_t5-pagedgrid-noresults {
- color: red;
- font-weight: bold;
- font-size: smaller;
-}
View
44 src/main/resources/nl/intercommit/weaves/components/PagedGrid.tml
@@ -1,9 +1,9 @@
-<div xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd" id="pagedgrid">
+<div class="weaves-pagedgrid" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">
+ <div t:id="grid" id="${clientid}"/>
- <div t:id="grid"/>
<div id="noGridBottom"/>
<t:if test="pagedSource.availablerows" negate="true">
- <div class="ic_t5-pagedgrid-noresults">${message:pagedgrid-no-result}</div>
+ <div class="weaves-pagedgrid-noresults">${message:pagedgrid-no-result}</div>
</t:if>
<t:block id="rowCell">
@@ -11,15 +11,49 @@
</t:block>
<t:block id="checkboxCell">
- <t:form><t:ck.AjaxCheckbox t:id="checkBox" value="checked" context="RowIdentifier"/></t:form>
+ <t:form><t:ck.AjaxCheckbox t:id="checkBox" value="literal:false" context="RowIdentifier" class="weaves-checkbox"/></t:form>
</t:block>
<t:block id="checkboxHeader">
- <t:form><t:ck.AjaxCheckbox value="checkall" t:id="checkall"/></t:form>
+ <t:form><t:ck.AjaxCheckbox value="literal:false" t:id="checkall"/></t:form>
</t:block>
<t:block>
<div t:id="pagedpager"/>
</t:block>
+ <t:block id="expanderHeader">
+ +
+ </t:block>
+
+ <t:block id="expanderCell">
+ <div class="expander">
+ <t:eventlink t:id="fetchChildren" zone="expansionZone" context="${rowIdentifier}"><img src="${expandImage}"/></t:eventlink>
+ </div>
+ <div class="contracter weaves-pagedgrid-hidden">
+ <a href="#">
+ <t:any t:id="closeChild" t:mixins="weaves/CallBack" t:callback="closeChildren"><img src="${collapseImage}"/></t:any>
+ </a>
+ </div>
+ </t:block>
+
+ <t:zone t:id="expansionZone" id="expansionZone" style="display: none;" show="none" update="none">
+ <t:if test="children">
+ <t:grid t:id="childrenGrid" id="childrenGrid" clientId="childrenGrid" source="children" model="childmodel" rowclass="literal:child" overrides="childOverrides" row="grid.row" pagerPosition="NONE" rowsPerPage="999">
+ <t:parameter name="checkboxHeader">
+ <div style="visibility: hidden;">
+ <form>
+ <input type="checkbox" class="input"/>
+ </form>
+ </div>
+ </t:parameter>
+ </t:grid>
+ </t:if>
+ </t:zone>
+
+ <t:zone t:id="somezone" id="somezone"/>
+
+ <t:block t:id="expanderCellChild">
+ <img src="${branchImage}"/>
+ </t:block>
</div>
View
3  src/main/resources/nl/intercommit/weaves/components/PagedGridPager.properties
@@ -2,4 +2,5 @@ prev_page=Previous page
prev_page_disabled=At first page
next_page=Next page
next_page_disabled=No more pages
-refresh=refresh
+refresh=refresh
+records_per_page=Records per page
View
88 src/main/resources/nl/intercommit/weaves/components/PagedGridScript.js
@@ -1,88 +0,0 @@
-var prevRowColor;
-var prevSelectedRow;
-
-function listenToCheckAllBox() {
- Event.observe($('checkall'),'click',selectAllCheckBoxes);
- $('checkall').checked = false;
-}
-
-function observeGrid() {
- Event.observe($('pagedgrid'),'click',highlightrow);
-}
-
-function selectAllCheckBoxes(event) {
-
- if (!$('checkall').checked) {
-
- if ($('checkBox') != null) {
- $('checkBox').checked = false;
- var checkboxNumber = '0';
-
- while ($('checkBox_'+checkboxNumber) != undefined) {
- $('checkBox_'+checkboxNumber).checked = false;
- checkboxNumber++;
- }
- }
- } else {
- if ($('checkBox') != null) {
- $('checkBox').checked = true;
- var checkboxNumber = '0';
-
- while ($('checkBox_'+checkboxNumber) != undefined) {
- $('checkBox_'+checkboxNumber).checked = true;
- checkboxNumber++;
- }
- }
- }
-}
-
-function highlightrow(event) {
- highlightRowElement(event.target);
-}
-
-function highlightRowElement(element) {
-
- if (element != null) {
-
- while (element.offsetParent.hasClassName('t-data-grid') &&
- !(element.hasClassName('odd') || element.hasClassName('even'))) {
- element = element.up();
- }
- if (element.nodeName == 'TR') {
-
- if (element.rowIndex > 0) {
- if (prevSelectedRow != null) {
- prevSelectedRow.style.backgroundColor = prevRowColor;
- }
-
- prevRowColor = getstyle(element,'backgroundColor');
- prevSelectedRow = element;
-
- element.style.backgroundColor='#bbbbbb';
- // fire a custom event to indicate to the outside world that this row was clicked
- $(element).fire("pagedgrid:selectrow");
- }
- }
- }
-}
-
-/*
- * Override tapestry's ajax call to update the zone, after the selected row has been highlighted..
- */
-Tapestry.findZoneManager = function(element)
-{
- highlightRowElement(element);
-
- var zoneId = $T(element).zoneId;
-
- return Tapestry.findZoneManagerForZone(zoneId);
-}
-
-function getstyle(obj, cAttribute) {
- if (obj.currentStyle) {
- this.getstyle = function (obj, cAttribute) {return obj.currentStyle[cAttribute];};
- } else {
- this.getstyle = function (obj, cAttribute) {return window.getComputedStyle(obj, null)[cAttribute];};
- }
- return getstyle(obj, cAttribute);
-}
View
4 src/main/resources/nl/intercommit/weaves/components/PopupWindow.tml
@@ -2,7 +2,9 @@
<div t:id="window">
<t:zone t:id="zone" id="prop:zonename">
- <t:body/>
+ <div style="padding: 5px;">
+ <t:body/>
+ </div>
</t:zone>
</div>
</div>
View
1  src/main/resources/nl/intercommit/weaves/components/TextMarker.tml
@@ -1,4 +1,3 @@
<div xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd" class="textmarker">
-
<t:loop source="matches" value="match">${match.prefix}<t:if test="match.word"><div class="highlight">${match.word}</div></t:if></t:loop>
</div>
View
156 src/main/resources/nl/intercommit/weaves/components/datatable/dataTables.min.js
@@ -0,0 +1,156 @@
+/*
+ * File: jquery.dataTables.min.js
+ * Version: 1.9.3
+ * Author: Allan Jardine (www.sprymedia.co.uk)
+ * Info: www.datatables.net
+ *
+ * Copyright 2008-2012 Allan Jardine, all rights reserved.
+ *
+ * This source file is free software, under either the GPL v2 license or a
+ * BSD style license, available at:
+ * http://datatables.net/license_gpl2
+ * http://datatables.net/license_bsd
+ *
+ * This source file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
+ */
+(function(i,O,l,n){var j=function(e){function o(a,b){var c=j.defaults.columns,d=a.aoColumns.length,c=i.extend({},j.models.oColumn,c,{sSortingClass:a.oClasses.sSortable,sSortingClassJUI:a.oClasses.sSortJUI,nTh:b?b:l.createElement("th"),sTitle:c.sTitle?c.sTitle:b?b.innerHTML:"",aDataSort:c.aDataSort?c.aDataSort:[d],mData:c.mData?c.oDefaults:d});a.aoColumns.push(c);if(a.aoPreSearchCols[d]===n||null===a.aoPreSearchCols[d])a.aoPreSearchCols[d]=i.extend({},j.models.oSearch);else if(c=a.aoPreSearchCols[d],
+c.bRegex===n&&(c.bRegex=!0),c.bSmart===n&&(c.bSmart=!0),c.bCaseInsensitive===n)c.bCaseInsensitive=!0;r(a,d,null)}function r(a,b,c){var d=a.aoColumns[b];c!==n&&null!==c&&(c.mDataProp&&!c.mData&&(c.mData=c.mDataProp),c.sType!==n&&(d.sType=c.sType,d._bAutoType=!1),i.extend(d,c),p(d,c,"sWidth","sWidthOrig"),c.iDataSort!==n&&(d.aDataSort=[c.iDataSort]),p(d,c,"aDataSort"));var h=d.mRender?S(d.mRender):null,f=S(d.mData);d.fnGetData=function(a,b){var c=f(a,b);return d.mRender&&b&&""!==b?h(c,b,a):c};d.fnSetData=
+ta(d.mData);a.oFeatures.bSort||(d.bSortable=!1);!d.bSortable||-1==i.inArray("asc",d.asSorting)&&-1==i.inArray("desc",d.asSorting)?(d.sSortingClass=a.oClasses.sSortableNone,d.sSortingClassJUI=""):d.bSortable||-1==i.inArray("asc",d.asSorting)&&-1==i.inArray("desc",d.asSorting)?(d.sSortingClass=a.oClasses.sSortable,d.sSortingClassJUI=a.oClasses.sSortJUI):-1!=i.inArray("asc",d.asSorting)&&-1==i.inArray("desc",d.asSorting)?(d.sSortingClass=a.oClasses.sSortableAsc,d.sSortingClassJUI=a.oClasses.sSortJUIAscAllowed):
+-1==i.inArray("asc",d.asSorting)&&-1!=i.inArray("desc",d.asSorting)&&(d.sSortingClass=a.oClasses.sSortableDesc,d.sSortingClassJUI=a.oClasses.sSortJUIDescAllowed)}function k(a){if(!1===a.oFeatures.bAutoWidth)return!1;ca(a);for(var b=0,c=a.aoColumns.length;b<c;b++)a.aoColumns[b].nTh.style.width=a.aoColumns[b].sWidth}function G(a,b){var c=v(a,"bVisible");return"number"===typeof c[b]?c[b]:null}function t(a,b){var c=v(a,"bVisible"),c=i.inArray(b,c);return-1!==c?c:null}function w(a){return v(a,"bVisible").length}
+function v(a,b){var c=[];i.map(a.aoColumns,function(a,h){a[b]&&c.push(h)});return c}function D(a){for(var b=j.ext.aTypes,c=b.length,d=0;d<c;d++){var h=b[d](a);if(null!==h)return h}return"string"}function y(a,b){for(var c=b.split(","),d=[],h=0,f=a.aoColumns.length;h<f;h++)for(var g=0;g<f;g++)if(a.aoColumns[h].sName==c[g]){d.push(g);break}return d}function H(a){for(var b="",c=0,d=a.aoColumns.length;c<d;c++)b+=a.aoColumns[c].sName+",";return b.length==d?"":b.slice(0,-1)}function ua(a,b,c,d){var h,f,
+g,e,s;if(b)for(h=b.length-1;0<=h;h--){var m=b[h].aTargets;i.isArray(m)||E(a,1,"aTargets must be an array of targets, not a "+typeof m);f=0;for(g=m.length;f<g;f++)if("number"===typeof m[f]&&0<=m[f]){for(;a.aoColumns.length<=m[f];)o(a);d(m[f],b[h])}else if("number"===typeof m[f]&&0>m[f])d(a.aoColumns.length+m[f],b[h]);else if("string"===typeof m[f]){e=0;for(s=a.aoColumns.length;e<s;e++)("_all"==m[f]||i(a.aoColumns[e].nTh).hasClass(m[f]))&&d(e,b[h])}}if(c){h=0;for(a=c.length;h<a;h++)d(h,c[h])}}function J(a,
+b){var c;c=i.isArray(b)?b.slice():i.extend(!0,{},b);var d=a.aoData.length,h=i.extend(!0,{},j.models.oRow);h._aData=c;a.aoData.push(h);for(var f,h=0,g=a.aoColumns.length;h<g;h++)c=a.aoColumns[h],"function"===typeof c.fnRender&&c.bUseRendered&&null!==c.mData?I(a,d,h,T(a,d,h)):I(a,d,h,x(a,d,h)),c._bAutoType&&"string"!=c.sType&&(f=x(a,d,h,"type"),null!==f&&""!==f&&(f=D(f),null===c.sType?c.sType=f:c.sType!=f&&"html"!=c.sType&&(c.sType="string")));a.aiDisplayMaster.push(d);a.oFeatures.bDeferRender||da(a,
+d);return d}function va(a){var b,c,d,h,f,g,e,s,m;if(a.bDeferLoading||null===a.sAjaxSource){e=a.nTBody.childNodes;b=0;for(c=e.length;b<c;b++)if("TR"==e[b].nodeName.toUpperCase()){s=a.aoData.length;e[b]._DT_RowIndex=s;a.aoData.push(i.extend(!0,{},j.models.oRow,{nTr:e[b]}));a.aiDisplayMaster.push(s);g=e[b].childNodes;d=f=0;for(h=g.length;d<h;d++)if(m=g[d].nodeName.toUpperCase(),"TD"==m||"TH"==m)I(a,s,f,i.trim(g[d].innerHTML)),f++}}e=U(a);g=[];b=0;for(c=e.length;b<c;b++){d=0;for(h=e[b].childNodes.length;d<
+h;d++)f=e[b].childNodes[d],m=f.nodeName.toUpperCase(),("TD"==m||"TH"==m)&&g.push(f)}h=0;for(e=a.aoColumns.length;h<e;h++){m=a.aoColumns[h];null===m.sTitle&&(m.sTitle=m.nTh.innerHTML);f=m._bAutoType;s="function"===typeof m.fnRender;var o=null!==m.sClass,k=m.bVisible,r,n;if(f||s||o||!k){b=0;for(c=a.aoData.length;b<c;b++)d=a.aoData[b],r=g[b*e+h],f&&"string"!=m.sType&&(n=x(a,b,h,"type"),""!==n&&(n=D(n),null===m.sType?m.sType=n:m.sType!=n&&"html"!=m.sType&&(m.sType="string"))),"function"===typeof m.mData&&
+(r.innerHTML=x(a,b,h,"display")),s&&(n=T(a,b,h),r.innerHTML=n,m.bUseRendered&&I(a,b,h,n)),o&&(r.className+=" "+m.sClass),k?d._anHidden[h]=null:(d._anHidden[h]=r,r.parentNode.removeChild(r)),m.fnCreatedCell&&m.fnCreatedCell.call(a.oInstance,r,x(a,b,h,"display"),d._aData,b,h)}}if(0!==a.aoRowCreatedCallback.length){b=0;for(c=a.aoData.length;b<c;b++)d=a.aoData[b],C(a,"aoRowCreatedCallback",null,[d.nTr,d._aData,b])}}function K(a,b){return b._DT_RowIndex!==n?b._DT_RowIndex:null}function ea(a,b,c){for(var b=
+L(a,b),d=0,a=a.aoColumns.length;d<a;d++)if(b[d]===c)return d;return-1}function Y(a,b,c,d){for(var h=[],f=0,g=d.length;f<g;f++)h.push(x(a,b,d[f],c));return h}function x(a,b,c,d){var h=a.aoColumns[c];if((c=h.fnGetData(a.aoData[b]._aData,d))===n)return a.iDrawError!=a.iDraw&&null===h.sDefaultContent&&(E(a,0,"Requested unknown parameter "+("function"==typeof h.mData?"{mData function}":"'"+h.mData+"'")+" from the data source for row "+b),a.iDrawError=a.iDraw),h.sDefaultContent;if(null===c&&null!==h.sDefaultContent)c=
+h.sDefaultContent;else if("function"===typeof c)return c();return"display"==d&&null===c?"":c}function I(a,b,c,d){a.aoColumns[c].fnSetData(a.aoData[b]._aData,d)}function S(a){if(null===a)return function(){return null};if("function"===typeof a)return function(b,d,h){return a(b,d,h)};if("string"===typeof a&&(-1!==a.indexOf(".")||-1!==a.indexOf("["))){var b=function(a,d,h){var f=h.split("."),g;if(""!==h){var e=0;for(g=f.length;e<g;e++){if(h=f[e].match(V)){f[e]=f[e].replace(V,"");""!==f[e]&&(a=a[f[e]]);
+g=[];f.splice(0,e+1);for(var f=f.join("."),e=0,i=a.length;e<i;e++)g.push(b(a[e],d,f));a=h[0].substring(1,h[0].length-1);a=""===a?g:g.join(a);break}if(null===a||a[f[e]]===n)return n;a=a[f[e]]}}return a};return function(c,d){return b(c,d,a)}}return function(b){return b[a]}}function ta(a){if(null===a)return function(){};if("function"===typeof a)return function(b,d){a(b,"set",d)};if("string"===typeof a&&(-1!==a.indexOf(".")||-1!==a.indexOf("["))){var b=function(a,d,h){var h=h.split("."),f,g,e=0;for(g=
+h.length-1;e<g;e++){if(f=h[e].match(V)){h[e]=h[e].replace(V,"");a[h[e]]=[];f=h.slice();f.splice(0,e+1);g=f.join(".");for(var i=0,m=d.length;i<m;i++)f={},b(f,d[i],g),a[h[e]].push(f);return}if(null===a[h[e]]||a[h[e]]===n)a[h[e]]={};a=a[h[e]]}a[h[h.length-1].replace(V,"")]=d};return function(c,d){return b(c,d,a)}}return function(b,d){b[a]=d}}function Z(a){for(var b=[],c=a.aoData.length,d=0;d<c;d++)b.push(a.aoData[d]._aData);return b}function fa(a){a.aoData.splice(0,a.aoData.length);a.aiDisplayMaster.splice(0,
+a.aiDisplayMaster.length);a.aiDisplay.splice(0,a.aiDisplay.length);A(a)}function ga(a,b){for(var c=-1,d=0,h=a.length;d<h;d++)a[d]==b?c=d:a[d]>b&&a[d]--; -1!=c&&a.splice(c,1)}function T(a,b,c){var d=a.aoColumns[c];return d.fnRender({iDataRow:b,iDataColumn:c,oSettings:a,aData:a.aoData[b]._aData,mDataProp:d.mData},x(a,b,c,"display"))}function da(a,b){var c=a.aoData[b],d;if(null===c.nTr){c.nTr=l.createElement("tr");c.nTr._DT_RowIndex=b;c._aData.DT_RowId&&(c.nTr.id=c._aData.DT_RowId);c._aData.DT_RowClass&&
+i(c.nTr).addClass(c._aData.DT_RowClass);for(var h=0,f=a.aoColumns.length;h<f;h++){var g=a.aoColumns[h];d=l.createElement(g.sCellType);d.innerHTML="function"===typeof g.fnRender&&(!g.bUseRendered||null===g.mData)?T(a,b,h):x(a,b,h,"display");null!==g.sClass&&(d.className=g.sClass);g.bVisible?(c.nTr.appendChild(d),c._anHidden[h]=null):c._anHidden[h]=d;g.fnCreatedCell&&g.fnCreatedCell.call(a.oInstance,d,x(a,b,h,"display"),c._aData,b,h)}C(a,"aoRowCreatedCallback",null,[c.nTr,c._aData,b])}}function wa(a){var b,
+c,d;if(0!==a.nTHead.getElementsByTagName("th").length){b=0;for(d=a.aoColumns.length;b<d;b++)if(c=a.aoColumns[b].nTh,c.setAttribute("role","columnheader"),a.aoColumns[b].bSortable&&(c.setAttribute("tabindex",a.iTabIndex),c.setAttribute("aria-controls",a.sTableId)),null!==a.aoColumns[b].sClass&&i(c).addClass(a.aoColumns[b].sClass),a.aoColumns[b].sTitle!=c.innerHTML)c.innerHTML=a.aoColumns[b].sTitle}else{var h=l.createElement("tr");b=0;for(d=a.aoColumns.length;b<d;b++)c=a.aoColumns[b].nTh,c.innerHTML=
+a.aoColumns[b].sTitle,c.setAttribute("tabindex","0"),null!==a.aoColumns[b].sClass&&i(c).addClass(a.aoColumns[b].sClass),h.appendChild(c);i(a.nTHead).html("")[0].appendChild(h);W(a.aoHeader,a.nTHead)}i(a.nTHead).children("tr").attr("role","row");if(a.bJUI){b=0;for(d=a.aoColumns.length;b<d;b++){c=a.aoColumns[b].nTh;h=l.createElement("div");h.className=a.oClasses.sSortJUIWrapper;i(c).contents().appendTo(h);var f=l.createElement("span");f.className=a.oClasses.sSortIcon;h.appendChild(f);c.appendChild(h)}}if(a.oFeatures.bSort)for(b=
+0;b<a.aoColumns.length;b++)!1!==a.aoColumns[b].bSortable?ha(a,a.aoColumns[b].nTh,b):i(a.aoColumns[b].nTh).addClass(a.oClasses.sSortableNone);""!==a.oClasses.sFooterTH&&i(a.nTFoot).children("tr").children("th").addClass(a.oClasses.sFooterTH);if(null!==a.nTFoot){c=P(a,null,a.aoFooter);b=0;for(d=a.aoColumns.length;b<d;b++)c[b]&&(a.aoColumns[b].nTf=c[b],a.aoColumns[b].sClass&&i(c[b]).addClass(a.aoColumns[b].sClass))}}function X(a,b,c){var d,h,f,g=[],e=[],i=a.aoColumns.length,m;c===n&&(c=!1);d=0;for(h=
+b.length;d<h;d++){g[d]=b[d].slice();g[d].nTr=b[d].nTr;for(f=i-1;0<=f;f--)!a.aoColumns[f].bVisible&&!c&&g[d].splice(f,1);e.push([])}d=0;for(h=g.length;d<h;d++){if(a=g[d].nTr)for(;f=a.firstChild;)a.removeChild(f);f=0;for(b=g[d].length;f<b;f++)if(m=i=1,e[d][f]===n){a.appendChild(g[d][f].cell);for(e[d][f]=1;g[d+i]!==n&&g[d][f].cell==g[d+i][f].cell;)e[d+i][f]=1,i++;for(;g[d][f+m]!==n&&g[d][f].cell==g[d][f+m].cell;){for(c=0;c<i;c++)e[d+c][f+m]=1;m++}g[d][f].cell.rowSpan=i;g[d][f].cell.colSpan=m}}}function z(a){var b=
+C(a,"aoPreDrawCallback","preDraw",[a]);if(-1!==i.inArray(!1,b))F(a,!1);else{var c,d,b=[],h=0,f=a.asStripeClasses.length;c=a.aoOpenRows.length;a.bDrawing=!0;a.iInitDisplayStart!==n&&-1!=a.iInitDisplayStart&&(a._iDisplayStart=a.oFeatures.bServerSide?a.iInitDisplayStart:a.iInitDisplayStart>=a.fnRecordsDisplay()?0:a.iInitDisplayStart,a.iInitDisplayStart=-1,A(a));if(a.bDeferLoading)a.bDeferLoading=!1,a.iDraw++;else if(a.oFeatures.bServerSide){if(!a.bDestroying&&!xa(a))return}else a.iDraw++;if(0!==a.aiDisplay.length){var g=
+a._iDisplayStart;d=a._iDisplayEnd;a.oFeatures.bServerSide&&(g=0,d=a.aoData.length);for(;g<d;g++){var e=a.aoData[a.aiDisplay[g]];null===e.nTr&&da(a,a.aiDisplay[g]);var s=e.nTr;if(0!==f){var m=a.asStripeClasses[h%f];e._sRowStripe!=m&&(i(s).removeClass(e._sRowStripe).addClass(m),e._sRowStripe=m)}C(a,"aoRowCallback",null,[s,a.aoData[a.aiDisplay[g]]._aData,h,g]);b.push(s);h++;if(0!==c)for(e=0;e<c;e++)if(s==a.aoOpenRows[e].nParent){b.push(a.aoOpenRows[e].nTr);break}}}else b[0]=l.createElement("tr"),a.asStripeClasses[0]&&
+(b[0].className=a.asStripeClasses[0]),c=a.oLanguage,f=c.sZeroRecords,1==a.iDraw&&null!==a.sAjaxSource&&!a.oFeatures.bServerSide?f=c.sLoadingRecords:c.sEmptyTable&&0===a.fnRecordsTotal()&&(f=c.sEmptyTable),c=l.createElement("td"),c.setAttribute("valign","top"),c.colSpan=w(a),c.className=a.oClasses.sRowEmpty,c.innerHTML=ia(a,f),b[h].appendChild(c);C(a,"aoHeaderCallback","header",[i(a.nTHead).children("tr")[0],Z(a),a._iDisplayStart,a.fnDisplayEnd(),a.aiDisplay]);C(a,"aoFooterCallback","footer",[i(a.nTFoot).children("tr")[0],
+Z(a),a._iDisplayStart,a.fnDisplayEnd(),a.aiDisplay]);h=l.createDocumentFragment();c=l.createDocumentFragment();if(a.nTBody){f=a.nTBody.parentNode;c.appendChild(a.nTBody);if(!a.oScroll.bInfinite||!a._bInitComplete||a.bSorted||a.bFiltered)for(;c=a.nTBody.firstChild;)a.nTBody.removeChild(c);c=0;for(d=b.length;c<d;c++)h.appendChild(b[c]);a.nTBody.appendChild(h);null!==f&&f.appendChild(a.nTBody)}C(a,"aoDrawCallback","draw",[a]);a.bSorted=!1;a.bFiltered=!1;a.bDrawing=!1;a.oFeatures.bServerSide&&(F(a,!1),
+a._bInitComplete||$(a))}}function aa(a){a.oFeatures.bSort?Q(a,a.oPreviousSearch):a.oFeatures.bFilter?M(a,a.oPreviousSearch):(A(a),z(a))}function ya(a){var b=i("<div></div>")[0];a.nTable.parentNode.insertBefore(b,a.nTable);a.nTableWrapper=i('<div id="'+a.sTableId+'_wrapper" class="'+a.oClasses.sWrapper+'" role="grid"></div>')[0];a.nTableReinsertBefore=a.nTable.nextSibling;for(var c=a.nTableWrapper,d=a.sDom.split(""),h,f,g,e,s,m,o,k=0;k<d.length;k++){f=0;g=d[k];if("<"==g){e=i("<div></div>")[0];s=d[k+
+1];if("'"==s||'"'==s){m="";for(o=2;d[k+o]!=s;)m+=d[k+o],o++;"H"==m?m=a.oClasses.sJUIHeader:"F"==m&&(m=a.oClasses.sJUIFooter);-1!=m.indexOf(".")?(s=m.split("."),e.id=s[0].substr(1,s[0].length-1),e.className=s[1]):"#"==m.charAt(0)?e.id=m.substr(1,m.length-1):e.className=m;k+=o}c.appendChild(e);c=e}else if(">"==g)c=c.parentNode;else