From 4afef8215a764c20d34c96febd32d34b64dc8e60 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 5 Mar 2015 12:12:36 +1100 Subject: [PATCH] Basic implementation of single line selectors --- .../controllers/products_controller.js.coffee | 3 + .../directives/single_line_selector.coffee | 33 ++++++++ .../directives/taxon_selector.js.coffee | 12 ++- .../templates/taxon_selector.html.haml | 4 +- .../darkswarm/_shop-filters.css.sass | 17 ++-- app/views/shop/products/_filters.html.haml | 78 +++++++++---------- 6 files changed, 94 insertions(+), 53 deletions(-) create mode 100644 app/assets/javascripts/darkswarm/directives/single_line_selector.coffee diff --git a/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee b/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee index 019a09e96f..e18aebb267 100644 --- a/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee +++ b/app/assets/javascripts/darkswarm/controllers/products_controller.js.coffee @@ -9,6 +9,9 @@ Darkswarm.controller "ProductsCtrl", ($scope, $rootScope, Products, OrderCycle, $scope.limit = 3 $scope.order_cycle = OrderCycle.order_cycle + $scope.$watch "Products.loading", (newValue, oldValue) -> + $scope.$broadcast("loadTaxonSelectors") if !newValue + $scope.incrementLimit = -> if $scope.limit < Products.products.length $scope.limit = $scope.limit + 1 diff --git a/app/assets/javascripts/darkswarm/directives/single_line_selector.coffee b/app/assets/javascripts/darkswarm/directives/single_line_selector.coffee new file mode 100644 index 0000000000..5b154c42ac --- /dev/null +++ b/app/assets/javascripts/darkswarm/directives/single_line_selector.coffee @@ -0,0 +1,33 @@ +Darkswarm.directive 'singleLineSelector', ($timeout) -> + restrict: 'E' + link: (scope,element,attrs) -> + scope.activeTaxons = [] + scope.taxonSelectors = [] + + # From: http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing + debouncer = (func, timeout) -> + timeoutID = undefined + timeout = timeout or 200 + -> + subject = this + args = arguments + clearTimeout timeoutID + timeoutID = setTimeout(-> + func.apply subject, Array::slice.call(args) + , timeout) + + fit = -> + used = $(element).find("li.more").outerWidth(true) + available = $(element).parent(".filter-box").innerWidth() + $(element).find("li").not(".more").each (i) -> + used += $(this).outerWidth(true) + scope.taxonSelectors[i].fits = used <= available + return null # So we don't exit the loop on false + + scope.$watchCollection "taxonSelectors", -> + selector.fits = true for selector in scope.taxonSelectors + $timeout fit, 0, true + + $(window).resize debouncer (e) -> + scope.$apply -> selector.fits = true for selector in scope.taxonSelectors + $timeout fit, 0, true diff --git a/app/assets/javascripts/darkswarm/directives/taxon_selector.js.coffee b/app/assets/javascripts/darkswarm/directives/taxon_selector.js.coffee index 633ecd22f4..5fb67c8405 100644 --- a/app/assets/javascripts/darkswarm/directives/taxon_selector.js.coffee +++ b/app/assets/javascripts/darkswarm/directives/taxon_selector.js.coffee @@ -5,7 +5,8 @@ Darkswarm.directive "taxonSelector", (FilterSelectorsService)-> replace: true scope: objects: "&" - results: "=" + activeTaxons: "=" + taxonSelectors: "=" templateUrl: "taxon_selector.html" link: (scope, elem, attr)-> @@ -13,14 +14,17 @@ Darkswarm.directive "taxonSelector", (FilterSelectorsService)-> selectors = null # To get scoping/closure right scope.emit = -> - scope.results = selectors.filter (selector)-> + scope.activeTaxons = selectors.filter (selector)-> selector.active .map (selector)-> selector.taxon.id + scope.$on 'loadTaxonSelectors', -> + scope.taxonSelectors = scope.selectors() + # Build hash of unique taxons, each of which gets an ActiveSelector scope.selectors = -> - taxons = {} + taxons = {} selectors = [] for object in scope.objects() for taxon in object.taxons @@ -28,7 +32,7 @@ Darkswarm.directive "taxonSelector", (FilterSelectorsService)-> if object.supplied_taxons for taxon in object.supplied_taxons taxons[taxon.id] = taxon - + # Generate a selector for each taxon. # NOTE: THESE ARE MEMOIZED to stop new selectors from being created constantly, otherwise function always returns non-identical results # This means the $digest cycle can never close and times out diff --git a/app/assets/javascripts/templates/taxon_selector.html.haml b/app/assets/javascripts/templates/taxon_selector.html.haml index 02450c8d12..513225d6f4 100644 --- a/app/assets/javascripts/templates/taxon_selector.html.haml +++ b/app/assets/javascripts/templates/taxon_selector.html.haml @@ -1,3 +1,3 @@ -%active-selector{"ng-repeat" => "selector in selectors()"} - %render-svg{path: "{{selector.taxon.icon}}"} +%active-selector{"ng-repeat" => "selector in taxonSelectors", "ng-show" => "selector.fits"} + %render-svg{path: "{{selector.taxon.icon}}"} %span {{ selector.taxon.name }} diff --git a/app/assets/stylesheets/darkswarm/_shop-filters.css.sass b/app/assets/stylesheets/darkswarm/_shop-filters.css.sass index fbebe3a431..a714c4a361 100644 --- a/app/assets/stylesheets/darkswarm/_shop-filters.css.sass +++ b/app/assets/stylesheets/darkswarm/_shop-filters.css.sass @@ -1,7 +1,7 @@ @import mixins @import branding @import big-input -@import animations +@import animations // Alert when search, taxon, filter is triggered @@ -27,6 +27,10 @@ .filter-box.filter-box-shopfront, .filter-box.property-box-shopfront background: transparent + single-line-selector + overflow-x: hidden + white-space: nowrap + ul margin: 0 ul, ul li @@ -35,11 +39,11 @@ display: inline-block @include border-radius(0) padding: 0 - margin: 0 0 0.25rem 0.25rem + margin: 0 0 0.25rem 0.25rem &:hover, &:focus background: transparent - - li.active + + li.active @include box-shadow(none) a, a:hover, a:focus, a:active, a.active border: 1px solid $clr-blue @@ -52,7 +56,7 @@ li a @include border-radius(0.5em) border: 1px solid $clr-blue-light - padding: 0.625em + padding: 0.625em font-size: 0.875em color: $clr-blue font-size: 0.75em @@ -77,7 +81,7 @@ // Shopfront properties .filter-box.property-box-shopfront - li.active + li.active @include box-shadow(none) a, a:hover, a:focus, a:active, a.active border: 1px solid #333 @@ -89,4 +93,3 @@ &:hover, &:focus border: 1px solid #999 color: #666 - diff --git a/app/views/shop/products/_filters.html.haml b/app/views/shop/products/_filters.html.haml index 61f807c684..6b8a9de1a7 100644 --- a/app/views/shop/products/_filters.html.haml +++ b/app/views/shop/products/_filters.html.haml @@ -1,45 +1,43 @@ .filter-box.filter-box-shopfront.animate-hide.text-right - %ul - %taxon-selector{objects: "Products.products | products:query | products:showProfiles", - results: "activeTaxons"} + %single-line-selector + %ul + %taxon-selector{objects: "Products.products | products:query | products:showProfiles", + "active-taxons" => "activeTaxons", "taxon-selectors" => "taxonSelectors" } - %li - %a - %span - + 7 more - %i.ofn-i_052-point-down + %li.more + %a + %span + + {{ (taxonSelectors | filter:{ fits: false }).length }} more + %i.ofn-i_052-point-down - / TODO: Needs controller for Angular Bootstrap directive for dropdown: - / {"ng-controller" => "DropdownCtrl"} - - / %li - / .btn-group{:dropdown => "", "is-open" => "status.isopen"} - / %button.btn.btn-primary.dropdown-toggle{"dropdown-toggle" => "", "ng-disabled" => "disabled", :type => "button"} - / + 7 more - / %span.caret - / %ul.dropdown-menu{:role => "menu"} - / %li - / %a{:href => "#"} Action - / %li - / %a{:href => "#"} Another action - / %li - / %a{:href => "#"} Something else here - / %li.divider - / %li - / %a{:href => "#"} Separated link + / TODO: Needs controller for Angular Bootstrap directive for dropdown: + / {"ng-controller" => "DropdownCtrl"} -.filter-box.property-box-shopfront.animate-hide.text-right - %ul - %li - %a Organic Certified - %li - %a Free Range - %li - %a Biodynamic - %li - %a - + 2 more - %span.caret + / %li + / .btn-group{:dropdown => "", "is-open" => "status.isopen"} + / %button.btn.btn-primary.dropdown-toggle{"dropdown-toggle" => "", "ng-disabled" => "disabled", :type => "button"} + / + 7 more + / %span.caret + / %ul.dropdown-menu{:role => "menu"} + / %li + / %a{:href => "#"} Action + / %li + / %a{:href => "#"} Another action + / %li + / %a{:href => "#"} Something else here + / %li.divider + / %li + / %a{:href => "#"} Separated link - - \ No newline at end of file +-# .filter-box.property-box-shopfront.animate-hide.text-right +-# %ul +-# %li +-# %a Organic Certified +-# %li +-# %a Free Range +-# %li +-# %a Biodynamic +-# %li +-# %a +-# + 2 more +-# %span.caret