Template source: components/advanced_sidebar.html

<template id="adv-layer-group-template"> <div class="group" data-bind="attr: { id: slug() + '-group' }, css: { inactive: !visible() }"> <div class="group-folder" data-bind="click: ace.webMap.addGroupViewPane"> <div class="group-name collapsed"> <span data-bind="text: name"></span> <span><i class="fa fa-angle-right" aria-hidden="true"></i></span> </div> </div> <div class="group-contents collapse" data-bind="attr: {id: slug() + '-group-contents'}"> <div class="groups" data-bind="template: {name: 'layer-group-template', foreach: groups}"></div> <div class="layers" data-bind="template: {name: 'layer-template', foreach: layers}"></div> </div> </div> </template> <template id="viewpane-template"> <div class="viewpane" data-bind="attr: {id: 'viewpane-' + groupId}"> <div id="layers-groups"> <div class="layer master-ctrls" > <!-- ko if: masterCtrls --> <span class="layer-master-btn" data-bind="click: $parent.showAll.bind(layers)">Show All</span> <span class="layer-master-btn" data-bind="click: $parent.hideAll.bind(layers)">Hide All</span> <!-- /ko --> </div> <div class="groups" data-bind="template: { name: 'adv-layer-group-template', foreach: groups }"></div> <div class="layers" data-bind="template: { name: 'layer-template', foreach: layers }"></div> </div> </div> </template> <template id="advanced-sidebar-template"> <div class="path-bar"> <span class="navigation"> <span class="layer-mananger-menu-btn" data-bind="click: ace.webMap.layerManagerButtonAction"> <i class="fa fa-th-large" aria-hidden="true"></i> <span>Main Menu</span> </span> <span class="path" data-bind="foreach: panes"> <!-- ko if: groupId != 'root' --> <span><i class="fa fa-caret-right" aria-hidden="true"></i></span> <span class="nav-element" data-bind="text: groupName, attr: { id: 'nav-item-' + groupName }, click: ace.webMap.goToViewPane"></span> <!-- /ko --> </span> </span> <div id="div-search-container"> <span class="glyphicon glyphicon-search" ></span> <input id="search-input" type="text" data-bind="textInput: webmap.searchQuery" placeholder="Search active layers"> <span id="help-button" class="glyphicon glyphicon-question-sign" data-toggle="modal" data-target="#search-help"></span> </div> </div> <div id="div-search-results" class="adv-search-results" data-bind="visible: webmap.searchResultsTotal() > 0"> <div id="div-search-results-count"> <span class="total-results" data-bind="text: webmap.searchResultsTotalLabel"></span> <i class="fa fa-close" data-bind="click: webmap.clearSearchQuery()"></i> </div> <div id="div-search-results-list" data-bind="template: { name: 'search-result-template', foreach: webmap.allLayers }"></div> </div> <div class="close-sidebar-btn" data-bind="css: { visible: visible }, click: ace.webMap.hideLayerManager"> <i class="fa fa-times" aria-hidden="true"></i> </div> <div class="advanced-sidebar" data-bind="css: { visible: visible }"> {% if user.is_authenticated %} <div class="viewpanes with-user-info" data-bind="template: {name: 'viewpane-template', foreach: panes}"></div> <div class="user-info-panel"> <i class="fa fa-user-circle-o portrait" aria-hidden="true"></i> <span class="username">{{ user.first_name }} {{ user.last_name }}</span> <a class="logout-action" href='{% url "logout" %}?next={% url "login" %}' title="Log out"> <i class="fa fa-sign-out" aria-hidden="true"></i> </a> </div> {% else %} <div class="viewpanes" data-bind="template: {name: 'viewpane-template', foreach: panes}"></div> {% endif %} </div> </template> <script type="text/javascript"> ko.components.register('advanced-sidebar', { viewModel: function(params) { var self = this; var VIEWPANE_WIDTH = 345; // making this a constant for now self.groups = params.groups; self.layers = params.layers; self.webmap = params.webmap; self.visible = ko.observable(true); // This will act as a stack of view panes. The current pane is at the top self.panes = ko.observableArray(); self.push = function(viewPane) { self.panes.push(viewPane); }; self.hasHistory = ko.computed(function() { return self.panes().length > 1; }); self.showAll = function(view){ // console.log("Crystal layers",layers); $.each(view.layers,function(index,layer){ layer.active(true); }) } self.hideAll = function(view){ // console.log("Crystal layers",layers); $.each(view.layers,function(index,layer){ layer.active(false); }) } // Initialization self.init = function() { // Add the first pane self.panes.push({ 'groups': self.groups, 'layers': self.layers, 'groupId': 'root', 'groupName': '', 'masterCtrls': false }); }; // Add the groupViewPane management functions to the webmap // Need to group these nicely params.webmap.addGroupViewPane = function(layerGroup) { var viewPane = { 'groups': layerGroup.groups(), 'layers': layerGroup.layers(), 'groupId': layerGroup.slug(), 'groupName': layerGroup.name(), 'masterCtrls': layerGroup.hasGroups() }; var numPanes = self.panes().length; var currentViewPane = self.panes()[numPanes - 1]; if (currentViewPane) { if (currentViewPane.groupId != layerGroup.slug()) { self.panes.push(viewPane); } // else do nothing, the viewPane is already on the stack } else { self.panes.push(viewPane); } // Animation: var scrollPosition = VIEWPANE_WIDTH * (self.panes().length - 1); $('.advanced-sidebar').animate({ scrollLeft: scrollPosition }, 200); }; params.webmap.previousPane = function() { if (self.hasHistory()) { var scrollPosition = VIEWPANE_WIDTH * (self.panes().length - 2); $('.advanced-sidebar').animate({ scrollLeft: scrollPosition }, 200, function() { self.panes.pop(); }); } }; params.webmap.layerManagerButtonAction = function () { // Show menu if it is hidden if (!self.visible()) { self.visible(true); } else { // if it is visible, go back to the main list if (self.hasHistory()) { var scrollPosition = 0; $('.advanced-sidebar').animate({ scrollLeft: scrollPosition }, 200, function() { var lastIndex = self.panes().length - 1; self.panes.splice(1, lastIndex); }); } } // clicking the path bar should also show the layer manager }; params.webmap.hideLayerManager = function() { self.visible(false); } params.webmap.goToViewPane = function(viewPane) { console.log('Show view pane: ', viewPane); var index = self.panes.indexOf(viewPane); if (index >= 0) { var scrollPosition = VIEWPANE_WIDTH * index; $('.advanced-sidebar').animate({ scrollLeft: scrollPosition }, 200, function() { var lastIndex = self.panes().length - 1; self.panes.splice(index + 1, lastIndex); }); } }; self.init(); }, // template: { element: 'advanced-sidebar-template' } template: { element: 'advanced-sidebar-template' } }); </script> <advanced-sidebar params="webmap: $root, groups: groups, layers: layers"></advanced-sidebar>