Rebuild the Error component for Bootstrap 3
Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/0a78cab9 Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/0a78cab9 Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/0a78cab9 Branch: refs/heads/master Commit: 0a78cab9e10bfd71f9590a679309aede0f19af13 Parents: 4e2e8cf Author: Howard M. Lewis Ship <[email protected]> Authored: Thu Sep 5 09:59:21 2013 -0700 Committer: Howard M. Lewis Ship <[email protected]> Committed: Thu Sep 5 09:59:21 2013 -0700 ---------------------------------------------------------------------- 54_RELEASE_NOTES.txt | 9 ++++ .../tapestry5/corelib/components/Error.java | 53 ++++++++------------ tapestry-core/src/test/app1/SingleErrorDemo.tml | 28 +++++++---- .../tapestry5/integration/app1/pages/Index.java | 2 + 4 files changed, 51 insertions(+), 41 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/0a78cab9/54_RELEASE_NOTES.txt ---------------------------------------------------------------------- diff --git a/54_RELEASE_NOTES.txt b/54_RELEASE_NOTES.txt index c6e4669..6ed7c3c 100644 --- a/54_RELEASE_NOTES.txt +++ b/54_RELEASE_NOTES.txt @@ -213,6 +213,15 @@ CSS class names with the `class` informal parameter. Generally, you will want t The Label component now renders the CSS class attribute as "control-label"; you may add additional CSS class names with the `class` informal parameter. +## Error Component + +When Tapestry must present a validation exception, it will often dynamically create the `<p class="help-block">` +needed to display the message; it does a reasonable job of positioning the new element just after the field, or +just after the `.input-group` containing the field. The Error component can be used to explicitly place this element. + +Also, note that part of the styling of the element is predicated on containment inside a `.form-group` (which may have +the `has-error` selector added or removed). + ## BeanEditor / BeanEditForm The property edit blocks contributed to the BeanBlockSource service should expect to be nested inside a http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/0a78cab9/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Error.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Error.java b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Error.java index e6f823b..328e62f 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Error.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Error.java @@ -13,21 +13,26 @@ // limitations under the License. package org.apache.tapestry5.corelib.components; -import org.apache.tapestry5.*; -import org.apache.tapestry5.annotations.Environmental; +import org.apache.tapestry5.BindingConstants; +import org.apache.tapestry5.ComponentResources; +import org.apache.tapestry5.Field; +import org.apache.tapestry5.MarkupWriter; import org.apache.tapestry5.annotations.HeartbeatDeferred; import org.apache.tapestry5.annotations.Parameter; +import org.apache.tapestry5.annotations.SupportsInformalParameters; import org.apache.tapestry5.dom.Element; +import org.apache.tapestry5.ioc.annotations.Inject; /** - * Presents validation errors of a single field. Must be enclosed by a - * {@link org.apache.tapestry5.corelib.components.Form} component. - * - * @since 5.2.0 + * Provides a client-side element to contain validation errors; this renders as a {@code <p class="help-block">}. + * Must be enclosed by a + * {@link org.apache.tapestry5.corelib.components.Form} component and assumes the field and the Error component + * are enclosed by a {@code <div class="form-group">}. + * * @tapestrydoc - * @deprecated Deprecated in 5.4 with no replacement; the significant changes in 5.4 ensure that validation errors - * on re-rendered forms appear with the controls. + * @since 5.2.0 */ +@SupportsInformalParameters public class Error { /** @@ -36,41 +41,25 @@ public class Error @Parameter(name = "for", required = true, allowNull = false, defaultPrefix = BindingConstants.COMPONENT) private Field field; - /** - * The CSS class for the div element rendered by the component. The default value is "t-error-single". - */ - @Parameter(name = "class") - private String className = CSSClassConstants.ERROR_SINGLE; - - @Environmental(false) - private ValidationTracker tracker; + @Inject + private ComponentResources resources; - void beginRender(final MarkupWriter writer) + boolean beginRender(final MarkupWriter writer) { - if (tracker == null) - throw new RuntimeException("The Error component must be enclosed by a Form component."); + Element element = writer.element("p", "class", "help-block"); - Element element = writer.element("div"); + resources.renderInformalParameters(writer); updateElement(element); writer.end(); + + return false; } @HeartbeatDeferred private void updateElement(final Element element) { - final String error = tracker.getError(field); - - if (error == null) - { - element.remove(); - } - else - { - element.forceAttributes("class", className); - element.text(error); - } + element.attribute("data-error-block-for", field.getClientId()); } - } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/0a78cab9/tapestry-core/src/test/app1/SingleErrorDemo.tml ---------------------------------------------------------------------- diff --git a/tapestry-core/src/test/app1/SingleErrorDemo.tml b/tapestry-core/src/test/app1/SingleErrorDemo.tml index 34b512e..c9ab0a8 100644 --- a/tapestry-core/src/test/app1/SingleErrorDemo.tml +++ b/tapestry-core/src/test/app1/SingleErrorDemo.tml @@ -1,20 +1,30 @@ -<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"> - <h1>Error Demo</h1> +<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"> +<h1>Error Component</h1> + +<t:form clientvalidation="none"> + + <t:remove> + So we build these form groups basically upside down. + </t:remove> + + <div class="form-group"> - <t:form clientvalidation="none"> - <t:error for="username"/> <input t:type="TextField" t:id="username" validate="required"/> <t:label for="username"/> - <br/> - + </div> + + <div class="form-group"> + <t:error for="password"/> <input t:type="PasswordField" t:id="password" validate="required"/> <t:label for="password"/> - <br/> + </div> - <input type="submit"/> - </t:form> + <div class="form-group"> + <input class="btn btn-primary" type="submit"/> + </div> +</t:form> </html> http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/0a78cab9/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java index af510b6..0145200 100644 --- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java +++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java @@ -59,6 +59,8 @@ public class Index private static final List<Item> ITEMS = CollectionFactory .newList( + new Item("SingleErrorDemo", "Single Error", "Using Error component to customize where the errors for a field will be displayed."), + new Item("JavaScriptTests", "JavaScript Tests", "Client-side tests using Mocha and Chai"), new Item("ModuleInitDemo", "Module-based Initialization Demo", "Invoke a module function to perform page initialization"),
