|
|
@@ -0,0 +1,160 @@
|
|
|
+## Licensed to Cloudera, Inc. under one
|
|
|
+## or more contributor license agreements. See the NOTICE file
|
|
|
+## distributed with this work for additional information
|
|
|
+## regarding copyright ownership. Cloudera, Inc. licenses this file
|
|
|
+## to you under the Apache License, Version 2.0 (the
|
|
|
+## "License"); you may not use this file except in compliance
|
|
|
+## with the License. You may obtain a copy of the License at
|
|
|
+##
|
|
|
+## http://www.apache.org/licenses/LICENSE-2.0
|
|
|
+##
|
|
|
+## Unless required by applicable law or agreed to in writing, software
|
|
|
+## distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
+## See the License for the specific language governing permissions and
|
|
|
+## limitations under the License.
|
|
|
+
|
|
|
+<%!
|
|
|
+from desktop import conf
|
|
|
+from desktop.lib.i18n import smart_unicode
|
|
|
+from django.utils.translation import ugettext as _
|
|
|
+from desktop.views import _ko
|
|
|
+%>
|
|
|
+
|
|
|
+<%def name="all()">
|
|
|
+ <script type="text/html" id="hue-drop-down-template">
|
|
|
+ <!-- ko if: !dropDownVisible() || !searchable -->
|
|
|
+ <a class="inactive-action active-database margin-left-10" href="javascript:void(0)" data-bind="toggle: dropDownVisible, css: { 'blue': dropDownVisible }">
|
|
|
+ <span data-bind="text: value, visible: ! dropDownVisible()" title="${ _('Selected database') }"></span>
|
|
|
+ <i class="fa fa-caret-down"></i>
|
|
|
+ </a>
|
|
|
+ <!-- /ko -->
|
|
|
+ <!-- ko if: dropDownVisible() && searchable -->
|
|
|
+ <input class="hue-drop-down-input" type="text" data-bind="textInput: filter, attr: { 'placeHolder': value }, visible: dropDownVisible, style: { color: filterEdited() ? '#000' : '#AAA', 'min-height': '22px', 'margin-left': '10px' }"/>
|
|
|
+ <i class="fa fa-caret-down"></i>
|
|
|
+ <!-- /ko -->
|
|
|
+ <div data-bind="css: { 'open' : dropDownVisible }" style="position: absolute;">
|
|
|
+ <div class="dropdown-menu" data-bind="visible: filteredEntries().length > 0" style="overflow-y: scroll; width: 190px; margin-left: 10px; min-height: 34px; max-height: 200px;">
|
|
|
+ <!-- ko if: foreachVisible -->
|
|
|
+ <ul class="hue-inner-drop-down" data-bind="foreachVisible: { data: filteredEntries, minHeight: 34, container: '.dropdown-menu' }">
|
|
|
+ <li><a href="javascript:void(0)" data-bind="text: $data, click: function () { $parent.value($data); }"></a></li>
|
|
|
+ </ul>
|
|
|
+ <!-- /ko -->
|
|
|
+ <!-- ko ifnot: foreachVisible -->
|
|
|
+ <ul class="hue-inner-drop-down" data-bind="foreach: filteredEntries">
|
|
|
+ <li><a href="javascript:void(0)" data-bind="text: $data, click: function () { $parent.value($data); }"></a></li>
|
|
|
+ </ul>
|
|
|
+ <!-- /ko -->
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </script>
|
|
|
+
|
|
|
+ <script type="text/javascript" charset="utf-8">
|
|
|
+ (function () {
|
|
|
+ var HueDropDown = function (params, element) {
|
|
|
+ var self = this;
|
|
|
+ self.dropDownVisible = ko.observable(false);
|
|
|
+ self.value = params.value;
|
|
|
+ self.entries = params.entries;
|
|
|
+ self.searchable = params.searchable || false;
|
|
|
+ self.foreachVisible = params.foreachVisible || false;
|
|
|
+
|
|
|
+ var closeOnOutsideClick = function (e) {
|
|
|
+ var $input = $(element).find('.hue-drop-down-input');
|
|
|
+ if (!$input.is($(e.target))) {
|
|
|
+ self.dropDownVisible(false);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ var inputKeyup = function (e) {
|
|
|
+ var $currentActive = $(element).find('.hue-inner-drop-down > .active');
|
|
|
+ var activeTop = $currentActive.length !== 0 ? $currentActive.position().top : 0;
|
|
|
+ var activeHeight = $currentActive.length !== 0 ? $currentActive.outerHeight(true) : $(element).find('.hue-inner-drop-down li:first-child').outerHeight(true);
|
|
|
+ var containerHeight = $(element).find('.dropdown-menu').innerHeight();
|
|
|
+ var containerScrollTop = $(element).find('.dropdown-menu').scrollTop();
|
|
|
+
|
|
|
+ $currentActive.removeClass('active');
|
|
|
+ if (e.keyCode === 27) {
|
|
|
+ // esc
|
|
|
+ self.dropDownVisible(false);
|
|
|
+ } else if (e.keyCode === 38) {
|
|
|
+ // up
|
|
|
+ if ($currentActive.length !== 0 && $currentActive.prev().length !== 0) {
|
|
|
+ if (activeTop < containerScrollTop + activeHeight) {
|
|
|
+ $(element).find('.dropdown-menu').scrollTop(activeTop - containerHeight/2);
|
|
|
+ }
|
|
|
+ $currentActive.prev().addClass('active');
|
|
|
+ }
|
|
|
+ } else if (e.keyCode === 40) {
|
|
|
+ // down
|
|
|
+ if ($currentActive.length === 0) {
|
|
|
+ $(element).find('.hue-inner-drop-down li:first-child').addClass('active');
|
|
|
+ } else if ($currentActive.next().length !== 0) {
|
|
|
+ if ((activeTop + activeHeight *3) > containerHeight - containerScrollTop) {
|
|
|
+ $(element).find('.dropdown-menu').scrollTop(activeTop - containerHeight/2);
|
|
|
+ }
|
|
|
+ $currentActive.next().addClass('active');
|
|
|
+ } else {
|
|
|
+ $currentActive.addClass('active');
|
|
|
+ }
|
|
|
+ } else if (e.keyCode === 13) {
|
|
|
+ // enter
|
|
|
+ if ($currentActive.length > 0) {
|
|
|
+ self.value(ko.dataFor($currentActive[0]));
|
|
|
+ self.dropDownVisiblele(false);
|
|
|
+ $(element).find('.dropdown-menu').scrollTop(0)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ $(element).find('.dropdown-menu').scrollTop(0)
|
|
|
+ }
|
|
|
+ };
|
|
|
+ self.filter = ko.observable('');
|
|
|
+
|
|
|
+ self.value.subscribe(function () {
|
|
|
+ self.dropDownVisible(false);
|
|
|
+ });
|
|
|
+
|
|
|
+ self.filterEdited = ko.observable(false);
|
|
|
+
|
|
|
+ self.filter.subscribe(function () {
|
|
|
+ self.filterEdited(true);
|
|
|
+ $(element).find('.hue-inner-drop-down > .active').removeClass('.active');
|
|
|
+ });
|
|
|
+ self.dropDownVisible.subscribe(function (newValue) {
|
|
|
+ self.filterEdited(false);
|
|
|
+ if (newValue) {
|
|
|
+ window.setTimeout(function () {
|
|
|
+ self.filter('');
|
|
|
+ $(window).on('click', closeOnOutsideClick);
|
|
|
+ $(element).find('.hue-drop-down-input').on('keyup', inputKeyup);
|
|
|
+ $(element).find('.hue-drop-down-input').focus();
|
|
|
+ }, 0);
|
|
|
+ } else {
|
|
|
+ $(element).find('.hue-inner-drop-down > .active').removeClass('.active');
|
|
|
+ $(window).off('click', closeOnOutsideClick);
|
|
|
+ $(element).find('.hue-drop-down-input').off('keyup', inputKeyup);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ self.filteredEntries = ko.pureComputed(function () {
|
|
|
+ if (self.filter() === '' || ! self.filterEdited()) {
|
|
|
+ return self.entries();
|
|
|
+ } else {
|
|
|
+ var lowerFilter = self.filter().toLowerCase();
|
|
|
+ return self.entries().filter(function (database) {
|
|
|
+ return database.toLowerCase().indexOf(lowerFilter) !== -1;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ ko.components.register('hue-drop-down', {
|
|
|
+ viewModel: {
|
|
|
+ createViewModel: function(params, componentInfo) {
|
|
|
+ return new HueDropDown(params, componentInfo.element);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ template: { element: 'hue-drop-down-template' }
|
|
|
+ });
|
|
|
+ })();
|
|
|
+ </script>
|
|
|
+</%def>
|