commit 6e82064d5827ca4f1d67a8d6d7f1699183adbda8 Author: Vivek Teega Date: Thu Feb 28 13:46:20 2019 +0530 First commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..13f0f82 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +Fullscreen Form Interface +========= + +An experimental fullscreen form concept where the idea is to allow distraction-free form filling with some fancy animations when moving between form fields. + +[Article on Codrops](http://tympanus.net/codrops/?p=19520) + +[Demo](http://tympanus.net/Development/FullscreenForm/) + +Integrate or build upon it for free in your personal or commercial projects. Don't republish, redistribute or sell "as-is". + +Read more here: [License](http://tympanus.net/codrops/licensing/) + +[© Codrops 2014](http://www.codrops.com) \ No newline at end of file diff --git a/css/component.css b/css/component.css new file mode 100755 index 0000000..e998a2d --- /dev/null +++ b/css/component.css @@ -0,0 +1,889 @@ +/* Main form wrapper */ +.fs-form-wrap { + position: relative; + width: 100%; + height: 100%; + color: #fff; +} + +.overview .fs-form-wrap { + height: auto; +} + +/* Title */ +.fs-title { + position: absolute; + top: 0; + left: 0; + margin: 0; + padding: 40px; + width: 100%; +} + +.fs-title h1 { + margin: 0; +} + +/* Form */ +.fs-form { + position: relative; + text-align: left; + font-size: 2.5em; +} + +.no-js .fs-form { + padding: 0 0 6em 0; +} + +/* Views (fullscreen and overview)*/ +.fs-form-full { + top: 32%; + margin: 0 auto; + width: 70%; +} + +.fs-form-full, +.fs-message-error { + max-width: 960px; +} + +.fs-form-overview { + padding: 2.5em 30% 6em; + width: 100%; + height: 100%; + background: #fffed8; + color: #3b3f45; + font-size: 1.2em; +} + +.fs-form-overview .fs-fields::before { + display: block; + margin-bottom: 2.5em; + color: #3b3f45; + content: 'Parsed FLO data'; + font-weight: 700; + font-size: 1.85em; +} + +/* Switch view animation (we hide the current view, switch the view class and show it again) */ +.fs-form.fs-show { + -webkit-animation: animFadeIn 0.5s; + animation: animFadeIn 0.5s; +} + +@-webkit-keyframes animFadeIn { + 0% { opacity: 0; } + 100% { opacity: 1; } +} + +@keyframes animFadeIn { + 0% { opacity: 0; } + 100% { opacity: 1; } +} + +.fs-form.fs-show .fs-fields { + -webkit-animation: animMove 0.5s; + animation: animMove 0.5s; +} + +@-webkit-keyframes animMove { + from { top: 100px; } +} + +@keyframes animMove { + from { top: 100px; } +} /* we need to use top here because otherwise all our fixed elements will become absolute */ + +/* Visibility control of elements */ +.fs-form-full .fs-fields > li, +.fs-nav-dots, +.fs-progress, +.fs-numbers, +button.fs-continue, +.fs-message-error, +.fs-message-final { + visibility: hidden; +} + +.no-js .fs-form-full .fs-fields > li { + visibility: visible; +} + +.fs-show { + visibility: visible !important; +} + +/* Some general styles */ +.fs-form-wrap button { + border: none; + background: none; +} + +.fs-form-wrap button[disabled] { + opacity: 0.3; + pointer-events: none; +} + +.fs-form-wrap input:focus, +.fs-form-wrap button:focus { + outline: none; +} + +/* Hide the submit button */ +.fs-form .fs-submit { + display: none; +} + +/* Fields */ +.fs-fields { + position: relative; + margin: 0 auto; + padding: 0; + top: 0; + list-style: none; +} + +.fs-form-overview ol { + max-width: ; +} + +.fs-fields > li { + position: relative; + z-index: 1; + margin: 0; + padding: 0; + border: none; +} + +.fs-fields > li:hover { + z-index: 999; +} + +.js .fs-form-full .fs-fields > li { + position: absolute; + width: 100%; +} + +.fs-form-overview .fs-fields > li, +.no-js .fs-form .fs-fields > li { + margin: 1em 0 2em; + padding: 0 0 2em 0; + border-bottom: 2px solid rgba(0,0,0,0.1); +} + +/* Labels & info */ +.fs-fields > li label { + position: relative; +} + +.fs-fields > li label.fs-field-label { + display: inline-block; + padding: 0 5px 1em 0; + font-weight: 700; + pointer-events: none; +} + +.fs-form-full .fs-fields > li label[data-info]::after { + position: relative; + display: inline-block; + margin-left: 10px; + width: 24px; + height: 24px; + border: 2px solid rgba(0,0,0,0.4); + color: rgba(0,0,0,0.4); + border-radius: 50%; + content: 'i'; + vertical-align: top; + text-align: center; + font-weight: 700; + font-style: italic; + font-size: 14px; + font-family: Georgia, serif; + line-height: 20px; + cursor: pointer; + pointer-events: auto; +} + +.fs-form-full .fs-fields > li label[data-info]::before { + position: absolute; + bottom: 100%; + left: 0; + padding: 0 0 10px; + min-width: 200px; + content: attr(data-info); + font-size: 0.4em; + color: #6a7b7e; + opacity: 0; + -webkit-transition: opacity 0.3s, -webkit-transform 0.3s; + transition: opacity 0.3s, transform 0.3s; + -webkit-transform: translate3d(0,-5px,0); + transform: translate3d(0,-5px,0); + pointer-events: none; +} + +.fs-form-full .fs-fields > li label[data-info]:hover::before { + opacity: 1; + -webkit-transform: translate3d(0,0,0); + transform: translate3d(0,0,0); +} + +.fs-form-full .fs-fields > li label:hover ~ .fs-info, +.fs-form-full .fs-fields > li .fs-info:hover { + opacity: 1; + -webkit-transform: translateY(0); + transform: translateY(0); + pointer-events: auto; +} + +/* Inputs */ +.fs-fields input { + display: block; + margin: 0; + padding: 0 0 0.15em; + width: 100%; + border: none; + border-bottom: 2px solid rgba(0,0,0,0.2); + background-color: transparent; + color: #fffed8; + text-overflow: ellipsis; + font-weight: bold; + font-size: 1.5em; + border-radius: 0; +} + +.fs-fields input:invalid { + box-shadow: none; /* removes red shadow in FF*/ +} + +.fs-form-overview .fs-fields input { + border-bottom-color: transparent; + color: rgba(0,0,0,0.5); +} + +.fs-fields [required] { + background-image: url(../img/abacusstar.svg); + background-position: top right; + background-size: 18px; + background-repeat: no-repeat; +} + +.fs-fields input:focus { + background-color: #3b3f45; /* Fixes chrome bug with placeholder */ +} + +.fs-form-overview .fs-fields input:focus { + background-color: #fffed8; /* Fixes chrome bug with placeholder */ +} + +.fs-form-overview .fs-fields input { + font-size: 1.2em; +} + +.fs-fields .fs-radio-custom input[type="radio"] { + position: absolute; + display: block; + margin: 30px auto 20px; + margin: 0 auto 20px; + width: 100%; + height: 100%; + opacity: 0; + cursor: pointer; +} + +.fs-fields > li .fs-radio-custom span { + float: left; + position: relative; + margin-right: 3%; + padding: 10px; + max-width: 200px; + width: 30%; + text-align: center; + font-weight: 700; + font-size: 50%; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +.fs-fields > li .fs-radio-custom span label { + color: rgba(0,0,0,0.4); + -webkit-transition: color 0.3s; + transition: color 0.3s; +} + +.fs-form-overview .fs-fields > li .fs-radio-custom span { + max-width: 140px; +} + +.fs-form-overview .fs-fields > li .fs-radio-custom span { + font-size: 75%; +} + +.fs-fields > li .fs-radio-custom label { + display: block; + padding-top: 100%; + width: 100%; + height: 100%; + cursor: pointer; +} + +.fs-fields .fs-radio-custom label::after { + position: absolute; + top: 50%; + left: 50%; + width: 100%; + height: 100%; + background-position: 50% 0%; + background-size: 85%; + background-repeat: no-repeat; + content: ''; + opacity: 0.5; + -webkit-transition: opacity 0.2s; + transition: opacity 0.2s; + -webkit-transform: translate(-50%,-50%); + transform: translate(-50%,-50%); +} + +.fs-fields .fs-radio-custom label.radio-mobile::after { + background-image: url(../img/mobile.svg); +} + +.fs-fields .fs-radio-custom label.radio-social::after { + background-image: url(../img/social.svg); +} + +.fs-fields .fs-radio-custom label.radio-conversion::after { + background-image: url(../img/conversion.svg); +} + +.fs-fields .fs-radio-custom label:hover::after, +.fs-fields input[type="radio"]:focus + label::after, +.fs-fields input[type="radio"]:checked + label::after { + opacity: 1; +} + +.fs-fields .fs-radio-custom input[type="radio"]:checked + label { + color: #fffed8; +} + +.fs-form-overview .fs-fields .fs-radio-custom input[type="radio"]:checked + label { + color: rgba(0,0,0,0.8); +} + +.fs-fields textarea { + padding: 0.25em; + width: 100%; + height: 200px; + border: 2px solid rgba(0,0,0,0.2); + background-color: transparent; + color: #fffed8; + font-weight: 700; + font-size: 0.85em; + resize: none; +} + +.fs-form-overview .fs-fields textarea { + height: 100px; + color: rgba(0,0,0,0.5); +} + +.fs-fields textarea:focus { + outline: none; +} + +. .fs-fields textarea { + padding: 0; + border-color: transparent; +} + +.fs-form-overview .fs-fields textarea:focus { + background: #fffed8; +} + +.fs-form div.cs-select.cs-skin-boxes { + display: block; +} + +.fs-form-overview .cs-skin-boxes > span { + border-radius: 5px; + width: 90px; + height: 70px; + font-size: 0.8em; +} + +.fs-form-overview .cs-skin-boxes > span::before { + padding-top: 50px; + box-shadow: 0 20px 0 #292c30, inset 0 -5px #292c30; +} + +.fs-fields input.fs-mark { + padding-left: 1em; + background-image: url(../img/dollar.svg); + background-position: 0% 0.15em; + background-size: auto 75%; + background-repeat: no-repeat; +} + +.fs-fields input.fs-mark[required] { + background-image: url(../img/dollar.svg), url(../img/abacusstar.svg); + background-position: 0% 0.15em, top right; + background-size: auto 75%, 18px; + background-repeat: no-repeat; +} + +/* placeholder */ +.fs-fields input::-webkit-input-placeholder, +.fs-fields textarea::-webkit-input-placeholder { + color: rgba(0,0,0,0.1); +} + +.fs-fields input:-moz-placeholder, +.fs-fields textarea:-moz-placeholder { + color: rgba(0,0,0,0.1); +} + +.fs-fields input::-moz-placeholder, +.fs-fields textarea::-moz-placeholder { + color: rgba(0,0,0,0.1); +} + +.fs-fields input:-ms-input-placeholder, +.fs-fields textarea:-ms-input-placeholder { + color: rgba(0,0,0,0.1); +} + +/* Hide placeholder when focused in Webkit browsers */ +.fs-fields input:focus::-webkit-input-placeholder { + color: transparent; +} + +/* Dot navigation */ +.fs-nav-dots { + position: absolute; + top: 50%; + right: 60px; + left: auto; + -webkit-transform: translateY(-50%); + transform: translateY(-50%); +} + +.fs-nav-dots button { + position: relative; + display: block; + padding: 0; + margin: 16px 0; + width: 16px; + height: 16px; + border-radius: 50%; + background: transparent; + -webkit-transition: -webkit-transform 0.3s ease, opacity 0.3s ease; + transition: transform 0.3s ease, opacity 0.3s ease; +} + +.fs-nav-dots button::before, +.fs-nav-dots button::after { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + border-radius: 50%; + background-color: rgba(0,0,0,0.5); + content: ''; + text-indent: 0; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; +} + +.fs-nav-dots button::after { + background-color: rgba(0,0,0,0.4); + -webkit-transform: perspective(1000px) rotate3d(0,1,0,180deg); + transform: perspective(1000px) rotate3d(0,1,0,180deg); +} + +.fs-nav-dots button.fs-dot-current { + -webkit-transform: perspective(1000px) rotate3d(0,1,0,180deg); + transform: perspective(1000px) rotate3d(0,1,0,180deg); +} + +.fs-nav-dots button:hover::before, +.fs-nav-dots button.fs-dot-current::before { + background: #fffed8; +} + +/* Progress bar */ +.fs-progress { + position: absolute; + top: 0; + width: 0%; + height: 0.5em; + background: #fffed8; + -webkit-transition: width 0.3s ease-in-out; + transition: width 0.3s ease-in-out; +} + +/* Number indicator */ +.fs-numbers { + position: absolute; + top: 0; + right: 0; + overflow: hidden; + color: rgba(0,0,0,0.4); + margin: 40px; + width: 2em; + font-weight: 700; + font-size: 2em; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + cursor: default; +} + +.fs-numbers:after { + position: absolute; + width: 100%; + text-align: center; + content: '/'; + font-weight: 300; + opacity: 0.4; + left: 0; +} + +.fs-numbers span { + float: right; + width: 40%; + text-align: center; +} + +.fs-numbers .fs-number-current { + float: left; +} + +.fs-numbers .fs-number-new { + position: absolute; + left: 0; + -webkit-transform: translateY(100%); + transform: translateY(100%); +} + +/* Animations for numbers */ +/* Show next number */ +.fs-numbers.fs-show-next .fs-number-new { + -webkit-animation: animMoveUpFromDown 0.4s both; + animation: animMoveUpFromDown 0.4s both; +} + +@-webkit-keyframes animMoveUpFromDown { + from { -webkit-transform: translateY(100%); } + to { -webkit-transform: translateY(0); } +} + +@keyframes animMoveUpFromDown { + from { -webkit-transform: translateY(100%); transform: translateY(100%); } + to { -webkit-transform: translateY(0); transform: translateY(0); } +} + +.fs-numbers.fs-show-next .fs-number-current { + -webkit-animation: animMoveUp 0.4s both; + animation: animMoveUp 0.4s both; +} + +@-webkit-keyframes animMoveUp { + to { -webkit-transform: translateY(-100%); } +} + +@keyframes animMoveUp { + to { -webkit-transform: translateY(-100%); transform: translateY(-100%); } +} + +/* Show previous number */ +.fs-numbers.fs-show-prev .fs-number-new { + -webkit-animation: animMoveDownFromUp 0.4s both; + animation: animMoveDownFromUp 0.4s both; +} + +@-webkit-keyframes animMoveDownFromUp { + from { -webkit-transform: translateY(-100%); } + to { -webkit-transform: translateY(0); } +} + +@keyframes animMoveDownFromUp { + from { -webkit-transform: translateY(-100%); transform: translateY(-100%); } + to { -webkit-transform: translateY(0); transform: translateY(0); } +} + +.fs-numbers.fs-show-prev .fs-number-current { + -webkit-animation: animMoveDown 0.4s both; + animation: animMoveDown 0.4s both; +} + +@-webkit-keyframes animMoveDown { + to { -webkit-transform: translateY(100%); } +} + +@keyframes animMoveDown { + to { -webkit-transform: translateY(100%); transform: translateY(100%); } +} + +/* Continue button and submit button */ +button.fs-submit, +button.fs-continue { + padding: 0.6em 1.5em; + border: 3px solid #232529; + border-radius: 40px; + font-weight: 700; + color: rgba(0,0,0,0.4); +} + +.fs-form-overview .fs-submit, +.no-js .fs-form .fs-submit { + display: block; + float: right; +} + +.fs-form-overview .fs-submit { + border-color: #232529; + color: #232529; +} + +button.fs-continue { + position: absolute; + right: 0; + bottom: 0; + margin: 0 40px 60px 0; + font-size: 1.25em; +} + +button.fs-submit:hover, +button.fs-submit:focus, +button.fs-continue:hover { + background: #232529; + color: #fff; +} + +.fs-continue::after { + position: absolute; + top: 100%; + left: 0; + width: 100%; + line-height: 3; + text-align: center; + background: transparent; + color: rgba(0,0,0,0.3); + content: 'or press ENTER'; + font-size: 0.65em; + pointer-events: none; +} + +/* Error message */ +.fs-message-error { + position: absolute; + bottom: 75%; + left: 50%; + z-index: 800; + max-width: 960px; + width: 70%; + color: #eb7e7f; + font-weight: 700; + font-size: 1em; + opacity: 0; + -webkit-transform: translate3d(-50%,-5px,0); + transform: translate3d(-50%,-5px,0); +} + +.fs-message-error.fs-show { + opacity: 1; + -webkit-transition: -webkit-transform 0.3s, opacity 0.3s; + transition: transform 0.3s, opacity 0.3s; + -webkit-transform: translate3d(-50%,0,0); + transform: translate3d(-50%,0,0); +} + +/* Animation classes & animations */ +.fs-form li.fs-current { + visibility: visible; +} + +.fs-form li.fs-hide, +.fs-form li.fs-show { + pointer-events: none; +} + +/* Hide current li when navigating to next question */ +.fs-form .fs-display-next .fs-hide { + visibility: visible; +} + +.fs-form .fs-display-next .fs-hide .fs-anim-lower, +.fs-form .fs-display-next .fs-hide .fs-anim-upper { + -webkit-animation: animHideNext 0.5s cubic-bezier(0.7,0,0.3,1) forwards; + animation: animHideNext 0.5s cubic-bezier(0.7,0,0.3,1) forwards; +} + +.fs-form .fs-display-next .fs-hide .fs-anim-lower { + -webkit-animation-delay: 0.1s; + animation-delay: 0.1s; +} + +@-webkit-keyframes animHideNext { + to { opacity: 0; -webkit-transform: translate3d(0,-500px,0); } +} + +@keyframes animHideNext { + to { opacity: 0; -webkit-transform: translate3d(0,-500px,0); transform: translate3d(0,-500px,0); } +} + +/* Show new li when navigating to next question */ +.fs-form .fs-display-next .fs-show .fs-anim-lower, +.fs-form .fs-display-next .fs-show .fs-anim-upper { + -webkit-animation: animShowNext 0.5s cubic-bezier(0.7,0,0.3,1) both 0.15s; + animation: animShowNext 0.5s cubic-bezier(0.7,0,0.3,1) both 0.15s; +} + +.fs-form .fs-display-next .fs-show .fs-anim-lower { + -webkit-animation-delay: 0.25s; + animation-delay: 0.25s; +} + +@-webkit-keyframes animShowNext { + from { opacity: 0; -webkit-transform: translate3d(0,500px,0); } +} + +@keyframes animShowNext { + from { opacity: 0; -webkit-transform: translate3d(0,500px,0); transform: translate3d(0,500px,0); } +} + +/* Hide current li when navigating to previous question */ +.fs-form .fs-display-prev .fs-hide { + visibility: visible; +} + +.fs-form .fs-display-prev .fs-hide .fs-anim-lower, +.fs-form .fs-display-prev .fs-hide .fs-anim-upper { + -webkit-animation: animHidePrev 0.5s cubic-bezier(0.7,0,0.3,1) forwards; + animation: animHidePrev 0.5s cubic-bezier(0.7,0,0.3,1) forwards; +} + +.fs-form .fs-display-prev .fs-hide .fs-anim-upper { + -webkit-animation-delay: 0.1s; + animation-delay: 0.1s; +} + +@-webkit-keyframes animHidePrev { + to { opacity: 0; -webkit-transform: translate3d(0,500px,0); } +} + +@keyframes animHidePrev { + to { opacity: 0; -webkit-transform: translate3d(0,500px,0); transform: translate3d(0,500px,0); } +} + +/* Show new li when navigating to previous question */ +.fs-form .fs-display-prev .fs-show .fs-anim-lower, +.fs-form .fs-display-prev .fs-show .fs-anim-upper { + -webkit-animation: animShowPrev 0.5s cubic-bezier(0.7,0,0.3,1) both 0.15s; + animation: animShowPrev 0.5s cubic-bezier(0.7,0,0.3,1) both 0.15s; +} + +.fs-form .fs-display-prev .fs-show .fs-anim-upper { + -webkit-animation-delay: 0.25s; + animation-delay: 0.25s; +} + +@-webkit-keyframes animShowPrev { + from { opacity: 0; -webkit-transform: translate3d(0,-500px,0); } +} + +@keyframes animShowPrev { + from { opacity: 0; -webkit-transform: translate3d(0,-500px,0); transform: translate3d(0,-500px,0); } +} + +/* Remove IE clear cross */ +input[type=text]::-ms-clear { + display: none; +} + +/* Adjust form for smaller screens */ +@media screen and (max-width: 52.5em) { + body { + min-height: 500px; + } + + .fs-form-wrap { + font-size: 70%; + } + + .fs-form { + top: 6em; + right: 2em; + left: 0; + padding: 0 3.75em 0 1em; + width: auto; + font-size: 2em; + } + + .fs-form.fs-form-overview { + top: 0; + right: 0; + padding: 1.5em 1em 8em 1em; + font-size: 1.5em; + } + + .fs-title { + padding: 20px; + } + + .fs-numbers { + margin: 20px; + } + + .fs-nav-dots { + right: 25px; + } + + button.fs-continue { + right: 20px; + bottom: 20px; + margin: 0; + padding: 50px 0 0 50px; + width: 50px; + height: 50px; + border-radius: 50%; + font-size: 2em; + } + + button.fs-continue::before { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + content: '\27A1'; + text-align: center; + font-size: 1em; + line-height: 50px; + } + + .fs-continue::after { + content: ''; + } + + button.fs-submit { + width: 100%; + font-size: 1.25em; + } + + .fs-message-error { + bottom: 1.75em; + left: 0; + padding: 0 90px 0 2em; + width: 100%; + font-size: 1.5em; + -webkit-transform: translate3d(0,-5px,0); + transform: translate3d(0,-5px,0); + } + + .fs-message-error.fs-show { + -webkit-transform: translate3d(0,0,0); + transform: translate3d(0,0,0); + } +} + +.hideElement { + display: none; +} diff --git a/css/cs-select.css b/css/cs-select.css new file mode 100644 index 0000000..15c9d61 --- /dev/null +++ b/css/cs-select.css @@ -0,0 +1,109 @@ +/* Custom select */ +/* Read the article: http://tympanus.net/codrops/2014/07/10/inspiration-for-custom-select-elements/ */ +/* Demo: http://tympanus.net/Development/SelectInspiration/ */ +/* GitHub: https://github.com/codrops/SelectInspiration */ + +/* Default custom select styles */ +div.cs-select { + display: inline-block; + vertical-align: middle; + position: relative; + text-align: left; + background: #fff; + z-index: 100; + width: 100%; + max-width: 500px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +div.cs-select:focus { + outline: none; /* For better accessibility add a style for this in your skin */ +} + +.cs-select select { + display: none; +} + +.cs-select span { + display: block; + position: relative; + cursor: pointer; + padding: 1em; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +/* Placeholder and selected option */ +.cs-select > span { + padding-right: 3em; +} + +.cs-select > span::after, +.cs-select .cs-selected span::after { + speak: none; + position: absolute; + top: 50%; + -webkit-transform: translateY(-50%); + transform: translateY(-50%); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.cs-select > span::after { + content: '\25BE'; + right: 1em; +} + +.cs-select .cs-selected span::after { + content: '\2713'; + margin-left: 1em; +} + +.cs-select.cs-active > span::after { + -webkit-transform: translateY(-50%) rotate(180deg); + transform: translateY(-50%) rotate(180deg); +} + +/* Options */ +.cs-select .cs-options { + position: absolute; + overflow: hidden; + width: 100%; + background: #fff; + visibility: hidden; + z-index: 10000; +} + +.cs-select.cs-active .cs-options { + visibility: visible; +} + +.cs-select ul { + list-style: none; + margin: 0; + padding: 0; + width: 100%; +} + +.cs-select ul span { + padding: 1em; +} + +.cs-select ul li.cs-focus span { + background-color: #ddd; +} + +/* Optgroup and optgroup label */ +.cs-select li.cs-optgroup ul { + padding-left: 1em; +} + +.cs-select li.cs-optgroup > span { + cursor: default; +} diff --git a/css/cs-skin-boxes.css b/css/cs-skin-boxes.css new file mode 100644 index 0000000..ed4d540 --- /dev/null +++ b/css/cs-skin-boxes.css @@ -0,0 +1,319 @@ +/* Custom select */ +/* Read the article: http://tympanus.net/codrops/2014/07/10/inspiration-for-custom-select-elements/ */ +/* Demo: http://tympanus.net/Development/SelectInspiration/ */ +/* GitHub: https://github.com/codrops/SelectInspiration */ + +/* Custom select skin: fullscreen color picker (adjusted for fullscreen form) */ +div.cs-skin-boxes { + background: transparent; + font-size: 0.65em; + font-weight: 700; + max-width: 300px; + z-index: 2000; + color: #fff; +} + +@media screen and (max-width: 30em) { + div.cs-skin-boxes { font-size: 1em; } +} + +.cs-skin-boxes > span { + border: 3px solid #292c30; + border-radius: 5px; + width: 150px; + height: 140px; + font-size: 0.5em; + padding: 0 0 0 10px; + background: #555b64; +} + +div.cs-skin-boxes:focus > span { + box-shadow: 0 0 0 2px rgba(255,255,255,0.1); +} + +.cs-skin-boxes > span::before { + content: ''; + display: block; + padding-top: 110px; + margin-left: -10px; + box-shadow: 0 25px 0 #292c30, inset 0 -10px #292c30; +} + +.cs-skin-boxes > span::after, +.cs-skin-boxes.cs-active > span::after { + top: auto; + -webkit-transform: none; + transform: none; +} + +.cs-skin-boxes .cs-options { + position: fixed; + width: 100%; + height: 100%; + top: 0; + left: 0; + overflow: auto; + background: #3b3f45; + font-size: 12px; + opacity: 0; + -webkit-transition: opacity 0.3s, visibility 0s 0.3s; + transition: opacity 0.3s, visibility 0s 0.3s; +} + +.cs-skin-boxes.cs-active .cs-options { + opacity: 1; + -webkit-transition: opacity 0.3s; + transition: opacity 0.3s; +} + +.cs-skin-boxes .cs-options ul { + position: absolute; + width: 100%; + height: 100%; + padding: 10px; +} + +.cs-skin-boxes .cs-options li { + width: 20%; + height: 25%; + float: left; + position: relative; + cursor: pointer; + border-radius: 14px; + overflow: hidden; + opacity: 0; + color: rgba(255,255,255,0.6); + border: 10px solid transparent; + background-clip: padding-box; + -webkit-transform: scale3d(0.8,0.8,1); + transform: scale3d(0.8,0.8,1); + box-shadow: inset 0 -6em 0 -2em #282b30, inset 0 -1px 1px #000; + -webkit-transition: -webkit-transform 0.3s, opacity 0.3s; + transition: transform 0.3s, opacity 0.3s; +} + +@media screen and (max-width: 30em) { + .cs-skin-boxes .cs-options li { box-shadow: none; border-width: 3px; border-radius: 8px;} +} + +.cs-skin-boxes.cs-active .cs-options li { + opacity: 1; + -webkit-transform: scale3d(1,1,1); + transform: scale3d(1,1,1); +} + +.cs-skin-boxes.cs-active .cs-options li:nth-child(2) { + -webkit-transition-delay: 0.01s; + transition-delay: 0.01s; +} + +.cs-skin-boxes.cs-active .cs-options li:nth-child(3) { + -webkit-transition-delay: 0.02s; + transition-delay: 0.02s; +} + +.cs-skin-boxes.cs-active .cs-options li:nth-child(4) { + -webkit-transition-delay: 0.03s; + transition-delay: 0.03s; +} + +.cs-skin-boxes.cs-active .cs-options li:nth-child(5) { + -webkit-transition-delay: 0.04s; + transition-delay: 0.04s; +} + +.cs-skin-boxes.cs-active .cs-options li:nth-child(6) { + -webkit-transition-delay: 0.05s; + transition-delay: 0.05s; +} + +.cs-skin-boxes.cs-active .cs-options li:nth-child(7) { + -webkit-transition-delay: 0.06s; + transition-delay: 0.06s; +} + +.cs-skin-boxes.cs-active .cs-options li:nth-child(8) { + -webkit-transition-delay: 0.07s; + transition-delay: 0.07s; +} + +.cs-skin-boxes.cs-active .cs-options li:nth-child(9) { + -webkit-transition-delay: 0.08s; + transition-delay: 0.08s; +} + +.cs-skin-boxes.cs-active .cs-options li:nth-child(10) { + -webkit-transition-delay: 0.09s; + transition-delay: 0.09s; +} + +.cs-skin-boxes.cs-active .cs-options li:nth-child(11) { + -webkit-transition-delay: 0.1s; + transition-delay: 0.1s; +} + +.cs-skin-boxes.cs-active .cs-options li:nth-child(12) { + -webkit-transition-delay: 0.11s; + transition-delay: 0.11s; +} + +.cs-skin-boxes.cs-active .cs-options li:nth-child(13) { + -webkit-transition-delay: 0.12s; + transition-delay: 0.12s; +} + +.cs-skin-boxes.cs-active .cs-options li:nth-child(14) { + -webkit-transition-delay: 0.13s; + transition-delay: 0.13s; +} + +.cs-skin-boxes.cs-active .cs-options li:nth-child(15) { + -webkit-transition-delay: 0.14s; + transition-delay: 0.14s; +} + +.cs-skin-boxes.cs-active .cs-options li:nth-child(16) { + -webkit-transition-delay: 0.15s; + transition-delay: 0.15s; +} + +.cs-skin-boxes.cs-active .cs-options li:nth-child(17) { + -webkit-transition-delay: 0.16s; + transition-delay: 0.16s; +} + +.cs-skin-boxes.cs-active .cs-options li:nth-child(18) { + -webkit-transition-delay: 0.17s; + transition-delay: 0.17s; +} + +.cs-skin-boxes.cs-active .cs-options li:nth-child(19) { + -webkit-transition-delay: 0.18s; + transition-delay: 0.18s; +} + +.cs-skin-boxes.cs-active .cs-options li:nth-child(20) { + -webkit-transition-delay: 0.19s; + transition-delay: 0.19s; +} + +.cs-skin-boxes .cs-options li.cs-selected::after { + content: '\2714'; + color: rgba(0,0,0,0.1); + position: absolute; + font-size: 2em; + top: 50%; + left: 50%; + -webkit-transform: translate3d(-50%,-50%,0) translate3d(0,-1em,0); + transform: translate3d(-50%,-50%,0) translate3d(0,-1em,0); +} + +.cs-skin-boxes .cs-options li.cs-selected span::after { + content: ''; +} + +@media screen and (max-width: 30em) { + .cs-skin-boxes .cs-options li.cs-selected::after { + -webkit-transform: translate3d(-50%,-50%,0); + transform: translate3d(-50%,-50%,0); + } +} + +.cs-skin-boxes .cs-options li.color-588c75 { + background-color: #588c75; +} + +.cs-skin-boxes .cs-options li.color-b0c47f { + background-color: #b0c47f; +} + +.cs-skin-boxes .cs-options li.color-f3e395 { + background-color: #f3e395; +} + +.cs-skin-boxes .cs-options li.color-f3ae73 { + background-color: #f3ae73; +} + +.cs-skin-boxes .cs-options li.color-da645a { + background-color: #da645a; +} + +.cs-skin-boxes .cs-options li.color-79a38f { + background-color: #79a38f; +} + +.cs-skin-boxes .cs-options li.color-c1d099 { + background-color: #c1d099; +} + +.cs-skin-boxes .cs-options li.color-f5eaaa { + background-color: #f5eaaa; +} + +.cs-skin-boxes .cs-options li.color-f5be8f { + background-color: #f5be8f; +} + +.cs-skin-boxes .cs-options li.color-e1837b { + background-color: #e1837b; +} + +.cs-skin-boxes .cs-options li.color-9bbaab { + background-color: #9bbaab; +} + +.cs-skin-boxes .cs-options li.color-d1dcb2 { + background-color: #d1dcb2; +} + +.cs-skin-boxes .cs-options li.color-f9eec0 { + background-color: #f9eec0; +} + +.cs-skin-boxes .cs-options li.color-f7cda9 { + background-color: #f7cda9; +} + +.cs-skin-boxes .cs-options li.color-e8a19b { + background-color: #e8a19b; +} + +.cs-skin-boxes .cs-options li.color-bdd1c8 { + background-color: #bdd1c8; +} + +.cs-skin-boxes .cs-options li.color-e1e7cd { + background-color: #e1e7cd; +} + +.cs-skin-boxes .cs-options li.color-faf4d4 { + background-color: #faf4d4; +} + +.cs-skin-boxes .cs-options li.color-fbdfc9 { + background-color: #fbdfc9; +} + +.cs-skin-boxes .cs-options li.color-f1c1bd { + background-color: #f1c1bd; +} + +.cs-skin-boxes .cs-options span { + position: absolute; + bottom: 0; + width: 100%; + line-height: 2em; + text-transform: uppercase; + letter-spacing: 1px; +} + +@media screen and (max-width: 30em) { + .cs-skin-boxes .cs-options span { display: none; } +} + +.cs-skin-boxes .cs-options li span:hover, +.cs-skin-boxes li.cs-focus span, +.cs-skin-boxes li.cs-selected span { + color: #fff; +} diff --git a/css/demo.css b/css/demo.css new file mode 100644 index 0000000..dfd7fe6 --- /dev/null +++ b/css/demo.css @@ -0,0 +1,135 @@ +@import url(http://fonts.googleapis.com/css?family=Raleway:400,700); +@font-face { + font-weight: normal; + font-style: normal; + font-family: 'codropsicons'; + src:url('../fonts/codropsicons/codropsicons.eot'); + src:url('../fonts/codropsicons/codropsicons.eot?#iefix') format('embedded-opentype'), + url('../fonts/codropsicons/codropsicons.woff') format('woff'), + url('../fonts/codropsicons/codropsicons.ttf') format('truetype'), + url('../fonts/codropsicons/codropsicons.svg#codropsicons') format('svg'); +} + +*, *:after, *:before { -webkit-box-sizing: border-box; box-sizing: border-box; } +.clearfix:before, .clearfix:after { content: ''; display: table; } +.clearfix:after { clear: both; } + +html, body, .container { + height: 100%; +} + +body { + background: #3b3f45; + color: #fff; + font-weight: 400; + font-size: 1em; + font-family: 'Raleway', Arial, sans-serif; + overflow: hidden; + overflow-y: scroll; + min-height: 590px; +} + +a { + color: rgba(0,0,0,0.3); + text-decoration: none; + outline: none; +} + +a:hover, a:focus { + color: #fff; +} + +/* Top Navigation Style */ +.codrops-top { + margin-top: 1em; +} + +.codrops-top a { + font-size: 0.69em; + padding: 0 0.25em; + display: inline-block; + text-decoration: none; + font-size: 1.2em; +} + +.codrops-icon:before { + margin: 0 4px; + text-transform: none; + font-weight: normal; + font-style: normal; + font-variant: normal; + font-family: 'codropsicons'; + line-height: 1; + speak: none; + -webkit-font-smoothing: antialiased; +} + +.codrops-icon-drop:before { + content: "\e001"; +} + +.codrops-icon-prev:before { + content: "\e004"; +} + +.codrops-icon-info:before { + content: "\e003"; +} + +.codrops-icon span { + display: none; + position: absolute; + font-size: 0.85em; + padding: 0.5em 0 0 0.25em; + font-weight: 700; +} + +.codrops-icon:hover span { + display: block; + color: #6a7b7e; +} + +/* Related demos */ +.related { + font-weight: 700; + text-align: center; + padding: 5em 0; + display: none; + background: #fff; + color: rgba(0,0,0,0.3); +} + +.overview .related { + display: block; +} + +.related > a { + border: 3px solid black; + border-color: initial; + display: inline-block; + text-align: center; + margin: 20px 10px; + padding: 25px; +} + +.related > a:hover, +.related > a:focus { + color: rgba(0,0,0,0.5); +} + +.related a img { + max-width: 100%; + opacity: 0.8; +} + +.related a:hover img, +.related a:active img { + opacity: 1; +} + +.related a h3 { + margin: 0; + padding: 0.5em 0 0.3em; + max-width: 300px; + text-align: left; +} diff --git a/css/normalize.css b/css/normalize.css new file mode 100644 index 0000000..77feb20 --- /dev/null +++ b/css/normalize.css @@ -0,0 +1 @@ +article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}audio,canvas,video{display:inline-block;}audio:not([controls]){display:none;height:0;}[hidden]{display:none;}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;}body{margin:0;}a:focus{outline:thin dotted;}a:active,a:hover{outline:0;}h1{font-size:2em;margin:0.67em 0;}abbr[title]{border-bottom:1px dotted;}b,strong{font-weight:bold;}dfn{font-style:italic;}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0;}mark{background:#ff0;color:#000;}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em;}pre{white-space:pre-wrap;}q{quotes:"\201C" "\201D" "\2018" "\2019";}small{font-size:80%;}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sup{top:-0.5em;}sub{bottom:-0.25em;}img{border:0;}svg:not(:root){overflow:hidden;}figure{margin:0;}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em;}legend{border:0;padding:0;}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;}button,input{line-height:normal;}button,select{text-transform:none;}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}button[disabled],html input[disabled]{cursor:default;}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}textarea{overflow:auto;vertical-align:top;}table{border-collapse:collapse;border-spacing:0;} \ No newline at end of file diff --git a/css/testcss.css b/css/testcss.css new file mode 100644 index 0000000..f503e73 --- /dev/null +++ b/css/testcss.css @@ -0,0 +1,7 @@ +.firstcss { + color: red; +} + +.secondcss { + color: blue; +} \ No newline at end of file diff --git a/fonts/.DS_Store b/fonts/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/fonts/.DS_Store differ diff --git a/fonts/codropsicons/codropsicons.eot b/fonts/codropsicons/codropsicons.eot new file mode 100644 index 0000000..f46c7f4 Binary files /dev/null and b/fonts/codropsicons/codropsicons.eot differ diff --git a/fonts/codropsicons/codropsicons.svg b/fonts/codropsicons/codropsicons.svg new file mode 100644 index 0000000..d202d21 --- /dev/null +++ b/fonts/codropsicons/codropsicons.svg @@ -0,0 +1,24 @@ + + + + +This is a custom SVG font generated by IcoMoon. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/codropsicons/codropsicons.ttf b/fonts/codropsicons/codropsicons.ttf new file mode 100644 index 0000000..72bed1f Binary files /dev/null and b/fonts/codropsicons/codropsicons.ttf differ diff --git a/fonts/codropsicons/codropsicons.woff b/fonts/codropsicons/codropsicons.woff new file mode 100644 index 0000000..1003218 Binary files /dev/null and b/fonts/codropsicons/codropsicons.woff differ diff --git a/fonts/codropsicons/license.txt b/fonts/codropsicons/license.txt new file mode 100644 index 0000000..88a5cbc --- /dev/null +++ b/fonts/codropsicons/license.txt @@ -0,0 +1,6 @@ +Icon Set: Font Awesome -- http://fortawesome.github.com/Font-Awesome/ +License: SIL -- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL + + +Icon Set: Eco Ico -- http://dribbble.com/shots/665585-Eco-Ico +License: CC0 -- http://creativecommons.org/publicdomain/zero/1.0/ \ No newline at end of file diff --git a/img/.DS_Store b/img/.DS_Store new file mode 100644 index 0000000..ab7ff7b Binary files /dev/null and b/img/.DS_Store differ diff --git a/img/Readme.txt b/img/Readme.txt new file mode 100644 index 0000000..dda7640 --- /dev/null +++ b/img/Readme.txt @@ -0,0 +1 @@ +Star Icon from http://wiki.sugarlabs.org/go/File:Abacus-star.svg -------------------------------- Freebie: Roundicons Icon Set (60 Icons, PNG, SVG, EPS, AI) from Smashing Magazine: This freebie has been brought to you by SmashingMagazine.com. The icon set was designed by Ramy Wafaa, Suzanne de Jong and Natalie Schaubert (http://roundicons.com/about-us/) from Roundicons (http://roundicons.com/), and released exclusively for Smashing Magazine and its readers. - - - - - - - - - - - - - - - - - - Dearest Smashing reader, Thank you for downloading this icon set! :-) All round icons are royalty-free. You can use them in your commercial as well as your personal works. You may modify the size, color or shape of the icons. No attribution is required. However, reselling of bundles or individual pictograms is prohibited. You may make one copy of the assets solely for backup or archival purposes or transfer the assets to a single hard drive, provided that you keep the original and accompanying documentation in your possession. You may enter projects into contests, film festivals, publications and or exhibitions that use the assets in the permitted listed methods. Furthermore, no claim or action of any sort can arise against "roundicons.com" in this agreement for the use of these assets and no liability can attach to "roundicons.com" for any acts, omissions or failures on the part the terms. The icons may not be resold, sublicensed, rented, transferred or otherwise made available for use. The icons may not be offered for free downloading from websites other than SmashingMagazine.com. Please link to the article in which this freebie was released if you would like to spread the word: http://www.smashingmagazine.com/2014/01/24/roundicons-set-60-icons-png-ai-source/ Sincerely yours, The Smashing Magazine Team www.smashingmagazine.com \ No newline at end of file diff --git a/img/abacusstar.svg b/img/abacusstar.svg new file mode 100644 index 0000000..32b2bc4 --- /dev/null +++ b/img/abacusstar.svg @@ -0,0 +1,13 @@ + + + + + + diff --git a/img/conversion.svg b/img/conversion.svg new file mode 100644 index 0000000..f83967e --- /dev/null +++ b/img/conversion.svg @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/img/dollar.svg b/img/dollar.svg new file mode 100644 index 0000000..8cfd3b8 --- /dev/null +++ b/img/dollar.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/img/mobile.svg b/img/mobile.svg new file mode 100644 index 0000000..149a4af --- /dev/null +++ b/img/mobile.svg @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/img/relatedposts/MorphingButtons-300x162.png b/img/relatedposts/MorphingButtons-300x162.png new file mode 100644 index 0000000..214fc4f Binary files /dev/null and b/img/relatedposts/MorphingButtons-300x162.png differ diff --git a/img/relatedposts/minimalform1-300x162.png b/img/relatedposts/minimalform1-300x162.png new file mode 100644 index 0000000..2ee82ce Binary files /dev/null and b/img/relatedposts/minimalform1-300x162.png differ diff --git a/img/social.svg b/img/social.svg new file mode 100644 index 0000000..ebd81f8 --- /dev/null +++ b/img/social.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/index.html b/index.html new file mode 100755 index 0000000..1df3a48 --- /dev/null +++ b/index.html @@ -0,0 +1,80 @@ + + + + + + + FLOdata tester + + + + + + + + + + + + +
+ +
+ +
+
    +
  1. + + +
  2. +
+ +
+
+ + + + +
+ + + + + + \ No newline at end of file diff --git a/js/classie.js b/js/classie.js new file mode 100755 index 0000000..1c7be2f --- /dev/null +++ b/js/classie.js @@ -0,0 +1,80 @@ +/*! + * classie - class helper functions + * from bonzo https://github.com/ded/bonzo + * + * classie.has( elem, 'my-class' ) -> true/false + * classie.add( elem, 'my-new-class' ) + * classie.remove( elem, 'my-unwanted-class' ) + * classie.toggle( elem, 'my-class' ) + */ + +/*jshint browser: true, strict: true, undef: true */ +/*global define: false */ + +( function( window ) { + +'use strict'; + +// class helper functions from bonzo https://github.com/ded/bonzo + +function classReg( className ) { + return new RegExp("(^|\\s+)" + className + "(\\s+|$)"); +} + +// classList support for class management +// altho to be fair, the api sucks because it won't accept multiple classes at once +var hasClass, addClass, removeClass; + +if ( 'classList' in document.documentElement ) { + hasClass = function( elem, c ) { + return elem.classList.contains( c ); + }; + addClass = function( elem, c ) { + elem.classList.add( c ); + }; + removeClass = function( elem, c ) { + elem.classList.remove( c ); + }; +} +else { + hasClass = function( elem, c ) { + return classReg( c ).test( elem.className ); + }; + addClass = function( elem, c ) { + if ( !hasClass( elem, c ) ) { + elem.className = elem.className + ' ' + c; + } + }; + removeClass = function( elem, c ) { + elem.className = elem.className.replace( classReg( c ), ' ' ); + }; +} + +function toggleClass( elem, c ) { + var fn = hasClass( elem, c ) ? removeClass : addClass; + fn( elem, c ); +} + +var classie = { + // full names + hasClass: hasClass, + addClass: addClass, + removeClass: removeClass, + toggleClass: toggleClass, + // short names + has: hasClass, + add: addClass, + remove: removeClass, + toggle: toggleClass +}; + +// transport +if ( typeof define === 'function' && define.amd ) { + // AMD + define( classie ); +} else { + // browser global + window.classie = classie; +} + +})( window ); diff --git a/js/createResult.js b/js/createResult.js new file mode 100644 index 0000000..93480af --- /dev/null +++ b/js/createResult.js @@ -0,0 +1,28 @@ +var div = document.createElement("div"); +div.setAttribute("id", "myform"); +div.setAttribute("class", "fs-form fs-form-overview fs-show"); + +var ol = document.createElement('ol'); +ol.setAttribute("class","fs-fields"); + +var fieldnames = [{'FLO data':'hey i wrote FLO data'},{'Type':'transfer'},{'Identification':'rmt#'},{'Amount':5000}] + +for (var i=0; i= 0) { + ++n; + pos += step; + } else break; + } + return n; + } + + function isTransfer(text){ + var wordlist = ['transfer','send','give']; // keep list's content lowercase + var textList = text.split(' '); + for (var i=0; i1){ + return 'too many'; + } + if (count==1 && !returnval) { + returnval = operationList[i]; + } + } + return returnval; + } + + function extractAmount(text) { + var count=0; + var returnval; + var splitText = text.split(/\W+/); + + for (var i=0; i1){ + return 'Too many'; + } + } + return returnval; + } + + function extractInitTokens(text){ + var base_units = {'thousand':10**3 , 'million':10**6 ,'billion':10**9, 'trillion':10**12}; + var textList = text.split(' '); + for (var i=0; i' : ''; + } + this.ctrlNav.innerHTML = dots; + this._showCtrl( this.ctrlNav ); + this.ctrlNavDots = [].slice.call( this.ctrlNav.children ); + } + + // field number status + if( this.options.ctrlNavPosition ) { + this.ctrlFldStatus = createElement( 'span', { cName : 'fs-numbers', appendTo : this.ctrls } ); + + // current field placeholder + this.ctrlFldStatusCurr = createElement( 'span', { cName : 'fs-number-current', inner : Number( this.current + 1 ) } ); + this.ctrlFldStatus.appendChild( this.ctrlFldStatusCurr ); + + // total fields placeholder + this.ctrlFldStatusTotal = createElement( 'span', { cName : 'fs-number-total', inner : this.fieldsCount } ); + this.ctrlFldStatus.appendChild( this.ctrlFldStatusTotal ); + this._showCtrl( this.ctrlFldStatus ); + } + + // progress bar + if( this.options.ctrlProgress ) { + this.ctrlProgress = createElement( 'div', { cName : 'fs-progress', appendTo : this.ctrls } ); + this._showCtrl( this.ctrlProgress ); + } + } + + /** + * addErrorMsg function + * create and insert the structure for the error message + */ + FForm.prototype._addErrorMsg = function() { + // error message + this.msgError = createElement( 'span', { cName : 'fs-message-error', appendTo : this.el } ); + } + + /** + * init events + */ + FForm.prototype._initEvents = function() { + var self = this; + + // show next field + this.ctrlContinue.addEventListener( 'click', function() { + var flodata = document.getElementById('q1'); + var result = parse_flodata(flodata.value); + console.log(result); + self._nextField(undefined,result); + } ); + + // navigation dots + if( this.options.ctrlNavDots ) { + this.ctrlNavDots.forEach( function( dot, pos ) { + dot.addEventListener( 'click', function() { + self._showField( pos ); + } ); + } ); + } + + // jump to next field without clicking the continue button (for fields/list items with the attribute "data-input-trigger") + this.fields.forEach( function( fld ) { + if( fld.hasAttribute( 'data-input-trigger' ) ) { + var input = fld.querySelector( 'input[type="radio"]' ) || /*fld.querySelector( '.cs-select' ) ||*/ fld.querySelector( 'select' ); // assuming only radio and select elements (TODO: exclude multiple selects) + if( !input ) return; + + switch( input.tagName.toLowerCase() ) { + case 'select' : + input.addEventListener( 'change', function() { self._nextField(); } ); + break; + + case 'input' : + [].slice.call( fld.querySelectorAll( 'input[type="radio"]' ) ).forEach( function( inp ) { + inp.addEventListener( 'change', function(ev) { self._nextField(); } ); + } ); + break; + + /* + // for our custom select we would do something like: + case 'div' : + [].slice.call( fld.querySelectorAll( 'ul > li' ) ).forEach( function( inp ) { + inp.addEventListener( 'click', function(ev) { self._nextField(); } ); + } ); + break; + */ + } + } + } ); + + // keyboard navigation events - jump to next field when pressing enter + document.addEventListener( 'keydown', function( ev ) { + if( !self.isLastStep && ev.target.tagName.toLowerCase() !== 'textarea' ) { + var keyCode = ev.keyCode || ev.which; + if( keyCode === 13 ) { + ev.preventDefault(); + var flodata = document.getElementById('q1'); + var result = parse_flodata(flodata.value); + console.log(result); + self._nextField(undefined,result); + } + } + } ); + }; + + /** + * nextField function + * jumps to the next field + */ + FForm.prototype._nextField = function( backto, result ) { + if( this.isLastStep || !this._validade() || this.isAnimating ) { + return false; + } + this.isAnimating = true; + + // check if on last step + this.isLastStep = this.current === this.fieldsCount - 1 && backto === undefined ? true : false; + + // clear any previous error messages + this._clearError(); + + // current field + var currentFld = this.fields[ this.current ]; + + // save the navigation direction + this.navdir = backto !== undefined ? backto < this.current ? 'prev' : 'next' : 'next'; + + // update current field + this.current = backto !== undefined ? backto : this.current + 1; + + if( backto === undefined ) { + // update progress bar (unless we navigate backwards) + this._progress(); + + // save farthest position so far + this.farthest = this.current; + } + + // add class "fs-display-next" or "fs-display-prev" to the list of fields + classie.add( this.fieldsList, 'fs-display-' + this.navdir ); + + // remove class "fs-current" from current field and add it to the next one + // also add class "fs-show" to the next field and the class "fs-hide" to the current one + classie.remove( currentFld, 'fs-current' ); + classie.add( currentFld, 'fs-hide' ); + + if( !this.isLastStep ) { + // update nav + this._updateNav(); + + // change the current field number/status + this._updateFieldNumber(); + + var nextField = this.fields[ this.current ]; + classie.add( nextField, 'fs-current' ); + classie.add( nextField, 'fs-show' ); + } + + // after animation ends remove added classes from fields + var self = this, + onEndAnimationFn = function( ev ) { + if( support.animations ) { + this.removeEventListener( animEndEventName, onEndAnimationFn ); + } + + classie.remove( self.fieldsList, 'fs-display-' + self.navdir ); + classie.remove( currentFld, 'fs-hide' ); + + if( self.isLastStep ) { + // show the complete form and hide the controls + self._hideCtrl( self.ctrlNav ); + self._hideCtrl( self.ctrlProgress ); + self._hideCtrl( self.ctrlContinue ); + self._hideCtrl( self.ctrlFldStatus ); + // replace class fs-form-full with fs-form-overview + classie.remove( self.formEl, 'fs-form-full' ); + classie.add( self.formEl, 'fs-form-overview' ); + classie.add( self.formEl, 'fs-show' ); + classie.add( self.formEl, 'hideElement' ); + + // Result display page + var div = document.createElement("div"); + div.setAttribute("id", "resultPage"); + div.setAttribute("class", "fs-form fs-form-overview fs-show"); + + var ol = document.createElement('ol'); + ol.setAttribute("class","fs-fields"); + + if (result['type'] == 'transfer'){ + var fieldnames = [{'FLO data':result['flodata']},{'Type':'Transfer'},{'Identification':result['marker']},{'Amount':result['amount']}] + }else if (result['type'] == 'incorporation'){ + var fieldnames = [{'FLO data':result['flodata']},{'Type':'Incorporation'},{'Identification':result['marker']},{'Amount':result['initTokens']}] + }else{ + var fieldnames = [{'FLO data':result['flodata']},{'Type':'Noise'}] + } + + for (var i=0; i this.fieldsCount - 1 ) { + return false; + } + this._nextField( pos ); + } + + /** + * updateFieldNumber function + * changes the current field number + */ + FForm.prototype._updateFieldNumber = function() { + if( this.options.ctrlNavPosition ) { + // first, create next field number placeholder + this.ctrlFldStatusNew = document.createElement( 'span' ); + this.ctrlFldStatusNew.className = 'fs-number-new'; + this.ctrlFldStatusNew.innerHTML = Number( this.current + 1 ); + + // insert it in the DOM + this.ctrlFldStatus.appendChild( this.ctrlFldStatusNew ); + + // add class "fs-show-next" or "fs-show-prev" depending on the navigation direction + var self = this; + setTimeout( function() { + classie.add( self.ctrlFldStatus, self.navdir === 'next' ? 'fs-show-next' : 'fs-show-prev' ); + }, 25 ); + } + } + + /** + * progress function + * updates the progress bar by setting its width + */ + FForm.prototype._progress = function() { + if( this.options.ctrlProgress ) { + this.ctrlProgress.style.width = this.current * ( 100 / this.fieldsCount ) + '%'; + } + } + + /** + * updateNav function + * updates the navigation dots + */ + FForm.prototype._updateNav = function() { + if( this.options.ctrlNavDots ) { + classie.remove( this.ctrlNav.querySelector( 'button.fs-dot-current' ), 'fs-dot-current' ); + classie.add( this.ctrlNavDots[ this.current ], 'fs-dot-current' ); + this.ctrlNavDots[ this.current ].disabled = false; + } + } + + /** + * showCtrl function + * shows a control + */ + FForm.prototype._showCtrl = function( ctrl ) { + classie.add( ctrl, 'fs-show' ); + } + + /** + * hideCtrl function + * hides a control + */ + FForm.prototype._hideCtrl = function( ctrl ) { + classie.remove( ctrl, 'fs-show' ); + } + + // TODO: this is a very basic validation function. Only checks for required fields.. + FForm.prototype._validade = function() { + var fld = this.fields[ this.current ], + input = fld.querySelector( 'input[required]' ) || fld.querySelector( 'textarea[required]' ) || fld.querySelector( 'select[required]' ), + error; + + if( !input ) return true; + + switch( input.tagName.toLowerCase() ) { + case 'input' : + if( input.type === 'radio' || input.type === 'checkbox' ) { + var checked = 0; + [].slice.call( fld.querySelectorAll( 'input[type="' + input.type + '"]' ) ).forEach( function( inp ) { + if( inp.checked ) { + ++checked; + } + } ); + if( !checked ) { + error = 'NOVAL'; + } + } + else if( input.value === '' ) { + error = 'NOVAL'; + } + break; + + case 'select' : + // assuming here '' or '-1' only + if( input.value === '' || input.value === '-1' ) { + error = 'NOVAL'; + } + break; + + case 'textarea' : + if( input.value === '' ) { + error = 'NOVAL'; + } + break; + } + + if( error != undefined ) { + this._showError( error ); + return false; + } + + return true; + } + + // TODO + FForm.prototype._showError = function( err ) { + var message = ''; + switch( err ) { + case 'NOVAL' : + message = 'Please fill the field before continuing'; + break; + case 'INVALIDEMAIL' : + message = 'Please fill a valid email address'; + break; + // ... + }; + this.msgError.innerHTML = message; + this._showCtrl( this.msgError ); + } + + // clears/hides the current error message + FForm.prototype._clearError = function() { + this._hideCtrl( this.msgError ); + } + + // add to global namespace + window.FForm = FForm; + + +})( window ); diff --git a/js/modernizr.custom.js b/js/modernizr.custom.js new file mode 100644 index 0000000..9a75ce3 --- /dev/null +++ b/js/modernizr.custom.js @@ -0,0 +1,257 @@ +/* Modernizr 2.8.3 (Custom Build) | MIT & BSD + * Build: http://modernizr.com/download/#-cssanimations-shiv-cssclasses-prefixed-teststyles-testprop-testallprops-prefixes-domprefixes-css_calc-css_vhunit-load + */ +; +window.Modernizr = function(a, b, c) { + function z(a) { j.cssText = a } + + function A(a, b) { return z(m.join(a + ";") + (b || "")) } + + function B(a, b) { return typeof a === b } + + function C(a, b) { return !!~("" + a).indexOf(b) } + + function D(a, b) { for (var d in a) { var e = a[d]; if (!C(e, "-") && j[e] !== c) return b == "pfx" ? e : !0 } return !1 } + + function E(a, b, d) { for (var e in a) { var f = b[a[e]]; if (f !== c) return d === !1 ? a[e] : B(f, "function") ? f.bind(d || b) : f } return !1 } + + function F(a, b, c) { + var d = a.charAt(0).toUpperCase() + a.slice(1), + e = (a + " " + o.join(d + " ") + d).split(" "); + return B(b, "string") || B(b, "undefined") ? D(e, b) : (e = (a + " " + p.join(d + " ") + d).split(" "), E(e, b, c)) + } + var d = "2.8.3", + e = {}, + f = !0, + g = b.documentElement, + h = "modernizr", + i = b.createElement(h), + j = i.style, + k, l = {}.toString, + m = " -webkit- -moz- -o- -ms- ".split(" "), + n = "Webkit Moz O ms", + o = n.split(" "), + p = n.toLowerCase().split(" "), + q = {}, + r = {}, + s = {}, + t = [], + u = t.slice, + v, w = function(a, c, d, e) { + var f, i, j, k, l = b.createElement("div"), + m = b.body, + n = m || b.createElement("body"); + if (parseInt(d, 10)) + while (d--) j = b.createElement("div"), j.id = e ? e[d] : h + (d + 1), l.appendChild(j); + return f = ["­", '"].join(""), l.id = h, (m ? l : n).innerHTML += f, n.appendChild(l), m || (n.style.background = "", n.style.overflow = "hidden", k = g.style.overflow, g.style.overflow = "hidden", g.appendChild(n)), i = c(l, a), m ? l.parentNode.removeChild(l) : (n.parentNode.removeChild(n), g.style.overflow = k), !!i + }, + x = {}.hasOwnProperty, + y; + !B(x, "undefined") && !B(x.call, "undefined") ? y = function(a, b) { return x.call(a, b) } : y = function(a, b) { return b in a && B(a.constructor.prototype[b], "undefined") }, Function.prototype.bind || (Function.prototype.bind = function(b) { + var c = this; + if (typeof c != "function") throw new TypeError; + var d = u.call(arguments, 1), + e = function() { + if (this instanceof e) { + var a = function() {}; + a.prototype = c.prototype; + var f = new a, + g = c.apply(f, d.concat(u.call(arguments))); + return Object(g) === g ? g : f + } + return c.apply(b, d.concat(u.call(arguments))) + }; + return e + }), q.cssanimations = function() { return F("animationName") }; + for (var G in q) y(q, G) && (v = G.toLowerCase(), e[v] = q[G](), t.push((e[v] ? "" : "no-") + v)); + return e.addTest = function(a, b) { + if (typeof a == "object") + for (var d in a) y(a, d) && e.addTest(d, a[d]); + else { + a = a.toLowerCase(); + if (e[a] !== c) return e; + b = typeof b == "function" ? b() : b, typeof f != "undefined" && f && (g.className += " " + (b ? "" : "no-") + a), e[a] = b + } + return e + }, z(""), i = k = null, + function(a, b) { + function l(a, b) { + var c = a.createElement("p"), + d = a.getElementsByTagName("head")[0] || a.documentElement; + return c.innerHTML = "x", d.insertBefore(c.lastChild, d.firstChild) + } + + function m() { var a = s.elements; return typeof a == "string" ? a.split(" ") : a } + + function n(a) { var b = j[a[h]]; return b || (b = {}, i++, a[h] = i, j[i] = b), b } + + function o(a, c, d) { + c || (c = b); + if (k) return c.createElement(a); + d || (d = n(c)); + var g; + return d.cache[a] ? g = d.cache[a].cloneNode() : f.test(a) ? g = (d.cache[a] = d.createElem(a)).cloneNode() : g = d.createElem(a), g.canHaveChildren && !e.test(a) && !g.tagUrn ? d.frag.appendChild(g) : g + } + + function p(a, c) { + a || (a = b); + if (k) return a.createDocumentFragment(); + c = c || n(a); + var d = c.frag.cloneNode(), + e = 0, + f = m(), + g = f.length; + for (; e < g; e++) d.createElement(f[e]); + return d + } + + function q(a, b) { b.cache || (b.cache = {}, b.createElem = a.createElement, b.createFrag = a.createDocumentFragment, b.frag = b.createFrag()), a.createElement = function(c) { return s.shivMethods ? o(c, a, b) : b.createElem(c) }, a.createDocumentFragment = Function("h,f", "return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&(" + m().join().replace(/[\w\-]+/g, function(a) { return b.createElem(a), b.frag.createElement(a), 'c("' + a + '")' }) + ");return n}")(s, b.frag) } + + function r(a) { a || (a = b); var c = n(a); return s.shivCSS && !g && !c.hasCSS && (c.hasCSS = !!l(a, "article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")), k || q(a, c), a } + var c = "3.7.0", + d = a.html5 || {}, + e = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i, + f = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i, + g, h = "_html5shiv", + i = 0, + j = {}, + k; + (function() { + try { + var a = b.createElement("a"); + a.innerHTML = "", g = "hidden" in a, k = a.childNodes.length == 1 || function() { b.createElement("a"); var a = b.createDocumentFragment(); return typeof a.cloneNode == "undefined" || typeof a.createDocumentFragment == "undefined" || typeof a.createElement == "undefined" }() + } catch (c) { g = !0, k = !0 } + })(); + var s = { elements: d.elements || "abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video", version: c, shivCSS: d.shivCSS !== !1, supportsUnknownElements: k, shivMethods: d.shivMethods !== !1, type: "default", shivDocument: r, createElement: o, createDocumentFragment: p }; + a.html5 = s, r(b) + }(this, b), e._version = d, e._prefixes = m, e._domPrefixes = p, e._cssomPrefixes = o, e.testProp = function(a) { return D([a]) }, e.testAllProps = F, e.testStyles = w, e.prefixed = function(a, b, c) { return b ? F(a, b, c) : F(a, "pfx") }, g.className = g.className.replace(/(^|\s)no-js(\s|$)/, "$1$2") + (f ? " js " + t.join(" ") : ""), e + }(this, this.document), + function(a, b, c) { + function d(a) { return "[object Function]" == o.call(a) } + + function e(a) { return "string" == typeof a } + + function f() {} + + function g(a) { return !a || "loaded" == a || "complete" == a || "uninitialized" == a } + + function h() { + var a = p.shift(); + q = 1, a ? a.t ? m(function() { + ("c" == a.t ? B.injectCss : B.injectJs)(a.s, 0, a.a, a.x, a.e, 1) + }, 0) : (a(), h()) : q = 0 + } + + function i(a, c, d, e, f, i, j) { + function k(b) { if (!o && g(l.readyState) && (u.r = o = 1, !q && h(), l.onload = l.onreadystatechange = null, b)) { "img" != a && m(function() { t.removeChild(l) }, 50); for (var d in y[c]) y[c].hasOwnProperty(d) && y[c][d].onload() } } + var j = j || B.errorTimeout, + l = b.createElement(a), + o = 0, + r = 0, + u = { t: d, s: c, e: f, a: i, x: j }; + 1 === y[c] && (r = 1, y[c] = []), "object" == a ? l.data = c : (l.src = c, l.type = a), l.width = l.height = "0", l.onerror = l.onload = l.onreadystatechange = function() { k.call(this, r) }, p.splice(e, 0, u), "img" != a && (r || 2 === y[c] ? (t.insertBefore(l, s ? null : n), m(k, j)) : y[c].push(l)) + } + + function j(a, b, c, d, f) { return q = 0, b = b || "j", e(a) ? i("c" == b ? v : u, a, b, this.i++, c, d, f) : (p.splice(this.i++, 0, a), 1 == p.length && h()), this } + + function k() { var a = B; return a.loader = { load: j, i: 0 }, a } + var l = b.documentElement, + m = a.setTimeout, + n = b.getElementsByTagName("script")[0], + o = {}.toString, + p = [], + q = 0, + r = "MozAppearance" in l.style, + s = r && !!b.createRange().compareNode, + t = s ? l : n.parentNode, + l = a.opera && "[object Opera]" == o.call(a.opera), + l = !!b.attachEvent && !l, + u = r ? "object" : l ? "script" : "img", + v = l ? "script" : u, + w = Array.isArray || function(a) { return "[object Array]" == o.call(a) }, + x = [], + y = {}, + z = { timeout: function(a, b) { return b.length && (a.timeout = b[0]), a } }, + A, B; + B = function(a) { + function b(a) { + var a = a.split("!"), + b = x.length, + c = a.pop(), + d = a.length, + c = { url: c, origUrl: c, prefixes: a }, + e, f, g; + for (f = 0; f < d; f++) g = a[f].split("="), (e = z[g.shift()]) && (c = e(c, g)); + for (f = 0; f < b; f++) c = x[f](c); + return c + } + + function g(a, e, f, g, h) { + var i = b(a), + j = i.autoCallback; + i.url.split(".").pop().split("?").shift(), i.bypass || (e && (e = d(e) ? e : e[a] || e[g] || e[a.split("/").pop().split("?")[0]]), i.instead ? i.instead(a, e, f, g, h) : (y[i.url] ? i.noexec = !0 : y[i.url] = 1, f.load(i.url, i.forceCSS || !i.forceJS && "css" == i.url.split(".").pop().split("?").shift() ? "c" : c, i.noexec, i.attrs, i.timeout), (d(e) || d(j)) && f.load(function() { k(), e && e(i.origUrl, h, g), j && j(i.origUrl, h, g), y[i.url] = 2 }))) + } + + function h(a, b) { + function c(a, c) { + if (a) { + if (e(a)) c || (j = function() { + var a = [].slice.call(arguments); + k.apply(this, a), l() + }), g(a, j, b, 0, h); + else if (Object(a) === a) + for (n in m = function() { + var b = 0, + c; + for (c in a) a.hasOwnProperty(c) && b++; + return b + }(), a) a.hasOwnProperty(n) && (!c && !--m && (d(j) ? j = function() { + var a = [].slice.call(arguments); + k.apply(this, a), l() + } : j[n] = function(a) { + return function() { + var b = [].slice.call(arguments); + a && a.apply(this, b), l() + } + }(k[n])), g(a[n], j, b, n, h)) + } else !c && l() + } + var h = !!a.test, + i = a.load || a.both, + j = a.callback || f, + k = j, + l = a.complete || f, + m, n; + c(h ? a.yep : a.nope, !!i), i && c(i) + } + var i, j, l = this.yepnope.loader; + if (e(a)) g(a, 0, l, 0); + else if (w(a)) + for (i = 0; i < a.length; i++) j = a[i], e(j) ? g(j, 0, l, 0) : w(j) ? B(j) : Object(j) === j && h(j, l); + else Object(a) === a && h(a, l) + }, B.addPrefix = function(a, b) { z[a] = b }, B.addFilter = function(a) { x.push(a) }, B.errorTimeout = 1e4, null == b.readyState && b.addEventListener && (b.readyState = "loading", b.addEventListener("DOMContentLoaded", A = function() { b.removeEventListener("DOMContentLoaded", A, 0), b.readyState = "complete" }, 0)), a.yepnope = k(), a.yepnope.executeStack = h, a.yepnope.injectJs = function(a, c, d, e, i, j) { + var k = b.createElement("script"), + l, o, e = e || B.errorTimeout; + k.src = a; + for (o in d) k.setAttribute(o, d[o]); + c = j ? h : c || f, k.onreadystatechange = k.onload = function() {!l && g(k.readyState) && (l = 1, c(), k.onload = k.onreadystatechange = null) }, m(function() { l || (l = 1, c(1)) }, e), i ? k.onload() : n.parentNode.insertBefore(k, n) + }, a.yepnope.injectCss = function(a, c, d, e, g, i) { + var e = b.createElement("link"), + j, c = i ? h : c || f; + e.href = a, e.rel = "stylesheet", e.type = "text/css"; + for (j in d) e.setAttribute(j, d[j]); + g || (n.parentNode.insertBefore(e, n), m(c, 0)) + } + }(this, document), Modernizr.load = function() { yepnope.apply(window, [].slice.call(arguments, 0)) }, Modernizr.addTest("csscalc", function() { + var a = "width:", + b = "calc(10px);", + c = document.createElement("div"); + return c.style.cssText = a + Modernizr._prefixes.join(b + a), !!c.style.length + }), Modernizr.addTest("cssvhunit", function() { + var a; + return Modernizr.testStyles("#modernizr { height: 50vh; }", function(b, c) { + var d = parseInt(window.innerHeight / 2, 10), + e = parseInt((window.getComputedStyle ? getComputedStyle(b, null) : b.currentStyle).height, 10); + a = e == d + }), a + }); diff --git a/js/selectFx.js b/js/selectFx.js new file mode 100644 index 0000000..f75bdfb --- /dev/null +++ b/js/selectFx.js @@ -0,0 +1,326 @@ +/** + * selectFx.js v1.0.0 + * http://www.codrops.com + * + * Licensed under the MIT license. + * http://www.opensource.org/licenses/mit-license.php + * + * Copyright 2014, Codrops + * http://www.codrops.com + */ +;( function( window ) { + + 'use strict'; + + /** + * based on from https://github.com/inuyaksa/jquery.nicescroll/blob/master/jquery.nicescroll.js + */ + function hasParent( e, p ) { + if (!e) return false; + var el = e.target||e.srcElement||e||false; + while (el && el != p) { + el = el.parentNode||false; + } + return (el!==false); + }; + + /** + * extend obj function + */ + function extend( a, b ) { + for( var key in b ) { + if( b.hasOwnProperty( key ) ) { + a[key] = b[key]; + } + } + return a; + } + + /** + * SelectFx function + */ + function SelectFx( el, options ) { + this.el = el; + this.options = extend( {}, this.options ); + extend( this.options, options ); + this._init(); + } + + /** + * SelectFx options + */ + SelectFx.prototype.options = { + // if true all the links will open in a new tab. + // if we want to be redirected when we click an option, we need to define a data-link attr on the option of the native select element + newTab : true, + // when opening the select element, the default placeholder (if any) is shown + stickyPlaceholder : true, + // callback when changing the value + onChange : function( val ) { return false; } + } + + /** + * init function + * initialize and cache some vars + */ + SelectFx.prototype._init = function() { + // check if we are using a placeholder for the native select box + // we assume the placeholder is disabled and selected by default + var selectedOpt = this.el.querySelector( 'option[selected]' ); + this.hasDefaultPlaceholder = selectedOpt && selectedOpt.disabled; + + // get selected option (either the first option with attr selected or just the first option) + this.selectedOpt = selectedOpt || this.el.querySelector( 'option' ); + + // create structure + this._createSelectEl(); + + // all options + this.selOpts = [].slice.call( this.selEl.querySelectorAll( 'li[data-option]' ) ); + + // total options + this.selOptsCount = this.selOpts.length; + + // current index + this.current = this.selOpts.indexOf( this.selEl.querySelector( 'li.cs-selected' ) ) || -1; + + // placeholder elem + this.selPlaceholder = this.selEl.querySelector( 'span.cs-placeholder' ); + + // init events + this._initEvents(); + } + + /** + * creates the structure for the select element + */ + SelectFx.prototype._createSelectEl = function() { + var self = this, options = '', createOptionHTML = function(el) { + var optclass = '', classes = '', link = ''; + + if( el.selectedOpt && !this.foundSelected && !this.hasDefaultPlaceholder ) { + classes += 'cs-selected '; + this.foundSelected = true; + } + // extra classes + if( el.getAttribute( 'data-class' ) ) { + classes += el.getAttribute( 'data-class' ); + } + // link options + if( el.getAttribute( 'data-link' ) ) { + link = 'data-link=' + el.getAttribute( 'data-link' ); + } + + if( classes !== '' ) { + optclass = 'class="' + classes + '" '; + } + + return '
  • ' + el.textContent + '
  • '; + }; + + [].slice.call( this.el.children ).forEach( function(el) { + if( el.disabled ) { return; } + + var tag = el.tagName.toLowerCase(); + + if( tag === 'option' ) { + options += createOptionHTML(el); + } + else if( tag === 'optgroup' ) { + options += '
  • ' + el.label + '
      '; + [].slice.call( el.children ).forEach( function(opt) { + options += createOptionHTML(opt); + } ) + options += '
  • '; + } + } ); + + var opts_el = '
      ' + options + '
    '; + this.selEl = document.createElement( 'div' ); + this.selEl.className = this.el.className; + this.selEl.tabIndex = this.el.tabIndex; + this.selEl.innerHTML = '' + this.selectedOpt.textContent + '' + opts_el; + this.el.parentNode.appendChild( this.selEl ); + this.selEl.appendChild( this.el ); + } + + /** + * initialize the events + */ + SelectFx.prototype._initEvents = function() { + var self = this; + + // open/close select + this.selPlaceholder.addEventListener( 'click', function() { + self._toggleSelect(); + } ); + + // clicking the options + this.selOpts.forEach( function(opt, idx) { + opt.addEventListener( 'click', function() { + self.current = idx; + self._changeOption(); + // close select elem + self._toggleSelect(); + } ); + } ); + + // close the select element if the target it´s not the select element or one of its descendants.. + document.addEventListener( 'click', function(ev) { + var target = ev.target; + if( self._isOpen() && target !== self.selEl && !hasParent( target, self.selEl ) ) { + self._toggleSelect(); + } + } ); + + // keyboard navigation events + this.selEl.addEventListener( 'keydown', function( ev ) { + var keyCode = ev.keyCode || ev.which; + + switch (keyCode) { + // up key + case 38: + ev.preventDefault(); + self._navigateOpts('prev'); + break; + // down key + case 40: + ev.preventDefault(); + self._navigateOpts('next'); + break; + // space key + case 32: + ev.preventDefault(); + if( self._isOpen() && typeof self.preSelCurrent != 'undefined' && self.preSelCurrent !== -1 ) { + self._changeOption(); + } + self._toggleSelect(); + break; + // enter key + case 13: + ev.stopPropagation(); + ev.preventDefault(); + if( self._isOpen() && typeof self.preSelCurrent != 'undefined' && self.preSelCurrent !== -1 ) { + self._changeOption(); + self._toggleSelect(); + } + break; + // esc key + case 27: + ev.preventDefault(); + if( self._isOpen() ) { + self._toggleSelect(); + } + break; + } + } ); + } + + /** + * navigate with up/dpwn keys + */ + SelectFx.prototype._navigateOpts = function(dir) { + if( !this._isOpen() ) { + this._toggleSelect(); + } + + var tmpcurrent = typeof this.preSelCurrent != 'undefined' && this.preSelCurrent !== -1 ? this.preSelCurrent : this.current; + + if( dir === 'prev' && tmpcurrent > 0 || dir === 'next' && tmpcurrent < this.selOptsCount - 1 ) { + // save pre selected current - if we click on option, or press enter, or press space this is going to be the index of the current option + this.preSelCurrent = dir === 'next' ? tmpcurrent + 1 : tmpcurrent - 1; + // remove focus class if any.. + this._removeFocus(); + // add class focus - track which option we are navigating + classie.add( this.selOpts[this.preSelCurrent], 'cs-focus' ); + } + } + + /** + * open/close select + * when opened show the default placeholder if any + */ + SelectFx.prototype._toggleSelect = function() { + // remove focus class if any.. + this._removeFocus(); + + if( this._isOpen() ) { + if( this.current !== -1 ) { + // update placeholder text + this.selPlaceholder.textContent = this.selOpts[ this.current ].textContent; + } + classie.remove( this.selEl, 'cs-active' ); + } + else { + if( this.hasDefaultPlaceholder && this.options.stickyPlaceholder ) { + // everytime we open we wanna see the default placeholder text + this.selPlaceholder.textContent = this.selectedOpt.textContent; + } + classie.add( this.selEl, 'cs-active' ); + } + } + + /** + * change option - the new value is set + */ + SelectFx.prototype._changeOption = function() { + // if pre selected current (if we navigate with the keyboard)... + if( typeof this.preSelCurrent != 'undefined' && this.preSelCurrent !== -1 ) { + this.current = this.preSelCurrent; + this.preSelCurrent = -1; + } + + // current option + var opt = this.selOpts[ this.current ]; + + // update current selected value + this.selPlaceholder.textContent = opt.textContent; + + // change native select element´s value + this.el.value = opt.getAttribute( 'data-value' ); + + // remove class cs-selected from old selected option and add it to current selected option + var oldOpt = this.selEl.querySelector( 'li.cs-selected' ); + if( oldOpt ) { + classie.remove( oldOpt, 'cs-selected' ); + } + classie.add( opt, 'cs-selected' ); + + // if there´s a link defined + if( opt.getAttribute( 'data-link' ) ) { + // open in new tab? + if( this.options.newTab ) { + window.open( opt.getAttribute( 'data-link' ), '_blank' ); + } + else { + window.location = opt.getAttribute( 'data-link' ); + } + } + + // callback + this.options.onChange( this.el.value ); + } + + /** + * returns true if select element is opened + */ + SelectFx.prototype._isOpen = function(opt) { + return classie.has( this.selEl, 'cs-active' ); + } + + /** + * removes the focus class from the option + */ + SelectFx.prototype._removeFocus = function(opt) { + var focusEl = this.selEl.querySelector( 'li.cs-focus' ) + if( focusEl ) { + classie.remove( focusEl, 'cs-focus' ); + } + } + + /** + * add to global namespace + */ + window.SelectFx = SelectFx; + +} )( window ); diff --git a/test-css-priority.html b/test-css-priority.html new file mode 100644 index 0000000..e659509 --- /dev/null +++ b/test-css-priority.html @@ -0,0 +1,11 @@ + + + Testing css priority + + + +

    + From now on I am not going to be in denial of my feelings. +

    + + \ No newline at end of file diff --git a/test-js.html b/test-js.html new file mode 100644 index 0000000..3e49f21 --- /dev/null +++ b/test-js.html @@ -0,0 +1,47 @@ + + + + + + + Fullscreen Form Interface + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test.html b/test.html new file mode 100644 index 0000000..10ae1cd --- /dev/null +++ b/test.html @@ -0,0 +1,107 @@ + + + + + + + Fullscreen Form Interface + + + + + + + + + + + + +
    + + + + + + +
    +
      +
    1. + + +
    2. +
    3. + + +
    4. +
    5. + + +
    6. +
    7. + + +
    8. +
    + +
    + + + + +
    + + + + + + \ No newline at end of file