dropdown.typeahead.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. define([
  2. 'angular',
  3. 'app',
  4. 'lodash',
  5. 'jquery',
  6. ],
  7. function (angular, app, _, $) {
  8. 'use strict';
  9. angular
  10. .module('grafana.directives')
  11. .directive('dropdownTypeahead', function($compile) {
  12. var inputTemplate = '<input type="text"'+
  13. ' class="tight-form-input input-medium tight-form-input"' +
  14. ' spellcheck="false" style="display:none"></input>';
  15. var buttonTemplate = '<a class="tight-form-item tight-form-func dropdown-toggle"' +
  16. ' tabindex="1" gf-dropdown="menuItems" data-toggle="dropdown"' +
  17. ' data-placement="top"><i class="fa fa-plus"></i></a>';
  18. return {
  19. scope: {
  20. menuItems: "=dropdownTypeahead",
  21. dropdownTypeaheadOnSelect: "&dropdownTypeaheadOnSelect",
  22. model: '=ngModel'
  23. },
  24. link: function($scope, elem, attrs) {
  25. var $input = $(inputTemplate);
  26. var $button = $(buttonTemplate);
  27. $input.appendTo(elem);
  28. $button.appendTo(elem);
  29. if (attrs.linkText) {
  30. $button.html(attrs.linkText);
  31. }
  32. if (attrs.ngModel) {
  33. $scope.$watch('model', function(newValue) {
  34. _.each($scope.menuItems, function(item) {
  35. _.each(item.submenu, function(subItem) {
  36. if (subItem.value === newValue) {
  37. $button.html(subItem.text);
  38. }
  39. });
  40. });
  41. });
  42. }
  43. var typeaheadValues = _.reduce($scope.menuItems, function(memo, value, index) {
  44. _.each(value.submenu, function(item, subIndex) {
  45. item.click = 'menuItemSelected(' + index + ',' + subIndex + ')';
  46. memo.push(value.text + ' ' + item.text);
  47. });
  48. return memo;
  49. }, []);
  50. $scope.menuItemSelected = function(index, subIndex) {
  51. var item = $scope.menuItems[index];
  52. $scope.dropdownTypeaheadOnSelect({$item: item, $subItem: item.submenu[subIndex]});
  53. };
  54. $input.attr('data-provide', 'typeahead');
  55. $input.typeahead({
  56. source: typeaheadValues,
  57. minLength: 1,
  58. items: 10,
  59. updater: function (value) {
  60. var result = {};
  61. _.each($scope.menuItems, function(menuItem) {
  62. _.each(menuItem.submenu, function(submenuItem) {
  63. if (value === (menuItem.text + ' ' + submenuItem.text)) {
  64. result.$item = menuItem;
  65. result.$subItem = submenuItem;
  66. }
  67. });
  68. });
  69. if (result.$item) {
  70. $scope.$apply(function() {
  71. $scope.dropdownTypeaheadOnSelect(result);
  72. });
  73. }
  74. $input.trigger('blur');
  75. return '';
  76. }
  77. });
  78. $button.click(function() {
  79. $button.hide();
  80. $input.show();
  81. $input.focus();
  82. });
  83. $input.keyup(function() {
  84. elem.toggleClass('open', $input.val() === '');
  85. });
  86. $input.blur(function() {
  87. $input.hide();
  88. $input.val('');
  89. $button.show();
  90. $button.focus();
  91. // clicking the function dropdown menu wont
  92. // work if you remove class at once
  93. setTimeout(function() {
  94. elem.removeClass('open');
  95. }, 200);
  96. });
  97. $compile(elem.contents())($scope);
  98. }
  99. };
  100. });
  101. });