Author: hlship
Date: Mon Nov 3 10:36:07 2008
New Revision: 710122
URL: http://svn.apache.org/viewvc?rev=710122&view=rev
Log:
TAP5-25: Client-side validation is triggered onblur even when switching to a
different form in the same page, or to a non-form element such as a link
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/BeanEditorDemo.tml
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditorDemo.java
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js?rev=710122&r1=710121&r2=710122&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js
Mon Nov 3 10:36:07 2008
@@ -45,7 +45,7 @@
*/
FIELD_VALIDATE_EVENT : "tapestry:fieldvalidate",
- /** Event, triggered on the document object, which identifies the current
focus element. */
+ /** Event, triggered on the document object, which identifies the current
focus input element. */
FOCUS_CHANGE_EVENT : "tapestry:focuschange",
/** When false, the default, the Tapestry.debug() function will be a
no-op. */
@@ -97,7 +97,14 @@
{
element.observe("focus", function()
{
- document.fire(Tapestry.FOCUS_CHANGE_EVENT, element);
+ if (element != Tapestry.currentFocusField)
+ {
+ Tapestry.debug("Focus changed to #{id}", element);
+
+ document.fire(Tapestry.FOCUS_CHANGE_EVENT, element);
+
+ Tapestry.currentFocusField = element;
+ }
});
t.observingFocusChange = true;
@@ -105,8 +112,8 @@
});
// When a submit element is clicked, record the name of the element
- // on the associated form. This is necessary for some Ajax processing
- // TAPESTRY-2324.
+ // on the associated form. This is necessary for some Ajax processing,
+ // see TAPESTRY-2324.
$$("INPUT[type=submit]").each(function(element)
{
@@ -949,16 +956,16 @@
return;
}
- var focused = event.memo;
-
- if (focused == this.field)
+ if (event.memo == this.field)
{
this.fadeIn();
+ return;
}
- else
- {
- this.fadeOut();
- }
+
+ // If this field is not the focus field after a focus change, then
it's bubble,
+ // if visible, should fade out. This covers tabbing from one form
to another.
+ this.fadeOut();
+
}.bind(this));
},
@@ -986,17 +993,27 @@
fadeIn : function()
{
+ Tapestry.debug("fadeIn: " + this.field.id);
+
if (! this.hasMessage) return;
this.repositionBubble();
- if (this.status == "fadeIn") return;
-
- if (this.outerDiv.visible()) return;
+ if (this.animation) return;
- this.animation = new Effect.Appear(this.outerDiv, { queue: this.queue
});
+ this.animation = new Effect.Appear(this.outerDiv, {
+ queue: this.queue,
+ afterFinish: function()
+ {
+ this.animation = null;
- this.status = "fadeIn";
+ if (this.field != Tapestry.currentFocusField)
+ {
+ Tapestry.debug("Field #{id} lost focus, fading bubble",
this.field);
+ this.fadeOut();
+ }
+ }.bind(this)
+ });
},
stopAnimation : function()
@@ -1004,18 +1021,19 @@
if (this.animation) this.animation.cancel();
this.animation = null;
- this.status = null;
},
fadeOut : function ()
{
- // Tapestry.debug("fadeOut: " + this.field.id);
-
- if (this.status == "fadeOut") return;
+ Tapestry.debug("fadeOut: " + this.field.id);
- this.animation = new Effect.Fade(this.outerDiv, { queue : this.queue
});
+ if (this.animation) return;
- this.status = "fadeOut";
+ this.animation = new Effect.Fade(this.outerDiv, { queue : this.queue,
+ afterFinish: function()
+ {
+ this.animation = null;
+ }.bind(this) });
},
hide : function()
@@ -1122,9 +1140,18 @@
this.label = $(id + ':label');
this.icon = $(id + ':icon');
- this.field.observe("blur", function()
+ document.observe(Tapestry.FOCUS_CHANGE_EVENT, function(event)
{
- this.validateInput(false);
+ // If changing focus *within the same form* then
+ // perform validation. Note that Tapestry.currentFocusField does
not change
+ // until after the FOCUS_CHANGE_EVENT notification.
+
+ if (Tapestry.currentFocusField == this.field &&
+ this.field.form == event.memo.form)
+ {
+ Tapestry.debug("Validating input for #{id} on focus change",
this.field);
+ this.validateInput();
+ }
}.bindAsEventListener(this));
},
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/BeanEditorDemo.tml
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/BeanEditorDemo.tml?rev=710122&r1=710121&r2=710122&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/BeanEditorDemo.tml
(original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/BeanEditorDemo.tml Mon
Nov 3 10:36:07 2008
@@ -1,14 +1,31 @@
<t:border xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
- <h1>${pageTitle}</h1>
+ <h1>${pageTitle}</h1>
- <form t:id="registrationData" submitlabel="Register">
+ <form t:id="registrationData" submitlabel="Register">
- <t:parameter name="firstName">
- <t:label for="firstName"/>
- <input t:type="TextField" t:id="firstName"
value="registrationData.firstName" size="40"/>
- (First Name is Required) </t:parameter>
+ <t:parameter name="firstName">
+ <t:label for="firstName"/>
+ <input t:type="TextField" t:id="firstName"
value="registrationData.firstName" size="40"/>
+ (First Name is Required)
+ </t:parameter>
- </form>
+ </form>
- <p>[<a t:type="ActionLink" t:id="clear">Clear Data</a>]</p>
+ <p>[<a t:type="ActionLink" t:id="clear">Clear Data</a>]
+ </p>
+
+ <h2>Second Form</h2>
+
+ <p>Used to test tabbing
+ <em>between</em>
+ forms.
+ </p>
+
+ <p>
+ <t:form t:id="search">
+ <t:label for="searchTerm"/>
+ <t:textfield t:id="searchTerm"/>
+ <input type="submit"/>
+ </t:form>
+ </p>
</t:border>
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditorDemo.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditorDemo.java?rev=710122&r1=710121&r2=710122&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditorDemo.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditorDemo.java
Mon Nov 3 10:36:07 2008
@@ -17,19 +17,24 @@
import org.apache.tapestry5.annotations.ApplicationState;
import org.apache.tapestry5.annotations.Component;
import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.beaneditor.Validate;
import org.apache.tapestry5.corelib.components.BeanEditForm;
import org.apache.tapestry5.integration.app1.data.RegistrationData;
public class BeanEditorDemo
{
@Component(id = "registrationData", parameters =
- { "clientValidation=clientValidation" })
+ {"clientValidation=clientValidation"})
private BeanEditForm form;
@ApplicationState
@Property
private RegistrationData registrationData;
+ @Property
+ @Validate("required")
+ private String searchTerm;
+
Object onSuccess()
{
return ViewRegistration.class;