You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by an...@apache.org on 2006/06/08 04:39:14 UTC
svn commit: r412635 - in /cocoon: branches/BRANCH_2_1_X/
trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/
trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/flow/
trunk/blocks/co...
Author: antonio
Date: Wed Jun 7 19:39:13 2006
New Revision: 412635
URL: http://svn.apache.org/viewvc?rev=412635&view=rev
Log:
CForms Block: Add multiple repeater drag & drop sample. Thanks to Carlos Chávez and Eric Meyer.
Added:
cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/CFormsDragAndDropRepeater.js (with props)
cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeaters.xml (with props)
cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeaters_binding.xml (with props)
cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeaters_dojo_template.xml (with props)
Modified:
cocoon/branches/BRANCH_2_1_X/status.xml
cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/CFormsRepeater.js
cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/flow/forms_flow_example.js
cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeater.xml
cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeater_dojo_template.xml
cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeater_template.xml
Modified: cocoon/branches/BRANCH_2_1_X/status.xml
URL: http://svn.apache.org/viewvc/cocoon/branches/BRANCH_2_1_X/status.xml?rev=412635&r1=412634&r2=412635&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/status.xml (original)
+++ cocoon/branches/BRANCH_2_1_X/status.xml Wed Jun 7 19:39:13 2006
@@ -182,8 +182,14 @@
<release version="@version@" date="@date@">
-->
<release version="2.1.10" date="TBD">
+ <action dev="AG" type="add" due-to="Carlos Chávez & Eric Meyer" due-to-email="cchavez@agssa.net & emeyer@quoininc.com">
+ CForms Block: Add multiple repeater drag & drop dojo sample.
+ </action>
<action dev="CZ" type="fix" fixes-bug="COCOON-1857" due-to="Brian Vargas" due-to-email="ardvaark-apachebugs@procrastinators.org">
Set instrumentation manager on child component managers to enable instrumentation of all components including sitemap components.
+ </action>
+ <action dev="AG" type="update">
+ Updated dojo to 20060605.
</action>
<action dev="CZ" type="fix">
Fix bug in wildcard matcher where a uri containing a pattern twice did not always match. For example,
Added: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/CFormsDragAndDropRepeater.js
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/CFormsDragAndDropRepeater.js?rev=412635&view=auto
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/CFormsDragAndDropRepeater.js (added)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/CFormsDragAndDropRepeater.js Wed Jun 7 19:39:13 2006
@@ -0,0 +1,230 @@
+/*
+ * Copyright 1999-2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+dojo.provide("cocoon.forms.CFormsDragAndDropRepeater");
+dojo.require("cocoon.forms.CFormsRepeater");
+
+/**
+ * Dojo widget for repeaters, that handles drag'n drop reordering and selection
+ * by clicking in the rows.
+ * <p>
+ * The drop indicator can be styled with the "forms-dropIndicator" CSS class.
+ *
+ * @version $Id: CFormsRepeater.js 393543 2006-04-12 17:32:25Z cziegeler $
+ */
+
+// Extends the base CFormsRepeater class.
+cocoon.forms.CFormsDragAndDropRepeater = function() {
+ cocoon.forms.CFormsRepeater.call(this);
+};
+
+dojo.inherits(cocoon.forms.CFormsDragAndDropRepeater, cocoon.forms.CFormsRepeater);
+
+dojo.lang.extend(cocoon.forms.CFormsDragAndDropRepeater, {
+ // Properties
+ // Widget definition
+ widgetType: "CFormsDragAndDropRepeater",
+ /**
+ * Returns the action name to be called on the server for model update.
+ */
+ getDndAction: function() {
+ var addAction = this.domNode.getAttribute("dnd-action");
+ dojo.debug("getDndAction: action=" + addAction);
+ return addAction;
+ },
+ /**
+ * Returns the drag & drop id used to share row between repeaters.
+ */
+ getType: function() {
+ var type = this.domNode.getAttribute("dnd-id");
+ if (type == null) {
+ type = this.id;
+ }
+ return "cforms-" + type;
+ },
+ buildRendering: function(args, parserFragment, parentWidget) {
+ // FIXME: we should destroy all drag sources and drop targets when the widget is destroyed
+ // Magical statement to get the dom node, stolen in DomWidget
+ this.domNode = parserFragment["dojo:"+this.widgetType.toLowerCase()].nodeRef;
+
+ this.id = this.domNode.getAttribute("id");
+ if (!this.orderable && this.select == "none") {
+ dojo.debug(this.widgetType + " '" + this.id + "' is not orderable nor selectable");
+ }
+
+ if (this.orderable) {
+ // Get the parent of the first repeater row (may be different from this.domNode)
+ var firstRow = dojo.byId(this.id + ".0");
+ if (!firstRow) return;
+
+ // Check that TR's are in TBODY otherwise it doesn't work
+ if (firstRow.tagName.toLowerCase() == "tr" && firstRow.parentNode.tagName.toLowerCase() != "tbody") {
+ throw this.widgetType + " requires TR's to be in a TBODY (check '" + this.id + "')";
+ }
+
+ var type = this.getType();
+ var dropTarget = new dojo.dnd.HtmlDropTarget(firstRow.parentNode, [type]);
+
+ dropTarget.createDropIndicator = function() {
+ this.dropIndicator = document.createElement("div");
+ this.dropIndicator.className = "forms-dropIndicator";
+ with (this.dropIndicator.style) {
+ position = "absolute";
+ zIndex = 1;
+ width = dojo.style.getInnerWidth(this.domNode) + "px";
+ left = dojo.style.getAbsoluteX(this.domNode) + "px";
+ }
+ };
+ dojo.event.connect("before", dropTarget, "insert", this, "beforeInsert");
+ dojo.event.connect(dropTarget, "insert", this, "afterInsert");
+
+ var row;
+ for (var idx = 0; row = dojo.byId(this.id + "." + idx); idx++) {
+ row.setAttribute("dndType", 'repeaterRow');
+ row.setAttribute("dndRepeaterId", this.id);
+ row.setAttribute("dndRowIndex", idx);
+ var dragSource = new dojo.dnd.HtmlDragSource(row, type);
+ row.style.cursor = "move";
+ }
+ }
+
+ if (this.select != "$no$") {
+ var row;
+ var widget = this;
+ for (var idx = 0; row = dojo.byId(this.id + "." + idx); idx++) {
+ var selectId = row.getAttribute("id") + "." + this.select + ":input";
+ var selectInput = dojo.byId(selectId);
+ if (!selectInput) {
+ throw "No select input found for row '" + row.getAttribute("id") + "'";
+ }
+
+ if (selectInput.checked) {
+ dojo.html.prependClass(row, "forms-row-selected");
+ }
+ (function() {
+ var localIdx = idx; // to use it in the closure
+ var localRow = row;
+ dojo.event.connect(row, "onclick", function(e) { widget.selectRow(e, localRow, localIdx) });
+ dojo.event.connect(row, "onmouseover", function(e) { dojo.html.prependClass(localRow, "forms-row-hover") });
+ dojo.event.connect(row, "onmouseout", function(e) { dojo.html.removeClass(localRow, "forms-row-hover") });
+ })()
+ }
+ }
+ },
+
+ beforeInsert: function(e, refNode, position) {
+ if (this.keepSourceInPlace(e, refNode, position)) {
+ e.dragObject.domNode = e.dragObject.domNode.cloneNode(true);
+ }
+ },
+
+ /**
+ * The dragged item should be copied instead of moved.
+ *
+ * return true - the item will be copied.
+ */
+ keepSourceInPlace: function(e, refNode, position) {
+ var parts = e.dragObject.domNode.getAttribute("id").split('.');
+ var sourceRepeaterId = parts[0];
+ return sourceRepeaterId != this.id;
+ },
+
+ /**
+ * Return an object with predefined method to retrieve information
+ * about the source object to be inserted into this repeater
+ * @param e the event (has a "dragObject" property)
+ */
+ makeDragSource: function(e) {
+ var repeater = this;
+ var result = {
+ _init: function(e) {
+ this.e = e;
+ this.sourceRowIndex = e.dragObject.domNode.getAttribute("dndRowIndex");
+ this.sourceRepeaterId = e.dragObject.domNode.getAttribute("dndRepeaterId");
+ },
+ getRowIdx: function() { return this.sourceRowIndex;},
+ getRepeaterId: function() { return this.sourceRepeaterId;},
+ isRepeater: function() { return e.dragObject.domNode.getAttribute("dndType") == 'repeaterRow';},
+ makeParameters: function() {
+ var res = {};
+ res[repeater.id + ".sourceRowIndex"] = this.sourceRowIndex;
+ res[repeater.id + ".sourceRepeaterId"] = this.sourceRepeaterId;
+ return res;
+ }
+ };
+ result._init(e);
+ return result;
+ },
+
+ /**
+ * Called after a dropped node has been inserted at its target position
+ * @param e the event (has a "dragObject" property)
+ * @param refNode the reference node for the insertion
+ * @param position the insertion position relative to refNode ("before" or "after")
+ */
+ afterInsert: function(e, refNode, position) {
+ // Compute the row number before which to place the moved row
+ var targetRowIndex = refNode.getAttribute("dndRowIndex");
+ if (position == "after") {
+ targetRowIndex++;
+ }
+
+ var dragSource = this.makeDragSource(e);
+ if (dragSource.isRepeater(e)) {
+ var sourceRowIndex = dragSource.getRowIdx();
+ var sourceRepeaterId = dragSource.getRepeaterId();
+ dojo.debug("afterInsert: sourceRepeaterId=" + sourceRepeaterId);
+ dojo.debug("afterInsert: sourceRowIndex=" + sourceRowIndex);
+ }
+
+ dojo.debug("afterInsert: targetRepeaterId=" + this.id);
+ dojo.debug("afterInsert: targetRowIndex=" + targetRowIndex);
+
+ var params = dragSource.makeParameters();
+ params[this.id + ".before"] = targetRowIndex;
+ params["dndTarget.id"] = this.id;
+
+ // submit the form to update server-side model
+ if (sourceRepeaterId == this.id) {
+ // move
+ if (targetRowIndex == sourceRowIndex || targetRowIndex == sourceRowIndex + 1) {
+ return; // no change needed
+ }
+ var form = cocoon.forms.getForm(this.domNode);
+ params[this.id + ".action"] = "move";
+ params[this.id + ".from"] = sourceRowIndex;
+ dojo.widget.byId(form.getAttribute("dojoWidgetId")).submit(this.id, params);
+ } else if (this.getDndAction()) {
+ // Run dndAction
+ var form = cocoon.forms.getForm(this.domNode);
+ var dojoForm = dojo.widget.byId(form.getAttribute("dojoWidgetId"));
+ this.dndAction(dojoForm, dragSource, targetRowIndex, params);
+ }
+ },
+ /**
+ * Calls the server-side event to update the form model
+ * @param dojoForm the dojoForm
+ * @param dragSource the customized source reference node to be inserted into this repeater
+ * @param targeRowtIndex the row insertion index into this repeater
+ * @param params the parameter of the server-side event
+ */
+ dndAction : function(dojoForm, dragSource, targetRowIndex, params) {
+ dojoForm.submit(this.getDndAction(), params);
+ }
+});
+
+dojo.widget.tags.addParseTreeHandler("dojo:CFormsDragAndDropRepeater");
+// Register this module as a widget package
+dojo.widget.manager.registerWidgetPackage("cocoon.forms");
Propchange: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/CFormsDragAndDropRepeater.js
------------------------------------------------------------------------------
svn:eol-style = native
Modified: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/CFormsRepeater.js
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/CFormsRepeater.js?rev=412635&r1=412634&r2=412635&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/CFormsRepeater.js (original)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-impl/src/main/resources/org/apache/cocoon/forms/resources/js/CFormsRepeater.js Wed Jun 7 19:39:13 2006
@@ -26,8 +26,9 @@
*
* @version $Id$
*/
+
// Extends the base DomWidget class. We don't need all the HtmlWidget stuff
-// but need traversal of the DOM to build child widgets
+// but need traversal of the DOM to build child widgets.
cocoon.forms.CFormsRepeater = function() {
dojo.widget.DomWidget.call(this);
};
@@ -35,22 +36,26 @@
dojo.inherits(cocoon.forms.CFormsRepeater, dojo.widget.DomWidget);
dojo.lang.extend(cocoon.forms.CFormsRepeater, {
- // Properties
- orderable: false,
- select: "$no$", // default value used to type the property, but indicating that
- // no selection will occur
-
- // Widget definition
- widgetType: "CFormsRepeater",
+ // Properties
+ orderable: false,
+ select: "$no$", // default value used to type the property, but indicating that
+ // no selection will occur
+
+ // Widget definition
+ widgetType: "CFormsRepeater",
isContainer: true,
+ //
+ getType: function() {
+ return "cforms-" + this.id;
+ },
buildRendering: function(args, parserFragment, parentWidget) {
// FIXME: we should destroy all drag sources and drop targets when the widget is destroyed
// Magical statement to get the dom node, stolen in DomWidget
this.domNode = parserFragment["dojo:"+this.widgetType.toLowerCase()].nodeRef;
-
+
this.id = this.domNode.getAttribute("id");
if (!this.orderable && this.select == "none") {
- dojo.debug("CFormsRepeater '" + this.id + "' is not orderable nor selectable");
+ dojo.debug(this.widgetType + " '" + this.id + "' is not orderable nor selectable");
}
if (this.orderable) {
@@ -60,11 +65,11 @@
// Check that TR's are in TBODY otherwise it doesn't work
if (firstRow.tagName.toLowerCase() == "tr" && firstRow.parentNode.tagName.toLowerCase() != "tbody") {
- throw "CFormsRepeater requires TR's to be in a TBODY (check '" + this.id + "')";
+ throw this.widgetType + " requires TR's to be in a TBODY (check '" + this.id + "')";
}
- var type = "cforms-" + this.id;
- var dropTarget = new dojo.dnd.HtmlDropTarget(firstRow.parentNode, [type]);
+ var type = this.getType();
+ var dropTarget = new dojo.dnd.HtmlDropTarget(firstRow.parentNode, [type]);
dropTarget.createDropIndicator = function() {
this.dropIndicator = document.createElement("div");
@@ -77,7 +82,7 @@
}
};
dojo.event.connect(dropTarget, "insert", this, "afterInsert");
-
+
var row;
for (var idx = 0; row = dojo.byId(this.id + "." + idx); idx++) {
var dragSource = new dojo.dnd.HtmlDragSource(row, type);
@@ -123,8 +128,8 @@
// Compute the row number before which to place the moved row
if (position == "after") before++;
if (before == source || before == source + 1) return; // no change needed
-
-// dojo.debug("moving row " + source + " before " + before + " (" + position + ")");
+
+ // dojo.debug("moving row " + source + " before " + before + " (" + position + ")");
// submit the form to update server-side model
var form = cocoon.forms.getForm(this.domNode);
Modified: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/flow/forms_flow_example.js
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/flow/forms_flow_example.js?rev=412635&r1=412634&r2=412635&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/flow/forms_flow_example.js (original)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/flow/forms_flow_example.js Wed Jun 7 19:39:13 2006
@@ -124,6 +124,30 @@
);
}
+function do_dojoRepeaters() {
+ var form = new Form("forms/dynamicrepeaters.xml");
+ form.setAttribute("counter1", new java.lang.Integer(0));
+ form.setAttribute("counter2", new java.lang.Integer(0));
+ form.setAttribute("counter3", new java.lang.Integer(0));
+ form.getChild("addcontact1").performAction(); // to increment the counter
+ form.getChild("addcontact2").performAction(); // to increment the counter
+ form.getChild("addcontact3").performAction(); // to increment the counter
+ form.showForm("dynamicrepeaters_dojo-display-pipeline.jx");
+
+ var doc = Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+ var rootElement = doc.createElement("contact_root");
+ rootElement.appendChild(doc.createElement("contacts1"));
+ rootElement.appendChild(doc.createElement("contacts2"));
+ rootElement.appendChild(doc.createElement("contacts3"));
+ doc.appendChild(rootElement);
+ form.createBinding("forms/dynamicrepeaters_binding.xml");
+
+ form.save(doc);
+ cocoon.sendPage("xmlresult-display-pipeline.jx",
+ {title: "Contact list", document: doc}
+ );
+}
+
function do_datasourceChooser() {
var form = new Form("forms/datasource_chooser.xml");
form.showForm("datasource_chooser-display-pipeline.jx");
Modified: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeater.xml
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeater.xml?rev=412635&r1=412634&r2=412635&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeater.xml (original)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeater.xml Wed Jun 7 19:39:13 2006
@@ -36,13 +36,13 @@
<fd:field id="firstname">
<fd:label>Firstname</fd:label>
- <fd:hint>First name</fd:hint>
+ <fd:hint>First name</fd:hint>
<fd:datatype base="string"/>
</fd:field>
<fd:field id="lastname">
<fd:label>Lastname</fd:label>
- <fd:hint>Last name</fd:hint>
+ <fd:hint>Last name</fd:hint>
<fd:datatype base="string"/>
</fd:field>
Modified: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeater_dojo_template.xml
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeater_dojo_template.xml?rev=412635&r1=412634&r2=412635&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeater_dojo_template.xml (original)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeater_dojo_template.xml Wed Jun 7 19:39:13 2006
@@ -26,7 +26,7 @@
<fi:init>
<script type="text/javascript">
// Uncomment this to see Dojo debug
- // var djConfig = { isDebug: true };
+ var djConfig = { isDebug: true };
</script>
</fi:init>
Modified: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeater_template.xml
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeater_template.xml?rev=412635&r1=412634&r2=412635&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeater_template.xml (original)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeater_template.xml Wed Jun 7 19:39:13 2006
@@ -55,6 +55,8 @@
</ul>
<p>This sample has a <a href="do-dojoRepeater.flow">variation using Dojo</a> that allows drag-and-drop reordering
of rows and clicking anywhere in a row to select it.</p>
+ <p>Here is another <a href="do-dojoRepeaters.flow">Dojo sample</a> that extends the above dojo sample by
+ allowing drag-and-drop support between different repeaters.</p>
<ft:repeater id="contacts">
<div>
<jx:choose>
Added: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeaters.xml
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeaters.xml?rev=412635&view=auto
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeaters.xml (added)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeaters.xml Wed Jun 7 19:39:13 2006
@@ -0,0 +1,211 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 1999-2004 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+ @version $Id: dynamicrepeater.xml 385334 2006-03-12 18:27:44Z sylvain $
+-->
+
+<fd:form xmlns:fd="http://apache.org/cocoon/forms/1.0#definition"
+ xmlns:i18n="http://apache.org/cocoon/i18n/2.1">
+
+ <fd:widgets>
+ <fd:repeater id="contacts1" orderable="true">
+ <fd:widgets>
+
+ <!-- The ID is here to keep track of row creation order, which can
+ have no relation with row index when the users used move up/down -->
+ <fd:output id="ID">
+ <fd:label>ID</fd:label>
+ <fd:datatype base="integer"/>
+ </fd:output>
+
+ <fd:field id="firstname">
+ <fd:label>Firstname</fd:label>
+ <fd:hint>First name</fd:hint>
+ <fd:datatype base="string"/>
+ </fd:field>
+
+ <fd:field id="lastname">
+ <fd:label>Lastname</fd:label>
+ <fd:hint>Last name</fd:hint>
+ <fd:datatype base="string"/>
+ </fd:field>
+
+ <fd:row-action id="up" command="move-up"/>
+ <fd:row-action id="down" command="move-down"/>
+
+ <fd:booleanfield id="select">
+ <fd:label>Select</fd:label>
+ </fd:booleanfield>
+
+ </fd:widgets>
+ </fd:repeater>
+
+ <fd:repeater-action id="removecontacts1" command="delete-rows" repeater="contacts1" select="select">
+ <fd:label>Remove selected contacts</fd:label>
+ </fd:repeater-action>
+
+ <fd:repeater-action id="addcontact1" command="add-row" repeater="contacts1">
+ <fd:label>Add contact</fd:label>
+ <fd:on-action>
+ <fd:javascript>
+ // Increment the row creation ID counter (it has been initialized in
+ // the flowscript when the form was created).
+ // This shows how attributes can be used as a communication means between
+ // application logic and widget event handlers.
+ var form = event.source.form;
+ var count = new java.lang.Integer(form.getAttribute("counter1").intValue() + 1);
+ form.setAttribute("counter1", count);
+ var repeater = form.getChild("contacts1");
+ repeater.getRow(repeater.getSize() - 1).getChild("ID").setValue(count);
+ </fd:javascript>
+ </fd:on-action>
+ </fd:repeater-action>
+
+ <!-- Second repeater -->
+ <fd:repeater id="contacts2" orderable="true">
+ <fd:widgets>
+
+ <!-- The ID is here to keep track of row creation order, which can
+ have no relation with row index when the users used move up/down -->
+ <fd:output id="ID">
+ <fd:label>ID</fd:label>
+ <fd:datatype base="integer"/>
+ </fd:output>
+
+ <fd:field id="firstname">
+ <fd:label>Firstname</fd:label>
+ <fd:hint>First name</fd:hint>
+ <fd:datatype base="string"/>
+ </fd:field>
+
+ <fd:field id="lastname">
+ <fd:label>Lastname</fd:label>
+ <fd:hint>Last name</fd:hint>
+ <fd:datatype base="string"/>
+ </fd:field>
+
+ <fd:row-action id="up" command="move-up"/>
+ <fd:row-action id="down" command="move-down"/>
+
+ <fd:booleanfield id="select">
+ <fd:label>Select</fd:label>
+ </fd:booleanfield>
+ </fd:widgets>
+ </fd:repeater>
+
+ <fd:repeater-action id="removecontacts2" command="delete-rows" repeater="contacts2" select="select">
+ <fd:label>Remove selected contacts</fd:label>
+ </fd:repeater-action>
+
+ <fd:repeater-action id="addcontact2" command="add-row" repeater="contacts2">
+ <fd:label>Add contact</fd:label>
+ <fd:on-action>
+ <fd:javascript>
+ // Increment the row creation ID counter (it has been initialized in
+ // the flowscript when the form was created).
+ // This shows how attributes can be used as a communication means between
+ // application logic and widget event handlers.
+ var form = event.source.form;
+ var count = new java.lang.Integer(form.getAttribute("counter2").intValue() + 1);
+ form.setAttribute("counter2", count);
+ var repeater = form.getChild("contacts2");
+ repeater.getRow(repeater.getSize() - 1).getChild("ID").setValue(count);
+ </fd:javascript>
+ </fd:on-action>
+ </fd:repeater-action>
+
+ <!-- 3rd repeater -->
+ <fd:repeater id="contacts3" orderable="true">
+ <fd:widgets>
+
+ <!-- The ID is here to keep track of row creation order, which can
+ have no relation with row index when the users used move up/down -->
+ <fd:output id="ID">
+ <fd:label>ID</fd:label>
+ <fd:datatype base="integer"/>
+ </fd:output>
+
+ <fd:field id="firstname">
+ <fd:label>Firstname</fd:label>
+ <fd:hint>First name</fd:hint>
+ <fd:datatype base="string"/>
+ </fd:field>
+
+ <fd:field id="lastname">
+ <fd:label>Lastname</fd:label>
+ <fd:hint>Last name</fd:hint>
+ <fd:datatype base="string"/>
+ </fd:field>
+
+ <fd:row-action id="up" command="move-up"/>
+ <fd:row-action id="down" command="move-down"/>
+
+ <fd:booleanfield id="select">
+ <fd:label>Select</fd:label>
+ </fd:booleanfield>
+ </fd:widgets>
+ </fd:repeater>
+
+ <fd:repeater-action id="removecontacts3" command="delete-rows" repeater="contacts3" select="select">
+ <fd:label>Remove selected contacts</fd:label>
+ </fd:repeater-action>
+
+ <fd:repeater-action id="addcontact3" command="add-row" repeater="contacts3">
+ <fd:label>Add contact</fd:label>
+ <fd:on-action>
+ <fd:javascript>
+ // Increment the row creation ID counter (it has been initialized in
+ // the flowscript when the form was created).
+ // This shows how attributes can be used as a communication means between
+ // application logic and widget event handlers.
+ var form = event.source.form;
+ var count = new java.lang.Integer(form.getAttribute("counter3").intValue() + 1);
+ form.setAttribute("counter3", count);
+ var repeater = form.getChild("contacts3");
+ repeater.getRow(repeater.getSize() - 1).getChild("ID").setValue(count);
+ </fd:javascript>
+ </fd:on-action>
+ </fd:repeater-action>
+ <fd:action id="dnd" status="invisible">
+ <fd:on-action>
+ <fd:javascript>
+ // Retrieve special action parameters
+ var targetRepeaterId = cocoon.request.getParameter("dndTarget.id");
+
+ var sourceRepeaterId = cocoon.request.getParameter(targetRepeaterId + ".sourceRepeaterId");
+ var sourceRowIndex = cocoon.request.getParameter(targetRepeaterId + ".sourceRowIndex");
+ var targetRowIndex = cocoon.request.getParameter(targetRepeaterId + ".before");
+ // Processing: Copy the row from the source repeater to target
+ var form = event.source.form;
+ var sourceRepeater = form.getChild(sourceRepeaterId);
+ var sourceRow = sourceRepeater.getRow(sourceRowIndex);
+
+ var targetRepeater = form.getChild(targetRepeaterId);
+ var targetRow = targetRepeater.addRow(targetRowIndex);
+ targetRow.getChild("firstname").setValue(sourceRow.getChild("firstname").getValue());
+ targetRow.getChild("lastname").setValue(sourceRow.getChild("lastname").getValue());
+ targetRow.getChild("ID").setValue(sourceRow.getChild("ID").getValue());
+ </fd:javascript>
+ </fd:on-action>
+ </fd:action>
+
+ <fd:submit id="ok">
+ <fd:label>Submit</fd:label>
+ </fd:submit>
+ </fd:widgets>
+</fd:form>
Propchange: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeaters.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeaters_binding.xml
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeaters_binding.xml?rev=412635&view=auto
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeaters_binding.xml (added)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeaters_binding.xml Wed Jun 7 19:39:13 2006
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 1999-2004 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+ @version $Id: dynamicrepeater_binding.xml 151045 2005-02-02 20:36:01Z tim $
+-->
+
+<fb:context xmlns:fb="http://apache.org/cocoon/forms/1.0#binding"
+ path="contact_root">
+
+ <fb:simple-repeater id="contacts1" parent-path="contacts1" row-path="contact1">
+ <fb:value id="ID" path="@id"/>
+ <fb:value id="firstname" path="firstname"/>
+ <fb:value id="lastname" path="lastname"/>
+ </fb:simple-repeater>
+ <fb:simple-repeater id="contacts2" parent-path="contacts2" row-path="contact2">
+ <fb:value id="ID" path="@id"/>
+ <fb:value id="firstname" path="firstname"/>
+ <fb:value id="lastname" path="lastname"/>
+ </fb:simple-repeater>
+ <fb:simple-repeater id="contacts3" parent-path="contacts3" row-path="contact3">
+ <fb:value id="ID" path="@id"/>
+ <fb:value id="firstname" path="firstname"/>
+ <fb:value id="lastname" path="lastname"/>
+ </fb:simple-repeater>
+</fb:context>
Propchange: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeaters_binding.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeaters_dojo_template.xml
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeaters_dojo_template.xml?rev=412635&view=auto
==============================================================================
--- cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeaters_dojo_template.xml (added)
+++ cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeaters_dojo_template.xml Wed Jun 7 19:39:13 2006
@@ -0,0 +1,186 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 1999-2004 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- This file is similar to form1_template_action.xml. They differ in group layout,
+ form's action attribute (to use continuations) and, this one is a dynamic form
+ template that changes the 'contacts' repeater layout depending on its size -->
+<page xmlns:ft="http://apache.org/cocoon/forms/1.0#template"
+ xmlns:fi="http://apache.org/cocoon/forms/1.0#instance"
+ xmlns:jx="http://apache.org/cocoon/templates/jx/1.0">
+
+ <!-- Import the macros that define CForms template elements -->
+ <jx:import uri="resource://org/apache/cocoon/forms/generation/jx-macros.xml"/>
+ <fi:init>
+ <script type="text/javascript">
+ // Uncomment next line to see Dojo debug
+ // var djConfig = { isDebug: true };
+ </script>
+ </fi:init>
+ <h4 class="samplesGroup">Repeater widget with advanced interaction</h4>
+ <title>Repeater widget with advanced interaction</title>
+ <style type="text/css">
+ .forms-row td {
+ padding: 5px;
+ }
+
+ /* Ensure the inline edit is visible on selected rows */
+ .forms-row-selected .editableRegion {
+ color: black;
+ }
+ </style>
+
+ <content>
+ <ft:form-template action="#{$cocoon/continuation/id}.continue" method="POST" ajax="true">
+
+ <p>This example expands on the <a href="do-dynaRepeater.flow">dynamic repeater sample</a> and uses
+ <a href="http://dojotoolkit.org">Dojo</a> to provide additional interaction features.
+ After adding rows in any repeater below, you will be able to:</p>
+ <ul>
+ <li>move rows between repeaters using drag-and-drop,</li>
+ <li>reorder rows into the same repater using drag-and-drop,</li>
+ <li>select and deselect rows by clicking anywhere rather than in a checkbox,</li>
+ <li>use in-place editing (an input appears when you click on the text) in the third repeater.</li>
+ </ul>
+ <ft:repeater id="contacts1">
+ <div dojoType="CFormsDragAndDropRepeater" dnd-id="contacto" dnd-action="dnd" orderable="true" select="select">
+ <jx:choose>
+ <jx:when test="${repeater.getSize() == 0}">
+ <p><strong><em>There are no contacts to display</em></strong></p>
+ </jx:when>
+ <jx:otherwise>
+ <table border="1">
+ <tr>
+ <th width="300"><ft:repeater-widget-label widget-id="firstname"/></th>
+ <th width="300"><ft:repeater-widget-label widget-id="lastname"/></th>
+ <th><ft:repeater-widget-label widget-id="ID"/></th>
+ </tr>
+ <tbody>
+ <!-- The contents of the repeater-widget element is a template that will
+ be applied to each row in the repeater. -->
+ <ft:repeater-rows>
+ <tr class="forms-row">
+ <td><ft:widget id="firstname"/></td>
+ <td><ft:widget id="lastname"/>
+ </td>
+ <td><ft:widget id="ID"/>
+ <ft:widget id="select">
+ <fi:styling style="display: none"/>
+ </ft:widget>
+ </td>
+ </tr>
+ </ft:repeater-rows>
+ </tbody>
+ </table>
+ </jx:otherwise>
+ </jx:choose>
+ <p>
+ <ft:widget id="../addcontact1"/>
+ <jx:if test="${widget.getSize() > 0}">
+ <ft:widget id="../removecontacts1"/>
+ </jx:if>
+ </p>
+ </div>
+ </ft:repeater>
+ <!-- 2nd repeater -->
+ <ft:repeater id="contacts2">
+ <div dojoType="CFormsDragAndDropRepeater" dnd-id="contacto" dnd-action="dnd" orderable="true" select="select">
+ <jx:choose>
+ <jx:when test="${repeater.getSize() == 0}">
+ <p><strong><em>There are no contacts to display</em></strong></p>
+ </jx:when>
+ <jx:otherwise>
+
+ <table border="1">
+ <tr>
+ <th width="300"><ft:repeater-widget-label widget-id="firstname"/></th>
+ <th width="300"><ft:repeater-widget-label widget-id="lastname"/></th>
+ <th><ft:repeater-widget-label widget-id="ID"/></th>
+ </tr>
+ <tbody>
+ <!-- The contents of the repeater-widget element is a template that will
+ be applied to each row in the repeater. -->
+ <ft:repeater-rows>
+ <tr class="forms-row">
+ <td><ft:widget id="firstname"/></td>
+ <td><ft:widget id="lastname"/>
+ </td>
+ <td><ft:widget id="ID"/>
+ <ft:widget id="select">
+ <fi:styling style="display: none"/>
+ </ft:widget>
+ </td>
+ </tr>
+ </ft:repeater-rows>
+ </tbody>
+ </table>
+ </jx:otherwise>
+ </jx:choose>
+ <p>
+ <ft:widget id="../addcontact2"/>
+ <jx:if test="${widget.getSize() > 0}">
+ <ft:widget id="../removecontacts2"/>
+ </jx:if>
+ </p>
+ </div>
+ </ft:repeater>
+ <!-- 3rd repeater -->
+ <ft:repeater id="contacts3">
+ <div dojoType="CFormsDragAndDropRepeater" dnd-id="contacto" dnd-action="dnd" orderable="true" select="select">
+ <jx:choose>
+ <jx:when test="${repeater.getSize() == 0}">
+ <p><strong><em>There are no contacts to display</em></strong></p>
+ </jx:when>
+ <jx:otherwise>
+
+ <table border="1">
+ <tr>
+ <th width="300"><ft:repeater-widget-label widget-id="firstname"/></th>
+ <th width="300"><ft:repeater-widget-label widget-id="lastname"/></th>
+ <th><ft:repeater-widget-label widget-id="ID"/></th>
+ </tr>
+ <tbody>
+ <!-- The contents of the repeater-widget element is a template that will
+ be applied to each row in the repeater. -->
+ <ft:repeater-rows>
+ <tr class="forms-row">
+ <td><ft:widget id="firstname" fi:type="inplace" fi:submit-on-change="true"/></td>
+ <td><ft:widget id="lastname" fi:type="inplace"/>
+ </td>
+ <td><ft:widget id="ID"/>
+ <ft:widget id="select">
+ <fi:styling style="display: none"/>
+ </ft:widget>
+ </td>
+ </tr>
+ </ft:repeater-rows>
+ </tbody>
+ </table>
+ </jx:otherwise>
+ </jx:choose>
+ <p>
+ <ft:widget id="../addcontact3"/>
+ <jx:if test="${widget.getSize() > 0}">
+ <ft:widget id="../removecontacts3"/>
+ </jx:if>
+ </p>
+ </div>
+ </ft:repeater>
+ <ft:widget id="ok"/><br/>
+ <a href="./do-dojoRepeaters.flow">Restart this sample</a> - <a href="./">Back to samples</a>
+
+ </ft:form-template>
+ </content>
+</page>
Propchange: cocoon/trunk/blocks/cocoon-forms/cocoon-forms-sample/src/main/resources/COB-INF/forms/dynamicrepeaters_dojo_template.xml
------------------------------------------------------------------------------
svn:eol-style = native