--- /dev/null
+/* https://github.com/paulstraw/FancySelect */
+(function() {
+ var $;
+
+ $ = window.jQuery || window.Zepto || window.$;
+
+ $.fn.fancySelect = function(opts) {
+ var isiOS, settings;
+ if (opts == null) {
+ opts = {};
+ }
+ settings = $.extend({
+ forceiOS: false,
+ includeBlank: false,
+ optionTemplate: function(optionEl) {
+ return optionEl.text();
+ },
+ triggerTemplate: function(optionEl) {
+ return optionEl.text();
+ }
+ }, opts);
+ isiOS = !!navigator.userAgent.match(/iP(hone|od|ad)/i);
+ return this.each(function() {
+ var copyOptionsToList, disabled, options, sel, trigger, updateTriggerText, wrapper;
+ sel = $(this);
+ if (sel.hasClass('fancified') || sel[0].tagName !== 'SELECT') {
+ return;
+ }
+ sel.addClass('fancified');
+ sel.css({
+ width: 1,
+ height: 1,
+ display: 'block',
+ position: 'absolute',
+ top: 0,
+ left: 0,
+ opacity: 0
+ });
+ sel.wrap('<div class="fancy-select">');
+ wrapper = sel.parent();
+ if (sel.data('class')) {
+ wrapper.addClass(sel.data('class'));
+ }
+ wrapper.append('<div class="trigger">');
+ if (!(isiOS && !settings.forceiOS)) {
+ wrapper.append('<ul class="options">');
+ }
+ trigger = wrapper.find('.trigger');
+ options = wrapper.find('.options');
+ disabled = sel.prop('disabled');
+ if (disabled) {
+ wrapper.addClass('disabled');
+ }
+ updateTriggerText = function() {
+ var triggerHtml;
+ triggerHtml = settings.triggerTemplate(sel.find(':selected'));
+ return trigger.html(triggerHtml);
+ };
+ sel.on('blur.fs', function() {
+ if (trigger.hasClass('open')) {
+ return setTimeout(function() {
+ return trigger.trigger('close.fs');
+ }, 120);
+ }
+ });
+ trigger.on('close.fs', function() {
+ trigger.removeClass('open');
+ return options.removeClass('open');
+ });
+ trigger.on('click.fs', function() {
+
+ // Close if it is already open
+ if(trigger.hasClass('open')) {
+ return trigger.trigger('close.fs');
+ }
+
+ var offParent, parent;
+ if (!disabled) {
+ trigger.toggleClass('open');
+ if (isiOS && !settings.forceiOS) {
+ if (trigger.hasClass('open')) {
+ return sel.focus();
+ }
+ } else {
+ if (trigger.hasClass('open')) {
+ parent = trigger.parent();
+ offParent = parent.offsetParent();
+ if ((parent.offset().top + parent.outerHeight() + options.outerHeight() + 20) > $(window).height() + $(window).scrollTop()) {
+ options.addClass('overflowing');
+ } else {
+ options.removeClass('overflowing');
+ }
+ }
+ options.toggleClass('open');
+ if (!isiOS) {
+ return sel.focus();
+ }
+ }
+ }
+ });
+ sel.on('enable', function() {
+ sel.prop('disabled', false);
+ wrapper.removeClass('disabled');
+ disabled = false;
+ return copyOptionsToList();
+ });
+ sel.on('disable', function() {
+ sel.prop('disabled', true);
+ wrapper.addClass('disabled');
+ return disabled = true;
+ });
+ sel.on('change.fs', function(e) {
+ if (e.originalEvent && e.originalEvent.isTrusted) {
+ return e.stopPropagation();
+ } else {
+ return updateTriggerText();
+ }
+ });
+ sel.on('keydown', function(e) {
+ var hovered, newHovered, w;
+ w = e.which;
+ hovered = options.find('.hover');
+ hovered.removeClass('hover');
+ if (!options.hasClass('open')) {
+ if (w === 13 || w === 32 || w === 38 || w === 40) {
+ e.preventDefault();
+ return trigger.trigger('click.fs');
+ }
+ } else {
+ if (w === 38) {
+ e.preventDefault();
+ if (hovered.length && hovered.index() > 0) {
+ hovered.prev().addClass('hover');
+ } else {
+ options.find('li:last-child').addClass('hover');
+ }
+ } else if (w === 40) {
+ e.preventDefault();
+ if (hovered.length && hovered.index() < options.find('li').length - 1) {
+ hovered.next().addClass('hover');
+ } else {
+ options.find('li:first-child').addClass('hover');
+ }
+ } else if (w === 27) {
+ e.preventDefault();
+ trigger.trigger('click.fs');
+ } else if (w === 13 || w === 32) {
+ e.preventDefault();
+ hovered.trigger('mousedown.fs');
+ } else if (w === 9) {
+ if (trigger.hasClass('open')) {
+ trigger.trigger('close.fs');
+ }
+ }
+ newHovered = options.find('.hover');
+ if (newHovered.length) {
+ options.scrollTop(0);
+ return options.scrollTop(newHovered.position().top - 12);
+ }
+ }
+ });
+ options.on('mousedown.fs', 'li', function(e) {
+ var clicked;
+ clicked = $(this);
+ sel.val(clicked.data('raw-value'));
+ if (!isiOS) {
+ sel.trigger('blur.fs').trigger('focus.fs');
+ }
+ options.find('.selected').removeClass('selected');
+ clicked.addClass('selected');
+ trigger.addClass('selected');
+ return sel.val(clicked.data('raw-value')).trigger('change.fs').trigger('blur.fs').trigger('focus.fs');
+ });
+ options.on('mouseenter.fs', 'li', function() {
+ var hovered, nowHovered;
+ nowHovered = $(this);
+ hovered = options.find('.hover');
+ hovered.removeClass('hover');
+ return nowHovered.addClass('hover');
+ });
+ options.on('mouseleave.fs', 'li', function() {
+ return options.find('.hover').removeClass('hover');
+ });
+ copyOptionsToList = function() {
+ var selOpts;
+ updateTriggerText();
+ if (isiOS && !settings.forceiOS) {
+ return;
+ }
+ selOpts = sel.find('option');
+ return sel.find('option').each(function(i, opt) {
+ var optHtml;
+ opt = $(opt);
+ if (!opt.prop('disabled') && (opt.val() || settings.includeBlank)) {
+ optHtml = settings.optionTemplate(opt);
+ if (opt.prop('selected')) {
+ return options.append("<li data-raw-value=\"" + (opt.val()) + "\" class=\"selected\">" + optHtml + "</li>");
+ } else {
+ return options.append("<li data-raw-value=\"" + (opt.val()) + "\">" + optHtml + "</li>");
+ }
+ }
+ });
+ };
+ sel.on('update.fs', function() {
+ wrapper.find('.options').empty();
+ return copyOptionsToList();
+ });
+ return copyOptionsToList();
+ });
+ };
+
+}).call(this);
\ No newline at end of file
--- /dev/null
+@import "000-imports";
+
+div.fancy-select {
+ position: relative;
+ font-weight: 300;
+ font-size: inherit;
+
+ &.disabled {
+ opacity: 0.5;
+ }
+
+ select:focus + div.trigger {
+ //box-shadow: 0 0 0 1px #aaa; // Outline box
+ }
+
+ select:focus + div.trigger.open {
+ box-shadow: none;
+ }
+
+ div.trigger {
+ box-sizing: content-box; // To match other input elements
+ cursor: pointer;
+ padding: 0 2.2em 0 0.4em;
+ line-height: 3.4;
+ min-height: 3.4em;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ position: relative;
+ background: #fff;
+ border: 1px solid #000;
+ color: #aaa; // Placeholder text
+ z-index: 2;
+ transition: all 140ms ease-out;
+
+ &.selected {
+ color: #323232;
+ }
+
+ // Arrow
+ &:after {
+ .icon('V');
+ display: block;
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ color: #c2c4c7;
+ font-size: 1.7em; // Relative to select box font size
+ width: 2em; // Adjust to match font-size for arrow icon (3.4/1.7 = 2em)
+ line-height: 2em;
+ text-align: center;
+ }
+
+ &.open {
+ box-shadow: none;
+
+ &:after {
+ // adjustments to dropdown arrow when select is open
+ }
+ }
+ }
+
+ ul.options {
+ list-style: none;
+ margin: 0;
+ position: absolute;
+ top: 105%;
+ left: 0;
+ visibility: hidden;
+ opacity: 0;
+ z-index: 1;
+ //max-height: 0; // Start hidden and expand up
+ max-height: 12.8em;
+ width: 100%;
+ overflow: auto;
+ background: #f8f8f8;
+ //border-top: 1px solid #7DD8D2;
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
+ transition: all 150ms ease-out;
+
+ &.open {
+ z-index: 10;
+ visibility: visible;
+ opacity: 1;
+ max-height: 12.8em; // Each item is 80% of 2em high. We want to show 8 so: 8*2*0.8 = 12.8
+
+ /* have to use a non-visibility transition to prevent this iOS issue (bug?): */
+ /*http://stackoverflow.com/questions/10736478/css-animation-visibility-visible-works-on-chrome-and-safari-but-not-on-ios*/
+ //transition: opacity, max-height 200ms ease-out;
+ }
+
+ &.overflowing {
+ top: auto;
+ bottom: 110%;
+
+ &.open {
+ //transition: opacity, max-height 300ms ease-out;
+ }
+ }
+
+ li {
+ font-size: 80%;
+ line-height: 2;
+ padding: 0 12px;
+ color: #323232;
+ cursor: pointer;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ //transition: all 100ms ease-out;
+
+ &.selected {
+ background: rgba(200,200,200,0.3);
+ color: #000;
+ }
+
+ &.hover {
+ background: #ddd;
+ color: #000;
+ }
+ }
+ }
+
+}
\ No newline at end of file