Created
March 31, 2017 21:08
-
-
Save gscottolson/e73298f1296e111071ff28b8ead40e38 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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