Milimetric has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/159407

Change subject: [WIP] Add toggle functionality
......................................................................

[WIP] Add toggle functionality

Change-Id: I6e81143ffbe0ecc1adf32089c295311811193abc
---
A src/app/global-bindings.js
M src/app/startup.js
M src/components/metric-selector/metric-selector.html
M src/components/metric-selector/metric-selector.js
4 files changed, 78 insertions(+), 10 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/analytics/dashiki 
refs/changes/07/159407/1

diff --git a/src/app/global-bindings.js b/src/app/global-bindings.js
new file mode 100644
index 0000000..20ed236
--- /dev/null
+++ b/src/app/global-bindings.js
@@ -0,0 +1,64 @@
+define(['knockout', 'jquery'], function(ko) {
+    /**
+     * Convention-based binding that expects html like this:
+     *   <div data-bind="toggle: 'observableName'">... style this as the 
trigger that toggles ...</div>
+     *   <div class="... target">... style this as the target that is being 
toggled ...</div>
+     *
+     * With this setup, clicking on the trigger will cause the target to 
toggle on and off
+     *   an observable named "observableName" in the bindingContext.$data
+     * Also, the target will be turned off if the user clicks outside of it
+     */
+    function Toggle (element, observable) {
+        this.trigger = element;
+        this.observable = observable;
+    }
+    ko.bindingHandlers.toggle = {
+        init: function(element, valueAccessor, allBindings, viewModel, 
bindingContext){
+            var open = ko.observable(false),
+                target = 
$(element).next(ko.bindingHandlers.toggle.targetSelector),
+                observableName = valueAccessor();
+
+            // add an observable named according to the binding
+            bindingContext.$data[observableName] = open;
+
+            $(element).addClass(ko.bindingHandlers.toggle.triggerClass);
+            target.addClass(ko.bindingHandlers.toggle.targetClass);
+
+            ko.bindingHandlers.toggle.toggles.push(new Toggle(element, open));
+
+            return {
+                controlsDescendantBindings: false
+            };
+        }
+    };
+    ko.bindingHandlers.toggle.toggles = [];
+    ko.bindingHandlers.toggle.targetClass = 'target';
+    ko.bindingHandlers.toggle.targetSelector = '.target';
+    ko.bindingHandlers.toggle.triggerClass = 'trigger';
+    ko.bindingHandlers.toggle.triggerSelector = '.trigger';
+
+    $(window).on('click', function (event) {
+        var hitTarget = 
$(event.target).closest(ko.bindingHandlers.toggle.targetSelector);
+
+        if (hitTarget && hitTarget.length) {
+            return;
+        }
+
+        var hitTrigger = 
$(event.target).closest(ko.bindingHandlers.toggle.triggerSelector);
+        // if a trigger was hit, find it in the cached toggle array and toggle 
it
+        if (hitTrigger && hitTrigger.length) {
+            var toggle = ko.bindingHandlers.toggle.toggles.find(function 
(toggle) {
+                return toggle.trigger === hitTrigger[0];
+            });
+            if (toggle) {
+                toggle.observable(!toggle.observable());
+            }
+            return;
+        }
+
+        // if no target and no trigger was clicked, close all targets through 
their observables
+        ko.bindingHandlers.toggle.toggles.forEach(function (toggle) {
+            toggle.observable(false);
+        });
+    });
+});
diff --git a/src/app/startup.js b/src/app/startup.js
index da437d4..afa3880 100644
--- a/src/app/startup.js
+++ b/src/app/startup.js
@@ -2,7 +2,7 @@
 All requires below live on global scope.
 There is no need to specify them as such
 **/
-define(['knockout', 'jquery', 'ajaxWrapper','logger'], function(ko) {
+define(['knockout', 'jquery', 'ajaxWrapper', 'logger', './global-bindings'], 
function(ko) {
 
     'use strict';
 
diff --git a/src/components/metric-selector/metric-selector.html 
b/src/components/metric-selector/metric-selector.html
index f1d42b9..88e714a 100644
--- a/src/components/metric-selector/metric-selector.html
+++ b/src/components/metric-selector/metric-selector.html
@@ -1,17 +1,10 @@
-<div class="ui dropdown orange label" data-bind="click: toggle">
+<div class="ui dropdown orange label" data-bind="toggle: 'open'">
     <i class="add sign box icon"></i>
     <!-- ko ifnot: selectedMetric -->
     <div class="text" data-bind="text: open() ? 'Close' : 'Add Metric'"></div>
     <!-- /ko -->
     <i class="dropdown icon vertically" data-bind="css: {flipped: open}"></i>
 </div>
-
-<!-- ko foreach: addedMetrics -->
-<div class="ui large label" data-bind="css: {teal: $data === 
$parent.selectedMetric()}">
-    <a data-bind="click: $parent.selectMetric, metricName: $data"></a>
-    <i class="delete icon" data-bind="click: $parent.removeMetric"></i>
-</div>
-<!-- /ko -->
 
 <div class="ui two column grid target" data-bind="css: {open: open}">
     <div class="column">
@@ -28,6 +21,11 @@
     <div class="column">
         <div class="ui vertical menu">
         <!-- ko if: selectedCategory -->
+        <!-- ko foreach: categories -->
+            <!-- ko if: $data.name < $parent.selectedCategory().name -->
+            <div class="item">&nbsp;</div>
+            <!-- /ko -->
+        <!-- /ko -->
         <!-- ko foreach: selectedCategory().metrics -->
             <a class="item" data-bind="metricName: $data, click: 
$parent.addMetric"></a>
         <!-- /ko -->
@@ -35,3 +33,10 @@
         </div>
     </div>
 </div>
+
+<!-- ko foreach: addedMetrics -->
+<div class="ui large label" data-bind="css: {teal: $data === 
$parent.selectedMetric()}">
+    <a data-bind="click: $parent.selectMetric, metricName: $data"></a>
+    <i class="delete icon" data-bind="click: $parent.removeMetric"></i>
+</div>
+<!-- /ko -->
diff --git a/src/components/metric-selector/metric-selector.js 
b/src/components/metric-selector/metric-selector.js
index 9542909..47dcc03 100644
--- a/src/components/metric-selector/metric-selector.js
+++ b/src/components/metric-selector/metric-selector.js
@@ -35,7 +35,6 @@
     function MetricSelector(params) {
         var self = this;
 
-        this.open = ko.observable(false);
         this.toggle = function () {
             this.open(!this.open());
         };

-- 
To view, visit https://gerrit.wikimedia.org/r/159407
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I6e81143ffbe0ecc1adf32089c295311811193abc
Gerrit-PatchSet: 1
Gerrit-Project: analytics/dashiki
Gerrit-Branch: master
Gerrit-Owner: Milimetric <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to