Skip to content

Instantly share code, notes, and snippets.

@gscottolson
Created March 31, 2017 21:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gscottolson/e73298f1296e111071ff28b8ead40e38 to your computer and use it in GitHub Desktop.
Save gscottolson/e73298f1296e111071ff28b8ead40e38 to your computer and use it in GitHub Desktop.
# this functionality relies on Moment.js 2.0.0
# http://momentjs.com/docs/
$scheduleSelects = $('.schedule__select')
$scheduleYear = $('.schedule__year')
$scheduleMonth = $('.schedule__month')
$scheduleDay = $('.schedule__day')
$scheduleHour = $('.schedule__hour')
$scheduleMinute = $('.schedule__minute')
$scheduleReset = $('.schedule__reset')
$ampm = $('.schedule__am-pm')
$createdAt = $('input[name=createdAt]')
$button = $createdAt.closest('form').find('input[type=submit]')
generateDate = ->
now = moment().utc() # see moment.js for more info
offset = if now.isDST() then 4 else 5 # offset based on EDT or EST
# we're going to generate a date-time via an array of [year, month, ...].
# assume the year is the current year...
dateArr = [now.year()]
# ...but derive the month, day, hour, and minutes from the inputs
$scheduleSelects.each ->
dateArr.push parseInt(this.value, 10)
# we want to update the year to next year if the resulting date-time is in
# the past (e.g. on Dec 31, the input says Jan 1). we require the month
# and day to be specified, but for the purposes of this check, we're okay
# with an unspecified hour. this'll be the placeholder value. (minutes are
# always valid -- we have a default value of :00.) so for the purposes of
# this check, we default the hour to 00 (midnight) if it's not valid.
if isNaN dateArr[3] # from parseInt-ing '-'
dateArr[3] = 0
# now we create a date -- as UTC, manually adjusting for EDT/EST:
shareDate = moment.utc(dateArr).add(offset, 'hours')
# and check if it's in the past, updating the year if so:
if shareDate.diff(now, 'minutes') < 0
dateArr[0] = now.year() + 1
# we update/clear the year in the UI based the date validity
setYear(if shareDate.isValid() then dateArr[0] else '')
# with this check complete, we revert to the actual inputted hour:
dateArr[3] = parseInt $scheduleHour.val(), 10
# and return *that* resulting date -- again as EDT/EST:
moment.utc(dateArr).add(offset, 'hours')
# set AM/PM in the UI based on hour val
setAMPM = (hour) ->
hour = parseInt hour, 10
$ampm.text(
if 12 > hour >= 0 then 'AM'
else if 23 >= hour >= 12 then 'PM'
else ''
)
# set a scheduled date in the schedule select fields
setScheduledDate = (scheduled) ->
current = moment scheduled
if current.isValid()
current.second 0 # clear the seconds value
# update UI to the current date and time
updateFields current
# set the supplied year in the UI
setYear = (year = '') ->
$scheduleYear.text year
# change button text
updateButtonLabel = (shareNow = false) ->
$button.val(if shareNow then 'Share Now' else 'Schedule Share')
updateFields = (dateTime) ->
# scheduled creations should have a minute value of 5-minute
# granularity, but some may be edited outside the web app so...
# calculate the next 5 slot and update current
dateTime.minute Math.ceil(dateTime.minute() / 5) * 5
$scheduleMonth.val dateTime.month()
$scheduleDay.val dateTime.date()
$scheduleHour.val dateTime.hour()
$scheduleMinute.val dateTime.minute()
setAMPM dateTime.hour() # set AM/PM in the UI
setYear dateTime.year() # set year in the UI
updateButtonLabel()
$scheduleSelects.removeClass 'schedule__disabled'
updateCreatedAt = ($select) ->
shareDate = generateDate()
isValidDate = shareDate.isValid()
if isValidDate
$createdAt.val shareDate.format()
else
$createdAt.val '' # share date is invalid, so clear it
isValidDate # return whether createdAt was updated with a valid date
$scheduleHour.change ->
setAMPM parseInt(this.value, 10)
$scheduleSelects.change ->
$(this).toggleClass 'schedule__disabled', $(this).val() == '-'
isValidDate = updateCreatedAt()
# change button value based on validity of share date
updateButtonLabel(not isValidDate)
$scheduleReset.click ->
$scheduleSelects
.each(->
$select = $(this)
$select
# disable the select and...
.addClass('schedule__disabled')
# set to the first (default) value
.val $select.find('option:first').val()
)
$scheduleMinute.removeClass 'schedule__disabled'
setAMPM '' # clear AM/PM label
setYear '' # clear year label
updateButtonLabel true # reset button label to 'Share now'
# if we get a scheduled date back from the model...
if $createdAt.val()
# populate the schedule selects
setScheduledDate $createdAt.val()
else
# determine the next schedule slot and set the fields
# add 5 minutes to now to account for possible race condition where
# the schedule time becomes stale
next = moment().add(5, 'minutes')
# update UI to the next available schedule date/time
updateFields next
# update createdAt hidden input
updateCreatedAt()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment