Added dates to repeater cells

advanced-prototyping

#1

I’ve been wondering if it’s possible to add dates via [[Day]] or [[Now.getDate()]] to a repeater. Entering either of these directly into a cell just gives a blank result and using “Set text to…” doesn’t do anything either. I’ve tried to trigger with both OnLoad and OnItemLoad.

I tried getting the dates for a simple rectangle widget using OnLoad and that works fine, but it doesn’t seem to work inside the repeater.

Does anyone know how to make this work? Or if it’s even possible?


#2

Hi -
It is possible. Here’s one way…

For this example:
Name of widget in the repeater where you want to display the date = [DateWidget]
Name of Repeater Column = [Item.Date]

OnItemLoad:
Case 1
(If True)
Set text on [DateWidget] to [Item.Date]

Case 2
(If “[[Item.Date]]” equals “”)
Set text on [DateWidget] equal to “[[Now.getDate()]]”

Below is example file.

Hope it helps
TG

Repeater-getDate-EXAMPLE.rp (57.4 KB)


#3

Hi!

Are you trying to add a full date to the repeater column based using date functions, or just the current day of the month? Do you just want the current date, or might you need other days?

When I have a full date column in a repeater, instead of entering a bunch of hard-coded dates in that column (which will be stale when the prototype is viewed six months from now), I create a column called dateOffset and for each row put the number-of-days offset from the current date. For example, 0 for a row yields today’s date, -1 yesterday’s, 7 is a week from now, etc.

To convert that date offset to an actual date, you’ll need to use the date functions .getMonth(), getDate(), and getFullYear(). And to adjust the day offset, you’ll also need the .addDays() function.

See below how the addDays() function is using the value in the dateOffset column:

Set text of (rectangle) dateDisplay to [[Now.addDays(Item.dateOffset).getMonth()]]/[[Now.addDays(Item.dateOffset).getDate()]]/[[Now.addDays(Item.dateOffset).getFullYear()]]

Notice that because we are using the.addDays() function for month, date, and year, the date value properly spans month and year borders.

Live sample

File: Repeater-getDate-EXAMPLE.rp (63.2 KB)


#4

@thatguymc - that works and it’s nice and simple.

@josephxbrick - while thatguymc answered my direct question you somehow read my mind, because what you described was my next step for my prototype. You just saved me a lot of time trying to work that one out next.

Thanks a lot both of you :slight_smile:


#5

If you use the dateOffset approach, how would you go about filtering the Date column?


#6

Hi dyarwood!

That could be tricky. What kind of filter are you looking for? Year, or date range, or…?


#7

Hi again -

Filtering on dates is always tricky, as you will always need to make some kind of conversion.

So, if using the method for displaying dates above, you wanted to filter on year (with a list of years in a dropdown list), you’d need to convert this negative number representing a day offset to its corresponding year value. This conversion occurs within the filter itself.

So, for today’s date (10/04/2017), -10 would need to be converted to 2017, -400 becomes 2016, etc. This way you can compare it to the dropdown value in the filter.

This expression makes that conversion:

Now.addDays(Item.dateOffset).getFullYear()

So the filter would look like this:

[[dropDownVal == Now.addDays(Item.dateOffset).getFullYear()]]

…where dropDownVal is a local variable containing the selected option of the year dropdown, and Item.dateOffset is the same as discussed above.

File: filter_date_column.rp (51.9 KB)


#8

Thanks Joseph,

I’m trying to take a user entered date and then let the user decide if they want all records for that date, from before that date, or from after that date.

That gives me 3 cases (DateEquals, DateIsBefore, DateIsAfter) which are driven by the drop down selection of the user. The I use the Add Filter option under each case (all of which are IFs).

Based on your example I thought this would work:

[[UserEnteredDate==[[Now.addDays(Item.dateOffset).getMonth()]]/[[Now.addDays(Item.dateOffset).getDate()]]/[[Now.addDays(Item.dateOffset).getFullYear()]]]] where UserEnteredDate is a local variable defined as the text on widget and the widget is the search field where the user types in their date.

At the moment, that’s not working for me so I’ll keep trying.






#9

Hi!

When you are comparing dates for the purpose of filtering, you’ll want to convert your dates into a numeric format, especially for greater-than/less-than filters. The native format of time is a simple number: the number of milliseconds (positive or negative) that have transpired since Jan 1, 1970.

There’s a poorly documented function in Axure called Date.parse(time string). The function parse() is listed as a date function, but nowhere is it mentioned that Date is an Axure key word, and that’s what you are expected to use with parse(). [Edit: it does populate this if you choose it from the function menu.] Date.parse(date string) returns the millisecond value above.

The issue is that the date format also includes hours, minutes, seconds, and milliseconds. For the date entered in the field, this won’t be an issue, since the time is not entered with it. However, Now does include the current hours, minutes, etc., and we are doing date math with functions based on Now in the repeater code. So the trick is to strip off the time portion. This does that:

Date.parse(Now.addDays(Item.dateOffset).toDateString())

So the following filter will give you the “equals” version of your filter:

[[ Date.parse(dateFieldVal) == Date.parse(Now.addDays(Item.dateOffset).toDateString()) ]]

… where dateFieldVal is the local variable pointing to your date field text.

To create the greater than/less than versions, just change the comparison operator.

The nice thing about Date.parse() is that your user could enter “October 4 2017” and it will still work.


#10

Thanks Joseph! I was on my way back to admit total defeat despite your help earlier and here you already have the solution for me :wink:

That gets me to a nice milestone for my prototype. Thanks again!

Viewable on AXShare here:
Untitled Document


#11

Nice! I learned something, too, as I used to do this without Date.parse(), which was much more complicated. Glad you got it working.


#12

hi! im looking to format date.
[[Now.addDays(28).getFullYear()]]-[[Now.addDays(28).getMonth()]]-[[Now.addDays(28).getDate()]]

gives me 2018-8-8, but i want it to show as 2018-08-08

ideas?


#13

Hi!

This response is late: somehow I missed this. To get leading zeros on month and date:

[[Now.addDays(28).getFullYear()]]-[[ "0".concat(Now.addDays(28).getMonth()).slice(-2) ]]-[[ "0".concat(Now.addDays(28).getDate()).slice(-2) ]]

Basically, you prepend “0” to whatever number the date function returns, and then you use slice() to take just the last two digits. So “1” becomes “01” and then its last two digits are taken (“01”), and “23” becomes “023” and then its last two digits are taken (“23”). (If you give the slice function a negative number, it slices from the back end of the string instead of the front end.)


#14

Hi Joseph,
I just posted a question about the date offset: Date offset in repeater
May I ask you, if you could please advise how to fix the script in my case?
Thank you in advance,
Natalie


#15

Hi Joseph!

May I please ask you if, by any chance, you might have an advise for how to add full second/AM to date
image

[[Now.addDays(Item.dateOffset1).getMonthName()]] [[Now.addDays(Item.dateOffset1).getDate()]], [[Now.addDays(Item.dateOffset1).getFullYear()]] [[Now.addHours(0).toLocaleTimeString().substring(0,4)]] [[Now.toLocaleTimeString().substring(8,10)]] [[Now.substr(Now.indexOf(’(’)+1,1)]]ST

My goal to show as
May 15, 2019 11:57 AM EST

Thank you in advance,
Natalie


#16

Hi Natalie!

The hardest part of this would be getting the abbreviated time zone. It’s currently set up to return only standard time, even when it should be, for example, PDT. The reason the time is failing is because this code doesn’t handle two-digit hours.

This code should work for you. The hard part was getting the abbreviated time zone, as Axure only gives it to you spelled out – E.g., ‘Pacific Standard Time.’ This code takes the first letter from each of the first two words of the spelled-out time zone and adds a T. It’s ugly.

[[Now.addDays(Item.dateOffset1).getMonthName()]] [[Now.addDays(Item.dateOffset1).getDate()]], [[Now.addDays(Item.dateOffset1).getFullYear()]] [[Now.toLocaleTimeString().substring(0,Now.toLocaleTimeString().indexOf(':'))]]:[[Now.getMinutes()]] [[Now.getHours()<12 && 'AM' || 'PM']] [[Now.toTimeString().substr(Now.toTimeString().indexOf('(')+1,1))]][[Now.toTimeString().substr(Now.toTimeString().indexOf(' ', Now.toTimeString().indexOf('('))+1,1)]]T

[Edit] Oops! Hang on: You’ll need a leading 0 for the minutes when it’s just one digit. THIS should work:

[[Now.addDays(Item.dateOffset1).getMonthName()]] [[Now.addDays(Item.dateOffset1).getDate()]], [[Now.addDays(Item.dateOffset1).getFullYear()]] [[Now.toLocaleTimeString().substring(0,Now.toLocaleTimeString().indexOf(':'))]]:[[0.concat(Now.getMinutes()).slice(-2)]] [[Now.getHours()<12 && 'AM' || 'PM']] [[Now.toTimeString().substr(Now.toTimeString().indexOf('(')+1,1))]][[Now.toTimeString().substr(Now.toTimeString().indexOf(' ', Now.toTimeString().indexOf('('))+1,1)]]T

[Edit] Okay, one last bug fix. The one above doesn’t properly adjust time to standard time for a date in, say, January, when offset from the current date. Basically I used the addDays() function everywhere I thought it might make a difference. It’s curious why the hour doesn’t offset when in standard time…

[[Now.addDays(Item.dateOffset1).getMonthName()]] [[Now.addDays(Item.dateOffset1).getDate()]], [[Now.addDays(Item.dateOffset1).getFullYear()]] [[Now.addDays(Item.dateOffset1).toLocaleTimeString().substring(0,Now.addDays(Item.dateOffset1).toLocaleTimeString().indexOf(':'))]]:[[0.concat(Now.getMinutes()).slice(-2)]] [[Now.addDays(Item.dateOffset1).getHours()<12 && 'AM' || 'PM']] [[Now.toTimeString().substr(Now.toTimeString().indexOf('(')+1,1))]][[Now.addDays(Item.dateOffset1).toTimeString().substr(Now.addDays(Item.dateOffset1).toTimeString().indexOf(' ', Now.addDays(Item.dateOffset1).toTimeString().indexOf('('))+1,1)]]T

By the way, I tested the AM/PM logic and it works fine.

timezonemath.rp (46.7 KB)


#17

Hi Joseph,
Thank you so much for your hard work! This code most complicated piece of code and it works like a charm! Truly appreciate it!
image
Natalie


closed #18

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.