bitbake: toaster: migrate typeahead library
Migrate from Bootstrap 2's built-in typeahead to Twitter's typeahead library. This is to facilitate moving to Bootstrap 3, which doesn't have a typeahead. (Bitbake rev: 0748177b40188a6fb735fe1ba1c17294afa4a3d0) Signed-off-by: Elliot Smith <elliot.smith@intel.com> Signed-off-by: Michael Wood <michael.g.wood@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
parent
64622029d7
commit
cd7b48cd0d
|
@ -9,4 +9,6 @@ Foundation and individual contributors.
|
||||||
|
|
||||||
* jQuery is redistributed under the MIT license.
|
* jQuery is redistributed under the MIT license.
|
||||||
|
|
||||||
|
* Twitter typeahead.js redistributed under the MIT license.
|
||||||
|
|
||||||
* QUnit is redistributed under the MIT license.
|
* QUnit is redistributed under the MIT license.
|
||||||
|
|
|
@ -341,3 +341,22 @@ input.input-lg {
|
||||||
line-height: 1.33333;
|
line-height: 1.33333;
|
||||||
padding: 10px 16px;
|
padding: 10px 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* styling for standalone typeahead library */
|
||||||
|
.tt-menu {
|
||||||
|
margin-top: 2px;
|
||||||
|
border-radius: 4px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tt-suggestion {
|
||||||
|
cursor: pointer;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tt-suggestion.active {
|
||||||
|
background-color: #0081c2;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
|
@ -3,96 +3,82 @@
|
||||||
* This object really just helps readability since we can then have
|
* This object really just helps readability since we can then have
|
||||||
* a traceable namespace.
|
* a traceable namespace.
|
||||||
*/
|
*/
|
||||||
var libtoaster = (function (){
|
var libtoaster = (function () {
|
||||||
|
// prevent conflicts with Bootstrap 2's typeahead (required during
|
||||||
|
// transition from v2 to v3)
|
||||||
|
var typeahead = jQuery.fn.typeahead.noConflict();
|
||||||
|
jQuery.fn._typeahead = typeahead;
|
||||||
|
|
||||||
/* makeTypeahead parameters
|
/* Make a typeahead from an input element
|
||||||
* elementSelector: JQuery elementSelector string
|
*
|
||||||
* xhrUrl: the url to get the JSON from expects JSON in the form:
|
* _makeTypeahead parameters
|
||||||
* { "list": [ { "name": "test", "detail" : "a test thing" }, .... ] }
|
* jQElement: input element as selected by $('selector')
|
||||||
|
* xhrUrl: the url to get the JSON from; this URL should return JSON in the
|
||||||
|
* format:
|
||||||
|
* { "results": [ { "name": "test", "detail" : "a test thing" }, ... ] }
|
||||||
* xhrParams: the data/parameters to pass to the getJSON url e.g.
|
* xhrParams: the data/parameters to pass to the getJSON url e.g.
|
||||||
* { 'type' : 'projects' } the text typed will be passed as 'search'.
|
* { 'type' : 'projects' }; the text typed will be passed as 'search'.
|
||||||
* selectedCB: function to call once an item has been selected one
|
* selectedCB: function to call once an item has been selected; has
|
||||||
* arg of the item.
|
* signature selectedCB(item), where item is an item in the format shown
|
||||||
|
* in the JSON list above, i.e.
|
||||||
|
* { "name": "name", "detail": "detail" }.
|
||||||
*/
|
*/
|
||||||
function _makeTypeahead (jQElement, xhrUrl, xhrParams, selectedCB) {
|
function _makeTypeahead(jQElement, xhrUrl, xhrParams, selectedCB) {
|
||||||
if (!xhrUrl || xhrUrl.length === 0)
|
if (!xhrUrl || xhrUrl.length === 0) {
|
||||||
throw("No url to typeahead supplied");
|
throw("No url supplied for typeahead");
|
||||||
|
}
|
||||||
|
|
||||||
var xhrReq;
|
var xhrReq;
|
||||||
|
|
||||||
jQElement.typeahead({
|
jQElement._typeahead(
|
||||||
// each time the typeahead's choices change, a
|
{
|
||||||
// "typeahead-choices-change" event is fired with an object
|
highlight: true,
|
||||||
// containing the available choices in a "choices" property
|
classNames: {
|
||||||
source: function(query, process){
|
open: "dropdown-menu",
|
||||||
|
cursor: "active"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: function (query, syncResults, asyncResults) {
|
||||||
xhrParams.search = query;
|
xhrParams.search = query;
|
||||||
|
|
||||||
/* If we have a request in progress don't fire off another one*/
|
// if we have a request in progress, cancel it and start another
|
||||||
if (xhrReq)
|
if (xhrReq) {
|
||||||
xhrReq.abort();
|
xhrReq.abort();
|
||||||
|
}
|
||||||
|
|
||||||
xhrReq = $.getJSON(xhrUrl, this.options.xhrParams, function(data){
|
xhrReq = $.getJSON(xhrUrl, xhrParams, function (data) {
|
||||||
if (data.error !== "ok") {
|
if (data.error !== "ok") {
|
||||||
console.log("Error getting data from server "+data.error);
|
console.error("Error getting data from server: " + data.error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
xhrReq = null;
|
xhrReq = null;
|
||||||
|
|
||||||
jQElement.trigger("typeahead-choices-change", {choices: data.results});
|
asyncResults(data.results);
|
||||||
|
|
||||||
return process(data.results);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
updater: function(item) {
|
|
||||||
var itemObj = this.$menu.find('.active').data('itemObject');
|
// how the selected item is shown in the input
|
||||||
selectedCB(itemObj);
|
display: function (item) {
|
||||||
return item;
|
return item.name;
|
||||||
},
|
},
|
||||||
matcher: function(item) {
|
|
||||||
if (!item.hasOwnProperty('name')) {
|
templates: {
|
||||||
console.log("Name property missing in data");
|
// how the item is displayed in the dropdown
|
||||||
return 0;
|
suggestion: function (item) {
|
||||||
|
var elt = document.createElement("div");
|
||||||
|
elt.innerHTML = item.name + " " + item.detail;
|
||||||
|
return elt;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
if (this.$element.val().length === 0)
|
// when an item is selected using the typeahead, invoke the callback
|
||||||
return 0;
|
jQElement.on("typeahead:select", function (event, item) {
|
||||||
|
selectedCB(item);
|
||||||
return 1;
|
|
||||||
},
|
|
||||||
highlighter: function (item) {
|
|
||||||
/* Use jquery to escape the item name and detail */
|
|
||||||
var current = $("<span></span>").text(item.name + ' '+item.detail);
|
|
||||||
current = current.html();
|
|
||||||
|
|
||||||
var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
|
|
||||||
return current.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
|
|
||||||
return '<strong>' + match + '</strong>'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
sorter: function (items) { return items; },
|
|
||||||
xhrUrl: xhrUrl,
|
|
||||||
xhrParams: xhrParams,
|
|
||||||
xhrReq: xhrReq,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/* Copy of bootstrap's render func but sets selectedObject value */
|
|
||||||
function customRenderFunc (items) {
|
|
||||||
var that = this;
|
|
||||||
|
|
||||||
items = $(items).map(function (i, item) {
|
|
||||||
i = $(that.options.item).attr('data-value', item.name).data('itemObject', item);
|
|
||||||
i.find('a').html(that.highlighter(item));
|
|
||||||
return i[0];
|
|
||||||
});
|
|
||||||
|
|
||||||
items.first().addClass('active');
|
|
||||||
this.$menu.html(items);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
jQElement.data('typeahead').render = customRenderFunc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* startABuild:
|
/* startABuild:
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -21,6 +21,8 @@
|
||||||
</script>
|
</script>
|
||||||
<script src="{% static 'js/bootstrap.min.js' %}">
|
<script src="{% static 'js/bootstrap.min.js' %}">
|
||||||
</script>
|
</script>
|
||||||
|
<script src="{% static 'js/typeahead.jquery.min.js' %}">
|
||||||
|
</script>
|
||||||
<script src="{% static 'js/prettify.js' %}">
|
<script src="{% static 'js/prettify.js' %}">
|
||||||
</script>
|
</script>
|
||||||
<script src="{% static 'js/libtoaster.js' %}">
|
<script src="{% static 'js/libtoaster.js' %}">
|
||||||
|
|
Loading…
Reference in New Issue