197 lines
5.3 KiB
CoffeeScript
197 lines
5.3 KiB
CoffeeScript
# -------------------------------------------------------------------
|
|
# plugins / wizard.coffee
|
|
|
|
|
|
setElementWidth = ($el, width) ->
|
|
$el.css
|
|
'width': width
|
|
'max-width': width
|
|
'min-width': width
|
|
|
|
|
|
###
|
|
* @class Wizard
|
|
###
|
|
|
|
Wizard = ($element, options={}) ->
|
|
@options = $.extend({}, Wizard.DEFAULTS, options || {})
|
|
@$element = $element
|
|
@$wrapper = $('.wizard-wrapper', @$element)
|
|
@$steps = $('.wizard-steps', @$wrapper)
|
|
@$step_items = $('> li', @$steps)
|
|
@steps_count = @$step_items.length
|
|
@$content = $('.wizard-content', @$element)
|
|
@current_step = null
|
|
@$current_item = null
|
|
@isFreeze = false
|
|
@isRtl = $('body').hasClass('right-to-left')
|
|
|
|
@resizeStepItems()
|
|
|
|
$cur_step = $('> li.active', @$steps)
|
|
$cur_step = $('> li:first-child', @$steps) if $cur_step.length is 0
|
|
|
|
@$current_item = $cur_step.addClass('active')
|
|
@current_step = $cur_step.index() + 1
|
|
|
|
$($cur_step.attr('data-target'), @$content).css({ display: 'block' })
|
|
@placeStepItems()
|
|
@_setPrevItemStates(@current_step - 1)
|
|
|
|
$(window).on 'pa.resize.wizard', =>
|
|
$.proxy(@resizeStepItems, @)()
|
|
$.proxy(@placeStepItems, @)()
|
|
|
|
self = @
|
|
@$steps.on 'click', '> li', ->
|
|
$this = $(@)
|
|
self.setCurrentStep($this.index() + 1) if $this.hasClass('completed')
|
|
@
|
|
|
|
#Defaults
|
|
Wizard.DEFAULTS =
|
|
step_item_min_width: 200
|
|
onChange: null
|
|
onFinish: null
|
|
|
|
###
|
|
* Resize steps
|
|
###
|
|
Wizard.prototype.resizeStepItems = ->
|
|
if @$element.width() > (Wizard.DEFAULTS.step_item_min_width * @$step_items.length)
|
|
width = Math.floor(@$element.width() / @$step_items.length)
|
|
else
|
|
width = Wizard.DEFAULTS.step_item_min_width
|
|
@$step_items.each -> setElementWidth $(@), width
|
|
|
|
###
|
|
* Move steps
|
|
###
|
|
Wizard.prototype.placeStepItems = ->
|
|
offset = 0
|
|
item_position = @$current_item.position()
|
|
element_width = @$element.outerWidth()
|
|
steps_width = @$steps.outerWidth()
|
|
current_item_width = @$current_item.outerWidth()
|
|
d = (element_width - current_item_width) / 2
|
|
|
|
if not @isRtl
|
|
if element_width < steps_width && item_position.left > d
|
|
offset = -1 * item_position.left + d
|
|
offset = -1 * steps_width + element_width if (steps_width + offset) < element_width
|
|
@$steps.css({ left: offset })
|
|
else
|
|
item_position_right = steps_width - item_position.left - current_item_width
|
|
if element_width < steps_width && item_position_right > d
|
|
offset = -1 * item_position_right + d
|
|
offset = -1 * steps_width + element_width if (steps_width + offset) < element_width
|
|
@$steps.css({ right: offset })
|
|
|
|
###
|
|
* Change step
|
|
*
|
|
* @param {Integer} step
|
|
###
|
|
Wizard.prototype.setCurrentStep = (step) ->
|
|
return if @isFreeze
|
|
$(@$current_item.attr('data-target'), @$content).css({ opacity: 1 }).animate({ opacity: 0 }, 200, =>
|
|
$(@$current_item.attr('data-target'), @$content).attr('style', '')
|
|
|
|
@_clearItemStates(step - 1)
|
|
@$current_item = @$step_items.eq(step - 1).addClass('active')
|
|
@current_step = step
|
|
@_setPrevItemStates(step - 1)
|
|
$(@$current_item.attr('data-target'), @$content).css({ display: 'block', opacity: 0 }).animate({ opacity: 1 }, 200, =>
|
|
$.proxy(@options.onChange, @)() if @options.onChange
|
|
@placeStepItems()
|
|
)
|
|
)
|
|
|
|
###
|
|
* Move to next step
|
|
###
|
|
Wizard.prototype.nextStep = ->
|
|
return if @isFreeze
|
|
if @current_step >= @steps_count
|
|
$.proxy(@options.onFinish, @)() if @options.onFinish
|
|
return
|
|
@$current_item.removeClass('active').addClass('completed')
|
|
@setCurrentStep(@current_step + 1)
|
|
|
|
###
|
|
* Move to previous step
|
|
###
|
|
Wizard.prototype.prevStep = ->
|
|
return if @isFreeze
|
|
return if @current_step <= 1
|
|
@setCurrentStep(@current_step - 1)
|
|
|
|
###
|
|
* Get current step
|
|
###
|
|
Wizard.prototype.currentStep = ->
|
|
@current_step
|
|
|
|
###
|
|
* @param {Integer} start_index
|
|
###
|
|
Wizard.prototype._clearItemStates = (start_index) ->
|
|
for i in [start_index...@steps_count]
|
|
@$step_items.eq(i).removeClass('active').removeClass('completed')
|
|
|
|
###
|
|
* @param {Integer} end_index
|
|
###
|
|
Wizard.prototype._setPrevItemStates = (end_index) ->
|
|
for i in [0...end_index]
|
|
@$step_items.eq(i).addClass('completed')
|
|
|
|
###
|
|
* Freeze wizard
|
|
###
|
|
Wizard.prototype.freeze = ->
|
|
@isFreeze = true
|
|
@$element.addClass('freeze')
|
|
|
|
###
|
|
* Unfreeze wizard
|
|
###
|
|
Wizard.prototype.unfreeze = ->
|
|
@isFreeze = false
|
|
@$element.removeClass('freeze')
|
|
|
|
###
|
|
* jQuery Wizard plugin initialization
|
|
*
|
|
* @param {Object|String} options
|
|
* @param {Object} attrs
|
|
###
|
|
$.fn.pixelWizard = (options, attrs) ->
|
|
methodReturn = undefined
|
|
$set = @.each ->
|
|
$this = $(@)
|
|
|
|
if not $.data(this, 'pixelWizard')
|
|
$.data(this, 'pixelWizard', new Wizard($this, options))
|
|
else if options and typeof(options) is 'string'
|
|
wizard_obj = $.data(this, 'pixelWizard')
|
|
|
|
if options is 'setCurrentStep'
|
|
wizard_obj.setCurrentStep(attrs)
|
|
else if options is 'currentStep'
|
|
methodReturn = wizard_obj.currentStep()
|
|
else if options is 'nextStep'
|
|
wizard_obj.nextStep()
|
|
else if options is 'prevStep'
|
|
wizard_obj.prevStep()
|
|
else if options is 'freeze'
|
|
wizard_obj.freeze()
|
|
else if options is 'unfreeze'
|
|
wizard_obj.unfreeze()
|
|
else if options is 'resizeSteps'
|
|
wizard_obj.resizeStepItems()
|
|
|
|
return (if methodReturn is undefined then $set else methodReturn)
|
|
|
|
$.fn.pixelWizard.Constructor = Wizard
|