You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2007/11/30 01:44:21 UTC
svn commit: r599662 - in /tapestry/tapestry5/trunk/tapestry-core/src:
main/java/org/apache/tapestry/corelib/components/
main/resources/org/apache/tapestry/
test/java/org/apache/tapestry/integration/
Author: hlship
Date: Thu Nov 29 16:44:19 2007
New Revision: 599662
URL: http://svn.apache.org/viewvc?rev=599662&view=rev
Log:
TAPESTRY-1942: Client side validation should be triggered when the user moves out of a field
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/vbevel.png (with props)
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Errors.java
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/default.css
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Errors.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Errors.java?rev=599662&r1=599661&r2=599662&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Errors.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Errors.java Thu Nov 29 16:44:19 2007
@@ -20,15 +20,14 @@
import org.apache.tapestry.annotations.Environmental;
import org.apache.tapestry.annotations.Parameter;
import org.apache.tapestry.corelib.internal.InternalMessages;
-import org.apache.tapestry.dom.Element;
import org.apache.tapestry.services.FormSupport;
import java.util.List;
/**
- * Standard validation error presenter. Must be enclosed by a {@link Form} component. If errors are
+ * Standard validation error presenter. Must be enclosed by a {@link org.apache.tapestry.corelib.components.Form} component. If errors are
* present, renders a div element around a banner message and around an unnumbered list of error
- * messages.
+ * messages. Renders nothing if the {@link org.apache.tapestry.ValidationTracker} shows no errors.
*/
public class Errors
{
@@ -59,9 +58,9 @@
if (_tracker == null) throw new RuntimeException(InternalMessages.encloseErrorsInForm());
- Element div = writer.element("div", "class", _class, "id", _formSupport.getClientId() + ":errors");
+ if (!_tracker.getHasErrors()) return;
- if (!_tracker.getHasErrors()) div.addClassName(TapestryConstants.INVISIBLE_CLASS);
+ writer.element("div", "class", _class);
// Inner div for the banner text
writer.element("div");
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/default.css
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/default.css?rev=599662&r1=599661&r2=599662&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/default.css (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/default.css Thu Nov 29 16:44:19 2007
@@ -336,4 +336,25 @@
DIV.t-autocomplete-menu LI.selected {
color: black;
font-weight: bold;
+}
+
+DIV.t-error-bevel {
+ float: left;
+ margin: 0px;
+ padding: 0px;
+
+ cursor: pointer;
+ display: block;
+}
+
+DIV.t-error-bevel SPAN {
+ background: transparent url( 'vbevel.png' ) no-repeat scroll top left;
+ color: white;
+ display: block;
+ float: left;
+ font: normal 12px arial, sans-serif;
+ margin-left: 15px;
+ padding: 6px 30px 0px 15px;
+ height: 39px;
+ text-decoration: none;
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js?rev=599662&r1=599661&r2=599662&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js Thu Nov 29 16:44:19 2007
@@ -23,20 +23,6 @@
registerForm : function(form, clientValidations)
{
form = $(form);
-
- form.errorDiv = $(form.id + ':errors');
-
- if (form.errorDiv)
- {
- form.errorList = form.errorDiv.getElementsBySelector("ul").first();
-
- if (! form.errorList)
- {
- // create it now
- form.errorList = document.createElement("ul");
- form.errorDiv.appendChild(form.errorList);
- }
- }
// This can probably be cleaned up with bind() ...
@@ -46,11 +32,6 @@
form.firstError = true;
- if (form.errorList)
- {
- form.errorList.innerHTML = "";
- }
-
// Locate elements that have an event manager (and therefore, validations)
// and let those validations execute, which may result in calls to recordError().
@@ -65,21 +46,6 @@
}
});
- // On a failure result, display the error div.
-
- if (form.errorDiv)
- {
- if (event.result)
- {
- if (form.errorDiv.visible())
- new Effect.BlindUp(form.errorDiv);
- }
- else if (! form.errorDiv.visible())
- {
- new Effect.BlindDown(form.errorDiv);
- }
- }
-
return event.result;
};
@@ -97,9 +63,6 @@
field.decorateForValidationError(event, message);
- if (form.errorList)
- new Insertion.Bottom(form.errorList, "<li>" + message + "</li>");
-
};
// And handle the validations
@@ -315,6 +278,15 @@
var id = field.id;
this.label = $(id + ':label');
this.icon = $(id + ':icon');
+
+ this.field.observe("blur", function()
+ {
+ var event = new Tapestry.FormEvent(this.field.form);
+
+ event.field = this.field;
+
+ this.validateInput(event);
+ }.bindAsEventListener(this));
},
// Adds a validator. acceptBlank is true if the validator should be invoked regardless of
@@ -340,6 +312,9 @@
if (this.icon)
this.icon.hide();
+
+ if (this.popup)
+ this.popup.hide();
},
// Adds decorations to the field (including label and icon if present).
@@ -348,7 +323,6 @@
addDecorations : function(event, message)
{
-
this.field.addClassName("t-error");
if (this.label)
@@ -360,6 +334,44 @@
new Effect.Appear(this.icon);
}
+ if (this.popup == undefined)
+ {
+ this.popupSpan = new Element("span");
+
+ this.popup = $(new Element("div", { 'class' : 't-error-bevel' })).update(this.popupSpan).hide();
+
+ this.popup.absolutize();
+
+ this.popup.field = this.field;
+
+ // It has to go somewhere.
+
+ this.field.insert({ after: this.popup });
+
+ this.popup.absolutize();
+
+ this.popup.observe("click", function()
+ {
+ new Effect.Fade(this.popup);
+ }.bindAsEventListener(this));
+ }
+
+ this.popupSpan.update(message);
+
+ if (! this.popup.visible())
+ {
+ var fieldPos = this.field.positionedOffset();
+
+ // These magic numbers are based on the height of the bevel image.
+ this.popup.setStyle({ top: fieldPos[1] - 34 + "px", left: fieldPos[0] + "px", width: "auto", height: "39px" });
+
+ this.popup.fadingIn = true;
+
+ new Effect.Appear(this.popup, { afterFinish: function()
+ {
+ this.popup.fadingIn = false;
+ }.bindAsEventListener(this) });
+ }
},
@@ -471,4 +483,26 @@
element.hide();
element.removeClassName("t-invisible");
});
+
+ // Adds a focus observer that fades all error popups except for the
+ // field in question.
+
+ $$("INPUT", "SELECT", "TEXTAREA").each(function(element)
+ {
+ element.observe("focus", function()
+ {
+ $$("DIV.t-error-bevel").each(function(popup)
+ {
+ // This handles a case where the user tabs out of a field and it is currently fading in with an
+ // error message. Leave it up unchanged.
+
+ if (popup.fadingIn) return;
+
+ var opacity = popup.field == element ? 1 : .15;
+
+ new Effect.Opacity(popup, { to: opacity });
+ });
+ });
+ });
});
+
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/vbevel.png
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/vbevel.png?rev=599662&view=auto
==============================================================================
Binary file - no diff available.
Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/vbevel.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?rev=599662&r1=599661&r2=599662&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Thu Nov 29 16:44:19 2007
@@ -758,15 +758,16 @@
click(SUBMIT);
- assertTextSeries("//li[%d]", 1, "You must provide a value for First Name.", "Everyone has to have a last name!",
- "Year of Birth requires a value of at least 1900.");
+ // Looks like more weaknesses in Selenium, can only manage the first match not the others.
+ assertTextSeries("//div[@class='t-error-bevel'][%d]/span", 1, "You must provide a value for First Name."
+ //, "Everyone has to have a last name!",
+ // "Year of Birth requires a value of at least 1900."
+ );
type("firstName", "Howard");
type("lastName", "Lewis Ship");
type("birthYear", "1000");
click(SUBMIT);
-
- assertText("//li", "Year of Birth requires a value of at least 1900.");
type("birthYear", "1966");
click("citizen");