Skip to content

Instantly share code, notes, and snippets.

@piotrze
Created November 24, 2012 19:09
Show Gist options
  • Save piotrze/4141049 to your computer and use it in GitHub Desktop.
Save piotrze/4141049 to your computer and use it in GitHub Desktop.
state machine with gui example
class views.search_filters.DateFilter extends views.AbstractRenderedComponent
constructor: ->
@createStateMachine()
@configure()
..
configure: ->
@configureFromToItems()
@element.find('.group-change').on 'click', (event) => @showMonthSelector()
@element.find('.month-selector span').on 'click', (event) => @selectMonth($(event.currentTarget))
configureFromToItems: ->
@element.find('.from-to').find('.notify-item .remove').on 'click', (event) =>
event.stopPropagation()
item = $(event.currentTarget).closest('.notify-item')
if item.attr('data-bind') == 'date_from'
@stateMachine.cleanFrom()
else
@stateMachine.cleanTo()
@element.find('.from-to').find('.notify-item').on 'click', (event) =>
@showDaySelector($(event.currentTarget))
@daysSlider = new views.search_filters.RangeWindowSlider @element.find('.from-to .range'),
onChange: (days) =>
@stateMachine.slideDate(days)
configureItem: (item) ->
item.on 'click', (event) =>
if _.isEmpty $(event.currentTarget).attr('data-value')
@showMonthSelector()
else
@showDaySelector($(event.currentTarget))
...
selectDay: (date, daySelector) ->
...
if @stateMachine.current == 'firstLevel'
@stateMachine.fillFrom new Date(date)
else
currentItem = daySelector.closest('.notify-item')
if currentItem.attr('data-bind') == 'date_from'
@stateMachine.fillFrom new Date(date)
else
@stateMachine.fillTo new Date(date)
createStateMachine: ->
@stateMachine = StateMachine.create
initial: 'firstLevel'
events: [
{name: 'fillFrom', from: 'firstLevel', to: 'fromFilled'},
{name: 'fillFrom', from: 'toFilled', to: 'fromToFilled'},
{name: 'fillTo', from: 'fromFilled', to: 'fromToFilled'},
{name: 'cleanFrom', from: 'fromFilled', to: 'firstLevel'},
{name: 'cleanFrom', from: 'fromToFilled', to: 'toFilled'},
{name: 'cleanTo', from: 'toFilled', to: 'firstLevel'}
{name: 'cleanTo', from: 'fromToFilled', to: 'fromFilled'}
{name: 'slideDate', from: 'fromFilled', to: 'fromToFilled'}
{name: 'slideDate', from: 'toFilled', to: 'fromToFilled'}
{name: 'slideDate', from: 'fromToFilled', to: 'fromToFilled'}
#on self
{name: 'fillFrom', from: 'fromToFilled', to: 'fromToFilled'},
{name: 'fillTo', from: 'fromToFilled', to: 'fromToFilled'},
{name: 'fillFrom', from: 'fromFilled', to: 'fromFilled'},
{name: 'fillTo', from: 'toFilled', to: 'toFilled'},
]
callbacks:
#callbacks for states
onfirstLevel: (event, from, to) =>
@cleanItems() if from != 'none'
@resetMonthSelector()
@element.find('.items').show()
@element.find('.from-to').hide()
item = @addItem()
@setValueOnItem(item)
@activateMonthSelecting()
onleavefirstLevel: =>
@cleanItems()
@showFromAndTo()
@showSlider()
@deactivateMonthSelecting()
onfromFilled: =>
@daysSlider.activate()
@daysSlider.reset()
@setValueOnItem @element.find('.from-to [data-bind="date_to"]')
@toDate = null
ontoFilled: =>
@daysSlider.deactivate()
@daysSlider.reset()
@setValueOnItem @element.find('.from-to [data-bind="date_from"]')
@fromDate = null
onfromToFilled: (event, from, to) =>
@daysSlider.activate()
#callbacks for events
onafterfillFrom: (event, fromState, toState, date) =>
@fromDate = date
@setValueOnItem @fromItem, @fromDate, $.datepicker.formatDate('d MM yy', date)
switch fromState
when 'fromToFilled' then @stateMachine.slideDate(@daysSlider.currentValue)
when 'toFilled' then @stateMachine.cleanTo()
onafterfillTo: (event, fromState, toState, date) =>
@toDate = date
@setValueOnItem @toItem, @toDate, $.datepicker.formatDate('d MM yy', date)
if toState == 'fromToFilled'
@daysSlider.setValue(@calculateDaysBeetwen(@fromDate, @toDate))
onafterslideDate: (event, from, to, days) =>
date = new Date(@fromDate.getTime() + days*views.search_filters.DateFilter.DAY)
@toDate = date
@setValueOnItem @toItem, @toDate, $.datepicker.formatDate('d MM yy', date)
onchangestate: (event, from, to) =>
console.log("event: #{event}, from: #{from}, to: #{to}")
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment