智能定位表单域

Posted

技术标签:

【中文标题】智能定位表单域【英文标题】:Smart location form field 【发布时间】:2011-07-30 03:27:54 【问题描述】:

我在位置的用户注册表单上有一个文本字段。

我基本上希望根据 Google 地图(或等效)验证此字段 - 只允许有效地点通过(最好采用 Waterloo, LondonLondon, England 之类的格式)。

要求

    除了位置名称之外,我还想返回该位置中心的坐标(lat、lng)(即使是宽泛的,例如 英国伦敦)交叉引用它以向用户提供相关信息。 根据用户在字段中输入的有效位置(理想情况下只是政治位置 - 不是特定街道)自动完成列表/智能建议列表 *(编辑:见下文)。 强制用户使用自动完成列表中的位置。

允许此字段的权限将使用 html5 Geolocation API 自动填充以获取用户 lat lng,然后转换为一般位置(即一般城镇 - 有点像 Chrome 的 Tweetdeck 在您点击“添加您的位置”时所做的那样)。

问题是 - 解决这个问题的最佳方法是什么?我使用什么 API?我使用 API 的哪些部分来实现这一点?

*编辑:在尝试了 Google Maps API v3 地理编码之后,结果似乎存在问题(我不确定是错误还是设计使然 - http://code.google.com/p/gmaps-api-issues/issues/detail?id=2042)。例如,如果我输入 Waterloo,我得到的只是 Waterloo, Canada。那么所有其他滑铁卢http://en.wikipedia.org/wiki/Waterloo 呢?我想要一个 X many 列表(其中 X !== 1)供用户选择。理想情况下,我预定义 X。此外,如果我在表单字段中输入“L”,我希望看到按最有可能的顺序返回的相关建议列表(可能受偏差 GeocodeRequest 参数的影响) - 所以 伦敦,英国利物浦,英国利兹,英国等。相反,我得到荷兰林堡 - 1 个随机结果。怎么回事?通过 Google Maps API 执行此操作的替代方法是什么?

*更新/解决方案: 好的,我已经做了一些使用地名http://jsfiddle.net/ekzMN/95/ 的东西。它工作得很好,尽管我确信它可以得到很大的改进。您可以随意使用此代码。在我的真实示例中,我还添加了 google geocode 作为辅助来源,因为它比地理名称更智能(即,如果我输入邮政编码或街道地址)。这取决于初始化地理编码器:

// 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);
)

两者的结合很好地提供了智能搜索和多个建议。困扰我的一个问题是,当我同时使用两种来源(地理名称和谷歌地理编码)时,输入选择范围非常不可靠 - 有时它会自动填充,选择附加部分,然后按应有的方式保持突出显示,其他时候蓝色突出显示消失(虽然它仍然存在,即在按键时选择消失),其他时候光标直接进入输入的末尾。我认为与谷歌地图有些冲突,而不是多源问题,因为如果我有两个地名源,就不会发生这种情况?

正确答案留给任何可以改进这一点的人!

谢谢

【问题讨论】:

你在为什么浏览器编写代码?您的 jsfiddle 在 Firefox 中以各种方式对我造成影响。 【参考方案1】:

这里有一个相关的jQuery插件页面: http://plugins.jquery.com/plugin-tags/geocoding

具体来说,对于您的问题:

    默认情况下,Google 地理编码会执行此操作。它将为广泛的区域等提供中心坐标。相关问题:using jquery.getJson with Google's GeoCoding HTTP Service

    http://code.google.com/p/geo-autocomplete/ 就是一个例子

    这主要是表单验证。您应该能够简单地进行最终的自动完成查找,如果它没有返回任何建议,则标记警告等。

至于使用哪些部分,这取决于您。更进一步,我们将为您编写它。我相信上面的许多 API 都有您可以从中收集到的示例。

【讨论】:

对不起,我不得不取消选中这个作为答案(关于第 2 点),因为这不会给出正确的自动完成结果或事实上所有匹配的结果。我现在只是要编辑这个问题,以澄清它是否基于谷歌并不重要,我只想要功能!不过答案很好(如果只有谷歌地理编码 API 能做到它所说的)。 我不知道为什么人们会投票支持它,因为它没有达到我想要的效果。【参考方案2】:

好的..所以看着你的“解决方案”,我注意到了几个问题。首先,它在我尝试的每一个浏览器中都完全崩溃了......

经过一些修复后,我发现您的“解决方案”存在一些问题:

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

    将合法值存储在全局变量中,然后使用blur 进行检查是个坏主意。虽然我不赞成存储从autocomplete 返回的所有合法价值,但目前我想不出更好的解决方案来解决您的问题。我所做的是将每个合法值存储在输入项的.data() 中,以便在.blur() 上进行检查。这存储为哈希/关联数组,这意味着我们可以免费删除重复项。

    如果您希望您的用户仅从后端选择合法值,最好的解决方案是在表单提交时针对后端验证输入。 (Blur 存在问题,因为从autocomplete 建议中选择一个项目会在填写所选值之前固有地模糊输入。换句话说,您很可能有一个无效的位置。)这需要您保存,作为一部分您的匹配数据,一个可以发送回服务器进行验证的字符串。另一个问题是,如果您的服务器速度较慢,例如免费访问 GeoNames 的情况,您可能无法立即获得用户的反馈。

话虽如此,我已经修复了您的代码(关于上面的第 1 点和第 2 点)以正确调用 autocomplete,并将有效的解决方案作为 jQuery 数据存储在 input 对象中。我还将它编码为扩展,因此可以在任何 jQuery 选择器上调用它:

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

【讨论】:

非常感谢!我昨天为此创建了一个插件***.com/questions/5714477/…,我一定会考虑实施这些建议!这应该适用于 chrome 和 firefox 4。

以上是关于智能定位表单域的主要内容,如果未能解决你的问题,请参考以下文章

为 Contact 7 表单 Wordpress 添加边框和背景

HTMLHTML 表单 ⑤ ( form 表单域 )

表单和表单域

从主表单域自动填充子表单域

easyUi隐藏域有个form表单 在关闭隐藏域出现校验提示

[HTML]表单标签(form表单域input输入表单label标签select下拉表单textarea文本域)