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>