智能位置表单字段 [英] Smart location form field

查看:104
本文介绍了智能位置表单字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在位置的用户注册表单上有一个文本字段。我基本上希望此字段能够针对Google进行验证地图(或等价) -
只允许有效的地点通过(理想情况下采用类似于滑铁卢,伦敦或伦敦,英格兰的格式)。



要求


  1. 还希望返回该位置中心的坐标(lat,lng)(即使广泛,例如伦敦,英格兰),因为我将交叉引用该坐标以向用户提供相关信息。

  2. 当用户在字段中输入*(编辑)时,基于有效位置的自动完成列表/智能建议列表(理想情况下只是政治位置 - :
  3. 强制用户使用自动完成列表中的某个位置。

允许此字段的权限为au使用HTML5 Geolocation API进行填充以获得用户经验,然后转换为一般位置(即,一般城镇 - 有点像Tweetdeck for Chrome,当你点击添加你的位置时)。



问题是 - 这样做的最好方法是什么?我使用哪些API?



* 编辑:在试用Google Maps API v3地理编码之后,似乎有一个API用来实现此功能问题的结果(一个错误或设计我不知道 - http://code.google.com/p/gmaps-api-issues/issues/detail?id=2042 )。例如,如果我输入 Waterloo ,我只能输入加拿大滑铁卢。那么所有其他Waterloos http://en.wikipedia.org/wiki/Waterloo 呢?我想要一个X多列表(其中X!== 1)供用户选择。理想情况下,我预先定义了X.此外,如果我在表单字段中输入'L',我希望看到最有可能的顺序返回的相关建议列表(可能受GeocodeRequest参数偏好影响) - 所以伦敦,英国利物浦,利兹,英国等等。相反,我得到,荷兰 - 1个随机结果。 WTF?通过Google Maps API完成此操作的替代方案有哪些?



* 更新/解决方案
好​​的我已经完成了一项一些使用geonames的东西 http://jsfiddle.net/ekzMN/95/ 。它工作得很好,但我相信它可以大大改进。你可以随心所欲地使用这些代码。在我真实世界的例子中,我还将Google地理编码添加为次要来源,因为它比地理名称更加智能(即,如果输入邮编或街道地址)。这取决于初始化地理编码器:

  //从Google geocode获取更具体的结果
geocoder.geocode({地址':request.term,'region':'GB'},函数(结果,状态){
$ .map(results,function(item){

var ignore = [ 'route','country','natural_feature','intersection','premise','subpremise','airport','park','point_of_interest','establishment','transit_station'];

if(valid_location(item.types,ignore)== 1){
var sublocality;
var locality;
var region;
var country;

$ .each(item.address_components,function(i,data){
if($ .inArray('sublocality',data.types)> -1){
sublocality = data .long_name;
}
if($ .inArray('locality',data.typ es)> -1){
if(typeof sublocality =='undefined'){
sublocality = data.long_name;
}
}
if($ .inArray('administrative_area_level_2',data.types)> -1){
locality = data.long_name;
}
if($ .inArray('administrative_area_level_1',data.types)> -1){
region = data.long_name;
}
if($ .inArray('country',data.types)> -1){
country = data.long_name;
}
}); $($!

) location = format_location(sublocality,locality,region,country);

if(duplicate(matches,location)== 0){
matches.push({
label:location,
value:location,
纬度:item.geometry.location.lat(),
longitude:item.geometry.location.lng()
});
}
}
}
});
//更新自动完成
响应(匹配);
})

这两种方法的结合很好地提供了智能搜索和多种建议。当我使用两个来源(geonames和google地理编码)时,输入选择范围非常不可靠 - 有时会自动填充,选择附加部分,然后保持突出显示状态,其他时候蓝色突出显示消失(尽管它仍然存在,即在按键上选择消失),并且其他时间光标直接到输入的末尾。我认为与谷歌地图有冲突,而不是多源问题,因为如果我有两个geonames源代码,这不会发生?

正确的答案是任何人都可以改善这一点!



谢谢

好吧,看看你的解决方案,我注意到几个问题。首先,它会在我尝试的每个浏览器中彻底崩溃....



经过一些修复后,我发现了许多与您的解决方案有关的问题:


  1. .autocomplete()是一个初始化函数。它不需要在每个 keyup 上调用。这是在jQuery元素上调用 .autocomplete()后自动处理的。在每一个 keyup 调用它会导致巨大的性能下降以及其他一些神秘的和/或意想不到的后果。


  2. 将合法值存储到全局变量中,然后使用 blur 来检查这些是一个糟糕的主意。虽然我不存储从 autocomplete 返回的每个合法值的想法,但现在我无法为您的案例想出更好的解决方案。我所做的就是将每个合法值存储在输入项目的 .data()中,以检查 .blur() 。这存储为散列/关联数组,这意味着我们可以免费删除重复项。如果您希望您的用户只从后端选择合法值,最好的解决方案是在表单提交上验证输入与后端的输入。 ( Blur )有问题,因为在填充所选值之前,从 autocomplete 建议中选择一个项目固有地模糊了输入。换句话说,你很可能会有一个无效的位置。)这将要求您保存一个字符串作为匹配数据的一部分,该字符串可以发送回服务器进行验证。另一个问题是,如果您的服务器速度较慢(例如GeoNames免费访问),则您可能无法立即获得用户反馈。


这就是说,我已经修正了你的代码(关于上面的第1点和第2点),以正确地调用 autocomplete ,并存储有效解决方案在输入对象中作为jQuery数据。我也将它编码为扩展名,所以可以在任何jQuery选择器上调用它:

http://jsfiddle.net/jtbowden/7NmLr/


I have a single text field on a user registration form for location.

I would essentially like this field to be validated against Google Maps (or equivilent) - only allowing valid locations to pass (ideally in a format something like Waterloo, London or London, England).

Requirements:

  1. As well as a location name, I also would like to return co-ordinates (lat, lng) for the center of that location (even if broad e.g. London, England) as I will be cross referencing this to serve relevent information to the user.
  2. An autocomplete list/ smart suggestion list based on valid locations (ideally just political locations - not street specific) as the user is typing in the field *(Edit: See below).
  3. Force the user to use a location from the autocomplete list.

Privilages permitting this field will be autofilled using HTML5 Geolocation API to get the user lat lng and then converted to a general location (i.e. general town - a bit like Tweetdeck for Chrome does when you hit 'Add your location').

The question is - what is the best way of going about this? What API's do I use? What sections of the API's do I use to achieve this?

*Edit: After experimenting with Google Maps API v3 geocoding it seems there is an issue regarding the results (a bug or by design I'm not sure - http://code.google.com/p/gmaps-api-issues/issues/detail?id=2042). For example if I type in Waterloo all I get is Waterloo, Canada. What about all the other Waterloos http://en.wikipedia.org/wiki/Waterloo? I want a list of X many (where X !== 1) for the user to select from. Ideally where I predefine X. Also if I type in 'L' to the form field I would like to see a list of relevent suggestions returned by order of most likely (perhaps influenced by the bias GeocodeRequest parameter) - so London, UK, Liverpool, UK, Leeds, UK etc etc. Instead I get Limburg, The Netherlands - 1 random result. WTF? What are the alternatives to doing this through Google Maps API?

*Update/Solution: Okay I've worked up a little something that uses geonames http://jsfiddle.net/ekzMN/95/. It's working pretty much okay, although I'm sure it can be massively improved on. You're all free to use this code as you wish. In my real world example I also add google geocode as a secondary source, as it's much smarter than geonames (i.e. if I type in a postcode, or a street address). This is dependent on intialising Geocoder:

// Get more specific results from Google geocode
geocoder.geocode( { 'address': request.term, 'region': 'GB' }, function(results, status) {
    $.map(results, function(item) {

        var ignore = ['route', 'country', 'natural_feature', 'intersection', 'premise', 'subpremise', 'airport', 'park', 'point_of_interest', 'establishment', 'transit_station'];

        if (valid_location(item.types, ignore) == 1) {                  
            var sublocality;
            var locality;
            var region;
            var country;

            $.each(item.address_components, function (i, data) {
                if ($.inArray('sublocality', data.types) > -1) {
                    sublocality = data.long_name;
                }
                if ($.inArray('locality', data.types) > -1) {
                    if (typeof sublocality == 'undefined') {
                        sublocality = data.long_name;
                    }
                }
                if ($.inArray('administrative_area_level_2', data.types) > -1) {
                    locality = data.long_name;
                }
                if ($.inArray('administrative_area_level_1', data.types) > -1) {
                    region = data.long_name;
                }
                if ($.inArray('country', data.types) > -1) {
                    country = data.long_name;
                }
            });

            if ((country != 'United Kingdom') || ($.inArray('administrative_area_level_1', item.types) == -1)) {

                var location = format_location(sublocality, locality, region, country);

                if (duplicate(matches, location) == 0) {
                    matches.push({
                        label: location,
                        value: location,
                        latitude: item.geometry.location.lat(),
                        longitude: item.geometry.location.lng()
                    });
                }                       
            }
        }
    });
    // Update autocomplete
    response(matches);
})

The combination of the two works well providing smart search and multiple suggestions. The one issue that's bugging me is when I use both sources (geonames & google geocode) then the input select range is very unreliable - sometimes it autofills, selects the additional section and then stays highlighted as it should, other times the blue highlight dissapears (although it acts as it's still there i.e. on keypress the selection dissapears), and other times the cursor goes straight to the end of the input. Some conflict with google maps I think, rather than multiple source issue, as this doesn't happen if I have two geonames sources instead?

Correct answer goes to anyone who can improve upon this!

Thanks

解决方案

OK.. so looking at your "solution", I notice several issues. First, it completely breaks in every browser I try....

After some fixes, I have identified a number of issues with your "solution":

  1. .autocomplete() is an initialization function. It does not need to be called on every keyup. This is handled automatically after calling .autocomplete() on a jQuery element. Calling it on every keyup will cause a huge performance hit as well as a number of other mysterious and/or unintended consequences.

  2. Storing legal values in a global variable, and then using blur to check against those is a bad idea. While I am not sold on the idea of storing every legal value that comes back from autocomplete, I can't think of a better solution for your case at the moment. What I did do, was to store each legal value in the .data() of the input item, to be checked against on .blur(). This is stored as a hash/associative-array, which means we get duplicates removed for free.

  3. If you want your users to only select legal values from the back-end, the best solution is to validate the input against the back-end on form submit. (Blur has issues because selecting an item from the autocomplete suggestions inherently blurs the input before filling in the selected value. In other words, you will most likely have an invalid location.) This would require you to save, as part of your match data, a string that can be sent back to the server for validation. The other issue is that if you have a slow server, such as is the case with GeoNames free access, you may not get immediate feedback for the user.

That being said, I have fixed your code (with regard to points 1 and 2 above) to call autocomplete correctly, and to store valid solutions in the input object as jQuery data. I also coded it as an extension, so it can be called on any jQuery selector:

http://jsfiddle.net/jtbowden/7NmLr/

这篇关于智能位置表单字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆