[转载]jQuery autocomplete with JSON / JSONP support, and overriding the default search parameter (q)...

Okay, I haven’t posted here in a long time, but after much head-smashing-against-the-wall – I’ve done something I’d like to post about.

I’m currently building a web application that uses jQuery and its autocomplete plugin.  While googling around to learn how to use it, I ran across something awesome: geonames.org.  It’s an amazing web service that has craploads of data on geographic places all over the world. Awesome!  They support JSON, so cross-domain requests aren’t an issue.

Rather than use my own, less complete database with an outdated zip code database, I thought “hey, I can use geonames!” — just a few problems:

1) The jQuery autocomplete plugin does not support JSON or JSONP as a data format.  It only accepts this ugly, pipe-delimited format.

2) The autocomplete plugin also has some hard coded defaults it sends on all “remote” queries: “q” and “limit”.  This sucks, because not every remote service uses ?q=foo as a search term.  Geonames does allow q as a search, but it doesn’t behave the way I want. The one that does is called name_startsWith.

So, what do we do?

Here’s my old autoComplete:

 
 
$("#city").autocomplete("/admin/autoComplete/getCity.php", {
selectFirst: true,
minChars: 1,
max: 50
});
My getCity.php searched for all cities in my database containing whatever was sent in the q= parameter, and returned list that jQuery’s autocomplete plugin would be happy with.  The plugin also sends limit=50 – using my max: parameter, and my php handles that.  All fine and good.

However, with a bit of trickery, I was able to make a city autocomplete using the geonames.org service.  Here’s the documentation for the geonames search web service.

First and foremost, the q= parameter searches for an exact match on geonames.org.  We can’t have that.  We need to use their name_startsWith= parameter to search.  This isn’t as nice as a contains type parameter, but it’s all they’ve got (that I know of)…

So, what are we to do?

1) Override q and limit by setting them equal to ” in extraParams.

2) Add the paramter dataType: ‘jsonp’; to our autocomplete.

3) Write a function to parse what geonames.org returns.

What does the code look like?

 
 
$("#city").autocomplete("http://ws.geonames.org/searchJSON", {
dataType: 'jsonp',
parse: function(data) {
var rows = new Array();
data = data.geonames;
for(var i=0; i<data.length; i++){
rows[i] = { data:data[i], value:data[i].name, result:data[i].name };
}
return rows;
},
formatItem: function(row, i, n) {
return row.name + ', ' + row.adminCode1;
},
extraParams: {
// geonames doesn't support q and limit, which are the autocomplete plugin defaults, so let's blank them out.
q: '',
limit: '',
country: 'US',
featureClass: 'P',
style: 'full',
maxRows: 50,
name_startsWith: function () { return $("#city").val() }
},
max: 50
});
So, what does that mess all mean?
 
 
$("#city").autocomplete("http://ws.geonames.org/searchJSON", {
There, we bind an autocomplete to the document element with ID=”city”, and we set it up to call the geonames.org service.
 
 
dataType: 'jsonp',

We tell the autocomplete we’re expecting jsonp as our data format – an undocumented feature!

 

parse: function(data) {
  var rows = new Array();
  data = data.geonames;
  for(var i=0; i<data.length; i++){
    rows[i] = { data:data[i], value:data[i].name, result:data[i].name };
  }
  return rows;
},

 

We write a function to parse the data we get back, and return it in a way that the autocomplete plugin is happy with.  This function digs into the “geonames” node of the JSON that the service returns, and then spits out data values row by row for the autocomplete.

 

formatItem: function(row, i, n) {
  return row.name + ', ' + row.adminCode1;
},

 

This part wasn’t necessary, but I format the item to include the adminCode1 field, which is the state – so my autocomplete will show “Chicago, IL” instead of just “Chicago” — however, the field is still only populated with “Chicago” when I choose that result.

 
 
     extraParams: {
       // geonames doesn't support q and limit, which are the autocomplete plugin defaults, so let's blank them out.
       q: '',
       limit: '',
       country: 'US',
       featureClass: 'P',
       style: 'full',
       maxRows: 50,
       name_startsWith: function () { return $("#city").val() }
     },

In the extraParams section, we override q and limit by setting them to nothing. We then set the country code to US – as I only wanted to search for cities in the US.  I also didn’t want other “geographic places besides cities” – such as rivers, etc – so we set featureClass to “P” – which is their code for cities.

Unfortunately, geonames doesn’t return the state (adminCode1 in their jargon) unless you request the “full” format (which returns a LOT more data), so that’s why style: ‘full’ is there.

geonames uses “maxRows” to specify the maximum number of results – I went with 50.

Next, we set name_startsWith – our most important search parameter – to whatever the user has typed into the #city field so far.

 
 
     max: 50
});
Finally, we tell the autocomplete plugin to expect a max of 50 rows, and close out our code.

The end result is a search box that uses geonames.ws and finds cities anywhere in the US.

Here’s a demonstration.

本文原始链接

转载于:https://www.cnblogs.com/suoqiang/archive/2010/07/26/1785399.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值