# Switcher widget written by Juha Mustonen / SC5
# Switches (reloads to another address) the dashboards in periodic manner # <div id=“container” data-switcher-interval=“10000” data-switcher-dashboards=“dashboard1 dashboard2”> # <%= yield %> # </div> # class DashboardSwitcher
constructor: () -> @dashboardNames = [] # Collect the dashboard names from attribute, if provided (otherwise skip switching) names = $('[data-switcher-dashboards]').first().attr('data-switcher-dashboards') || '' if names.length > 1 # Get names separated with comma or space @dashboardNames = (name.trim() for name in names.split(/[ ,]+/).filter(Boolean)) start: (interval=60000) -> interval = parseInt(interval, 10) @maxPos = @dashboardNames.length - 1 # Skip switching if no names defined if @dashboardNames.length == 0 return # Take the dashboard name from that last part of the path pathParts = window.location.pathname.split('/') @curName = pathParts[pathParts.length - 1] @curPos = @dashboardNames.indexOf(@curName) # If not found, default to first if @curPos == -1 @curPos = 0 @curName = @dashboardNames[@curPos] # instantiate switcher controls for countdown and manual switching @switcherControls = new DashboardSwitcherControls(interval, @) @switcherControls.start() if @switcherControls.present() @startLoop(interval) startLoop: (interval) -> self = @ @handle = setTimeout(() -> # Increase the position or reset back to zero self.curPos += 1 if self.curPos > self.maxPos self.curPos = 0 # Switch to new dashboard self.curName = self.dashboardNames[self.curPos] window.location.pathname = "/#{self.curName}" , interval) stopLoop: () -> clearTimeout @handle currentName: () -> @curName nextName: () -> @dashboardNames[@curPos + 1] || @dashboardNames[0] previousName: () -> @dashboardNames[@curPos - 1] || @dashboardNames[@dashboardNames.length - 1]
# Switches (hides and shows) elements within on list item # <li switcher-interval=“3000”> # <div widget-1></div> # <div widget-2></div> # <div widget-3></div> # </li> # # Supports optional switcher interval, defaults to 5sec class WidgetSwitcher
constructor: (@elements) -> @$elements = $(@elements) start: (interval=5000, control) -> self = @ @maxPos = @$elements.length - 1; @curPos = Math.min(1, @maxPos) # Show only first at start self.$elements.slice(1).hide() # instantiate switcher controls for countdown and manual switching @switcherControls = new WidgetSwitcherControls(interval, control, @) if @switcherControls.present() @switcherControls.start() else @startLoop(interval) startLoop: (interval) -> self = @ @handle = setInterval(()-> self.next() , parseInt(interval, 10)) next: () -> # Hide all at first - then show the current and ensure it uses table-cell display type @$elements.hide() $(@$elements[@curPos]).show().css('display', 'table-cell') # Increase the position or reset back to zero @curPos += 1 if @curPos > @maxPos @curPos = 0 prev: () -> @$elements.hide() previous = @curPos - 2 previous = @maxPos if previous == -1 previous = @maxPos - 1 if previous == -2 $(@$elements[previous]).show().css('display', 'table-cell') @curPos -= 1 if @curPos < 0 @curPos = @maxPos stopLoop: () -> clearInterval(@handle)
# currentName: () -> # @curName #
nextName: () -> $(@elements[@curPos]).attr("data-switcher-name") #@dashboardNames[@curPos + 1] || @dashboardNames[0]
# # previousName: () -> # @dashboardNames[@curPos - 1] || @dashboardNames[@dashboardNames.length - 1]
class WidgetSwitcherControls
arrowContent = "→" stopTimerContent = "stop timer" startTimerContent = "start timer" constructor: (interval=60000,id, widgetSwitcher) -> @currentTime = parseInt(interval, 10) @interval = parseInt(interval, 10) @$elements = $("##{id}") @widgetSwitcher = widgetSwitcher @incrementTime = 1000 # refresh every 1000 milliseconds @arrowContent = @$elements.data('next-widget-content') || WidgetSwitcherControls.arrowContent @stopTimerContent = @$elements.data('stop-widget-timer-content') || WidgetSwitcherControls.stopTimerContent @startTimerContent = @$elements.data('start-widget-timer-content') || WidgetSwitcherControls.startTimerContent @ present: () -> @$elements.length start: () -> @addElements() @$timer = $.timer(@updateTimer, @incrementTime, true) @updateWidgetName() addElements: () -> template = @$elements.find('widget-name-template') if template.length @$nextWidgetNameTemplate = template @$nextWidgetNameTemplate.remove() else @$nextWidgetNameTemplate = $("<widget-name-template>Next widget: $nextName in </widget-name-template>") @$nextWidgetNameContainer = $("<span id='dc-wid-switcher-next-name'></span>") @$countdown = $("<span id='dc-wid-switcher-countdown'></span>") @$manualPrev = $("<span id='dc-wid-switcher-prev' class='fa fa-backward'></span>"). html(@arrowContent). click () => @switchWidget(false) @$manualNext = $("<span id='dc-wid-switcher-next' class='fa fa-forward'></span>"). html(@arrowContent). click () => @switchWidget() @$switcherStopper = $("<span id='dc-wid-switcher-pause-reset' class='fa fa-pause'></span>"). html(@stopTimerContent). click(@pause) @$elements. append(@$nextWidgetNameContainer). append(@$countdown). append(@$manualPrev). append(@$switcherStopper). append(@$manualNext) pad: (number, length) => str = "#{number}" while str.length < length str = "0#{str}" str formatTime: (time) -> time = time / 10; min = parseInt(time / 6000, 10) sec = parseInt(time / 100, 10) - (min * 60) formattedMin = if min > 0 then @pad(min, 2) else "00" formattedSec = @pad(sec, 2) "#{formattedMin}:#{formattedSec}" pause: () => @$timer.toggle() if @isRunning() @$switcherStopper.removeClass('fa-pause').addClass('fa-play').html(@startTimerContent) else @$switcherStopper.removeClass('fa-play').addClass('fa-pause').html(@stopTimerContent) isRunning: () => @$switcherStopper.hasClass('fa-pause') resetCountdown: (next=true) -> @switchWidget(next) # Stop and reset timer @$timer.stop().play(true) switchWidget: (next=true) -> # Get time from form newTime = @interval if newTime > 0 @currentTime = newTime if next @widgetSwitcher.next() else @widgetSwitcher.prev(); @updateWidgetName() @updateTimeString() updateTimer: () => @updateTimeString() # If timer is complete, trigger alert if @currentTime is 0 #@pause() @resetCountdown() return # Increment timer position @currentTime -= @incrementTime if @currentTime < 0 @currentTime = 0 updateWidgetName: () -> @$nextWidgetNameContainer.html( @$nextWidgetNameTemplate.html().replace('$nextName', @widgetSwitcher.nextName()) ) updateTimeString: () -> timeString = @formatTime(@currentTime) @$countdown.html(timeString)
# Adds a countdown timer to show when next dashboard will appear # TODO: # - show the name of the next dashboard # - add controls for manually cycling through dashboards class DashboardSwitcherControls
arrowContent = "→" stopTimerContent = "stop timer" startTimerContent = "start timer" constructor: (interval=60000, dashboardSwitcher) -> @currentTime = parseInt(interval, 10) @interval = parseInt(interval, 10) @$elements = $('#dc-switcher-controls') @dashboardSwitcher = dashboardSwitcher @incrementTime = 1000 # refresh every 1000 milliseconds @arrowContent = @$elements.data('next-dashboard-content') || DashboardSwitcherControls.arrowContent @stopTimerContent = @$elements.data('stop-timer-content') || DashboardSwitcherControls.stopTimerContent @startTimerContent = @$elements.data('start-timer-content') || DashboardSwitcherControls.startTimerContent @ present: () -> @$elements.length start: () -> @addElements() @$timer = $.timer(@updateTimer, @incrementTime, true) addElements: () -> template = @$elements.find('dashboard-name-template') if template.length @$nextDashboardNameTemplate = template @$nextDashboardNameTemplate.remove() else @$nextDashboardNameTemplate = $("<dashboard-name-template>Next dashboard: $nextName in </dashboard-name-template>") @$nextDashboardNameContainer = $("<span id='dc-switcher-next-name'></span>") @$countdown = $("<span id='dc-switcher-countdown'></span>") @$manualSwitcher = $("<span id='dc-switcher-next' class='fa fa-forward'></span>"). html(@arrowContent). click () => location.href = "/#{@dashboardSwitcher.nextName()}" @$switcherStopper = $("<span id='dc-switcher-pause-reset' class='fa fa-pause'></span>"). html(@stopTimerContent). click(@pause) @$elements. append(@$nextDashboardNameContainer). append(@$countdown). append(@$manualSwitcher). append(@$switcherStopper) formatTime: (time) -> time = time / 10; min = parseInt(time / 6000, 10) sec = parseInt(time / 100, 10) - (min * 60) "#{(if min > 0 then @pad(min, 2) else "00")}:#{@pad(sec, 2)}" pad: (number, length) => str = "#{number}" while str.length < length str = "0#{str}" str pause: () => @$timer.toggle() if @isRunning() @dashboardSwitcher.stopLoop() @$switcherStopper.removeClass('fa-pause').addClass('fa-play').html(@startTimerContent) else @dashboardSwitcher.startLoop @currentTime @$switcherStopper.removeClass('fa-play').addClass('fa-pause').html(@stopTimerContent) isRunning: () => @$switcherStopper.hasClass('fa-pause') resetCountdown: () -> # Get time from form newTime = @interval if newTime > 0 @currentTime = newTime # Stop and reset timer @$timer.stop().once() updateTimer: () => # Update dashboard name @$nextDashboardNameContainer.html( @$nextDashboardNameTemplate.html().replace('$nextName', @dashboardSwitcher.nextName()) ) # Output timer position timeString = @formatTime(@currentTime) @$countdown.html(timeString) # If timer is complete, trigger alert if @currentTime is 0 @pause() @resetCountdown() return # Increment timer position @currentTime -= @incrementTime if @currentTime < 0 @currentTime = 0
# Expose our API Dashing.DashboardSwitcher = DashboardSwitcher Dashing.WidgetSwitcher = WidgetSwitcher Dashing.DashboardSwitcherControls = DashboardSwitcherControls Dashing.WidgetSwitcherControls = WidgetSwitcherControls
# Dashboard loaded and ready Dashing.on 'ready', ->
# If multiple widgets per list item, switch them periodically $('.gridster li').each (index, listItem) -> $listItem = $(listItem) # Take the element(s) right under the li $widgets = $listItem.children('div') if $widgets.length > 1 switcher = new WidgetSwitcher $widgets interval = $listItem.attr('data-switcher-interval') control = $listItem.attr('data-switcher-control') switcher.start(interval or 5000, control) # If multiple dashboards defined (using data-swticher-dashboards="board1 board2") $container = $('#container') ditcher = new DashboardSwitcher() ditcher.start($container.attr('data-switcher-interval') or 60000)