cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sylv...@apache.org
Subject svn commit: r168669 - in /cocoon/blocks/core/forms/trunk: java/org/apache/cocoon/forms/flow/javascript/Form.js java/org/apache/cocoon/forms/resources/js/cforms.js samples/forms/carselector_template.xml samples/welcome.xml
Date Fri, 06 May 2005 22:01:55 GMT
Author: sylvain
Date: Fri May  6 15:01:55 2005
New Revision: 168669

URL: http://svn.apache.org/viewcvs?rev=168669&view=rev
Log:
Ajax: fix a bug with boolean inputs, add some visual sugar by highlighting updated areas

Modified:
    cocoon/blocks/core/forms/trunk/java/org/apache/cocoon/forms/flow/javascript/Form.js
    cocoon/blocks/core/forms/trunk/java/org/apache/cocoon/forms/resources/js/cforms.js
    cocoon/blocks/core/forms/trunk/samples/forms/carselector_template.xml
    cocoon/blocks/core/forms/trunk/samples/welcome.xml

Modified: cocoon/blocks/core/forms/trunk/java/org/apache/cocoon/forms/flow/javascript/Form.js
URL: http://svn.apache.org/viewcvs/cocoon/blocks/core/forms/trunk/java/org/apache/cocoon/forms/flow/javascript/Form.js?rev=168669&r1=168668&r2=168669&view=diff
==============================================================================
--- cocoon/blocks/core/forms/trunk/java/org/apache/cocoon/forms/flow/javascript/Form.js (original)
+++ cocoon/blocks/core/forms/trunk/java/org/apache/cocoon/forms/flow/javascript/Form.js Fri
May  6 15:01:55 2005
@@ -114,11 +114,7 @@
         this.locale = java.util.Locale.getDefault();
     viewdata["locale"] = this.locale;
 
-    // Keep the first continuation that will be created as the result of this function
-    var result = null;
-
     var finished = false;
-    this.isValid = false;
 
     var comingBack = false;
     var bookmark = cocoon.createWebContinuation(ttl);
@@ -126,10 +122,11 @@
     if (comingBack) {
         // We come back to the bookmark: process the form
         
-        if (cocoon.request.getParameter("cocoon-ajax-continue") != null) {
-            //TODO(SW): when exiting AJAX rountrips, better send a new continuation
-            //to ensure we really come back from a "100-continue" response (see below)
-            //and this isn't a forged request
+        if (finished && cocoon.request.getParameter("cocoon-ajax-continue") != null)
{
+            // A request with this parameter is sent by the client upon receiving the indication
+            // that Ajax interaction on the form is finished (see below).
+            // We also check "finished" to ensure we won't exit showForm() because of some
+            // faulty or hacked request. It's set to false, this will simply redisplay the
form.
             return bookmark;
         }
         
@@ -155,7 +152,7 @@
                 // Ask the client to load the page
                 cocoon.response.setHeader("X-Cocoon-Ajax", "continue");
                 cocoon.response.setHeader("Content-Length", "0");
-                cocoon.sendStatus(200); // Continue
+                cocoon.sendStatus(200);
                 FOM_Cocoon.suicide();
             }
             

Modified: cocoon/blocks/core/forms/trunk/java/org/apache/cocoon/forms/resources/js/cforms.js
URL: http://svn.apache.org/viewcvs/cocoon/blocks/core/forms/trunk/java/org/apache/cocoon/forms/resources/js/cforms.js?rev=168669&r1=168668&r2=168669&view=diff
==============================================================================
--- cocoon/blocks/core/forms/trunk/java/org/apache/cocoon/forms/resources/js/cforms.js (original)
+++ cocoon/blocks/core/forms/trunk/java/org/apache/cocoon/forms/resources/js/cforms.js Fri
May  6 15:01:55 2005
@@ -94,10 +94,15 @@
     // Iterate on all form controls
     for (var i = 0; i < form.elements.length; i++) {
         input = form.elements[i];
-        if (input.type != "submit" && input.type != "image") {
+        if (input.type == "submit" || input.type == "image") {
             // Skip buttons
-            result += "&" + encodeURIComponent(input.name) + "=" + encodeURIComponent(input.value);
+            continue;
         }
+        if ((input.type == "checkbox" || input.type == "radio") && !input.checked)
{
+            // Skip unchecked checkboxes and radio buttons
+            continue;
+        }
+        result += "&" + encodeURIComponent(input.name) + "=" + encodeURIComponent(input.value);
     }
     return result;
 }
@@ -131,10 +136,20 @@
 	            return;
 	        }
         
-            BrowserUpdate.processResponse(doc);
-        }
+           BrowserUpdate.processResponse(doc);
+       }
     } else {
-        alert("request failed : " + request.status);
+/*        var str = "";
+        for(prop in request) {
+           str += prop
+           str += " = " 
+           str += request[prop];
+           str += '\n';
+        }
+        alert(str);
+        alert(request.getAllResponseHeaders());
+*/
+        alert("request failed - status: " + request.status);
     }
 }
 
@@ -146,7 +161,7 @@
     ATTRIBUTE_NODE : 2,
     TEXT_NODE : 3,
     CDATA_SECTION_NODE : 4,
-	ENTITY_REFERENCE_NODE : 5,
+    ENTITY_REFERENCE_NODE : 5,
     ENTITY_NODE : 6,
     PROCESSING_INSTRUCTION_NODE : 7,
     COMMENT_NODE : 8,
@@ -269,6 +284,140 @@
 	    oldElement.parentNode.replaceChild(newElement, oldElement);
 	    // Ensure the new node has the correct id
 	    newElement.setAttribute("id", id);
+	    
+	    if (BrowserUpdate.highlight) {
+	       BrowserUpdate.highlight(newElement);
+	    }
 	}
+}
+
+//-------------------------------------------------------------------------------------------------
+// Fader used to highlight page areas that have been updated
+//-------------------------------------------------------------------------------------------------
+
+/**
+ * Create a fader that will progressively change an element's background color from
+ * a given color back to its original color.
+ *
+ * @param elt the element to fade
+ * @param color the starting color (default yellow)
+ * @param duration the fade duration in msecs (default 1000)
+ * @param fps the animation frames per seconds (default 25)
+ */
+function Fader(elt, color, duration, fps) {
+   // Set default values
+   if (!color) color = "#FFFF80"; // yellow
+   if (!duration) duration = 1000; // 1 sec
+   if (!fps) fps = 25; // 25 frames/sec
+   
+   this.element = elt;
+   this.fromColor = Fader.colorToRgb(color);
+   this.toColor = Fader.colorToRgb(Fader.getBgColor(this.element));
+   
+   this.maxFrames = Math.round(fps * duration / 1000.0);
+   this.delay = duration / this.maxFrames;
+}
+
+/**
+ * Creates a default fader for a given element. This function can be used to set BrowserUpdate.highlight
+ */
+Fader.fade = function(elt) {
+   new Fader(elt).start();
+}
+
+Fader.prototype.start = function() {
+   this.frame = 0;
+   this._changeColor();
+}
+
+Fader.prototype._changeColor = function() {
+    if (this.frame < this.maxFrames) {
+        // Schedule the next iteration right now to keep a more accurate timing
+        var fader = this;
+        setTimeout(function() {fader._changeColor();}, this.delay);
+    }
+    var newColor = new Array(3);
+    for (var channel = 0; channel < 3; channel++) {
+        newColor[channel] = Math.floor(
+            this.fromColor[channel] * ((this.maxFrames - this.frame) / this.maxFrames) +
+            this.toColor[channel] * (this.frame/this.maxFrames)
+        );
+    }
+
+    this.frame++;
+    var color = Fader.rgbToColor(newColor[0], newColor[1], newColor[2]);
+    this.element.style.backgroundColor = color;
+}
+
+/** Converts a "#RRGGBB" color as an array of 3 ints */
+Fader.colorToRgb = function(hex) {
+    return [
+        parseInt(hex.substr(1,2),16),
+        parseInt(hex.substr(3,2),16),
+        parseInt(hex.substr(5,2),16) ];
+}
+
+/** Converts rgb values to a "#RRGGBB" color */
+Fader.rgbToColor = function(r, g, b) {
+    r = r.toString(16); if (r.length == 1) r = '0' + r;
+    g = g.toString(16); if (g.length == 1) g = '0' + g;
+    b = b.toString(16); if (b.length == 1) b = '0' + b;
+    return "#" + r + g + b;
+}
+
+/** Get the background color of an element */
+Fader.getBgColor = function(elt) {
+    while(elt) {
+        var c;
+        if (window.getComputedStyle) c = window.getComputedStyle(elt,null).getPropertyValue("background-color");
+        if (elt.currentStyle) c = elt.currentStyle.backgroundColor;
+        if ((c != "" && c != "transparent") || elt.tagName == "BODY") { break; }
+        elt = elt.parentNode;
+    }
+    if (c == undefined || c == "" || c == "transparent" || c == "white") c = "#FFFFFF";
+
+    var rgb = c.match(/rgb\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)/);
+    if (rgb) return this.rgbToColor(parseInt(rgb[1]),parseInt(rgb[2]),parseInt(rgb[3]));
+    return c;
+}
+
+BrowserUpdate.highlight = Fader.fade;
+
+//-------------------------------------------------------------------------------------------------
+// Blinker used to highlight page areas that have been updated
+//-------------------------------------------------------------------------------------------------
+
+function Blinker(elt, color, hltDelay, normalDelay, blinks) {
+    this.element = elt;
+    if (!color) color = "#FFFF80"; // yellow
+    if (!hltDelay) hltDelay = 100;
+    if (!normalDelay) normalDelay = 100;
+    if (!blinks) blinks = 2;
+    
+    this.hltColor = color;
+    this.hltDelay = hltDelay;
+    this.normalDelay = normalDelay;
+    this.normalColor = Fader.getBgColor(elt);
+    this.maxBlinks = blinks * 2;
+    this.blink = 0;
+}
+
+Blinker.prototype.start = function() {
+   this.blink = 0;
+   this._doBlink();
+}
+
+Blinker.blink = function(elt) {
+   new Blinker(elt).start();
+}
+
+Blinker.prototype._doBlink = function() {
+   var hlt = (this.blink % 2 == 0);
+   this.element.style.backgroundColor = hlt ? this.hltColor : this.normalColor;;
+   if (this.blink <= this.maxBlinks) {
+      var blinker = this;
+      setTimeout(function() {blinker._doBlink();}, hlt ? this.hltDelay : this.normalDelay);
+   }
+   this.blink++;
 }
 

Modified: cocoon/blocks/core/forms/trunk/samples/forms/carselector_template.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/core/forms/trunk/samples/forms/carselector_template.xml?rev=168669&r1=168668&r2=168669&view=diff
==============================================================================
--- cocoon/blocks/core/forms/trunk/samples/forms/carselector_template.xml (original)
+++ cocoon/blocks/core/forms/trunk/samples/forms/carselector_template.xml Fri May  6 15:01:55
2005
@@ -18,11 +18,11 @@
    <!-- Import the macros that define CForms template elements -->
    <jx:import uri="resource://org/apache/cocoon/forms/generation/jx-macros.xml"/>
   <title>Car selector</title>
-  <para>This example illustrates how you can programmatically update the
-    content of a selection list.</para>
-  <para>
-    This sample illustrates event-handling in Cocoon Forms and how selection lists can be
changed
-    programmatically.
+  <para>This example illustrates:
+     <ul>
+        <li>how you can programmatically update the content of a selection list,</li>
+        <li>the AJAX features that allow partial page reloads and the associated visual
effects.</li>
+     </ul>
   </para>
   <para>
     Event-handlers are defined in the form definition to update the selection lists and set
@@ -34,6 +34,30 @@
     See "carselector_form.xml" and "carselector_template.xml" to see how this is done.
   </para>
   <content>
+    <script language="JavaScript">
+       var currentEffect = "fade";
+       function setEffect(effect) {
+           if (effect == "none") {
+               BrowserUpdate.highlight = null;
+           } else if (effect == "fade") {
+               BrowserUpdate.highlight = Fader.fade;
+           } else if (effect == "blink") {
+               BrowserUpdate.highlight = Blinker.blink;
+           }
+           
+           document.getElementById(currentEffect).style.fontWeight = "";
+           document.getElementById(effect).style.fontWeight = "bold";
+           currentEffect = effect;
+           return false;
+       }
+    </script>
+    <para>
+      Page update effect:
+      <a id="none" href="#" onclick="setEffect('none')">None</a> - 
+      <a style="font-weight: bold" id="fade" href="#" onclick="setEffect('fade')">Fade</a>
- 
+      <a id="blink" href="#" onclick="setEffect('blink')">Blink</a>
+    </para>
+      
     <ft:form-template action="carselector" method="POST" ajax="true">
       <ft:continuation-id/>
       <fi:group>

Modified: cocoon/blocks/core/forms/trunk/samples/welcome.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/core/forms/trunk/samples/welcome.xml?rev=168669&r1=168668&r2=168669&view=diff
==============================================================================
--- cocoon/blocks/core/forms/trunk/samples/welcome.xml (original)
+++ cocoon/blocks/core/forms/trunk/samples/welcome.xml Fri May  6 15:01:55 2005
@@ -30,14 +30,18 @@
   <sample name="Cocoon Forms Documentation" href="http://cocoon.apache.org/2.1/userdocs/forms/">
     Documentation is available on the Cocoon site.
   </sample>
+  <note>
+     Samples with the (Ajax) mark use the new transparent Ajax (Asynchronous Javascript And
XML) framework
+     to reduce client/server roundtrips and perform partial page updates.
+  </note>
  </group>
 
  <group name="Basic Samples">
   <sample name="Various (Actions)" href="form1">This sample shows validation, event
handling and various Cocoon Forms features.</sample>
   <sample name="Various (Flowscript)" href="form1.flow">The same sample as above using
Flowscript.</sample>
   <sample name="Registration" href="registration">A simple registration form.</sample>
-  <sample name="Car selector" href="carselector">Illustrates programmatically changing
selectionlists.</sample>
-  <sample name="XHR Car selector" href="xhr_carselector">Same sample, using XmlHttpRequest
to reduce client/server roundtrips.</sample>
+  <sample name="Car selector" href="carselector">(Ajax) Illustrates programmatically
changing selectionlists.</sample>
+  <sample name="XHR Car selector" href="xhr_carselector">Same sample, with the historical
first use of XmlHttpRequest to reduce client/server roundtrips.</sample>
   <sample name="Country selector" href="countryselector">Illustrates programmatically
changing flow-jxpath selectionlists.</sample>
   <sample name="Upload" href="upload">Shows an upload widget used with Flowscript</sample>
   <sample name="Form Model GUI" href="form_model_gui.flow">Illustrates the use of Class,
New, Struct, and Union.</sample>
@@ -88,14 +92,14 @@
      widgets.
    </note>
    <sample name="Dynamic repeater template" href="do-dynaRepeater.flow">
-     Shows a simple repeater, which isn't displayed at all if empty, and whose row action
depend on
+     (Ajax) Shows a simple repeater, which isn't displayed at all if empty, and whose row
action depend on
      the row number.
    </sample>
    <sample name="Datasource chooser" href="do-datasourceChooser.flow">
-     A datasource chooser, illustrating the fd:union widget.
+     (Ajax) A datasource chooser, illustrating the fd:union widget.
    </sample>
    <sample name="Task tree" href="do-taskTree.flow">
-     A project work breakdown into a hierarchy of tasks, showing the use of the fd:class
and fd:new
+     (Ajax) A project work breakdown into a hierarchy of tasks, showing the use of the fd:class
and fd:new
      widgets.
    </sample>
  </group>



Mime
View raw message