Hi!
I’ve made a calendar with a repeater before. I first tried a model where I updated the repeater’s dataset to update it, but that turns out to be very slow. A nice thing about repeaters is the OnItemLoad interaction will run once per row in its dataset, but that doesn’t mean you need to display data from its dataset.
There is a useful repeater property called item.index, which just returns the number of the current row, starting at 1. So take the stock repeater (with just three items) and replace its OnItemLoad handler with this:
OnItemLoad
set text on dateShape to [[Item.index - 1]]
This will make the repeater display the values 0, 1, 2 - even though the stored values are 1, 2, 3. Now change the dataset values to “cat,” “dog,” “bird.” The repeater will still display 0, 1, 2. Add “mouse” to the dataset. You now get 0, 1, 2, 3.
So for the calendar, here’s the strategy I used
Put just a single shape in the repeater row with no text in it. I’m calling it dateShape. This is the shape you will be putting the dates in. In the Style tab for the repeater, set Layout to horizontal and have it wrap on every 7th item. (You can also set the spacing between rows and columns here.)
Put 37 rows in your repeater - the max number of dates that can appear (including the blank ones at the beginning of the month. Heck, put a few more to be safe). They can have any value you want because we won’t be looking at those values - just make them all 0.
Also, in the repeater’s property tab, below the dataset, turn OFF “fit content to HTML”
Now all you have to do is figure out which day of the week that the first date of the month starts on (with Sunday being 0 and Saturday being 6) and subtract that number from Item.index, just as we subtracted 1 in the expression above. Then you make sure (using a condition) that you don’t bother setting the text of the repeater’s shape when that expression returns zero or less, or if it’s greater than the number of days in the month.
Here are all of the variables you will need to define. If you want this to be a widget, I’d recommend using the text of shapes instead of variables to store your values so things don’t break when you copy your widget to a file that doesn’t have those variables defined. You’ll need to know about local variables. Here’s a post on that. You might try it with global variables first since that’s easier, just to get things working. Note that you can display the values of global variables in the browser by choosing Axure’s console tab on the left side (where the page listing is).
The variables below assume you want to show September 2018
monthNum = 9
yearNum = 2018
firstWeekdayNum = 6 (which means Saturday - see below)
firstDate = 9/01/2018
lastDate = 09/30/2018
The only variables you will need to set the values of is monthNum and yearNum. You can calculate all of the other variables from that.
firstDate = [[ (Date.parse(monthNum + "/01/" + yearNum)+0).toUTCString() ]]
lastDate = [[ firstDate.addMonths(1).addDays(-1) ]]
firstWeekdayNum = [[ firstDate.getDay() ]] -- conveniently returns 0 for Sunday, 6 for Saturday
Note: Date.parse(dateString) returns the date/time of the supplied string in milliseconds. We’re adding zero to that result to force .toUTCString() to interpret the result of Date.parse() as a number rather than a string.
So your strategy is the following:
- set the monthNum and yearNum as desired
- calculate the other variables
- force the repeater to redraw itself (see below)
Then in the repeater, your code would look like this:
OnItemLoad
If [[Item.index - firstWeekdayNum]] is greater than 0 AND
[[Item.index - firstWeekdayNum]] is less than or equals [[lastDate.getDate()]]
set text of dateShape to [[Item.index - firstWeekdayNum]]
Else If
hide dateShape
Note: the getDate() function returns the day-of-the-month portion of a date, so 20 for September 20th.
To force the repeater to redraw itself, you can set its itemsPerPage to the number of days you will need to draw:
set ItemsPerPage of (repeater) to [[firstWeekdayNum + lastDate.getDate()]]
[ Edit ] Here’s an implementation of the above. (I figured I should make sure it works!)
calendarexample.rp (66.6 KB)