Make time-aware popups with Arcade

4441
4
02-04-2020 09:47 AM
GeeFernando
Occasional Contributor
14 4 4,441

Did you know that you can customise popups based on time and dates? With Arcade you can .

This can come in handy when displaying opening hours for restaurants, cafes and other facilities. If you’re unfamiliar with Arcade - please refer to these ArcGIS Blogs, as this post assumes some prior knowledge.

Additional Arcade resources

Pop Up Variations

Let’s get started

First, find or create a data-set with opening hours (preferably for all days of the week). For this example I’ll be using Access Canberra locations (sourced from - dataACT). Please ensure opening hours are saved as numbers or text field types.

Time Types

Build expressions

Within the pop-up configuration window - build the following expressions or feel free to follow along with this web map.

Opening Hour Expressions

hoursOfOperationToday {expression/expr0}

This expression will return the current weekday alongside its opening hours.

For example:

Thursday: 08:30-16:30

var weekDays = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday']

//Returns the current weekday. Values range from 0-6 where sunday is 0 and saturday is 6
var currentWeekDay = Weekday(Now())

//Return weekday followed by opening hours
var hoursOfOperationToday = weekDays[currentWeekDay] + ": " + $feature[weekDays[currentWeekDay]]

return hoursOfOperationToday‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

hoursOfOperationRestOfWeek {expression/expr1}

This expression will return the remaining weekdays alongside their opening hours.

For example:

Friday: 08:30-16:30
Saturday: Closed
Sunday: Closed
Monday: 08:30-16:30
Tuesday: 08:30-16:30
Wednesday: 08:30-16:30

var weekDays = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday','Monday','Tuesday','Wednesday','Thursday','Friday'];

//Returns the current weekday. Values range from 0-6 where sunday is 0 and saturday is 6
var currentWeekDay = Weekday(Now())

var hoursOfOperationRestOfWeek = ""

//Iterate over the weekdays and opening hours for the remaning 6 days of the week
for(var i = currentWeekDay + 1; i < currentWeekDay + 7; i++){
    hoursOfOperationRestOfWeek += weekDays[i] + ": " + $feature[weekDays[i]] + TextFormatting.NewLine
}

return hoursOfOperationRestOfWeek‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

openCloseStatus {expression/expr2}

This expression will return whether the shopfront is Open, Closed, Opens soon or Closing soon based on opening hours and the time displayed on users' device .

var weekDays = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday']

//Returns the current weekday. Values range from 0-6 where sunday is 0 and saturday is 6
var currentWeekDay = Weekday(Now())

//Change 'Closed' to 00:00-00:00 to be consistent with the rest of opening hours information
var formattedOpeningHours = When($feature[weekDays[currentWeekDay]] == "Closed", "00:00-00:00", $feature[weekDays[currentWeekDay]])

//Separate Opening hours and minutes into an array
var separateOpening = Split(Replace(formattedOpeningHours,'-',':'),':')

//Assign hours and minutes to opening and close times
var startTime = Date(Year(Now()),Month(Now()),Day(Now()),separateOpening[0],separateOpening[1])
var endTime = Date(Year(Now()),Month(Now()),Day(Now()),separateOpening[2],separateOpening[3])

When(Now() > startTime && Now() < endTime && Now() > Dateadd(endTime, -1, 'hours'), "Closes soon:",
Now() > startTime && Now() < endTime, "Open",
Now() < startTime && Now() > Dateadd(startTime, -1, 'hours'), "Opens soon",
"Closed")‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

openCloseStatusColour {expression/expr3}

If you'd like to re-iterate the openCloseStatus values with added colour - rewrite and replace previous expression's return values with hexadecimal colour values.

For example:

#239B56 ⋅ Open

#CB4335 ⋅ Closed

#2ECC71 ⋅ Opens soon

#EC7063 ⋅ Closing soon

//First 15 lines the same as - openCloseStatus {expression/expr2}

When(Now() > startTime && Now() < endTime && Now() > Dateadd(endTime, -1, 'hours'), "#EC7063",
Now() > startTime && Now() < endTime, "#239B56",
Now() < startTime && Now() > Dateadd(startTime, -1, 'hours'), "#2ECC71",
"#CB4335")‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Now use this expression to replace the colour code within the popup HTML. For more information on this topic - refer to Bring Colors From Your Map Into Your Pop-up Using Arcade written by Lisa Berry‌.

Inserting Colour Expressions into HTML

closingOrOpeningTime {expression/expr4}

This expression can look a little daunting at first, but like any other piece of code - go through one line at a time and use your own test environment to test and experiment .

It will return the:

  • closing time, if the Access Canberra shop front is Open or Closes soon.
  • opening time for the current day, if it Opens soon, or Closed (before hours).
  • and next opening day and timeif it's Closed (after hours), Closes soon or Closed for the whole day.
var weekDays = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday','Monday','Tuesday','Wednesday','Thursday','Friday'];

//Returns the current weekday. Values range from 0-6 where sunday is 0 and saturday is 6
var currentWeekDay = Weekday(Now())

//Change 'Closed' to 00:00-00:00 to be consistent with the rest of of opening hours information
var formattedOpeningHours = When($feature[weekDays[currentWeekDay]] == "Closed", "00:00-00:00", $feature[weekDays[currentWeekDay]])

//Separate Opening hours and minutes into an array
var separateOpening = Split(Replace(formattedOpeningHours,'-',':'),':')

var startTime = Date(Year(Now()),Month(Now()),Day(Now()),separateOpening[0],separateOpening[1])
var endTime = Date(Year(Now()),Month(Now()),Day(Now()),separateOpening[2],separateOpening[3])

var openCloseStatus = When(Now() > startTime && Now() < endTime && Now() > Dateadd(endTime, -1, 'hours'), "Closes soon:",
Now() > startTime && Now() < endTime, "Open",
Now() < startTime && Now() > Dateadd(startTime, -1, 'hours'), "Opens soon",
"Closed")

//If openCloseStatus is Closed (before hours), return current day's opening time
//Else if openCloseStatus is Closed (after hours), Closes soon or Closed for the whole day, return next opening day and time
var nextOpening = ""
if (openCloseStatus == "Closed" && $feature[weekDays[currentWeekDay]] != "Closed" && Now() < startTime){
    nextOpening = "Opens " + LEFT($feature[weekDays[currentWeekDay]],5)
} else if ((openCloseStatus == "Closed" || openCloseStatus == "Closes soon:") && $feature[weekDays[currentWeekDay + 1]] != "Closed"){
    nextOpening = "Opens " + LEFT($feature[weekDays[currentWeekDay + 1]],5) + " " + weekDays[currentWeekDay + 1]
} else if (openCloseStatus == "Closed" || openCloseStatus == "Closes soon:") {
    for(var i = currentWeekDay + 1; $feature[weekDays[i]] == "Closed"; i++){
        nextOpening = "Opens " + LEFT($feature[weekDays[i + 1]],5) + " " + weekDays[i + 1]
    }
}

When(openCloseStatus == "Open", "⋅ " + RIGHT($feature[weekDays[currentWeekDay]],5),
openCloseStatus == "Opens soon", "⋅ " + LEFT($feature[weekDays[currentWeekDay]],5),
openCloseStatus == "Closes soon:", RIGHT($feature[weekDays[currentWeekDay]],5) + " ⋅ " + nextOpening,
"⋅ " + nextOpening)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Final thoughts

Once you’ve built the pop-ups to your heart's content you can further highlight them by using configurable app templates. Click here to see how I’ve extended the above web map using the NearBy configurable app.

Nearby Access Canberra GIF

Tips - Make sure to take advantage of Test your expressions feature to check whether return values look correct. If you have admin privileges to your computer you could also adjust time/date to test various return values based on opening hours.

Test Expressions

Challenge - As you may have figured out, these expressions are not time-zone aware. And in most instances this wouldn't be a problem - as the intended maps and apps are localised.

But, I'd still love to hear your thoughts around how you'd go about this. Please use the comments section below for ideas.

Cheers! - Gee Fernando

4 Comments
XanderBakker
Esri Esteemed Contributor

Hi Gee Fernando ,

Thanks for sharing. Great content and great examples!

I have a couple of related posts that might be interesting for those that read your blog (although the content is in Spanish, it is very visual and might be helpful to some):

If you run into Andres White and/or Nicholas Flett, please say hi and tell them I miss my mates. They will know what I mean 

GeeFernando
Occasional Contributor

Thanks Xander Bakker‌. Just read both your articles in English. And I LOVED it.

Just goes onto show the power of Aracde.

Yes, will definitely mention that you miss them 

AlanGuerra
New Contributor

I'm having trouble getting mine to work and I think it is because your configuration is for 24 hour time format.

GeeFernando
Occasional Contributor

Hi Alan Guerra,

You'll need to convert the time to 24 hour format. You can either change how the data is stored or write an Arcade expression to do the conversion.

Click here for more information on time formats - Date Functions | ArcGIS for Developers 

Also, feel free to share how your time formats are saved? And I might be able to help out.

Gee