{"version":3,"sources":["suggestion-box.js"],"names":["$","fn","suggestionBox","options","select","position","selectedHref","$suggestionBox","find","attr","addClass","unselect","removeClass","resetSelection","selectedLi","moveDown","listSize","size","moveUp","goToSelection","css","window","location","getSuggestions","url","ajaxCalledVal","$searchBox","val","ajax","data","request","dataType","success","selectionHasChanged","currentLi","jsonData","results","JSON","stringify","setJsonData","showSuggestions","settings","ajaxSuccess","error","e","ajaxError","getSelectionMouseIsOver","$parentLi","target","parent","children","index","setSuggestionBoxPosition","borders","getCssValue","padding","left","offset","leftOffset","top","height","topOffset","element","name","parseInt","replace","hideSuggestionBox","fadeOut","showSuggestionBox","fadeIn","setSuggestionBoxWidth","searchBoxWidth","getSearchBoxWidth","widthAdjustment","menuWidth","min-width","width","createSuggestionsList","$suggestions","heading","each","key","value","suggestion","matches","keys","Object","i","length","filterResults","active","html","showNoSuggestionsMessage","noSuggestionsMessage","json","parseJSON","loadJson","console","log","filterPattern","regex","RegExp","grep","test","sort","this","extend","delay","filter","enterKeyAction","paramName","append","ENTER_KEY","UP_ARROW_KEY","DOWN_ARROW_KEY","ESCAPE_KEY","mouseHover","timer","on","mousemove","nodeName","mouseout","click","blur","focus","keyup","which","clearTimeout","setTimeout","keydown","preventDefault","paste","resize","addSuggestions","loadSuggestions","getJson","selectedUrl","selectedSuggestion","text","reset","show","hide","ms","pattern","sortFunc","action","destroy","unbind","remove","jQuery"],"mappings":"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","file":"suggestion-box.min.js","sourcesContent":["(function ($) {\r\n\r\n $.fn.suggestionBox = function (options) {\r\n\r\n var $searchBox = this;\r\n\r\n var settings = $.extend({\r\n // default settings.\r\n topOffset: 0,\r\n leftOffset: 0,\r\n widthAdjustment: 0,\r\n delay: 400, // in ms\r\n heading: 'Suggestions',\r\n results: 10,\r\n fadeIn: true,\r\n fadeOut: false,\r\n menuWidth: 'auto',\r\n showNoSuggestionsMessage: false,\r\n noSuggestionsMessage: 'No Suggestions Found',\r\n filter: false,\r\n filterPattern: \"({INPUT})\",\r\n ajaxError: function (e) {\r\n console.log(e);\r\n },\r\n ajaxSuccess: function (data) {\r\n },\r\n enterKeyAction: function () {\r\n goToSelection();\r\n },\r\n paramName: 'search'\r\n },\r\n options);\r\n\r\n\r\n // Inject the suggestion box into the body of the web page\r\n $('body').append('
');\r\n\r\n // Turn off autocomplete\r\n $searchBox.attr('autocomplete', 'off');\r\n\r\n var $suggestionBox = $('#suggestion-box');\r\n setSuggestionBoxPosition();\r\n\r\n // Constants for key values\r\n var ENTER_KEY = 13;\r\n var UP_ARROW_KEY = 38;\r\n var DOWN_ARROW_KEY = 40;\r\n var ESCAPE_KEY = 27;\r\n\r\n // Default values for selected list item\r\n var selectedLi = -1;\r\n var selectedHref = '#';\r\n\r\n // Is the mouse hovering over the suggestion box?\r\n var mouseHover = false;\r\n // Timer for only making ajax calls when the user stops typing\r\n var timer = null;\r\n // Did we get any suggestions?\r\n var matches = false;\r\n // Is the search box active (does it have focus)\r\n var active = false;\r\n // create a blank object for our request\r\n var request = {};\r\n var jsonData = {};\r\n\r\n // The value of the input when ajax was called\r\n var ajaxCalledVal;\r\n\r\n\r\n $suggestionBox.on({\r\n mousemove: function (e) {\r\n if (e.target.nodeName === 'A') {\r\n unselect(selectedLi);\r\n selectedLi = getSelectionMouseIsOver(e);\r\n select(selectedLi);\r\n mouseHover = true;\r\n }\r\n },\r\n mouseout: function (e) {\r\n if (e.target.nodeName === 'A') {\r\n mouseHover = false;\r\n unselect(selectedLi);\r\n resetSelection();\r\n }\r\n },\r\n click: function (e) {\r\n if (e.target.nodeName === 'A') {\r\n $suggestionBox.css('display', 'none');\r\n }\r\n }\r\n });\r\n\r\n $searchBox.on({\r\n blur: function () {\r\n active = false;\r\n // Only close the menu if we are not clicking a link\r\n if (!mouseHover) {\r\n hideSuggestionBox();\r\n }\r\n },\r\n focus: function () {\r\n active = true;\r\n if ($(this).val()) {\r\n showSuggestions(jsonData);\r\n }\r\n },\r\n keyup: function (e) {\r\n\r\n // Ignore the navigation keys. We don't want to fire ajax calls when navigating\r\n if (e.which !== UP_ARROW_KEY && e.which !== DOWN_ARROW_KEY && e.which !== ESCAPE_KEY && e.which !== ENTER_KEY) {\r\n if (settings.url) {\r\n resetSelection();\r\n\r\n if (timer) {\r\n clearTimeout(timer);\r\n }\r\n }\r\n\r\n if (settings.url) {\r\n // set the request to be sent sent as the data parameter\r\n request[settings.paramName] = $searchBox.val();\r\n timer = setTimeout(function () {\r\n getSuggestions(settings.url)\r\n }, settings.delay);\r\n }\r\n if (settings.filter) {\r\n showSuggestions();\r\n }\r\n }\r\n },\r\n keydown: function (e) {\r\n if ($suggestionBox.css('display') !== 'none') {\r\n if (e.which == DOWN_ARROW_KEY) {\r\n e.preventDefault();\r\n moveDown();\r\n }\r\n if (e.which == UP_ARROW_KEY) {\r\n e.preventDefault();\r\n moveUp();\r\n }\r\n if (e.which === ENTER_KEY && selectedLi > -1) {\r\n e.preventDefault();\r\n settings.enterKeyAction();\r\n }\r\n if (e.which == ESCAPE_KEY) {\r\n e.preventDefault();\r\n hideSuggestionBox();\r\n }\r\n }\r\n },\r\n paste: function () {\r\n // Simulate keyup after 200ms otherwise the value of the search box will not be available\r\n setTimeout(function () {\r\n $searchBox.keyup();\r\n }, 200);\r\n }\r\n });\r\n\r\n // Reset the position of the suggestion box if the window is re-sized\r\n $(window).resize(function () {\r\n setSuggestionBoxPosition();\r\n });\r\n\r\n /**\r\n * Selects the suggestion at the given position\r\n * @param position\r\n */\r\n function select(position) {\r\n selectedHref = $suggestionBox.find(\"li:eq(\" + position + \") a\").attr('href');\r\n $suggestionBox.find(\"li:eq(\" + position + \")\").addClass('selected');\r\n }\r\n\r\n /**\r\n * Unselects the suggestion at the given position\r\n * @param position\r\n */\r\n function unselect(position) {\r\n $suggestionBox.find(\"li:eq(\" + position + \")\").removeClass('selected');\r\n }\r\n\r\n /**\r\n * Resets any selected suggestions\r\n */\r\n function resetSelection() {\r\n selectedHref = '#';\r\n selectedLi = -1;\r\n // remove all selected on reset\r\n $suggestionBox.find('li').removeClass('selected');\r\n }\r\n\r\n /**\r\n * Moves the selection down to the next suggestion\r\n */\r\n function moveDown() {\r\n var listSize = $suggestionBox.find('li').size();\r\n if (selectedLi === (listSize - 1)) {\r\n unselect(selectedLi);\r\n resetSelection();\r\n } else {\r\n unselect(selectedLi);\r\n selectedLi++;\r\n select(selectedLi);\r\n }\r\n }\r\n\r\n /**\r\n * Moves the selection up to the previous suggestions\r\n */\r\n function moveUp() {\r\n if (selectedLi > 0) {\r\n unselect(selectedLi);\r\n selectedLi--;\r\n select(selectedLi);\r\n } else if (selectedLi == -1) {\r\n unselect(selectedLi);\r\n selectedLi = $suggestionBox.find('li').size() - 1;\r\n select(selectedLi);\r\n } else {\r\n unselect(0);\r\n resetSelection();\r\n }\r\n }\r\n\r\n /**\r\n * Redirects the user to the selected suggestion location\r\n */\r\n function goToSelection() {\r\n $suggestionBox.css('display', 'none');\r\n window.location = selectedHref;\r\n }\r\n\r\n /**\r\n * Makes an ajax call to the given url\r\n * @param url\r\n */\r\n function getSuggestions(url) {\r\n ajaxCalledVal = $searchBox.val();\r\n $.ajax({\r\n url: url,\r\n data: request,\r\n dataType: 'json',\r\n success: function (data) {\r\n\r\n var selectionHasChanged = true;\r\n var currentLi = selectedLi;\r\n\r\n if (jsonData.results && data.results) {\r\n selectionHasChanged = (JSON.stringify(jsonData.results[selectedLi]) !== JSON.stringify(data.results[selectedLi]))\r\n }\r\n\r\n setJsonData(data);\r\n showSuggestions();\r\n\r\n // Keep selection if no new information has been entered since ajax was called and the selection is the same.\r\n // This prevents the flick back effect when menu has the same data but the ajax hasn't finished.\r\n if (currentLi > -1 && ($searchBox.val() === ajaxCalledVal) && !selectionHasChanged) {\r\n selectedLi = currentLi;\r\n select(selectedLi);\r\n }\r\n\r\n settings.ajaxSuccess(data);\r\n },\r\n error: function (e) {\r\n settings.ajaxError(e);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Returns the index of the list item the mouse is currently hovering over\r\n * @param e\r\n * @returns {Number}\r\n */\r\n function getSelectionMouseIsOver(e) {\r\n var $parentLi = $(e.target).parent('li');\r\n return $parentLi.parent().children().index($parentLi);\r\n }\r\n\r\n /**\r\n * Sets the position of the suggestion box\r\n */\r\n function setSuggestionBoxPosition() {\r\n var borders = getCssValue($searchBox, 'border-bottom-width') + getCssValue($searchBox, 'border-top-width');\r\n var padding = getCssValue($searchBox, 'padding-bottom') + getCssValue($searchBox, 'padding-top');\r\n\r\n $suggestionBox.css({\r\n 'position': 'absolute',\r\n 'left': ($searchBox.offset().left) + settings.leftOffset,\r\n 'top': ($searchBox.offset().top) + ($searchBox.height() + borders + padding + settings.topOffset)\r\n });\r\n }\r\n\r\n /**\r\n * Gets the css integer value for the given element.\r\n * @param element\r\n * @param name\r\n * @returns {Number}\r\n */\r\n function getCssValue(element, name) {\r\n return parseInt(element.css(name).replace('px', ''));\r\n }\r\n\r\n /**\r\n * Hides the suggestion box\r\n */\r\n function hideSuggestionBox() {\r\n if (settings.fadeOut) {\r\n $suggestionBox.fadeOut();\r\n } else {\r\n $suggestionBox.css('display', 'none');\r\n }\r\n resetSelection();\r\n }\r\n\r\n /**\r\n * Displays the suggestion-box\r\n */\r\n function showSuggestionBox() {\r\n if (settings.fadeIn) {\r\n $suggestionBox.fadeIn();\r\n } else {\r\n $suggestionBox.css('display', 'block');\r\n }\r\n }\r\n\r\n /**\r\n * Sets the width of the suggestion box\r\n */\r\n function setSuggestionBoxWidth() {\r\n var searchBoxWidth = getSearchBoxWidth() + settings.widthAdjustment;\r\n if (settings.menuWidth == 'auto') {\r\n $suggestionBox.css({\r\n 'min-width': searchBoxWidth\r\n });\r\n } else if (settings.menuWidth == 'constrain') {\r\n $suggestionBox.css({\r\n 'width': searchBoxWidth\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Returns the width of the search box\r\n * @returns {number}\r\n */\r\n function getSearchBoxWidth() {\r\n return (\r\n $searchBox.width() +\r\n getCssValue($searchBox, 'border-left-width') +\r\n getCssValue($searchBox, 'border-right-width') +\r\n getCssValue($searchBox, 'padding-left') +\r\n getCssValue($searchBox, 'padding-right')\r\n );\r\n }\r\n\r\n function createSuggestionsList(data) {\r\n var $suggestions = '
' + settings.heading + '
' +\r\n '';\r\n\r\n return $suggestions;\r\n }\r\n\r\n /**\r\n * Shows the suggestion-box suggestions if they are available based on the data passed in\r\n */\r\n function showSuggestions() {\r\n resetSelection();\r\n\r\n matches = false;\r\n\r\n var data = (settings.filter) ? filterResults($searchBox.val()) : jsonData;\r\n if (data) {\r\n if (data.results) {\r\n var $suggestions = createSuggestionsList(data);\r\n }\r\n }\r\n\r\n // Check for focus before showing suggestion box. User could have clicked outside before request finished.\r\n if (active) {\r\n if (matches) {\r\n $suggestionBox.html($suggestions);\r\n setSuggestionBoxWidth();\r\n showSuggestionBox();\r\n } else if (settings.showNoSuggestionsMessage && $searchBox.val().length > 0) {\r\n setSuggestionBoxWidth();\r\n showSuggestionBox();\r\n $suggestionBox.html('
' + settings.noSuggestionsMessage + '
');\r\n } else {\r\n hideSuggestionBox();\r\n }\r\n } else {\r\n hideSuggestionBox();\r\n }\r\n }\r\n\r\n /**\r\n * Sets the current JSON data ready for display\r\n * @param json\r\n */\r\n function setJsonData(json) {\r\n if (json) {\r\n jsonData = (json instanceof Object) ? json : $.parseJSON(json);\r\n } else {\r\n jsonData = {};\r\n }\r\n }\r\n\r\n /**\r\n * Loads JSON from the given url\r\n * @param url\r\n */\r\n function loadJson(url) {\r\n $.ajax({\r\n url: url,\r\n dataType: 'json',\r\n success: function (data) {\r\n setJsonData(data);\r\n },\r\n error: function (e) {\r\n console.log(e);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Filters the JSON based on the user input\r\n * @param value\r\n * @returns {Object}\r\n */\r\n function filterResults(value) {\r\n var data;\r\n\r\n // escape regex chars\r\n value = value.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\r\n filterPattern = settings.filterPattern.replace(\"{INPUT}\", value);\r\n if (!value) {\r\n return {};\r\n }\r\n if (jsonData) {\r\n if (jsonData.results) {\r\n\r\n var regex = new RegExp(filterPattern, \"i\");\r\n\r\n data = $.grep(jsonData.results, function (name) {\r\n return regex.test(name.suggestion);\r\n });\r\n }\r\n }\r\n\r\n if (settings.sort) {\r\n data.sort(settings.sort);\r\n }\r\n\r\n var json = JSON.stringify({\"results\": data});\r\n\r\n return $.parseJSON(json);\r\n }\r\n\r\n // returned methods\r\n return {\r\n getSuggestions: function (url) {\r\n getSuggestions(url);\r\n return this;\r\n },\r\n addSuggestions: function (json) {\r\n setJsonData(json);\r\n return this;\r\n },\r\n loadSuggestions: function (url) {\r\n loadJson(url);\r\n return this;\r\n },\r\n getJson: function () {\r\n return JSON.stringify(jsonData);\r\n },\r\n moveUp: function () {\r\n moveUp();\r\n return this;\r\n },\r\n moveDown: function () {\r\n moveDown();\r\n return this;\r\n },\r\n selectedUrl: function () {\r\n return selectedHref;\r\n },\r\n selectedSuggestion: function () {\r\n return $suggestionBox.find('li:eq(' + selectedLi + ')').text();\r\n },\r\n position: function () {\r\n return selectedLi;\r\n },\r\n select: function (position) {\r\n unselect(selectedLi);\r\n selectedLi = position;\r\n select(position);\r\n return this;\r\n },\r\n reset: function () {\r\n unselect(selectedLi);\r\n resetSelection();\r\n return this;\r\n },\r\n show: function () {\r\n $searchBox.focus();\r\n showSuggestions();\r\n return this;\r\n },\r\n hide: function () {\r\n hideSuggestionBox();\r\n return this;\r\n },\r\n url: function (url) {\r\n settings.url = url;\r\n return this;\r\n },\r\n fadeIn: function (fadeIn) {\r\n settings.fadeIn = fadeIn;\r\n return this;\r\n },\r\n fadeOut: function (fadeOut) {\r\n settings.fadeOut = fadeOut;\r\n return this;\r\n },\r\n delay: function (ms) {\r\n settings.delay = ms;\r\n return this;\r\n },\r\n heading: function (heading) {\r\n settings.heading = heading;\r\n return this;\r\n },\r\n results: function (results) {\r\n settings.results = results;\r\n return this;\r\n },\r\n ajaxError: function (ajaxError) {\r\n settings.ajaxError = ajaxError;\r\n return this;\r\n },\r\n ajaxSuccess: function (ajaxSuccess) {\r\n settings.ajaxSuccess = ajaxSuccess;\r\n return this;\r\n },\r\n filter: function (filter) {\r\n settings.filter = filter;\r\n return this;\r\n },\r\n filterPattern: function (pattern) {\r\n settings.filterPattern = pattern;\r\n return this;\r\n },\r\n sort: function (sortFunc) {\r\n settings.sort = sortFunc;\r\n return this;\r\n },\r\n enterKeyAction: function (action) {\r\n settings.enterKeyAction = action;\r\n return this;\r\n },\r\n destroy: function () {\r\n $searchBox.unbind(this);\r\n $suggestionBox.remove();\r\n return null;\r\n }\r\n };\r\n };\r\n}(jQuery));"],"sourceRoot":"/source/"}