Last active
July 22, 2018 13:19
-
-
Save scottserok/bce447843ec19411880fcfd068c695a7 to your computer and use it in GitHub Desktop.
Multi-step form with support for datepicker and chosen-select written in Coffeescript.
This file contains hidden or 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
# Abstract Wizard to assist user with building a resource step by step. | |
# Include https://daneden.github.io/animate.css/ for animations. | |
# | |
# <div class="step"> are icons used to indicate which step the user is currently in | |
# | |
# <fieldset> are used to define what is displayed in each step of the form | |
# | |
# There should be equal number of .step elements as there are fieldset elements | |
# Create an instance of App.Wizard with the div ID of the modal | |
# 1 form per App.Wizard instance | |
# | |
# @param [String] modal_id The div that the multi-step form elements resides in. | |
# | |
# @example | |
# %a{ href: '#', data: { toggle: 'modal', target: '#myModal' } } | |
# Start | |
# #myModal.modal.fade{ role: 'dialog' } | |
# .modal-dialog | |
# .modal-content | |
# .modal-body | |
# .steps | |
# .step | |
# .step | |
# %form{ action: '/' } | |
# %fieldset | |
# %label | |
# Step 1 | |
# %input | |
# .step-next | |
# Next | |
# %fieldset | |
# %label | |
# Step 2 | |
# %input | |
# %a{ type: 'submit' } | |
# :javascript | |
# new App.Wizard('#myModal'); | |
class App.Wizard | |
constructor: (@modal_id) -> | |
@current_step = 0 | |
@high_water_mark = @current_step | |
@fieldsets = $ @modal_id + ' fieldset' | |
@steps = $ @modal_id + ' .step' | |
$ @fieldsets | |
.first() | |
.addClass 'active' | |
$ @steps | |
.first() | |
.addClass 'active' | |
$ @modal_id + ' .datepicker' | |
.datepicker | |
onSelect: (date_string) -> | |
$(@).siblings('input').val(date_string) | |
@setupStepNavigation() | |
# setup Next Step and Prev Step buttons and setup step icon click event | |
setupStepNavigation: -> | |
$ '.step-next' | |
.click => | |
@nextSet() | |
$ '.step-prev' | |
.click => | |
@prevSet() | |
for step, index in $ @modal_id + ' .step' | |
$ step | |
.data 'step-id', index # start numbering at 0 | |
$ step | |
.click (e) => | |
i = $(e.currentTarget).data 'step-id' | |
if i <= @high_water_mark | |
@goToSet i | |
else | |
@goToSet @high_water_mark | |
# click on a step icon will take to you that step without animation | |
goToSet: (n) -> | |
@current_step = n | |
$ @steps | |
.removeClass 'active' | |
$ @fieldsets | |
.removeClass 'active animated fadeOutLeft fadeOutRight fadeInLeft fadeInRight' | |
$ @steps[@current_step] | |
.addClass 'active' | |
$ @fieldsets[@current_step] | |
.addClass 'active' | |
# animate to next fieldset | |
nextSet: -> | |
if @currentStepIsValid() | |
if @current_step >= @fieldsets.size() - 1 | |
@submitForm() | |
else | |
@current_step = @current_step + 1 | |
$ @modal_id + ' fieldset.active' | |
.addClass 'animated' | |
.addClass 'fadeOutLeft' | |
setTimeout => | |
$ @fieldsets[@current_step-1] | |
.removeClass 'active animated fadeOutLeft fadeOutRight fadeInLeft fadeInRight' | |
$ @fieldsets[@current_step] | |
.addClass 'active' | |
$ @fieldsets[@current_step] | |
.addClass 'animated' | |
.addClass 'fadeInRight' | |
, 500 | |
@showSet @current_step | |
# animate to previous fieldset | |
prevSet: -> | |
if @current_step > 0 | |
@current_step = @current_step - 1 | |
$ @modal_id + ' fieldset.active' | |
.addClass 'animated' | |
.addClass 'fadeOutRight' | |
setTimeout => | |
$ @fieldsets[@current_step+1] | |
.removeClass 'active animated fadeOutLeft fadeOutRight fadeInLeft fadeInRight' | |
$ @fieldsets[@current_step] | |
.addClass 'active' | |
$ @fieldsets[@current_step] | |
.addClass 'animated' | |
.addClass 'fadeInLeft' | |
, 500 | |
@showSet @current_step | |
# comment routine when showing a fieldset | |
showSet: (n) -> | |
@current_step = n | |
if @current_step > @high_water_mark | |
@high_water_mark = @current_step | |
$ @modal_id + ' .step.active' | |
.removeClass 'active' | |
$ $(@modal_id + ' .step')[n-1] | |
.addClass 'finished' | |
$ $(@modal_id + ' .step')[n] | |
.addClass 'active' | |
$ @modal_id + ' form fieldset.active input' | |
.focus() | |
# minimal input validation and animation | |
currentStepIsValid: -> | |
if $(@modal_id + ' form fieldset.active select.required')[0] | |
if $(@modal_id + ' form fieldset.active select.required').val()?.length > 0 | |
return true | |
else | |
$ @modal_id + ' form fieldset.active select.required' | |
.parent() | |
.addClass 'animated shake' | |
return false | |
if $(@modal_id + ' form fieldset.active input.required').val() == '' | |
$ @modal_id + ' form fieldset.active input.required, form fieldset.active .datepicker' | |
.addClass 'animated shake' | |
return false | |
true | |
submitForm: -> | |
$ @modal_id + ' form' | |
.submit() |
This file contains hidden or 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
.wizard { overflow:hidden; } | |
.wizard > .steps { text-align:center; margin-top:20px; } | |
/* Adjust the height, width, and padding if you won't be putting icons inside of the .step div */ | |
.wizard > .steps > .step { | |
height: 25px; | |
width: 25px; | |
padding: 3px; | |
margin: 0 2px; | |
background-color: #bbbbbb; | |
border: none; | |
border-radius: 50%; | |
display: inline-block; | |
opacity: 0.5; | |
} | |
.wizard > .steps > .step.active { opacity:1; } | |
.wizard > .steps > .step.finished { background-color:#4CAF50; } | |
.wizard > fieldset { margin-top:20px; display:none; width:100%; } | |
.wizard > fieldset .ui-datepicker-inline { margin:auto; } | |
.wizard > fieldset.active { display:inline; } | |
.wizard > fieldset input.required { border:solid 1px red; } | |
.wizard > fieldset .chosen-drop { position: inherit; } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment