Bloodhound - typeahead not showing suggestions that start with the typed search string - typeahead

I've been troubleshooting this for couple hours to no avail.
Basically, in the following code, I get the right results from the remote suggestions provider,
var descuentos = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.nonword,
queryTokenizer: Bloodhound.tokenizers.nonword,
remote: {
url: 'http://localhost:30045/Home/Suggest?q=%QUERY&type=name&fuzzy=false',
wildcard: "%QUERY",
filter: function (items) {
return $.map(items, function (item) {
return {
value: item.NombreComercio
};
});
}
}
});
$('#bloodhound .typeahead').typeahead({
hint: true,
highlight: true,
minLength: 0
},
{
name: 'descuentos',
source: descuentos
});
<body>
<div id="bloodhound">
<input class="typeahead" type="text" placeholder="Comercio Adherido...">
</div>
</body>
But, when the suggestion STARTS WITH the search string, is not displayed... Ideas?
Thanks!

Add displayKey to typeahead datasets parameter.
$('#bloodhound .typeahead').typeahead({
hint: true,
highlight: true,
minLength: 0
},{
name: 'descuentos',
displayKey: 'value',
source: descuentos
});
Hope this helps.

Related

ECharts refresh on data change

I'm currently working on an interactive chart which should calculate potential risk-factors of commercial project. I've been using Baidu ECharts for this, and got the graph working visually, but can't get the graph to update when data changes.
The data comes from an external questionnaire, which uses radiobuttons for the values and a checkbox to turn the whole set on and off.
<input type="checkbox" id="GPEbool" value="true"> Example Question 1</h4>
<form action="">
<input type="radio" id="polishedness" value="1"> Idea<br>
<input type="radio" id="polishedness" value="1"> Concept<br>
<input type="radio" id="polishedness" value="2"> Mockup<br>
<input type="radio" id="polishedness" value="5"> Prototype<br>
<input type="radio" id="polishedness" value="7"> Playable<br>
<input type="radio" id="polishedness" value="15"> Polish<br>
<input type="radio" id="polishedness" value="30"> Finished<br>
</form>
Now, the problem is getting the data into the graph. It gets the initially selected value right (when adding "checked" to one of them), but won't update after that.
data: [{ value: $('input[name=polishedness]:checked').val(), name: 'Design'}]
I've tried calling the refresh function whenever something changes, but it'll return refresh is not a function. I'm really at loss, and the Chinese documentation doesn't help me much :)
Any suggestions? Thanks in advance!
You have to call chartInstance.setOption() again with your new data.
I give you a small example:
// eChart is the chart instance!
echart.setOption({
// .... some configuration
series: [
{
type: "line",
name: "test",
data: [1,2,3,4,5,6]
}
]
})
After you changed the value of your select box, you have to catch that event, change the value of the configuration object and call chartInstance.setOption() again.
Therefore, it is sometimes advisable to save your complete configuration object and store your changes there.
You can use resize() method, for example
window.chartRadar = echarts.init(document.getElementById('echartId'));
window.chartRadar.setOption({
title: {
text: 'radar echart'
},
tooltip: {},
legend: {
data: ['data1', 'data2']
},
radar: {
// shape: 'circle',
name: {
textStyle: {
color: '#fff',
backgroundColor: '#999',
borderRadius: 3,
padding: [3, 5]
}
},
indicator: [
{ name: 'sales', max: 6500},
{ name: 'Administration', max: 16000},
{ name: 'Information Techology', max: 30000},
{ name: 'Customer Support', max: 38000},
{ name: 'Development', max: 52000},
{ name: 'Marketing', max: 25000}
]
},
series: [{
name: 'Budget vs spending',
type: 'radar',
// areaStyle: {normal: {}},
data : [
{
value : [4300, 10000, 28000, 35000, 50000, 19000],
name : 'data1'
},
{
value : [5000, 14000, 28000, 31000, 42000, 21000],
name : 'data2'
}
]
}]
});
Once you alreay make you echart you cloud use the method "resize()" for redraw the echar for example
window.chartRadar.resize();
If you are using Angular ,
You can also use the [merge] option to have the Chart responding for the value changes,
<div echarts [options]="initialValue" [merge]= "dynamicData" class="demo-chart"></div>
Reference : https://github.com/xieziyu/ngx-echarts#api
In your Module assign Initial Value as below,
initialValue: EChartOption = {
xAxis: {
type: 'time',
splitNumber : 20
},
yAxis: {
type: 'value',
name : '$',
nameLocation: 'middle'
},
series: [{
data : [],
type: 'line'
}]
}
and set the Dynamic value based on your data, Also initialize "this.dynamicData" before making the api calls to the external service
formDataforChart(backTestTrades) {
let i = 0;
for(let backTestTrade of backTestTrades){
let profitAndTime = [];
profitAndTime.push(backTestTrade.exitTime);
profitAndTime.push(backTestTrade.profitOrLoss);
this.eChartDataSeries.push(profitAndTime);
}
let data = {
data : this.eChartDataSeries,
type : 'bar'
};
this.dynamicData=this.initialValue;
this.dynamicData.series = [];
// Applying my dynamic data here
this.dynamicData.series.push(data);
}

Algolia - Search with a condition to look into an array of string

I am using rails and algolia gem with mongoid datastore.
I am sending data to algolia for a model Question. One of the doc example in Algolia system is
objectID: 5691e056410213a381000000
text: "what is #cool about your name Mr. John? #name #cool"
asked_to: ["565571704102139759000000", "i7683yiq7r8998778346q686", "kjgusa67g87y8e7qtwe87qwe898989"]
asked_by: "564a9b804102132465000000"
created_at: "2016-01-10T04:38:46.201Z"
card_url: "http://localhost:3000/cards/5691e056410213a381000000"
answerers: []
has_answer: false
requestor_count: 0
status: "active"
popularity_point: 0
created_at_i: 1452400726
_tags: ["cool", "name"]
I want to find all those documents, where it meets these two conditions:
1) text contains your name
2) asked_to contains i7683yiq7r8998778346q686
I am using Twitter's typeahead javascript library. And my UI's javascript to implement algolia search is as follows:
<input class="typeahead ui-widget form-control input-md search-box tt-input" id="typeahead-algolia" placeholder="Search questions" spellcheck="false" type="text" autocomplete="off" dir="auto" style="position: relative; vertical-align: top;">
$(document).on('ready page:load', function () {
var client = algoliasearch("APPLICATION_ID", "SEARCH_KEY");
var index = client.initIndex('Question');
$('#typeahead-algolia').typeahead(
{
hint: false,
highlight: true,
minLength: 1
},
{
source: index.ttAdapter({hitsPerPage: 10}),
displayKey: 'text'
}
).on('keyup', this, function (event) {
if (event.keyCode == 13) {
$('#typeahead-algolia').typeahead('close');
window.location.href = "/?keyword="+encodeURIComponent($('#typeahead-algolia').val());
}
});
$('.typeahead').bind('typeahead:select', function(ev, suggestion) {
window.location.href = suggestion.card_url;
});
});
So my question is:
This code works perfectly. But how to add condition for asked_to contains i7683yiq7r8998778346q686 in above javascript to filter out result.
You can use a facet filter on the asked_to attribute in your query.
You first need to declare the attribute asked_to as an attribute for faceting in your index settings and then pass asked_to:i7683yiq7r8998778346q686 as a facet filter in your query via the facetFiltersquery parameter.
When your index settings are changed, you can change your source to add the facetFilters parameter:
$('#typeahead-algolia').typeahead(
{
hint: false,
highlight: true,
minLength: 1
},
{
source: index.ttAdapter({hitsPerPage: 10, facetFilters: "asked_to:i7683yiq7r8998778346q686"}),
displayKey: 'text'
}
).on('keyup', this, function (event) {
if (event.keyCode == 13) {
$('#typeahead-algolia').typeahead('close');
window.location.href = "/?keyword="+encodeURIComponent($('#typeahead-algolia').val());
}
});

twitter typeahead.js autocomplete remote not working

I have a site with stocks. I would like to add typeahead functionality to my bootstrap template. Since there are about 5000 stocks and will be even more in the future. I am using haystack with whoosh index. I should be using remote version of typeahead.js, but it is not working. Could you please take a look and tell me what am I missing?
<script type="text/javascript">
var stocks = new Bloodhound({
datumTokenizer: function (datum) {
return Bloodhound.tokenizers.whitespace(datum.name);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
limit: 5,
remote: {
url: "/search/autocomplete/",
replace: function(url, query) {
return url + "?q=" + query;
},
filter: function(stocks) {
return $.map(stocks, function(data) {
return {
tokens: data.tokens,
symbol: data.symbol,
name: data.name
}
});
}
}
});
stocks.initialize();
$('.typeahead').typeahead(null, {
name: 'stocks',
displayKey: 'name',
minLength: 1, // send AJAX request only after user type in at least X characters
source: stocks.ttAdapter()
});
</script>
This is my form
<form class="input-prepend" method="get" action="/search/">
<div id="remote">
<button type="submit" class="btn">Search</button>
<input type="text" class="typeahead" id="id_q" placeholder="Stock symbol or name" autocomplete="off" name="q">
</div>
</form>
Urls.py
url(r'^search/autocomplete/', 'stocks.views.autocomplete'),
url(r'^search/', include('haystack.urls')),
autocomplete view
from haystack.query import SearchQuerySet
import json
def autocomplete(request):
sqs = SearchQuerySet().autocomplete(content_auto=request.GET.get('q', ''))[:5]
array = []
for result in sqs:
data = {"symbol": str(result.symbol),
"name": str(result.name),
"tokens": str(result.name).split()}
array.insert(0, data)
return HttpResponse(json.dumps(array), content_type='application/json')
json response:
[{"tokens": ["Arbor", "Realty", "Trus"], "symbol": "ABR", "name": "Arbor Realty Trus"}, {"tokens": ["ABM", "Industries", "In"], "symbol": "ABM", "name": "ABM Industries In"}, {"tokens": ["AmerisourceBergen"], "symbol": "ABC", "name": "AmerisourceBergen"}, {"tokens": ["ABB", "Ltd", "Common", "St"], "symbol": "ABB", "name": "ABB Ltd Common St"}, {"tokens": ["Allianceberstein"], "symbol": "AB", "name": "Allianceberstein "}]
This is my domain name: digrin.com and this is autocomplete url.
What am I missing?
I can see two problems:
1) Your script declaration is missing a type attribute:
<script src="http://code.jquery.com/jquery-1.11.0.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.js"></script>
<script type='text/javascript' src="http://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.js"></script>
add "type='text/javascript'" to the script declarations for jquery and bootstrap.
A more modern way of declaring your script tags can be found here.
2) To initialise Typeahead you need to place the code into your jQuery ready method i.e.
$(function(){
var stocks = new Bloodhound({
datumTokenizer: function (datum) {
return Bloodhound.tokenizers.whitespace(datum.name);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
limit: 5,
remote: {
url: "/search/autocomplete/",
replace: function(url, query) {
return url + "?q=" + query;
},
filter: function(stocks) {
return $.map(stocks, function(data) {
return {
tokens: data.tokens,
symbol: data.symbol,
name: data.name
}
});
}
}
});
stocks.initialize();
$('.typeahead').typeahead(null, {
name: 'stocks',
displayKey: 'name',
minLength: 1, // send AJAX request only after user type in at least X characters
source: stocks.ttAdapter()
});
});
As it is currently the typeahead code wont get loaded.

newbie mistake? JSON and Ember

new here to ember, and very much trying to learn - and learn where I'm going wrong.
I'm being fed json that looks like this:
"status": "success",
"data": {
"groups": [
{
"id": 2,
"name": "Test1234",
"kind": "Happy",
"parent_group_id": 1,
"children_count": {
"boy": 10,
"girl": 4,
"pets": 2
},
"is_top_level": true
},
The path to get this info would be /api/groups/top.
I have a (what I believe would be) simple app.js:
App = Ember.Application.create();
App.Router.map(function() {
this.route("login", {path: "/"});
this.route("groups");
this.resource('about');
});
App.GroupsRoute = Ember.Route.extend({
model: function() {
return App.Group.find('top');
}
});
App.LoginController = Ember.Controller.extend({
actions: {
login: function(username, password){
jQuery.ajax({
url: "/api/auth",
type: 'post',
data: JSON.stringify( { "username": "user", "password": "pass" } ),
contentType: 'application/json',
dataType: 'json',
async: false,
success: function(result) {
if (result.status === 'success') {
user = result.data.user;
App.User.id = user.id;
App.User.name = user.name;
App.User.isAuthenticated = true;
App.User.displayUnits = "F";
} else {
//debugger;
throw "The! username and/or password you have entered is incorrect, please try again ";
return false;
}
},
error: function(xhr, status, errorOut) {
throw "The? username and/or password you have entered is incorrect, please try again ";
return false;
}
});
if (App.User.isAuthenticated)
this.transitionToRoute('groups');
}}
});
App.RESTAdapter = RL.RESTAdapter.create({
host: 'http://localhost:3000',
namespace: 'api/'
});
App.Client = RL.Client.create({
adapter: App.RESTAdapter
});
App.User = RL.Model.extend({
username: RL.attr('string'),
id: RL.attr('string'),
isAuthenticated: RL.attr('boolean'),
});
App.Group = RL.Model.extend({
id: RL.attr('string'),
name: RL.attr('string'),
kind: RL.attr('string')
});
App.RESTAdapter = RL.RESTAdapter.create({
defaultData: { cookie: "data"}
});
I'm trying to display each "group" in my template. For example {{#each groups}} {{name}} {{/each}}, but no luck - I can see the JSON data in the response in inspector, and no errors - but still, nothing coming trough.
Any help?
Thanks!
Ptep
edit - template:
<script type="text/x-handlebars">
{{outlet}}
</script>
<script type="text/x-handlebars" id="groups">
<h3>Hello,
{{#each groups}}
{{name}}! <br>
{{kind}}, {{id}}
{{/each}}
</h3>
</script>
The array itself would be the context of your template, so you would either use
{{#each}}{{name}}{{/each}}
or
{{#each model}}{{name}}{{/each}}
or
{{#each controller}}{{name}}{{/each}}
or
{{#each item in controller}}{{item.name}}{{/each}}

How to get two different markers on Google map?

gmaps4rails 2 + rails 4 + ruby 2.0
<script>
handler = Gmaps.build('Google');
handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
markers = handler.addMarkers(<%= raw #geo_hash.to_json %>);
});
handler.map.centerOn({ lat: <%= raw #geo_city[0][:lat] %>, lng: <%=raw #geo_city[0][:lng] %> })
handler.getMap().setZoom(7)
</script>
#geo_hash = [{:lat=>16.9916,
:lng=>81.7838,
:infowindow=>"railway station",
:picture=>{:url=>"/assets/web/blank_red.png", :width=>32, :height=>32},
:title=>"abc temple"}
]
#geo_city = [{:lat=>15.8273,
:lng=>78.047,
:infowindow=>"Bus stand",
:picture=>{:picture=>"/assets/web/**blank.png", :width=>32, :height=>32},
:title=>"A.S. Peta"}]
I want two different marker on Google map but only one marker is coming ? any suggestion ?
I got the solution...
<script>
handler = Gmaps.build('Google');
handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
markers1 = handler.addMarkers(<%= raw #geo_hash.to_json %>);
markers2 = handler.addMarkers(<%= raw #geo_city.to_json %>);
});
handler.map.centerOn({ lat: <%= raw #geo_city[0][:lat] %>, lng: <%=raw #geo_city[0][:lng] %> })
handler.getMap().setZoom(7)
</script>
Thanks.