Announcement Announcement Module
Collapse
No announcement yet.
Bind month and year to date Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Bind month and year to date

    I have a form with credit card's expiration date as two select menu's: one for Year and one for Month. I'd like to bind these values to a Date object in my model (and set its Day to 1).

    Date.setMonth() is deprecated, so I probably shouldn't use this:

    <spring:bind path="command.creditCard.expirationDate.month">

    but is there another way to do it? Examples or suggestions are much appreciated!

    Thanks,
    - Ryan

  • #2
    You'll either have to manually bind the two inputs to your domain object on onBind for example, or use a little piece of JavaScript that transfers the values of the two input to a hidden field (this is what I usually do and it works just fine).

    Spring's ServletRequestDataBinder uses plain PropertyEditors under the hood and those only bind to one field at a time.

    Comment


    • #3
      I have what seems to be a pretty good solution, please let me know if you see any problems with this.

      I wrote a class TouchableDate which extends java.util.Date (see below). This class un-deprecates the getters/setters from Date and tracks which properties have been set.

      I set a new TouchableDate() on my formBackingObject, then I implemented onBindAndValidate to test whether the properties were accessed:

      Code:
          protected void onBindAndValidate&#40;HttpServletRequest request, Object command, BindException errors&#41; throws Exception &#123;
              Donation donation = &#40;Donation&#41; command;        
              TouchableDate tDate = &#40;TouchableDate&#41; donation.getCreditCard&#40;&#41;.getExpirationDate&#40;&#41;;
              if &#40;!tDate.hasMonth&#40;&#41; || !tDate.hasYear&#40;&#41;&#41; &#123;
                  errors.rejectValue&#40;"creditCard.expirationDate", "empty", "Expiration date is required"&#41;;
              &#125; else &#123;
      	        tDate.setDate&#40;1&#41;;
              &#125;
          &#125;

      This lets me determine whether a value has been set or not, as opposed to a regular Date object which cannot have empty/invalid values (month, for example).

      My binding looks the same, e.g.:

      Code:
      <spring&#58;bind path="command.creditCard.expirationDate.month">
      The only thing I wonder is whether spring:bind is using reflection to see that expirationDate is actually a TouchableDate, and therefore has a getMonth method, or whether spring:bind is using the deprecated Date.getMonth() method.

      Any other thoughts?


      Code:
      import java.util.Calendar;
      import java.util.Date;
      
      /**
       * A special Date object that un-deprecates the getXXX, setXXX methods from Date and
       * returns -1 for properties that haven't been set. Use hasXXX methods to determine 
       * if a property has been set.Uses a Calendar internally to set properties correctly.
       *  
       * @author Ryan Carver
       */
      public class TouchableDate extends Date &#123;
          
          public static final int NOT_SET = -1;
          
          private Calendar c;
          private boolean hasHours = false;
          private boolean hasMinutes = false;
          private boolean hasSeconds = false;
          private boolean hasDate = false;
          private boolean hasDay = false;
          private boolean hasMonth = false;
          private boolean hasYear = false;
          
          //~ Constructors
          
          public TouchableDate&#40;&#41; &#123;
              super&#40;&#41;;
              init&#40;&#41;;
          &#125;
          public TouchableDate&#40;long arg0&#41; &#123;
              super&#40;arg0&#41;;
              init&#40;&#41;;
          &#125;
          
          //~ Internal
          
          private void init&#40;&#41; &#123;
              c = Calendar.getInstance&#40;&#41;;
              c.setTime&#40;this&#41;;
          &#125;
          private void setProperty&#40;int code, int value&#41; &#123;
              c.set&#40;code, value&#41;;
          &#125;
          private int getProperty&#40;int code&#41; &#123;
              return c.get&#40;code&#41;;
          &#125;
          
          //~ Behavior
      
          public long getTime&#40;&#41; &#123;
              return c.getTimeInMillis&#40;&#41;;
          &#125;
          
          //~ Setters
          
          public int getHours&#40;&#41; &#123;
              return &#40;hasHours&#41; ? getProperty&#40;Calendar.HOUR_OF_DAY&#41; &#58; NOT_SET;
          &#125;
          public int getMinutes&#40;&#41; &#123;
              return &#40;hasMinutes&#41; ? getProperty&#40;Calendar.MINUTE&#41; &#58; NOT_SET;
          &#125;
          public int getSeconds&#40;&#41; &#123;
              return &#40;hasSeconds&#41; ? getProperty&#40;Calendar.SECOND&#41; &#58; NOT_SET;
          &#125;
          public int getDay&#40;&#41; &#123;
              return &#40;hasDay&#41; ? getProperty&#40;Calendar.DAY_OF_WEEK&#41; &#58; NOT_SET;
          &#125;
          public int getDate&#40;&#41; &#123;
              return &#40;hasDate&#41; ? getProperty&#40;Calendar.DAY_OF_MONTH&#41; &#58; NOT_SET;
          &#125;
          public int getMonth&#40;&#41; &#123;
              return &#40;hasMonth&#41; ? getProperty&#40;Calendar.MONTH&#41; &#58; NOT_SET;
          &#125;
          public int getYear&#40;&#41; &#123;
              return &#40;hasYear&#41; ? getProperty&#40;Calendar.YEAR&#41; &#58; NOT_SET;
          &#125;
          
          //~ Setters
      
          public void setHours&#40;int hours&#41; &#123;
              hasHours = true;
              setProperty&#40;Calendar.HOUR_OF_DAY, hours&#41;;
          &#125;
          public void setMinutes&#40;int minutes&#41; &#123;
              hasMinutes = true;
              setProperty&#40;Calendar.MINUTE, minutes&#41;;
          &#125;
          public void setSeconds&#40;int seconds&#41; &#123;
              hasSeconds = true;
              setProperty&#40;Calendar.SECOND, seconds&#41;;
          &#125;
          public void setDay&#40;int day&#41; &#123;
              hasDay = true;
              setProperty&#40;Calendar.DAY_OF_WEEK, day&#41;;
          &#125;
          public void setDate&#40;int date&#41; &#123;
              hasDate = true;
              setProperty&#40;Calendar.DAY_OF_MONTH, date&#41;;
          &#125;
          public void setMonth&#40;int months&#41; &#123;
              hasMonth = true;
              setProperty&#40;Calendar.MONTH, months&#41;;
          &#125;
          public void setYear&#40;int year&#41; &#123;
              hasYear = true;
              setProperty&#40;Calendar.YEAR, year&#41;;
          &#125;
          
          //~ Boolean checkers
          
          public boolean hasDate&#40;&#41; &#123;
              return hasDate;
          &#125;
          public boolean hasDay&#40;&#41; &#123;
              return hasDay;
          &#125;
          public boolean hasHours&#40;&#41; &#123;
              return hasHours;
          &#125;
          public boolean hasMinutes&#40;&#41; &#123;
              return hasMinutes;
          &#125;
          public boolean hasMonth&#40;&#41; &#123;
              return hasMonth;
          &#125;
          public boolean hasSeconds&#40;&#41; &#123;
              return hasSeconds;
          &#125;
          public boolean hasYear&#40;&#41; &#123;
              return hasYear;
          &#125;
      &#125;

      Comment


      • #4
        Originally posted by Alef Arendsen
        You'll either have to manually bind the two inputs to your domain object on onBind for example, or use a little piece of JavaScript that transfers the values of the two input to a hidden field (this is what I usually do and it works just fine).

        Spring's ServletRequestDataBinder uses plain PropertyEditors under the hood and those only bind to one field at a time.
        hi!
        i need to use only one field for date (my atual code):
        Code:
        <Spring:bind path="rate.rp_date">
         <input type="text" name="rp_date" size="10" value="${status.value}"/>
        </Spring:bind>
        the date is shown, like yyyy-mm-dd... without any problem, but when this field is modificated, the onSubmit method is not called because, i think, of some validation of spring, that cannot "translate" this new yyyy-mm-dd in Date again... can u plz help me with that, may be with some code exaples, forum-links or smthg else? i would appreciate any help
        thks a lot

        Comment

        Working...
        X