我已将Google Maps Javascript API V3中的google.maps.places.Autocomplete添加到基本搜索表单中。我试图找到一种可靠的方法来检测用户是从自动完成列表中选择了一项(使用鼠标还是键盘)还是提交了自由格式的文本。

代码:http://jsfiddle.net/2rhL3cyk/1/

我正在针对以下基本场景进行测试,每种基本场景都应导致提交表单。如果用户选择了自动完成项,则locMatch应该为true。

  • 输入自由格式的文本,然后按Enter:
  • place_changed解雇了
  • onSubmit被解雇。 locMatch:假
  • 输入文本,使用向下箭头选择一个位置,然后按Enter键:
  • onSubmit被解雇。 locMatch:假
  • place_changed被解雇(为时已晚!)
  • 输入文本,使用鼠标选择一个地方,然后单击“提交”:
  • place_changed被解雇(单击位置后)
  • onSubmit被解雇。 locMatch:true(单击按钮后)
  • 输入文本,使用鼠标选择一个位置,将文本更改为自由格式的字符串,然后按Enter:
  • place_changed被解雇(单击位置后)
  • place_changed被触发(输入新文本并按下回车后)
  • onSubmit被解雇。 locMatch:假
  • 输入文本,使用鼠标选择一个位置,将文本更改为自由格式的字符串,然后单击提交:
  • place_changed被解雇(单击位置后)
  • onSubmit被解雇。 locMatch:true(输入新文本并单击按钮后)
  • 输入文本,使用鼠标选择一个位置,输入新文本,使用向下箭头选择一个位置,然后按Enter
  • place_changed被解雇(单击位置后)
  • onSubmit被解雇。 locMatch:true(输入新文本并单击按钮后)
  • place_changed解雇了

  • 只有案例1、3和4可以正常工作。

    在#2中,onSubmit在place_changed之前被触发,因此直到提交表单之后才有机会设置locMatch。手动触发place_changed并没有帮助,因为即使输入字段具有正确的文本,autocomplete.getPlace()仍然是未定义的,直到表单提交触发。我能够强制它与可怕的setTimeout hack一起使用,如下所示:
    $('#loc_search').submit(function (e) {
      setTimeout(function () {
        console.log('submit for real! locMatch:', locMatch);
        $(this).submit();
      }, 150);
    });
    

    我真的很想找到一种更明智的方法来解决此问题。我认为超时值可能取决于用户的计算机规范,并且我不希望有任何不必要的延迟。

    在#5中,在按Enter键后根本不调用place_changed。再次,我尝试在提交处理程序中手动触发place_changed事件,但这没有效果,因为即使用户在输入字段中键入了getPlace(),它仍会返回先前选择的值。解决此问题的一种方法是在更改时重置locMatches,但这会破坏下面的#6。
    $('#location').change(function() {
      locMatch = false;
    });
    

    在#6中,locMatch从上一次单击开始仍然为真,因此它确实可以提供预期的结果,但是从技术上讲,这是不正确的,因为在提交表单后仍会触发place_changed。上面对#5的修复打破了这种情况,但是上面的setTimeout方法再次修复了这种情况。

    我整天都在梳头,任何建议都将不胜感激。谢谢!

    最佳答案

    在这里有完全相同的问题。自动完成库不提供除place_changed之外的任何其他事件。也没有状态属性,例如request_pending。

    这里有一个来自mmalone的“hack”:Google Autocomplete - enter to select
    对我来说很棒。

    10-06 03:58