You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by jk...@apache.org on 2007/06/17 20:36:03 UTC

svn commit: r548092 - in /tapestry/tapestry4/trunk: src/site/xdoc/components/dojo/ tapestry-examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/ tapestry-framework/src/java/org/apache/tapestry/dojo/html/

Author: jkuhnert
Date: Sun Jun 17 11:36:02 2007
New Revision: 548092

URL: http://svn.apache.org/viewvc?view=rev&rev=548092
Log:
TAPESTRY-1527.  Not an actual fix for the bug as that would be impossible without completely re-writing the client side Dialog widget code. (which has already been done in Dojo 0.9 anyways)  Updated the component documentation for Dialog with all the known gotchas / techniques for using this widget that I am aware of.

Modified:
    tapestry/tapestry4/trunk/src/site/xdoc/components/dojo/dialog.xml
    tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/TaskEntryPage.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/dojo/html/Dialog.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/dojo/html/Dialog.script

Modified: tapestry/tapestry4/trunk/src/site/xdoc/components/dojo/dialog.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/src/site/xdoc/components/dojo/dialog.xml?view=diff&rev=548092&r1=548091&r2=548092
==============================================================================
--- tapestry/tapestry4/trunk/src/site/xdoc/components/dojo/dialog.xml (original)
+++ tapestry/tapestry4/trunk/src/site/xdoc/components/dojo/dialog.xml Sun Jun 17 11:36:02 2007
@@ -14,6 +14,8 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.2//EN"
+    "http://maven.apache.org/dtd/xdoc_1_0.dtd">
 <document>
     <properties>
         <title>Dialog</title>
@@ -21,7 +23,6 @@
     <body>
 
         <section name="Dialog">
-
             <p>
                 Creates a modal Dialog on the client side (of sorts). This component may prove useful for cutting down
                 on typical CRUD operations where you normally have to navigate to a lot of seperate pages to do things
@@ -34,9 +35,17 @@
                 invoke in java code to hide and show the Dialog. They are aptly named <code>hide()</code> and
                 <code>show()</code>.
             </p>
-            
-            <img src="../../images/ComponentReference/Dialog.png" />
-            
+
+            <span class="warn">
+                <strong>Warning:</strong>
+                <p>
+                    There are quite a few gotchas and special conditions you need to be aware of when using this component.  You can find them outlined
+                    as well as solutions to common problems at the bottom of this document.
+                </p>
+            </span>
+
+            <img src="../../images/ComponentReference/Dialog.png" alt="Dialog Example"/>
+
             <p>
                 <strong>
                     See also:
@@ -47,7 +56,7 @@
 
             </p>
             
-            <section name="Parameters">
+            <subsection name="Parameters">
                 <table>
                     <tr>
                         <th>Name</th>
@@ -92,22 +101,161 @@
                     Body:
                     <strong>allowed</strong>
                 </p>
-
                 <p>
                     Informal parameters:
                     <strong>allowed</strong>
                 </p>
-
                 <p>
                     Reserved parameters:
                     <em>none</em>
                 </p>
 
-            </section>
+            </subsection>
+
+            <subsection name="Gotchas">
+                There are a few things that most poeple will need to keep in mind when using this component/client side control.
 
-            <section name="Examples">
-                TODO...
-            </section>
+                <ul>
+                    <li>
+                        <p>
+                        <b>Dialog display flickering</b> - In the typical situation of defining a simple html template definition of a Dialog - such
+                        as in:
+                        </p>
+                        <source xml:space="preserve"><![CDATA[
+<div jwcid="testDialog@Dialog" hidden="ognl:dialogHidden" >
+    <p>Sample dialog display</p>
+</div>
+]]></source>
+                        <p>
+                            With the definition given above you will inevitably get a <em>flickering</em> effect of the content within the dialog being
+                            breifly displayed before being hidden by the client side widget control.  This is simply because your html content is rendered
+                            in the browser before the client side widget has had a chance to hide it.  To be sure that you don't have flickering on your
+                            dialog content simply define a <code>style="display:none"</code> attribute on your Dialog tag:
+                        </p>
+
+                        <source xml:space="preserve"><![CDATA[
+<div jwcid="testDialog@Dialog" hidden="ognl:dialogHidden" style="display:none;">
+    <p>Sample dialog display</p>
+</div>
+]]></source>
+                    </li>
+                    <li>
+                        <p>
+                            <b>Dialog content background color</b> - By default the content you display within the dialog will have an opaque background because
+                            that is the background of the dialog itself.  If you don't want this <em>(the majoriy won't..)</em> you should define a background color
+                            and style accordingly for your content.  It is often easier to define a single css class definition for dialog content and apply it to
+                            a single outer node within the dialog like this:
+                        </p>
+                        <source xml:space="preserve"><![CDATA[
+..
+.dialog { background-color: white; width: 400px; height: 300px; }
+...
+
+<div jwcid="testDialog@Dialog" hidden="ognl:dialogHidden" style="display:none;">
+    <p class="dialog">
+        Sample dialog display
+    </p>
+</div>
+]]></source>
+                    </li>
+                    <li>
+                        <p>
+                            <b>Updating Dialog in AJAX requests</b> - This is by far the biggest gotcha,  so you'll want to read this section carefully.  Because of
+                            the way the client side widget displays/manipulates the Dialog the ultimate position your dialog html node in the overall document will not
+                            be the same as how it is initially rendered by Tapestry.  The short of it is that the client side takes your dialog html node and moves it to
+                            the very bottom of the document - regardless of what is surrounding it or any other careful semantics you have setup. ...So given a sample
+                            html template definition looking like this:
+                        </p>
+
+                        <source xml:space="preserve"><![CDATA[                 
+<body>
+
+  <div id="content">
+     <p>
+        <div jwcid="testDialog@Dialog" hidden="ognl:dialogHidden" style="display:none;">
+            <p>Sample dialog display</p>
+        </div>
+    </p>
+  </div>
+
+</body>
+]]></source>
+                        <p>..the actual placement of your dialog node will actually be more like:</p>
+
+                        <source xml:space="preserve"><![CDATA[
+<body>
+
+  <div id="content">
+     <p>
+
+    </p>
+  </div>
+
+<div id="testDialog" style="display:none;">
+  <p>Sample dialog display</p>
+</div>
+</body>
+]]></source>
+                        <p>
+                            This can cause endless hours of frustration if you don't know about its behaviour - and can get even worse with certain ajax
+                            updating semantics.  The key things to remember with doing ajax updates involving dialogs are:
+                        </p>
+                        <ul>
+                            <li>
+                                <p>
+                                    <b>Only update the dialog directly or things contained within it.</b>
+                                </p>
+                                <p>
+                                    This means that you can't do things like:
+                                </p>
+
+                                <source xml:space="preserve"><![CDATA[
+<a jwcid="@DirectLink" listener="listener:showDialog" updateComponents="dialogUpdateArea">Show Dialog</a>
+
+<div jwcid="dialogUpdateArea@Any">
+<div jwcid="testDialog@Dialog" hidden="ognl:dialogHidden" style="display:none;">
+    <p class="dialog">
+        Sample dialog display
+    </p>
+</div>
+</div>
+]]></source>
+                                <p>
+                                    The above example would have questionable results because the actual client side dom node of the dialog will be detached
+                                    and not actually be a child of the <code>dialogUpdateArea</code> Any component you are trying to update.  The good news is
+                                    that updating a Dialog directly or children within it should work fine, so rewriting the example above to the more correct version
+                                    will yield better results:
+                                </p>
+
+                                <source xml:space="preserve"><![CDATA[
+<a jwcid="@DirectLink" listener="listener:showDialog" updateComponents="testDialog">Show Dialog</a>
+
+<div jwcid="testDialog@Dialog" hidden="ognl:dialogHidden" style="display:none;">
+    <p class="dialog">
+        Sample dialog display
+    </p>
+</div>
+]]></source>
+                            </li>
+                            <li>
+                                <p>
+                                    <b>Don't wrap portions of a <a href="../form/form.html">Form</a>.</b>
+                                </p>
+                                <p>
+                                    Because the Dialog client dom node is always detached you are almost assured to have problems if you try and take
+                                    a small portion of a form and wrap it within a dialog.  The form input controls will be moved to the bottom of your
+                                    document - outside the scope of the containing form - along with all the other content the Dialog normally moves.  This will
+                                    likely result in your form breaking and / or just not submitting the input values contained within the dialog.
+                                </p>
+                                <p>
+                                    For this situation the only real answer is that you need to break the form up in to two separate forms - one that you will nest
+                                    within the Dialog itself and the other being your main outer form. 
+                                </p>
+                            </li>
+                        </ul>
+                    </li>
+                </ul>
+            </subsection>
             
         </section>
 

Modified: tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/TaskEntryPage.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/TaskEntryPage.java?view=diff&rev=548092&r1=548091&r2=548092
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/TaskEntryPage.java (original)
+++ tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/TaskEntryPage.java Sun Jun 17 11:36:02 2007
@@ -14,10 +14,7 @@
 package org.apache.tapestry.timetracker.page;
 
 import org.apache.log4j.Logger;
-import org.apache.tapestry.annotations.Component;
-import org.apache.tapestry.annotations.EventListener;
-import org.apache.tapestry.annotations.InjectObject;
-import org.apache.tapestry.annotations.Persist;
+import org.apache.tapestry.annotations.*;
 import org.apache.tapestry.dojo.form.*;
 import org.apache.tapestry.dojo.html.Dialog;
 import org.apache.tapestry.form.TextField;
@@ -88,6 +85,9 @@
     
     public abstract ResponseBuilder getBuilder();
 
+    @InjectComponent("testDialog")
+    public abstract Dialog getTestDialog();
+
     /**
      * Selection model for projects.
      * 
@@ -110,10 +110,9 @@
 
     public void showDialog()
     {
-        Dialog dlg = (Dialog)getComponent("testDialog");
-        dlg.show();
+        getTestDialog().show();
     }
-    
+
     /**
      * Invoked by form to add a new task.
      */

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/dojo/html/Dialog.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/dojo/html/Dialog.java?view=diff&rev=548092&r1=548091&r2=548092
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/dojo/html/Dialog.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/dojo/html/Dialog.java Sun Jun 17 11:36:02 2007
@@ -13,9 +13,6 @@
 // limitations under the License.
 package org.apache.tapestry.dojo.html;
 
-import java.util.HashMap;
-import java.util.Map;
-
 import org.apache.tapestry.IMarkupWriter;
 import org.apache.tapestry.IRequestCycle;
 import org.apache.tapestry.IScript;
@@ -23,11 +20,13 @@
 import org.apache.tapestry.dojo.AbstractWidget;
 import org.apache.tapestry.json.JSONObject;
 
+import java.util.HashMap;
+import java.util.Map;
+
 
 /**
  * Implementation of dojo Dialog widget.
  * 
- * @author jkuhnert
  */
 public abstract class Dialog extends AbstractWidget
 {
@@ -53,8 +52,8 @@
      */
     public void renderWidget(IMarkupWriter writer, IRequestCycle cycle)
     {
-        if (!cycle.isRewinding()) {
-            
+        if (!cycle.isRewinding())
+        {
             writer.begin(getTemplateTagName()); // use element specified
             renderIdAttribute(writer, cycle); // render id="" client id
             renderInformalParameters(writer, cycle);
@@ -62,11 +61,11 @@
         
         renderBody(writer, cycle);
         
-        if (!cycle.isRewinding()) {
+        if (!cycle.isRewinding())
             writer.end();
-        }
         
-        if (!cycle.isRewinding()) {
+        if (!cycle.isRewinding())
+        {
             JSONObject json = new JSONObject();
             json.put("bgColor", getBackgroundColor());
             json.put("bgOpacity", getOpacity());

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/dojo/html/Dialog.script
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/dojo/html/Dialog.script?view=diff&rev=548092&r1=548091&r2=548092
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/dojo/html/Dialog.script (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/dojo/html/Dialog.script Sun Jun 17 11:36:02 2007
@@ -1,7 +1,7 @@
 <?xml version="1.0"?>
 <!DOCTYPE script PUBLIC
-  "-//Apache Software Foundation//Tapestry Script Specification 3.0//EN"
-  "http://tapestry.apache.org/dtd/Script_3_0.dtd">
+        "-//Apache Software Foundation//Tapestry Script Specification 3.0//EN"
+        "http://tapestry.apache.org/dtd/Script_3_0.dtd">
 <!-- 
    Copyright 2004, 2005, 2006 The Apache Software Foundation
 
@@ -18,19 +18,26 @@
    limitations under the License.
 -->
 <script>
-<input-symbol key="component" required="yes" />
-<input-symbol key="props" required="yes" />
+    <input-symbol key="component" required="yes" />
+    <input-symbol key="props" required="yes" />
+    
+    <let key="widget" unique="yes">
+        dialog
+    </let>
+
     <body>
-    <unique>
-    dojo.require("tapestry.widget.Widget");
-    </unique>
+        <unique>
+            dojo.require("tapestry.widget.Widget");
+        </unique>
     </body>
+    
     <initialization>
-    tapestry.widget.synchronizeWidgetState("${component.clientId}", "Dialog", ${props}, ${component.destroy});
-    <if expression="component.hidden">
-        dojo.widget.byId("${component.clientId}").hide();
-    </if><if-not expression="component.hidden">
-        dojo.widget.byId("${component.clientId}").show();
-    </if-not>
+        tapestry.widget.synchronizeWidgetState("${component.clientId}", "Dialog", ${props}, ${component.destroy});
+        <if expression="component.hidden">
+            dojo.widget.byId("${component.clientId}").hide();
+        </if>
+        <if-not expression="component.hidden">
+            dojo.widget.byId("${component.clientId}").show();
+        </if-not>
     </initialization>
 </script>