diff options
Diffstat (limited to 'xstatic/pkg/magic_search/data/magic_search.js')
-rwxr-xr-x | xstatic/pkg/magic_search/data/magic_search.js | 154 |
1 files changed, 109 insertions, 45 deletions
diff --git a/xstatic/pkg/magic_search/data/magic_search.js b/xstatic/pkg/magic_search/data/magic_search.js index 943eda9..347bb33 100755 --- a/xstatic/pkg/magic_search/data/magic_search.js +++ b/xstatic/pkg/magic_search/data/magic_search.js @@ -16,7 +16,7 @@ angular.module('MagicSearch') return { restrict: 'E', scope: { - facets_json: '@facets', + facets_param: '@facets', filter_keys: '=filterKeys', strings: '=strings' }, @@ -24,11 +24,22 @@ angular.module('MagicSearch') return elem.template; }, controller: function ($scope, $timeout) { + $scope.promptString = $scope.strings['prompt']; $scope.currentSearch = []; $scope.initSearch = function() { - // Parse facets JSON and convert to a list of facets. - $scope.facetsJson = $scope.facets_json.replace(/__apos__/g, "\'").replace(/__dquote__/g, '\\"').replace(/__bslash__/g, "\\"); - $scope.facetsObj = JSON.parse($scope.facetsJson); + if (typeof $scope.facets_param === 'string') { + // Parse facets JSON and convert to a list of facets. + var tmp = $scope.facets_param.replace(/__apos__/g, "\'").replace(/__dquote__/g, '\\"').replace(/__bslash__/g, "\\"); + $scope.facetsObj = JSON.parse(tmp); + } + else { + // Assume this is a usable javascript object + $scope.facetsObj = $scope.facets_param; + } + $scope.facetsSave = $scope.copyFacets($scope.facetsObj); + $scope.initFacets(); + }; + $scope.initFacets = function() { // set facets selected and remove them from facetsObj var initialFacets = window.location.search; if (initialFacets.indexOf('?') === 0) { @@ -52,25 +63,47 @@ angular.module('MagicSearch') angular.forEach(value.options, function(option, idx) { if (option.key == facetParts[1]) { $scope.currentSearch.push({'name':facet, 'label':[value.label, option.label]}); - $scope.deleteFacetSelection(facetParts); + if (value.singleton === true) { + $scope.deleteFacetEntirely(facetParts); + } + else { + $scope.deleteFacetSelection(facetParts); + } } }); } } }); }); + if ($scope.textSearch !== undefined) { + $scope.currentSearch.push({'name':'text='+$scope.textSearch, 'label':[$scope.strings['text'], $scope.textSearch]}); + } $scope.filteredObj = $scope.facetsObj; }; + $scope.copyFacets = function(facets) { + var ret = [] + for (var i=0; i<facets.length; i++) { + var facet = Object.create(facets[i]); + if (facets[i].options !== undefined) { + facet.options = []; + for (var j=0; j<facets[i].options.length; j++) { + facet.options.push(Object.create(facets[i].options[j])); + } + } + ret.push(facet); + } + return ret; + } // removes a facet from the menu - $scope.deleteFacetSelection = function(facet_parts) { + $scope.deleteFacetSelection = function(facetParts) { angular.forEach($scope.facetsObj.slice(), function(facet, idx) { - if (facet.name == facet_parts[0]) { + if (facet.name == facetParts[0]) { if (facet.options === undefined) { return; // allow free-form facets to remain } for (var i=0; i<facet.options.length; i++) { var option = facet.options[i]; - if (option.key == facet_parts[1]) { + if (option.key == facetParts[1]) { $scope.facetsObj[idx].options.splice($scope.facetsObj[idx].options.indexOf(option), 1); } } @@ -80,17 +113,25 @@ angular.module('MagicSearch') } }); }; - $('#search-input').on('keydown', function($event) { // handle ctrl-char input + $scope.deleteFacetEntirely = function(facetParts) { + // remove entire facet + angular.forEach($scope.facetsObj.slice(), function(facet, idx) { + if (facet.name == facetParts[0]) { + $scope.facetsObj.splice($scope.facetsObj.indexOf(facet), 1); + } + }); + }; + $('.search-input').on('keydown', function($event) { // handle ctrl-char input var key = $event.keyCode || $event.charCode; if (key == 9) { // prevent default when we can. $event.preventDefault(); } }); - $('#search-input').on('keyup', function($event) { // handle ctrl-char input + $('.search-input').on('keyup', function($event) { // handle ctrl-char input if ($event.metaKey == true) { return; } - var search_val = $('#search-input').val(); + var searchVal = $('.search-input').val(); var key = $event.keyCode || $event.charCode; if (key == 9) { // tab, so select facet if narrowed down to 1 if ($scope.facetSelected === undefined) { @@ -98,30 +139,34 @@ angular.module('MagicSearch') $scope.facetClicked(0, '', $scope.filteredObj[0].name); } else { - if ($scope.filteredOptions.length != 1) return; + if ($scope.filteredOptions === undefined || $scope.filteredOptions.length != 1) return; $scope.optionClicked(0, '', $scope.filteredOptions[0].key); $scope.resetState(); } $timeout(function() { - $('#search-input').val(''); + $('.search-input').val(''); }); return; } if (key == 27) { // esc, so cancel and reset everthing $timeout(function() { $scope.hideMenu(); - $('#search-input').val(''); + $('.search-input').val(''); }); $scope.resetState(); - $scope.$emit('textSearch', '', $scope.filter_keys); + var textFilter = $scope.textSearch; + if (textFilter === undefined) { + textFilter = ''; + } + $scope.$emit('textSearch', textFilter, $scope.filter_keys); return; } if (key == 13) { // enter, so accept value // if tag search, treat as regular facet if ($scope.facetSelected && $scope.facetSelected.options === undefined) { var curr = $scope.facetSelected; - curr.name = curr.name + '=' + search_val; - curr.label[1] = search_val; + curr.name = curr.name + '=' + searchVal; + curr.label[1] = searchVal; $scope.currentSearch.push(curr); $scope.resetState(); $scope.emitQuery(); @@ -134,47 +179,48 @@ angular.module('MagicSearch') $scope.currentSearch.splice(i, 1); } } - $scope.currentSearch.push({'name':'text='+search_val, 'label':[$scope.strings['text'], search_val]}); + $scope.currentSearch.push({'name':'text='+searchVal, 'label':[$scope.strings['text'], searchVal]}); $scope.$apply(); $scope.hideMenu(); - $('#search-input').val(''); - $scope.$emit('textSearch', search_val, $scope.filter_keys); + $('.search-input').val(''); + $scope.$emit('textSearch', searchVal, $scope.filter_keys); + $scope.textSearch = searchVal; } $scope.filteredObj = $scope.facetsObj; } else { - if (search_val === '') { + if (searchVal === '') { $scope.filteredObj = $scope.facetsObj; $scope.$emit('textSearch', '', $scope.filter_keys); } else { - $scope.filterFacets(search_val); + $scope.filterFacets(searchVal); } } }); - $('#search-input').on('keypress', function($event) { // handle character input - var search_val = $('#search-input').val(); + $('.search-input').on('keypress', function($event) { // handle character input + var searchVal = $('.search-input').val(); var key = $event.which || $event.keyCode || $event.charCode; if (key != 8 && key != 46 && key != 13 && key != 9 && key != 27) { - search_val = search_val + String.fromCharCode(key).toLowerCase(); + searchVal = searchVal + String.fromCharCode(key).toLowerCase(); } - if (search_val == ' ') { // space and field is empty, show menu + if (searchVal == ' ') { // space and field is empty, show menu $scope.showMenu(); $timeout(function() { - $('#search-input').val(''); + $('.search-input').val(''); }); return; } - if (search_val === '') { + if (searchVal === '') { $scope.filteredObj = $scope.facetsObj; $scope.$emit('textSearch', '', $scope.filter_keys); return; } if (key != 8 && key != 46) { - $scope.filterFacets(search_val); + $scope.filterFacets(searchVal); } }); - $scope.filterFacets = function(search_val) { + $scope.filterFacets = function(searchVal) { // try filtering facets/options.. if no facets match, do text search var i, idx, label; var filtered = []; @@ -182,9 +228,9 @@ angular.module('MagicSearch') $scope.filteredObj = $scope.facetsObj; for (i=0; i<$scope.filteredObj.length; i++) { var facet = $scope.filteredObj[i]; - idx = facet.label.toLowerCase().indexOf(search_val); + idx = facet.label.toLowerCase().indexOf(searchVal); if (idx > -1) { - label = [facet.label.substring(0, idx), facet.label.substring(idx, idx + search_val.length), facet.label.substring(idx + search_val.length)]; + label = [facet.label.substring(0, idx), facet.label.substring(idx, idx + searchVal.length), facet.label.substring(idx + searchVal.length)]; filtered.push({'name':facet.name, 'label':label, 'options':facet.options}); } } @@ -195,7 +241,7 @@ angular.module('MagicSearch') }, 0.1); } else { - $scope.$emit('textSearch', search_val, $scope.filter_keys); + $scope.$emit('textSearch', searchVal, $scope.filter_keys); $scope.hideMenu(); } } @@ -206,9 +252,9 @@ angular.module('MagicSearch') } for (i=0; i<$scope.filteredOptions.length; i++) { var option = $scope.filteredOptions[i]; - idx = option.label.toLowerCase().indexOf(search_val); + idx = option.label.toLowerCase().indexOf(searchVal); if (idx > -1) { - label = [option.label.substring(0, idx), option.label.substring(idx, idx + search_val.length), option.label.substring(idx + search_val.length)]; + label = [option.label.substring(0, idx), option.label.substring(idx, idx + searchVal.length), option.label.substring(idx + searchVal.length)]; filtered.push({'key':option.key, 'label':label}); } } @@ -221,8 +267,8 @@ angular.module('MagicSearch') } }; // enable text entry when mouse clicked anywhere in search box - $('#search-main-area').on("click", function($event) { - $('#search-input').trigger("focus"); + $('.search-main-area').on("click", function($event) { + $('.search-input').trigger("focus"); if ($scope.facetSelected === undefined) { $scope.showMenu(); } @@ -241,11 +287,11 @@ angular.module('MagicSearch') $scope.showMenu(); } $timeout(function() { - $('#search-input').val(''); + $('.search-input').val(''); }); $scope.strings['prompt'] = ''; $timeout(function() { - $('#search-input').focus(); + $('.search-input').focus(); }); }; // when option clicked, complete facet and send event @@ -273,12 +319,23 @@ angular.module('MagicSearch') } if (removed !== undefined && removed.indexOf('text') === 0) { $scope.$emit('textSearch', '', $scope.filter_keys); + $scope.textSearch = undefined } else { $scope.$emit('searchUpdated', query); if ($scope.currentSearch.length > 0) { var newFacet = $scope.currentSearch[$scope.currentSearch.length-1].name; - $scope.deleteFacetSelection(newFacet.split('=')); + var facetParts = newFacet.split('='); + angular.forEach($scope.facetsSave, function(facet, idx) { + if (facet.name == facetParts[0]) { + if (facet.singleton === true) { + $scope.deleteFacetEntirely(facetParts); + } + else { + $scope.deleteFacetSelection(facetParts); + } + } + }); } } }; @@ -291,25 +348,32 @@ angular.module('MagicSearch') } else { $scope.resetState(); - $('#search-input').val(''); + $('.search-input').val(''); + } + if ($scope.currentSearch.length == 0) { + $scope.strings['prompt'] = $scope.promptString; } - // facet re-enabled by reload + // re-init to restore facets cleanly + $scope.facetsObj = $scope.copyFacets($scope.facetsSave); + $scope.currentSearch = []; + $scope.initFacets(); }; // clear entire searchbar $scope.clearSearch = function() { if ($scope.currentSearch.length > 0) { $scope.currentSearch = []; - $scope.facetsObj = JSON.parse($scope.facetsJson); + $scope.facetsObj = $scope.copyFacets($scope.facetsSave); $scope.resetState(); $scope.$emit('searchUpdated', ''); $scope.$emit('textSearch', '', $scope.filter_keys); + $scope.strings['prompt'] = $scope.promptString; } }; $scope.isMatchLabel = function(label) { return Array.isArray(label); }; $scope.resetState = function() { - $('#search-input').val(''); + $('.search-input').val(''); $scope.filteredObj = $scope.facetsObj; $scope.facetSelected = undefined; $scope.facetOptions = undefined; @@ -320,7 +384,7 @@ angular.module('MagicSearch') $scope.showMenu = function() { $timeout(function() { if ($('#facet-drop').hasClass('open') === false) { - $('#search-input').trigger('click'); + $('.search-input').trigger('click'); } }); }; |