Google Places Autocomplete SearchBox:如何控制(enable/disable)预测
Google Places Autocomplete SearchBox: How to control (enable/disable) predictions
是否可以控制 (enable/disable) Google 地点自动完成搜索框 (google.maps.places.SearchBox
) 服务预测?
或者换句话说:是否可以暂时从自动完成搜索框服务中分离 HTML 输入元素,然后重新附加它?
问题是我在附加到 SearchBox 服务的 HTML 输入元素下方显示服务结果。问题在于,在显示结果并且用户将注意力重新集中在输入元素上后,预测会显示在结果之上并遮挡他们的视线。在用户更改输入元素中的文本之前,我想禁用预测。
编辑 26/Aug/2016:
JavascriptAPI 目前不支持禁用预测。因此,我刚刚在 Google 上打开了一个功能请求。如果您对该功能感兴趣,请为它投票:Autocomplete SearchBox - Control (enable/disable) predictions..
编辑 07/Sep/2016 - 赏金更新:
感谢所有参与回答和推广问题的人。
奖励的主要 objective 是使用当前可用的方法找到解决方案。恐怕这并没有发生,所以我决定不授予赏金。
尽管下面的 none 个答案提供了解决方案,但每个答案都提供了某种线索,所以谢谢!也许这些线索会指向未来的解决方案。
第二个 objective 奖项(虽然没有直接传达)是为了促进 Autocomplete SearchBox - Control (enable/disable) predictions 功能请求。它的状态更改为 NeatIdea 并已分配内部跟踪号。这是一个好兆头。
没有办法,或者有很多意义:预测是 SearchBox, its reason to be. If you don't want predictions, you can just use Text Search in the Places library 的重点。
如果用户 clicks/focuses 再次在搜索框上,s/he 可能不关心被建议掩盖的结果。 Google 地图中也有同样的行为,这不是问题,是吗?
如果您不能在搜索框和结果之间放置一些 space(例如 this tool),并且您绝对必须暂时禁用建议,我认为您可以破坏google.maps.places.SearchBox
对象并稍后创建一个新对象,附加到同一个 HTML 输入元素。
您可以做的是,在用户选择地点后,您可以在该输入字段中添加 class disabled
..,这将帮助您 enable/disable 基于预测在 class 名字上。
在你有自动完成代码的地方,你可以将它包装在 if else 语句中。
let field = document.getElementById('location');
if ( field.className.indexOf('disabled') > -1 ) {
google.maps.event.clearInstanceListeners(field);
}
else {
let autocomplete = new google.maps.places.Autocomplete( field, {types: ['geocode']} );
autocomplete.addListener('place_changed', () => {
let place = autocomplete.getPlace();
let filed_val = field.value; // incase you need it
field.classList.add('disabled');
});
}
这将在用户选择一个地点后删除自动完成功能。以后如果需要,您可以从此字段中删除 disabled
class,它将再次起作用。
我在 AngularJS 中的解决方案 – 它是指令的摘录。
.pac-contained
在创建自动完成服务实例后创建,例如:new google.maps.places.Autocomplete(…)
或 new google.maps.places.SearchBox(…)
。
我所做的是在文档中找到刚刚创建的 .pac-container
,存储其引用并将该容器标记为已处理(通过在其上添加任意 class .predictions-control
) . "Marking" 仅当应用程序中预期存在多个 .pac-container
时才需要容器。
现在有了参考,我可以通过预测控制 .pac-contained
的可见性(隐藏或显示)。
// Container element with predictions.
var pacContainer = null;
/***
* Find predictions container without predictions-control class set.
* Then set predictions-control class to it and convert it into
* Angular's jqLite object.
* @return {jqLite object} - container or null when not found.
*/
function getPredictionsContainer() {
// Get div.pac-container without predictions-control class.
var e = document.querySelector('div.pac-container:not(.predictions-control)');
if (e){
var container = angular.element(e);
container.addClass('predictions-control');
console.log('predictions-control: Container found.');
return container;
} else {
console.warn('predictions-control: Container not found!');
}
return null;
} // getPredictionsContainer
/***
* Loop in 50ms intervals until container is found.
*/
function untilContainerFound(){
pacContainer = getPredictionsContainer();
if (pacContainer == null){
$timeout(untilContainerFound, 50);
}
} // untilContainerFound
this.init = function() {
untilContainerFound();
}; // this.init
/***
* Prevent predictions to be displayed when user clicks on the
* input element. It is achieved by adding ng-hide CSS class to
* predictions container. Predictions container is identified by
* ".pac-container" CSS class selector.
*/
this.hidePredictions = function() {
// If predictions container was not found at directive
// initialization try to find it now.
if (pacContainer === null){
pacContainer = getPredictionsContainer();
}
if (pacContainer){
console.log('predictions-control: Hiding predictions.');
pacContainer.addClass('ng-hide');
} else {
console.warn('predictions-control: Container not found!');
}
}; // this.hidePredictions
/***
* Show predictions again by removing ng-hide CSS class from
* predictions container.
*/
this.showPredictions = function() {
console.log('predictions-control: Showing predictions.');
if (pacContainer){
pacContainer.removeClass('ng-hide');
}
}; // this.showPredictions
创建服务实例后立即调用init()
:
// Create SearchBox service for auto completing search terms.
autocomplete = new google.maps.places.SearchBox( inputElem[0] );
// OR
// autocomplete = new google.maps.places.Autocomplete( ..... );
autocomplete .addListener('places_changed', callback);
predictionsCtrl.init();
注:
只要保证不会同时创建两个自动完成服务(例如:每个服务在不同的选项卡上)或者可以等待创建下一个服务直到找到 .pac-container
之前的服务,它就可以可靠地工作即使有多个自动完成服务实例。
可能是有价值的信息。
这与 API V3.29 相关(不确定它是否始终准确)。
API 为自动完成创建的 div 元素的 class 为 "pac-container pac-logo"。
利用 document.querySelector('.pac-container') 您可以将其样式属性设置为显示:none 在其他地方的点击事件中。
注意:当您的用户在搜索框中单击返回时 google 会将样式属性更改回任何合适的值,因此您只需设置一次,您不必再次设置它。
(这可能比让 angular 参与进来更容易、更干净)。
希望对某人有所帮助(我必须添加 CSS 规则来增加应用程序中的 z-index 以使自动完成显示)
是否可以控制 (enable/disable) Google 地点自动完成搜索框 (google.maps.places.SearchBox
) 服务预测?
或者换句话说:是否可以暂时从自动完成搜索框服务中分离 HTML 输入元素,然后重新附加它?
问题是我在附加到 SearchBox 服务的 HTML 输入元素下方显示服务结果。问题在于,在显示结果并且用户将注意力重新集中在输入元素上后,预测会显示在结果之上并遮挡他们的视线。在用户更改输入元素中的文本之前,我想禁用预测。
编辑 26/Aug/2016:
JavascriptAPI 目前不支持禁用预测。因此,我刚刚在 Google 上打开了一个功能请求。如果您对该功能感兴趣,请为它投票:Autocomplete SearchBox - Control (enable/disable) predictions..
编辑 07/Sep/2016 - 赏金更新:
感谢所有参与回答和推广问题的人。
奖励的主要 objective 是使用当前可用的方法找到解决方案。恐怕这并没有发生,所以我决定不授予赏金。
尽管下面的 none 个答案提供了解决方案,但每个答案都提供了某种线索,所以谢谢!也许这些线索会指向未来的解决方案。
第二个 objective 奖项(虽然没有直接传达)是为了促进 Autocomplete SearchBox - Control (enable/disable) predictions 功能请求。它的状态更改为 NeatIdea 并已分配内部跟踪号。这是一个好兆头。
没有办法,或者有很多意义:预测是 SearchBox, its reason to be. If you don't want predictions, you can just use Text Search in the Places library 的重点。
如果用户 clicks/focuses 再次在搜索框上,s/he 可能不关心被建议掩盖的结果。 Google 地图中也有同样的行为,这不是问题,是吗?
如果您不能在搜索框和结果之间放置一些 space(例如 this tool),并且您绝对必须暂时禁用建议,我认为您可以破坏google.maps.places.SearchBox
对象并稍后创建一个新对象,附加到同一个 HTML 输入元素。
您可以做的是,在用户选择地点后,您可以在该输入字段中添加 class disabled
..,这将帮助您 enable/disable 基于预测在 class 名字上。
在你有自动完成代码的地方,你可以将它包装在 if else 语句中。
let field = document.getElementById('location');
if ( field.className.indexOf('disabled') > -1 ) {
google.maps.event.clearInstanceListeners(field);
}
else {
let autocomplete = new google.maps.places.Autocomplete( field, {types: ['geocode']} );
autocomplete.addListener('place_changed', () => {
let place = autocomplete.getPlace();
let filed_val = field.value; // incase you need it
field.classList.add('disabled');
});
}
这将在用户选择一个地点后删除自动完成功能。以后如果需要,您可以从此字段中删除 disabled
class,它将再次起作用。
我在 AngularJS 中的解决方案 – 它是指令的摘录。
.pac-contained
在创建自动完成服务实例后创建,例如:new google.maps.places.Autocomplete(…)
或 new google.maps.places.SearchBox(…)
。
我所做的是在文档中找到刚刚创建的 .pac-container
,存储其引用并将该容器标记为已处理(通过在其上添加任意 class .predictions-control
) . "Marking" 仅当应用程序中预期存在多个 .pac-container
时才需要容器。
现在有了参考,我可以通过预测控制 .pac-contained
的可见性(隐藏或显示)。
// Container element with predictions.
var pacContainer = null;
/***
* Find predictions container without predictions-control class set.
* Then set predictions-control class to it and convert it into
* Angular's jqLite object.
* @return {jqLite object} - container or null when not found.
*/
function getPredictionsContainer() {
// Get div.pac-container without predictions-control class.
var e = document.querySelector('div.pac-container:not(.predictions-control)');
if (e){
var container = angular.element(e);
container.addClass('predictions-control');
console.log('predictions-control: Container found.');
return container;
} else {
console.warn('predictions-control: Container not found!');
}
return null;
} // getPredictionsContainer
/***
* Loop in 50ms intervals until container is found.
*/
function untilContainerFound(){
pacContainer = getPredictionsContainer();
if (pacContainer == null){
$timeout(untilContainerFound, 50);
}
} // untilContainerFound
this.init = function() {
untilContainerFound();
}; // this.init
/***
* Prevent predictions to be displayed when user clicks on the
* input element. It is achieved by adding ng-hide CSS class to
* predictions container. Predictions container is identified by
* ".pac-container" CSS class selector.
*/
this.hidePredictions = function() {
// If predictions container was not found at directive
// initialization try to find it now.
if (pacContainer === null){
pacContainer = getPredictionsContainer();
}
if (pacContainer){
console.log('predictions-control: Hiding predictions.');
pacContainer.addClass('ng-hide');
} else {
console.warn('predictions-control: Container not found!');
}
}; // this.hidePredictions
/***
* Show predictions again by removing ng-hide CSS class from
* predictions container.
*/
this.showPredictions = function() {
console.log('predictions-control: Showing predictions.');
if (pacContainer){
pacContainer.removeClass('ng-hide');
}
}; // this.showPredictions
创建服务实例后立即调用init()
:
// Create SearchBox service for auto completing search terms.
autocomplete = new google.maps.places.SearchBox( inputElem[0] );
// OR
// autocomplete = new google.maps.places.Autocomplete( ..... );
autocomplete .addListener('places_changed', callback);
predictionsCtrl.init();
注:
只要保证不会同时创建两个自动完成服务(例如:每个服务在不同的选项卡上)或者可以等待创建下一个服务直到找到 .pac-container
之前的服务,它就可以可靠地工作即使有多个自动完成服务实例。
可能是有价值的信息。
这与 API V3.29 相关(不确定它是否始终准确)。
API 为自动完成创建的 div 元素的 class 为 "pac-container pac-logo"。
利用 document.querySelector('.pac-container') 您可以将其样式属性设置为显示:none 在其他地方的点击事件中。
注意:当您的用户在搜索框中单击返回时 google 会将样式属性更改回任何合适的值,因此您只需设置一次,您不必再次设置它。
(这可能比让 angular 参与进来更容易、更干净)。
希望对某人有所帮助(我必须添加 CSS 规则来增加应用程序中的 z-index 以使自动完成显示)