Autocomplete postal code and place name with Ajax and Geonames - json

I would like to have a autocomplete for a textfield (tf_place), where you start to type the place name (of a German city) and it fills in the complete city name. As source I would like to use GeoNames. I already created a new user account and confirmed it.
$('[data-name="tf_place"]').autocomplete({
source: function (request, response) {
$.ajax({
url: "http://api.geonames.org/postalCodeSearchJSON",
dataType: "jsonp",
data: {
featureClass: "P",
maxRows: 10,
country: "DE",
placename_startsWith: request.term,
username: "myUser"
},
success: function (data) {
response($.map(data.postalCodes, function (item) {
return {
label: item.postalCode + "-" + item.placeName,
value: item.postalCode + "-" + item.placeName
}
}));
}
});
},
});
What's wrong?
Edit: I tried the complete URL:
http://api.geonames.org/postalCodeSearchJSON?featureClass=P&maxRows=10&country=DE&placename_startsWith=Be&username=myUser
It works! (to make it work for you, you need to replace myUser with your own username)
So why doesn't my code work?

Related

autocomplete to populate all values on input focus

I have autocomplete textbox whose values are populated using ajax call which returns json data. This works fine with following code lines.
$("#searchTitle").autocomplete({
source: function (request, response) {
$.ajax({
url: "/umbraco/Surface/MyApp/StartSearch",
type: "POST", dataType: "json",
data: { term: request.term },
success: function (data) {
debugger
response($.map(data, function (item) {
debugger
return { label: item.Cat_Name };
}));
}
});
},
messages: { noResults: "", results: "" },
minLength: 0
});
But this function gets called when user type something. Now, I want that when input is focused, all the values from response should be shown in autocomplete. How can I trigger the same?
You can achieve by using search event of autocomplete on focus of input.
For example
$( "#searchTitle" ).focus(function() {
// make sure you put space between double quote
$( "#searchTitle" ).autocomplete("search", " " );
});

Jquery Ui autocomplete is not loadin data from http://ws.geonames.org/

Visit my fiddle
The data from http://ws.geonames.org/searchJSON?&country=DE is not loading, and if I change that into http://www.geonames.org/searchJSON?&country=DE it says I need a username.
Here is jQuery code I'm using:
$(".city").autocomplete({
source: function (request, response) {
$.ajax({
url: "http://ws.geonames.org/searchJSON?&country=DE",
dataType: "jsonp",
data: {
featureClass: "P",
style: "full",
maxRows: 12,
name_startsWith: request.term,
countryName: "Germany"
},
success: function (data) {
response($.map(data.geonames, function (item) {
return {
label: item.name + (item.adminName1 ? ", " + item.adminName1 : "") + ", " + item.countryName,
value: item.name
}
}));
}
});
}
});
Is there any alternative to this?
Thanks.
First: You should use http://api.geonames.org/searchJSON?&country=DE instead of http://ws.geonames.org/searchJSON?&country=DE
The latter is for premium web service so you need an account
Second:http://api.geonames.org/searchJSON?q=DE&country=DE&lang=en&username=demo&callback=?
You can use demo but it has a hourly limit of 2000 queries (shared by a lot of people), you can create a free account but it has limited credits too. Not sure how much visits you are expecting per day.

Adding StateCode dash StateName to the autocomplete using MVC4.5 and a JsonResult

I am trying to get the state code to be followed by a dash and the state name using an ajax autocomplete syntax. I'm using jQuery and jQueryUI and the jQueryUI autocomplete function to attempt this.
I am using this json result:
[{"code":"AK","name":"Alaska"},{"code":"AL","name":"Alabama"},
{"code":"AR","name":"Arkansas"},{"code":"AZ","name":"Arizona"},
{"code":"CA","name":"California"}, ... ]
And I'm using this jQuery ajax call with an embedded
$.ajax({
url: '/Cats/State/List',
type: 'POST',
dataType: 'json',
success: function (data) {
$('#Cat_stateCode').autocomplete(
{
source: data.code + '-' + data.name,
minLength: 2
});
}
});
The mvc controller JSON Result looks like this:
public JsonResult List()
{
return Json(db.States.ToList(), JsonRequestBehavior.AllowGet);
}
How do I get the auto complete to show:
CA - California
CO - Colarado
If I type out C? Or does Autocomplete only work with simple json like {"AK", "AL", "AR" ... }?
Figured it out:
$("#Cat_stateCode").autocomplete({
source: function (request, response) {
$.ajax({
url: "/Cat/States/List",
dataType: "json",
data: {
style: "full",
maxRows: 12,
req_state_part: request.term
},
success: function (data) {
response($.map(data, function (item) {
return {
label: item.code + ' - ' + item.name,
value: item.code
}
}));
// alert("data.code:" + data);
},
error: function (e) {
alert("e.error:" + e.error);
}
});
},
minLength: 1,
select: function (event, ui) {
//alert("ui item:" + ui.item ? "Selected: " + ui.item.label : "Nothing selected, input was " + this.value); //todo: remove after dev
},
open: function () {
$(this).removeClass("ui-corner-all").addClass("ui-corner-top");
},
close: function () {
$(this).removeClass("ui-corner-top").addClass("ui-corner-all");
}
});
In my mvc CatStateController I have this:
public JsonResult List(String stateAbbreviation)
{
String StateNameORStateCodeContains = Request.Params["req_state_part"];
return Json(db.States.Where(state => state.name.Contains(StateNameORStateCodeContains) || state.code.Contains(StateNameORStateCodeContains)).ToList(), JsonRequestBehavior.AllowGet);
}
So it looks like it doesn't sent the term over, it only send over some params you make up in the data element. Since you can make up pretty much anything its up to the developers imagination. One thing I was trying to do was create a closure b/c I have a lot of different animals with different states. And I need to create this same autocomplete function for each of them. So I need to ask another question how do you remove the auto complete so I can call that same function from many different ids, or do I just separate them out with a comma like so:
$("#Cat_stateCode,#Dog_stateCode,#Penguin_stateCode...").autocomplete({ ... ???
And I believe the answer to the second part is in here. I think its insinuating just add some class or attribute to the applicable input tags and then just perform an each over them and them lastly apply the autocomplete to the $(this).autocomplete immediately after each each iteration occurs.
Found a better way with just set the input tag to have a class="cssClassName". Had to use the TextBoxFor:
#Html.TextBoxFor(model => model.Cat.stateCode, new { #class = "StateCodeAutoComplete" })

autocomplete jquery.get json doesn't complete

I'm having trouble with autocomplete, usign JSON data.
I'm getting the right response from the callback, but the autocomplete doesn't work properly. For example, when I type "Lon" I get this response:
[{\"value\":\"Dijon, (DIJ)\",\"code\":\"DIJ\"},{\"value\":\"Longview, (GGG)\",\"code\":\"GGG\"},{\"value\":\"Long Island, (HAP)\",\"code\":\"HAP\"},{\"value\":\"Islip, (ISP)\",\"code\":\"ISP\"},{\"value\":\"Long Banga, (LBP)\",\"code\":\"LBP\"},{\"value\":\"Londrina, (LDB)\",\"code\":\"LDB\"},{\"value\":\"Londonderry, (LDY)\",\"code\":\"LDY\"},{\"value\":\"Long Beach, (LGB)\",\"code\":\"LGB\"},{\"value\":\"Long Lellang, (LGL)\",\"code\":\"LGL\"},{\"value\":\"Long Akah, (LKH)\",\"code\":\"LKH\"},{\"value\":\"Londra, (All airports - LON)\",\"code\":\"LON\"},{\"value\":\" - Londra, Gatwick Arpt (LGW)\",\"code\":\"LGW\"},{\"value\":\" - Londra, London City Arpt (LCY)\",\"code\":\"LCY\"},{\"value\":\" - Londra, Stansted Arpt (STN)\",\"code\":\"STN\"},{\"value\":\" - Londra, London Biggin Hill Arpt (BQH)\",\"code\":\"BQH\"},{\"value\":\" - Londra, Heathrow (LHR)\",\"code\":\"LHR\"}]
But my autocomplete just adds Longview and Long Island.
The tricky thing is that after I keep typing "Lond", the autocomplete works perfect, I delete the "d", the autocomplete works perfect, it completes all the data from above.
Where do I go wrong...?
Here's my code:
$("#destination2").keyup(function(){
var term = $("#destination2").val();
//var query_type = $("#form_type").val();
jQuery.get('http://online.bileteavion.com.ro/q_travel_online_api/misc/hotels.autocomplete.php?query_type=flight&term='+term, function(data) {
data = eval('['+data.responseText.split('[')[1].split(']')[0]+']');
var source = $.map(data, function(item) {
return {
label: item.value,
value: item.value,
id: item.id,
iata: item.iata
}
});
$("#destination2").autocomplete({
source: source,
minLength: 3,
search: function(event, ui) {
$('#loading-spinner').show();
},
change: function(event, ui) {
//console.log(ui.item);
if( !ui.item ) {
$(this).val("");
$("input[name='cityId']").val("");
$("input[name='destinationIataCode']").val("");
$("input[name='destination']").val("");
}
},
open: function() {
$('#loading-spinner').hide();
},
select: function(event, ui) {
$("input[name='cityId']").val(ui.item.id);
$("input[name='destinationIataCode']").val(ui.item.iata);
$("input[name='destination']").val(ui.item.value);
$(this).blur();
}
});
}
);
});
jquery.autocomplete is not a function to call every single time you want to display the autocomplete dialog.
You should call jquery.autocomplete only once during initializion, to equip your input field with a full mechanism which allows autocompleting - and which will take care of the "keyup" event.
To achieve what you need, you should use a callback with the source option.
Here is how :
Instead of :
$("#destination2").keyup(function(){
...
jquery.get(<url>, function(data){
var source = ...
$("#destination2").autocomplete({
source: source
minLength: ...
search: ...
open: ...
select: ...
})
})
})
You should write :
$("#destination2").autocomplete({
source: function(request, response){
//request is an obj containing infos on what is typed
//response is a callback, which should be called if you want to display hints
jQuery.get(url + request.term, function(data){
var source = ...
response(source);
})
}
minLength: ...
search: ...
open: ...
select: ...
})
You should check the Remote JSONP datasource from the docs.
I use this in my site. Works quite well.
$("#id").autocomplete({
source: function (request, response) {
$.ajax({
url: 'http://online.bileteavion.com.ro/q_travel_online_api/misc/hotels.autocomplete.php',
dataType: "json",
data: {
//values to pass to server. in your case: query_type & term
term: request.term,
query_type: 'flight'
},
success: function (data) {
response($.map(eval(data), function (item) {
return {
//map values as you previously did
label: item.value,
value: item.value,
id: item.id,
iata: item.iata
}
})
);
}
})
},
minLength: 3,
search: function(event, ui) {
$('#loading-spinner').show();
},
change: function(event, ui) {
//console.log(ui.item);
if( !ui.item ) {
$(this).val("");
$("input[name='cityId']").val("");
$("input[name='destinationIataCode']").val("");
$("input[name='destination']").val("");
}
},
open: function() {
$('#loading-spinner').hide();
},
select: function(event, ui) {
$("input[name='cityId']").val(ui.item.id);
$("input[name='destinationIataCode']").val(ui.item.iata);
$("input[name='destination']").val(ui.item.value);
$(this).blur();
}
});

JSON returned data it is in {d:"data"} format

I am trying to get JQueryUI's Autocomplete code working with an ASMX web service. I am getting close, but hit yet another wall yesterday. The JSON data is being returned in {d:"data"} format (see http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx). My data now looks like:
d: "[{"DOTNumber":"001061010","JobTitle":"Project Architect"},{"DOTNumber":"003061005","JobTitle":"Principal Electrical Engineer"}]"
My code is:
$(function() {
function log(message) {
$("<div/").text(message).prependTo("#log");
$("#log").attr("scrollTop", 0);
}
});
$("#dotmatch").autocomplete({
source: function(request, response) {
$.ajax({
type: "POST",
url: "/AutoSuggestJSTest/AutoSuggest.asmx/DOTFind",
contentType: 'application/json',
dataType: "json",
data: JSON.stringify({ prefixText: request.term, count: 20 }),
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
},
success: function(data) {
var safe = data;
response($.map(safe.d, function(item) {
return {
label: item.JobTitle + "(" + item.DOTNumber + ")",
value: item.DOTNumber
}
}));
}
});
},
minLength: 2,
select: function(event, ui) {
log(ui.item ?
"Selected: " + ui.item.value + " aka " + ui.item.id :
"Nothing selected, input was " + this.value);
$get("DOTNumber").value = ui.item.value;
},
});
The problem lies in the success function.
What is the right syntax to get past the "d" issue?
Your data should look like this:
{"d":[{"DOTNumber":"001061010","JobTitle":"Project Architect"},"DOTNumber":"003061005","JobTitle":"Principal Electrical Engineer"}]}
It appears you are missing quotes around your "d" and you have extra quotes around your array.
Don't eval() your data - this opens you up to more security issues than the d: prevented.. You should have access to JSON.parse() or if not jQuery.parseJSON() (which wraps JSON.parse() if available... depends on your target platform(s)).
This has been an incredibly difficult process, but I finally got it working. There were a number of hurdles:
1) My JSON return string was getting wrapped in an XML blanket, so it would not parse
2) Solving this problem required the contentType: 'application/json' line
3) With that content type, a POST was required. GET would not work
4) POST required putting the data together using the JSON.stringify. I am still not sure about this one, but I found some code somewhere that did it.
5) Data coming back from the POST was prefixed with a "d " (see: http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx)
6) getting access to the data itself required the "eval(data.d)" line.
$("#dotmatch").autocomplete({
source: function(request, response) {
$.ajax({
type: "POST",
url: "/AutoSuggestJSTest/AutoSuggest.asmx/DOTFind",
contentType: 'application/json',
dataType: "json",
data: JSON.stringify({ prefixText: request.term, count: 20 }),
success: function(data) {
var output = eval(data.d);
response($.map(output, function(item) {
return {
label: item.JobTitle + "(" + item.DOTNumber + ")",
value: item.DOTNumber
}
}));
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});
},
minLength: 2
});
If I ever have this much trouble writing a few lines of code again, I am going to take a very large guage shotgun to my computer!
Bob Jones
If you use a WCF JSON service with the webHttpBehavior (instead of enableWebScriptBehavior), it will not emit the "d"