I started to give angularJS more attention today, and in my project I would need geonames.
I wanted to create something like jQuery UI's autocomplete with geonames like this.
All is fine when I console.log it, I get back the results, but for some reason I can't place it to typeahead's dropdown list.
scope
$scope.cities = function(cityName)
{
return $http.jsonp("http://ws.geonames.org/searchJSON?callback=JSON_CALLBACK&q="+cityName+"&maxRows=6").success(function(data){
$.map(data.geonames, function(item)
{
return item.name + (item.adminName1 ? ", " + item.adminName1 : "") + ", " + item.countryName;
});
});
};
input
<input type="text" class="span4" ng-model="result" typeahead="suggestion for suggestion in cities($viewValue)">
I am using UI Bootstrap for angular js and I tried based on that example but something is wrong, could please someone give me a hint?
Thank you
$http.jsonp performs requests asynchronously, so what you do in your success callback is lost.
You can use $q.defer or a watcher (but apparently the latter doesn't work properly with typeahead) to apply the values from the success callback:
$scope.cities = function(cityName)
{
var dfr = $q.defer();
$http.jsonp("http://ws.geonames.org/searchJSON?callback=JSON_CALLBACK&q="+cityName+"&maxRows=6").success(function(data){
dfr.resolve($.map(data.geonames, function(item)
{
return item.name + (item.adminName1 ? ", " + item.adminName1 : "") + ", " + item.countryName;
}));
});
return dfr.promise;
};
}
Related
Usecase
There are a total of 200000 records exist in my database, if i load all the option in one time the page is not loading at all, it is saying maximum transaction time crossed (i felt like its the worst approach).
I thought of loading the selectize options based on keyword search, i will show the 50 records close to the search keyword.
I implemented the search in backend(Serverside), it is returning the data correctly to the client but i'm not finding a way to show them as options in html.
Please find my code below:
$scope.$selectUser = $('#selectUser').selectize({
valueField: 'sys_id',
labelField: 'name',
maxItems: c.data.maxteam,
placeholder:"Enter names or select below",
create: false,
load: function (query, callback) {
if (!query.length) return callback();
$scope.data.funcName = 'getUsers';
$scope.data.searchQuery = query;
$scope.data.kudosTo = [];
//Server call happens here
c.server.update().then(function(){
//Search data coming fine in this variable
var results = c.data.activeUsers;
//??? AT this step i'm not what to do to appear the data as selectize options and select from them ??
callback(results);
});
},
render: {
option: function (item, escape) {
return '<div class="option">' +
'<div class="text">' +
'<span class="name">' + escape(item.name) +"<i class='fa fa-circle circleFont'></i>"+ escape(item.user_name) + '</span>' +
'</div>' +
'</div>';
}
},
});
$scope.selectizeControlUser = $scope.$selectUser[0].selectize;
<div class="form-group text-left clearfix">
<select class="form-control" id="selectUser" multiple></select>
</div>
Search data coming fine in client code:
Issue: Selectize options are not showing in the HTML view
Expected results: Options should come like below image
I figure it out myself.
Options are appending to the options but just not showing in the view.
I added searchField and it started working fine as expected.
searchField: ['name', 'email', 'user_name'],
I have to use templates to translate my grid's cells values.
For some reasons, the function I'm calling to translate is returning a promise.
I found the following topic related to my issue
Asynchronous cell template
I'm using the angular method with
ng-bind-html
$scope.lookUpEventNameAsync = function(data) {
refData.events().fetch(function() {
var eData = refData.events().data();
var refEvent = eData.find(function(re, i, a) {
return re.code === data.eventCode;
});
$("#async_tse_" + data.key).html(refEvent.name);
});
return $sce.trustAsHtml("<div id='async_tse_" + data.key + "'> </div>");
};
$scope.gridTimesheetColumns = [
{
field: "eventCode",
title: "Event",
template: "<span ng-bind-html='lookUpEventNameAsync(dataItem)'> </span>"
},
....
I made a similar thing to adapt it with the code I have and it's working.
But the problem now is that it's calling $scope.lookUpEventNameAsync several times and never stop calling it which is freezing the screen and make the app unusable.
Do you have an idea why and how can I prevent it ?
I needed a one way data binding like the following :
$scope.gridTimesheetColumns = [
{
field: "eventCode",
title: "Event",
template: "<span ng-bind-html='::lookUpEventNameAsync(dataItem)'> </span>"
},
After spending a lot of time in investigating to resolve the issue to allow any tag along with autocomplete feature in ngInputTag. I end up with no results.
The issue is when I type the text which is in autocomplete list the tags get added successfully but when point comes to add the tags which is not in the tag list it accepting the first tag but when I enter second tag which is not in autocomplete list it makes the text color Red and not accepting the tag input.
To resolve the issue I have used on-tag-added but it did not worked. Same issue has been reported on Git-Hub Issue Link
Below is my code:
HTML
<tags-input ng-model="model" display-property="Name" key-property="Key"
placeholder="Enter Tags" add-from-autocomplete-only="false"
allow-leftover-text="true">
<auto-complete source="loadTags($query)"
highlight-matched-text="true"
select-first-match="true">
</auto-complete>
</tags-input>
Controller JS Code:
$scope.model = [];
$scope.loadTags = function (query) {
var deferred = $q.defer();
$http.get(ApiUrls.GetTagsByQuery + (query != null ? ("?query=" + query) : ""))
.then(function (result) {
if (result.data == null) {
result = [];
}
deferred.resolve(result.data);
},
function (response) {
deferred.reject(response);
});
return deferred.promise;
};
Any Help will be Highly Appreciated. Thanks.
Same problem !!! But if you remove key-property then it will works.
key-property is only for duplicate issue
I tried to view different sources and also looked into the forums posting similar question, but it didnt quite help me with the issue that im facing.
I have a text input filed to which I'm adding a popover to show similar a list of names in the database. The inout field checks for validation, to see if the name entered is unique, if not it displays similar names available in the database that could be re-used.
here is the popover snippet:
$("#account_name_create").popover({
title: 'Twitter Bootstrap Popover',
content: function (process) {
this.accountCollection = new ipiadmin.collections.AccountCollection();
var newName = $("#new-account-form #account_name_create").val();
var userFilter = "accountName~'" + newName + "'";
this.accountCollection.fetch({
data: { "f": userFilter,
"sortby": null,
"type":"ipi",
"pageno":0,
"pagesize":2,
"reversesort" : true
},
cache: false,
success: function(model, response, options) {
var states = [];
map = {};
$.each(model.aDataSet, function (i, state) {
map[state.accountName] = state;
states.push(state.accountName);
});
process(states); //gives an error saying 'undefined is not a function (says process is undefined)'
},
error: function(model, response, options) {
console.log('error');
}
});
},
});
here is the html:
<input type="text" id="account_name_create" name="account_name" class="" size="40" />
I'm not sure how why it says 'process' as undefined. Also not sure if this would be the correct way of displaying the data in the popover.
Any ideas??
Thanks!
process doesn't have scope in the success function, only in the content function. If you want to call the process function from within the success function, you could define it somewhere outside of the jQuery call.
i want my facebook graph api /me/friends list in an autocomplete field. I want choose my friend, select one of them end have its ID.
Facebook response with a "data" json object with name and id. Perfect!
Some code:
$(document).ready(function(){
FB.api('/me/friends', function(fbresponse){
$("#input_13").autocomplete({
source : function(request, response){
response($.map(fbresponse.data, function(e){
return{
id : e.id,
name : e.name
}
}))
},
select : function(event, ui){
alert(ui.item.name);
$("#input_13").val(ui.item.name);
$("#input_10").val(ui.item.id);
return false;
}
}).data("autocomplete")._renderItem = function(ul, item){
return $("<li></li>")
.data("item.autocomplete", item)
.append( $("<a></a>").html(item.name) )
.appendTo(ul);
};
});
});
Results is at 90%, when I begin typing, the list of my friends appears but it's order from the first to the end, it's not filtered.
Example:
My list complete is:
marco
massimo
marino
mimmo
simone
sara
sonia
when I begin with "s" should result only
simone
sara
sonia
but the result list does not change.
What's happen?
Thanks a lot.
As your source property is pointing to a function it is called ever the plugin needs the datasource, the problem is: the FB Graph API don't accept a "term" param when searching for friends so it returns always the same data based on your input. What you need is something like this:
var makeItems = function(fbresponse) {
return $.map(fbresponse, function(item) {
return {
label: item.name,
value: item.id,
}
});
};
var setAutoComplete = function(parsed_items) {
$("#input_13").autocomplete({
source : parsed_items,
select : function(event, ui){
alert(ui.item.name);
$("#input_13").val(ui.item.name);
$("#input_10").val(ui.item.id);
return false;
}
}).data("autocomplete")._renderItem = function(ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append( $("<a></a>").html(item.name) )
.appendTo(ul);
};
};
FB.api('/me/friends', function(fbresponse) {
setAutoComplete(makeItems(fbresponse.data));
});
It will make only one request, will get all the friends and set a variable with an array of parsed items so the filter can act in the array.
I hope it help you.
take a look at this code example, its working fine.
http://blogs.microsoft.co.il/blogs/alon_nativ/archive/2011/05/30/search-facebook-friends-with-jquery-autocomplete.aspx