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"> </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