You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2013/10/11 23:41:13 UTC

[4/4] git commit: Allow multiple Errors components for a single field

Allow multiple Errors components for a single field


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/033e04cd
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/033e04cd
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/033e04cd

Branch: refs/heads/master
Commit: 033e04cdfb26987cb92ea1e6cc626b57f1c6caf5
Parents: 5140d1b
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Fri Oct 11 14:41:04 2013 -0700
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Fri Oct 11 14:41:04 2013 -0700

----------------------------------------------------------------------
 .../META-INF/modules/t5/core/fields.coffee      | 49 ++++++++++++--------
 .../tapestry5/corelib/components/Error.java     | 11 +++++
 2 files changed, 40 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/033e04cd/tapestry-core/src/main/coffeescript/META-INF/modules/t5/core/fields.coffee
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/coffeescript/META-INF/modules/t5/core/fields.coffee b/tapestry-core/src/main/coffeescript/META-INF/modules/t5/core/fields.coffee
index 3d44f8f..92a48f8 100644
--- a/tapestry-core/src/main/coffeescript/META-INF/modules/t5/core/fields.coffee
+++ b/tapestry-core/src/main/coffeescript/META-INF/modules/t5/core/fields.coffee
@@ -28,23 +28,26 @@ define ["underscore", "./events", "./dom", "./utils", "./forms"],
 
       return fieldId
 
-    # Finds a `.help-block` used for presenting errors for the provided field.
-    # Returns the found block as an ElementWrapper. May modify attributes of the field
-    # or the block to make future
+    # Finds any `.help-block` used for presenting errors for the provided field.
+    # Returns the found block(s) as an array of ElementWrapper. Returns null
+    # if no blocks can be found.
+    #
+    # Normally, you would expect just a single help block for a field, but in some cases,
+    # such as to support responsive layout, there will be multiple help blocks for a single field.
     #
     # * field - element wrapper for the field
-    findHelpBlock = (field) ->
+    findHelpBlocks = (field) ->
       fieldId = field.attribute "id"
 
       # When the field has an id (the normal case!), search the body for
-      # the matching help block.
+      # the matching help blocks.
       if fieldId
-        block = dom.body.findFirst "[data-error-block-for='#{fieldId}']"
+        blocks = dom.body.find "[data-error-block-for='#{fieldId}']"
 
-        return block if block
+        return blocks if blocks.length > 0
       else
         # Assign a unique (hopefully!) client id for the field, which will be
-        # used to link the field and the label together.
+        # used to link the field and the new help-block together.
         fieldId = ensureFieldId field
 
       # Not found by id, but see if an empty placeholder was provided within
@@ -54,12 +57,17 @@ define ["underscore", "./events", "./dom", "./utils", "./forms"],
 
       return null unless group
 
+      # This happens less often, now that the Errors component ensures (at render time)
+      # a fieldId and a data-error-block-for element. Even so, sometimes a template
+      # will just contain a div.help-block[data-presentation=error]
       block = group.findFirst "[data-presentation=error]"
 
       if block
         block.attribute "data-error-block-for", fieldId
+        return [block]
 
-      return block
+      # Not found, so perhaps it will be created dynamically.
+      return null
 
     createHelpBlock = (field) ->
       fieldId = ensureFieldId field
@@ -142,9 +150,9 @@ define ["underscore", "./events", "./dom", "./utils", "./forms"],
       return
 
     dom.onDocument events.field.clearValidationError, ->
-      block = exports.findHelpBlock this
+      blocks = exports.findHelpBlocks this
 
-      if block
+      for block in blocks or []
         block.hide().update("")
         block.parent().removeClass "has-error"
 
@@ -155,16 +163,17 @@ define ["underscore", "./events", "./dom", "./utils", "./forms"],
       return
 
     dom.onDocument events.field.showValidationError, (event, memo) ->
-      block = exports.findHelpBlock this
+      blocks = exports.findHelpBlocks this
 
-      unless block
-        block = exports.createHelpBlock this
+      unless blocks
+        blocks = [exports.createHelpBlock this]
 
-      block.removeClass("invisible").show().update(memo.message)
-      # Add "has-error" to the help-block's immediate container; this assist with some layout issues
-      # where the help block can't be under the same .form-group element as the field (more common
-      # with a horizontal form layout).
-      block.parent().addClass("has-error")
+      for block in blocks
+        block.removeClass("invisible").show().update(memo.message)
+        # Add "has-error" to the help-block's immediate container; this assist with some layout issues
+        # where the help block can't be under the same .form-group element as the field (more common
+        # with a horizontal form layout).
+        block.parent().addClass("has-error")
 
       group = @findParent ".form-group"
 
@@ -174,4 +183,4 @@ define ["underscore", "./events", "./dom", "./utils", "./forms"],
 
       return
 
-    exports = {findHelpBlock, createHelpBlock, showValidationError}
\ No newline at end of file
+    exports = {findHelpBlocks, createHelpBlock, showValidationError}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/033e04cd/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 5352055..37f7c8a 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
@@ -11,6 +11,7 @@
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 // See the License for the specific language governing permissions and
 // limitations under the License.
+
 package org.apache.tapestry5.corelib.components;
 
 import org.apache.tapestry5.BindingConstants;
@@ -28,6 +29,14 @@ import org.apache.tapestry5.ioc.annotations.Inject;
  * 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">}.
+ * <p/>
+ * It is acceptable to include multiple Errors components for a single field; this is sometimes necessary
+ * when creating a responsive layout - which should probably ensure that only one of the Errors is
+ * visible at any time.
+ * <p/>
+ * Errors is optional, and Tapestry's client-side logic will do a reasonable job of placing a help block
+ * dynamically when a validation error must be presented; this component is intended for use when the default logic
+ * doesn't place the help block in the right spot.
  *
  * @tapestrydoc
  * @since 5.2.0
@@ -51,6 +60,7 @@ public class Error
 
         resources.renderInformalParameters(writer);
 
+        // Wait until the end of the heartbeat to ensure the Field has had a chance to render.
         updateElement(element);
 
         writer.end();
@@ -61,6 +71,7 @@ public class Error
     @HeartbeatDeferred
     private void updateElement(final Element element)
     {
+        // The field may add an id attribute because of this call.
         element.attribute("data-error-block-for", field.getClientId());
     }
 }