Repeater with dates

repeater-widget

#1

hi there,

in the attached RP file, I created 2 repeaters. the data selected on the one in the bottom are added to the one on the top when clicking on the button. The rule states that the data should be added if the date provided by the user is matching with today date on the fields above.
Now, I would need to replicate the same logic for tomorrow date (today+1).
I really need help since I don’t know how to do that…example.rp (123.8 KB)


#2

Date manipulation and “date math” is hard. Axure makes it harder in some cases–including your scenario–because its date functions expect the “English United States” date format of Month/Date/Year, even if your country/language (known as “locale” in javascript) is different. @josephxbrick is the “date master” on this forum, but I’ll give this a swag–using some of his past posts to guide us.

First off, when you need to compare two dates or add/subtract days, months, etc. it is best to convert the human-readable date into a single number. The standard for this is the number of milliseconds elapsed since midnight January 1, 1970. As an example, today’s date is the 31st of March, 2021, or 31/03/2021 as you represent it in your prototype. If you want to add 1 day, you can’t just increment the first two digits (the “dd” value) or you would get an invalid date: 32/03/2021. Because it is the last day of the month, you need to “roll over” the date and add 1 to the month to get 01/04/2021. But if you can convert 31/03/2021 into its “milliseconds timecode” (where time defaults to midnight or 00:00) and add one days worth of milliseconds, you would get the next day’s timecode, which can then be converted back into human-readable format. Axure provides a lot of built-in date functions to do this–but again, expects a different format than you use: so first you need to convert dd/mm/yyyy into mm/dd/yyyy, then convert to timecode, add a day, compare timecodes, then if needed, convert back to mm/dd/yyyy, then dd/mm/yyyy.
(Did I mention this is hard?)

After a lot of fumbling around, I think i have a decent solution in this updated example file:
example-repeater-dates.rp (139.1 KB)

  • I started by generating “tomorrow’s date” in the Page Loaded event, to go along with your “today’s date”. This is relatively easy with the .addDays() function, and with your method is:
    [[Now.addDays(1).getDate()]]/[[Now.addDays(1).getMonth()]]/[[Now.addDays(1).getFullYear()]]
    • Note I add a day to all fields because if today is the last day of the month then the month needs to increment, and if today is last day of the year then year needs to increment.
  • This might be useful for users to see, but won’t serve you well for testing a user-entered date–you’ll want the timecode for that. There is also a built-in function you can use to get this date format. So, I added another case to show this:
    • Today’s formatted date is available with: [[Now.toLocaleDateString()]]
      • For you, this probably shows as mm/dd/yyyy but for me in the US it is dd/mm/yyyy
      • To force your format, you can use a “locale parameter” in this function. I’ll take a guess that Italian is what you want (but you can find a list of all locales)
        For Italian it is [[Now.toLocaleDateString('it-IT')]]
    • Today’s timecode is available with: [[Now.valueOf()]]
      • It turns out this timecode is not quite what you need because it includes all the milliseconds since midnight today, and you’ll be testing it against the timecode for a date only (where midnight is used.)
      • I tried several ways to get this “midnight timecode” and had to resort to using a 2-step method with a global variable:
        • a global variable named “tempdate” is set to [[Now.toLocaleDateString(‘en-US’)]] (forcing to the format that Axure needs to calculate the timecode properly)
        • then a widget named “todayCode” is set to [[tempdate.valueOf()]]
          ( this helps with showing what the timecode is in my demo. You could use a global variable to store this value “silently”)
    • Tomorrow’s formatted date and timecode are available in the same way by “chaining” the .addDays(1) function. This results in the “tomorrowCode” widget storing the important number to test against.

In the second repeater, here’s what I changed:

  • The date text field has a Lost Focus event that sets the value of tempdate to the format of mm/dd/yyyy (because that is needed for Axure’s functions.)
  • In the “allocate” button I added some cases to do error handling–ensuring the date format and slot number are correctly entered.
    • The first case tests the “inputDate” text field and throws an error if any of these conditions:
      • length of input is less than 10 (because dd/mm/yyyy has exactly 10 characters)
      • first two characters are not numeric, and likewise for the ‘mm’ and ‘yyyy’ characters
      • third and sixth character is not a slash (’`/’)
    • The second case tests if “inputDate” value is “earlier than tomorrow”
      • Else if [[tempdate.valueOf()]] is less than text on tomorrowCode
        // throw an error
    • The third case ensures that the slot text field is numeric and is one of the slots in the first repeater. So I’m assuming it must be between 1 and 4 as there are 4 slots in the top repeater.
  • The final “Else if” case is triggered upon successful entries in the date and slot fields. It assigns the associated row in the first repeater to the entered values in the current row of the second repeater.

Summing filtered columns
#3

thank you very much @mbc66 for your extensive explanation. Quite tricky, indeed!