I'm using Typeahead to render instances of my "User" model in a drop-down list:
Controller:
def typeahead
render json: User.where(name: params[:query])
end
View:
<input type="text" id="typeahead">
<script type="text/javascript">
var bloodhound = new Bloodhound({
datumTokenizer: function (d) {
return Bloodhound.tokenizers.whitespace(d.value);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: '/typeahead/%QUERY',
limit: 50
});
bloodhound.initialize();
$('#typeahead').typeahead(null, {
displayKey: 'name',
source: bloodhound.ttAdapter()
});
$('#typeahead').bind('typeahead:selected', function(event, datum, name) {
doSomething(datum.id);
});
</script>
This code causes a list of User.name
s to drop down as I type.
Can I render an image, in this case User.avatar.url(:thumb)
? When I change displayKey: 'name',
to displayKey: 'avatar.url(:thumb)',
the drop-down list simply says "undefined" for every User.
[I made sure that User.avatar.url(:thumb)
displays successfully elsewhere]
You need to encode the image as base64 on your server, then return the resulting string in your json response, and finally on the client side use this base64 string to populate your image
1- server side: encode image as base64
def typeahead
users = User.where(name: params[:query])
json = users.collect do |user|
path = user.avatar.url(:thumb)
image = open(path) { |io| io.read }
base64 = ActiveSupport::Base64.encode64(image)
{id: user.id, name: user.name, base64: base64}
end
render json: json
end
2- Client side: use templating to populate users name and image
$('#typeahead').typeahead(null, {
displayKey: 'name',
source: bloodhound.ttAdapter()
templates: {
suggestion: Handlebars.compile('<p><img src="data:image/png;base64,{{base64}}">{{name}}</p>')
}
});
Note1: not tested, you may have to do little adjustments
Note2: This will require a lot of power from your server when you have a big users table and a lot of concurrent connections, because the server would have to open and encode many image files for each query.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments