In a previous post, I talked about an AngularJS widget for searching. Now, that has been re-factored a little with an eye towards reuse and is available using Bower. There was a little discussion about re-use in the last post, but now the task is much simpler. If you are already using Bower, you can simply add “angular-magic-search” to your bower.json. The widget can now be integrated into your templates and leverages which ever flavor you use for resource location and parameter passing. For example, using Chameleon templates, we do the following:
<link rel="stylesheet" type-"text/css" href="${request.static_path('eucaconsole:static/js/thirdparty/magic-search/magic_search.css')}"/> <script src="${request.static_path('eucaconsole:static/js/thirdparty/magic-search/magic_search.js')}"></script>
<magic-search template="${request.static_path('eucaconsole:static/js/thirdparty/magic-search/magic_search.html')}" strings="{'remove':'${layout.ms_remove}', 'cancel':'${layout.ms_cancel}', 'prompt':'${layout.ms_prompt}'}" facets="${search_facets}" filter-keys="${filter_keys}"></magic-search>
The first 2 lines pull in the CSS and JS files. The div tag sets the ng-app and contains the magic-search element. Attributes are used to set that up, including template location, strings (which were run through i18n), as well as facets and filter keys.
The facets value is a JSON structure that looks like this:
[ {'name': 'owner_alias', 'label': 'Images owned by', 'options': [{'key': '', 'label': 'Anyone'}, {'key': 'self', 'label': 'Me (or shared with me)'}] }, {'name': 'platform', 'label': 'Platform', 'options': [{'key': 'linux', 'label': 'Linux'}, {'key': 'windows', 'label': 'Windows'}] }, {'name': 'architecture', 'label': 'Architecture', 'options': [{'key': 'x86_64', 'label': '64-bit'}, {'key': 'i386', 'label': '32-bit'}], } ]
It is used to populate the facets and is specific to the data being presented. Note that labels should have been run through your i18n function. The filter-keys value is an array of names. These are passed with the “textSearch” event so that the code you write to perform live text filtering can know which data values to look at.
['architecture', 'description', 'id', 'name', 'owner_alias', 'platform_name', 'root_device_type', 'tagged_name']
The final piece is to listen for events emitted by the search bar.
$scope.$on('searchUpdated', function($event, query) { ... });
$scope.$on('textSearch', function($event, text, filter_keys) { ... });
In the first function, “query” is a query fragment generated by the search facets. One use may be to append that to a URL for an XHR call to retrieve a new data set from the server. The second function gets the “filter_keys” discussed above and “text” which is simply the text the user typed which is not part of a pre-defined facet.
Hopefully, this makes it easier to re-use magic-seach in your application!
(coming next, magic-search and bootstrap)