Tapestry 5
  1. Tapestry 5
  2. TAP5-52

Add Error component that presents validation errors of a single field

    Details

    • Type: New Feature New Feature
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 5.0.15
    • Fix Version/s: 5.2.0
    • Component/s: None
    • Labels:
      None

      Description

      There shold be an easy way to use "normal text" as replacement for the popup bubbles, as we have the need to build our WebApps conforming to WAI (Web Accessibility Initiative). Tapestry provides <t:errors/> core component to display all form errors at once, but there is currently no easy way to control individual error messages. Following current design, an "intuitive" way for end user would be to look for <t:error/> tag but there is no such tag.

      Here is a draft of a proposed solution. The <t:errorMsg/> tag allows to control individual form error messages and can be placed inside or outside of a form effectively allowing end user to place form error anywhere on a page as plain text. This code should probably be enhanced to also allow control of individual fields: yes/no red X for icon next to a field, yes/no for automatic styling of field on error, etc.

      This component takes two arguments, a literal string denoting field
      for which error should be rendered, and form to which field is bound.
      The form must be accessible via getter from the page class.

      import org.apache.tapestry.Field;
      import org.apache.tapestry.MarkupWriter;
      import org.apache.tapestry.ValidationTracker;
      import org.apache.tapestry.annotations.BeginRender;
      import org.apache.tapestry.annotations.Parameter;
      import org.apache.tapestry.corelib.components.Form;

      public class ErrorMsg {

      @Parameter
      private String _fieldName;

      @Parameter
      private Form _form;

      public void setFieldName(String aFieldName)

      { _fieldName = aFieldName; }

      @BeginRender
      void renderMessage(MarkupWriter writer)
      {
      Field f = new Field() {
      public String getElementName()

      { return _fieldName; }
      public String getLabel() { return null; }
      public boolean isDisabled() { return false; }
      public String getClientId() { return _fieldName; }

      };

      ValidationTracker tracker = _form.getDefaultTracker();
      String err = tracker.getError(f);

      writer.write(err);
      }

      public void setForm(Form aForm)

      { _form = aForm; }

      }

      To display individual error messages simply place <t:errorMsg ../>
      anywhere on the page. It will render the error if there is one for a
      field.

      <t:layout xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">

      <strong><t:errorMsg fieldName="literal:foo" form="form"/></strong>

      <t:form t:id="myform">
      User Name:
      <input type="text" t:type="textfield" t:id="bar" t:value="bar"
      t:validate="required,minlength=3,maxlength=8"/><br/>
      Foo:
      <input type="text" t:type="textfield" t:id="foo" t:value="foo"
      t:validate="required"/>
      <p/>
      <input type="submit" t:type="submit" t:id="submitButton" value="Submit"/>
      <p/>
      <t:errorMsg fieldName="literal:bar" form="form"/><br/>
      <!-- you can even display same error twice -->
      <t:errorMsg fieldName="literal:bar" form="form"/>
      </t:form>

      </t:layout>

      Page Class:

      public class Start {

      @Persist
      private String _foo;

      @Persist
      private String _bar;

      @Component(id="myform")
      private Form _form;

      public Form getForm()

      { return _form; }

      public String getBar()

      { return _bar; }

      public String getFoo()

      { return _foo; }

      /* also foo/bar setters here */
      }

        Activity

        Hide
        Sinan Saral added a comment - - edited

        I guess; you can also write it without the explicit reference to Form component:

        public class ErrorMsg {
        @Parameter(name = "for", required = true, defaultPrefix = "component")
        private Field _field;

        @Environmental
        private ValidationTracker _tracker;

        void beginRender(MarkupWriter writer)

        { if (_tracker == null) throw new RuntimeException( InternalMessages.encloseErrorsInForm() ); String err = _tracker.getError(_field); writer.write(err); }

        }

        then you can use it like:

        <t:errorMsg for="username" />

        Show
        Sinan Saral added a comment - - edited I guess; you can also write it without the explicit reference to Form component: public class ErrorMsg { @Parameter(name = "for", required = true, defaultPrefix = "component") private Field _field; @Environmental private ValidationTracker _tracker; void beginRender(MarkupWriter writer) { if (_tracker == null) throw new RuntimeException( InternalMessages.encloseErrorsInForm() ); String err = _tracker.getError(_field); writer.write(err); } } then you can use it like: <t:errorMsg for="username" />
        Hide
        Igor Drobiazko added a comment -

        Both solutions are insufficient because you have to coordinate the rendering order of the field and its error message. The rendering of this component should executed at the end of a heartbeat

        Show
        Igor Drobiazko added a comment - Both solutions are insufficient because you have to coordinate the rendering order of the field and its error message. The rendering of this component should executed at the end of a heartbeat

          People

          • Assignee:
            Igor Drobiazko
            Reporter:
            Adam Zimowski
          • Votes:
            8 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Time Tracking

              Estimated:
              Original Estimate - 5h
              5h
              Remaining:
              Remaining Estimate - 5h
              5h
              Logged:
              Time Spent - Not Specified
              Not Specified

                Development