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 &amp; Eric Meyer" due-to-email="cchavez@agssa.net &amp; emeyer@quoininc.com">
+      CForms Block: Add multiple repeater drag &amp; 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