admin管理员组文章数量:1193758
I extended the bootstrap-typeahead in order to take an object instead of a string.
It works but I would like to know this is the right way to do the things.
Thanks.
Reference:
.html#typeahead
.js
_.extend($.fn.typeahead.Constructor.prototype, {
render: function (items) {
var that = this;
items = $(items).map(function (i, item) {
i = $(that.options.item)
.attr('data-value', item[that.options.display])
.attr('data-id', item.id);
i.find('a').html(that.highlighter(item));
return i[0];
});
items.first().addClass('active');
this.$menu.html(items);
return this;
},
select: function () {
var val = this.$menu.find('.active').attr('data-value'),
id = this.$menu.find('.active').attr('data-id');
this.$element
.val(this.updater(val, id))
.change();
return this.hide()
}
});
return function (element, options) {
var getSource = function () {
return {
id: 2,
full_name: 'first_name last_name'
};
};
element.typeahead({
minLength: 3,
source: getSource,
display: 'full_name',
sorter: function (items) {
var beginswith = [],
caseSensitive = [],
caseInsensitive = [],
item,
itemDisplayed;
while (item = items.shift()) {
itemDisplayed = item[this.options.display];
if (!itemDisplayed.toLowerCase().indexOf(this.query.toLowerCase())) {
beginswith.push(item);
} else if (~itemDisplayed.indexOf(this.query)) {
caseSensitive.push(item);
} else {
caseInsensitive.push(item);
}
}
return beginswith.concat(caseSensitive, caseInsensitive);
},
highlighter: function (item) {
var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&');
return item[this.options.display].replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
return '<strong>' + match + '</strong>';
});
},
matcher: function (item) {
var value = item[this.options.display];
return {
value: ~value.toLowerCase().indexOf(this.query.toLowerCase()),
id: item.id
};
},
updater: function (item, userId) {
options.hiddenInputElement.val(userId);
return item;
}
});
};
I extended the bootstrap-typeahead in order to take an object instead of a string.
It works but I would like to know this is the right way to do the things.
Thanks.
Reference:
http://twitter.github.com/bootstrap/javascript.html#typeahead
http://twitter.github.com/bootstrap/assets/js/bootstrap-typeahead.js
_.extend($.fn.typeahead.Constructor.prototype, {
render: function (items) {
var that = this;
items = $(items).map(function (i, item) {
i = $(that.options.item)
.attr('data-value', item[that.options.display])
.attr('data-id', item.id);
i.find('a').html(that.highlighter(item));
return i[0];
});
items.first().addClass('active');
this.$menu.html(items);
return this;
},
select: function () {
var val = this.$menu.find('.active').attr('data-value'),
id = this.$menu.find('.active').attr('data-id');
this.$element
.val(this.updater(val, id))
.change();
return this.hide()
}
});
return function (element, options) {
var getSource = function () {
return {
id: 2,
full_name: 'first_name last_name'
};
};
element.typeahead({
minLength: 3,
source: getSource,
display: 'full_name',
sorter: function (items) {
var beginswith = [],
caseSensitive = [],
caseInsensitive = [],
item,
itemDisplayed;
while (item = items.shift()) {
itemDisplayed = item[this.options.display];
if (!itemDisplayed.toLowerCase().indexOf(this.query.toLowerCase())) {
beginswith.push(item);
} else if (~itemDisplayed.indexOf(this.query)) {
caseSensitive.push(item);
} else {
caseInsensitive.push(item);
}
}
return beginswith.concat(caseSensitive, caseInsensitive);
},
highlighter: function (item) {
var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&');
return item[this.options.display].replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
return '<strong>' + match + '</strong>';
});
},
matcher: function (item) {
var value = item[this.options.display];
return {
value: ~value.toLowerCase().indexOf(this.query.toLowerCase()),
id: item.id
};
},
updater: function (item, userId) {
options.hiddenInputElement.val(userId);
return item;
}
});
};
Share
Improve this question
edited Aug 30, 2012 at 9:42
Lorraine Bernard
asked Aug 29, 2012 at 16:49
Lorraine BernardLorraine Bernard
13.4k23 gold badges85 silver badges137 bronze badges
8
|
Show 3 more comments
3 Answers
Reset to default 18 +50I recommend to not rewrite the prototype (which would impact all places where you could use the autocompleter, not only the following function).
This code should work:
var getSource = function () {
var users = new Backbone.Collection([
{
first_name: 'primo',
last_name: 'ultimo',
id: 1
},
{
first_name: 'altro_primo',
last_name: 'altro_ultimo',
id: 2
}
]).models;
return _.map(users, function (user) {
return {
id: user.get('id'),
full_name: user.get('first_name') + ' ' + user.get('last_name'),
// these functions allows Bootstrap typehead to use this item in places where it was expecting a string
toString: function () {
return JSON.stringify(this);
},
toLowerCase: function () {
return this.full_name.toLowerCase();
},
indexOf: function (string) {
return String.prototype.indexOf.apply(this.full_name, arguments);
},
replace: function (string) {
return String.prototype.replace.apply(this.full_name, arguments);
}
};
});
};
$('.full_name').typeahead({
minLength: 3,
source: getSource(),
display: 'full_name',
updater: function (itemString) {
var item = JSON.parse(itemString);
$('.id').val(item.id);
return item.full_name;
}
});
demo: http://jsfiddle.net/hyxMh/48/
In addition to @AntoJs answer, here is an ajax version (just 'source' part):
$('.full_name').typeahead({
/* ... */
source: function(query,process){
$.ajax({
url: 'your_url_here',
data: {term: query, additional_data: 'some_data'},
success: function(data){
process($.map(data, function(user){
return {
id: user.id,
full_name: user.first_name + ' ' + user.last_name,
toString: function () {
return JSON.stringify(this);
},
toLowerCase: function () {
return this.full_name.toLowerCase();
},
indexOf: function (string) {
return String.prototype.indexOf.apply(this.full_name, arguments);
},
replace: function (string) {
return String.prototype.replace.apply(this.full_name, arguments);
}
}
}));
}
});
},
/* ... */
});
Btw: @AntoJs - many thanks for your answer!
@antonjs's answer wasn't working for me and I was getting the following error
TypeError: item.substr is not a function
so with jQuery v2.1.3 and bootstrap3-typeahead.js v3.1.0 the following works for me
var getSource = function () {
var users = new Backbone.Collection([
{
first_name: 'primo',
last_name: 'ultimo',
id: 1
},
{
first_name: 'altro_primo',
last_name: 'altro_ultimo',
id: 2
}
]).models;
return _.map(users, function (user) {
return {
id: user.get('id'),
full_name: user.get('first_name') + ' ' + user.get('last_name'),
// these functions allows Bootstrap typehead to use this item in places where it was expecting a string
toString: function () {
return JSON.stringify(this);
},
toLowerCase: function () {
return this.full_name.toLowerCase();
},
indexOf: function (string) {
return String.prototype.indexOf.apply(this.full_name, arguments);
},
replace: function (string) {
return String.prototype.replace.apply(this.full_name, arguments);
},
substr: function(start, len){
return this.full_name.substr(start, len);
}
};
});
};
$('.full_name').typeahead({
minLength: 3,
source: getSource(),
display: 'full_name',
updater: function (itemString) {
var item = JSON.parse(itemString);
$('.id').val(item.id);
return item.full_name;
}
});
本文标签: javascriptExtend the bootstraptypeahead in order to take an object instead of a stringStack Overflow
版权声明:本文标题:javascript - Extend the bootstrap-typeahead in order to take an object instead of a string - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738493107a2089822.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
sorter()
method for trying apply string methods on objects. Were you altering that method? Or perhaps adding functions to the objects? – merv Commented Aug 29, 2012 at 17:23matcher()
andsorter()
both alteritems
before passing it to therender()
method. Also, overridingsorter()
is supported in the API, so there should be no need to edit that in the bootstrap-typeahead.js source. (not saying that's what you were doing - just pointing it out) – merv Commented Aug 29, 2012 at 18:00item.id
in therender()
function. Consider generalizingrender()
to either copy all key-values in the model, or introduce a user-specified option. – merv Commented Aug 30, 2012 at 19:39sorter
,matcher
,source
andhighlighter
, which is all supported in the existing API. Have you tried this? – jackwanders Commented Sep 6, 2012 at 20:35