]> _ Git - fluidbook-v3.git/commitdiff
WIP #554 @2
authorstephen@cubedesigners.com <stephen@cubedesigners.com@f5622870-0f3c-0410-866d-9cb505b7a8ef>
Mon, 18 Jul 2016 18:23:47 +0000 (18:23 +0000)
committerstephen@cubedesigners.com <stephen@cubedesigners.com@f5622870-0f3c-0410-866d-9cb505b7a8ef>
Mon, 18 Jul 2016 18:23:47 +0000 (18:23 +0000)
framework/application/views/helpers/QuoteForm.php
js/005-fancyselect.js [new file with mode: 0644]
js/315-quote.js
less/003-mixins.less
less/005-fancyselect.less [new file with mode: 0644]
less/315-quote.less

index ceb9820413db9623c0b837be51995a9baf2c5f5c..147d1368dd68b5b427d9d84c05a99c23b8cc10e7 100644 (file)
@@ -4,7 +4,8 @@ class Fluidbook_View_Helper_QuoteForm extends CubeIT_View_Helper_Abstract {
 
        public function quoteForm($formID = null) {
 
-               $this->headScript()->addScriptAndStyle('315-quote');
+        $this->headScript()->addScriptAndStyle('005-fancyselect');
+        $this->headScript()->addScriptAndStyle('315-quote');
 
                $form = new Fluidbook_Form_RequestQuote();
 
diff --git a/js/005-fancyselect.js b/js/005-fancyselect.js
new file mode 100644 (file)
index 0000000..083548a
--- /dev/null
@@ -0,0 +1,212 @@
+/* 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
index ef57c3eab4ebc3f7c992a69708d5826c3d1c59ed..58d95974e224e88ccc20186e927d90fdbab0dc31 100644 (file)
@@ -1,3 +1,10 @@
+registerLoader(load_quoteform, true);
+
+function load_quoteform() {
+    $('#requestQuote select').fancySelect();
+}
+
+
 function displayErrors() {
 
     var errors = [];
index a0fe580891d7d4a5147df6df827224692adfb10c..0b863ec37801b3eed7803d71055c7fac1bd1ff02 100644 (file)
        -moz-osx-font-smoothing: auto;
 }
 
+.icon(@char) {
+       content: @char;
+       font-family: @icons;
+       .font-thinning();
+}
+
 .button(@line-height: 54px, @horizontal-padding: 20px) {
        display: inline-block;
        border: 0;
diff --git a/less/005-fancyselect.less b/less/005-fancyselect.less
new file mode 100644 (file)
index 0000000..5dd410d
--- /dev/null
@@ -0,0 +1,125 @@
+@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
index 81d2c86cb41d252e81ba59b69e85d2f911d387fa..e42444b0891cb7984fe3ec1c93176935fc9c21b6 100644 (file)
                }
        }
 
-       select {
-               background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAICAYAAADuv08kAAAAnElEQVQoz2M4f/Hy8UNHjv8nhC9cunL4379/zAzUAt++f1c7cuzkN3yWAuW/ANUpM1AbPHn6rACfxU+fPc9hoAUABiHTxctXDmCz9NLlq3v+///PyEAr8P37D6Wjx09+RrYUyP/048cPeQZag2fPX2QgW/z8xctkBnoAUJBeunJtF8jSy1evb6NpEKMDYNDKnTpz7v7Pnz+laGkPAKftxKb2aSY8AAAAAElFTkSuQmCC');
-               background-position: center right;
-               background-repeat: no-repeat;
-               padding-right: 40px;
-       }
-
        textarea {
                line-height: 1.4;
                padding: 15px;