延迟表单提交,直到检索到位置

Delay form submission until location is retrieved

本文关键字:检索 位置 表单提交 延迟      更新时间:2023-09-26

我有一个应用程序尝试从浏览器获取位置设置,这往往需要一点时间,所以我希望它在页面加载时运行。 但是,如果在位置回调运行之前单击提交按钮,则没有位置数据。 我的问题很简单,在提交表单之前,如何等待我的位置成功回调完成?(没有像睡眠声明这样愚蠢的东西)。
理想情况下,我想闪烁一个繁忙的指示器并等待数据。这可能吗? 我有使繁忙指示器可见的代码,但不确定如何优雅地等待数据可用。

$(document).ready(function(){
    var lat = "";
    var lng = "";
    var accuracy = "";
    var locationFound = false;
    if(navigator.geolocation){
        navigator.geolocation.getCurrentPosition(function positionSuccess(loc){
            lat = loc.coords.latitude;
            lng = loc.coords.longitude;
            accuracy = loc.coords.accuracy;
            locationFound = true;               
        });
    }else{
        alert("I'm sorry, your jerk browser doesn't support geolocation");
        locationFound = true;
    }
$('#locForm').submit(function(e){  
        $('#lat').val(lat);
        $('#lng').val(lng);
        $('#boundary').val($('#boundary-select').val());
}

禁用提交按钮,直到传递位置数据。

$('input[type="submit"]').attr('disabled','disabled');

然后启用提交按钮

$('input[type="submit"]').removeAttr('disabled');

如果您使用的位置插件没有可用的回调函数,那么您需要以某种方式将结果绑定到页面并在用户提交之前对其进行检查。

一种方法是将位置的结果绑定到表单,然后仅允许在存在位置时提交表单。 下面是使用 .data() 完成此操作的示例。

    $(document).ready(function(){
        var lat = "";
        var lng = "";
        var accuracy = "";
        var locationFound = false;
        if(navigator.geolocation){
            navigator.geolocation.getCurrentPosition(function positionSuccess(loc){
                lat = loc.coords.latitude;
                lng = loc.coords.longitude;
                accuracy = loc.coords.accuracy;
                locationFound = true;  
                //bind the results to the form object using data()
                $("#locForm").data('lat' , lat)
                $("#locForm").data('lng' , lng)
                $("#locForm").data('accuracy' , accuracy)
                $("#locForm").data('locationFound' , locationFound)
            });
        }else{
            alert("I'm sorry, your jerk browser doesn't support geolocation");
            locationFound = true;
        }
    $('#locForm').submit(function(e){  
            e.preventDefault(); //prevents the normal submit
            if ( $("#locForm").data('lat') == "" || 
                 $("#locForm").data('lng') == "" || 
                 $("#locForm").data('accuracy') == "" || 
                 $("#locForm").data('locationFound') == ""
                ) {
             alert("Please wait for the browser to detect your location.");   
             return false;
                }
            else {       
              $.post( $(this).attr('action'),  $(this).serialize(), function(data){ 
                       // your callback data from the submit here
               } ); 
            }

    }

添加了此代码,该代码每秒检查一次位置插件中的值:

  function wait4location() {
            if ( $("#locForm").data('lat') == "" || 
                 $("#locForm").data('lng') == "" || 
                 $("#locForm").data('accuracy') == "" || 
                 $("#locForm").data('locationFound') == ""
                ) {
                   x = setTimeout('wait4location()',1000) //every second
              } else { 
                  $("#loading").hide();
                  return false; 
                }
  }
  $("#loading").show();
  wait4location();

使用两个信号量:

var geoLoaded = false,
    submittingForm = false;
function LoadGeoData() {
    // .. your load code
    geoLoaded = true;
    ReallySubmitForm();
}
$('form').submit(function(e) {
    // .. your code
    submittingForm = true;
    ReallySubmitForm();
})
function ReallySubmitForm() {
    if (submittingForm && geoLoaded) {
        // .. your submit code
    } else {
        // .. trigger loading code
    }
}

这样,仅当用户提交表单时地理数据尚未完全加载时,用户才会看到加载图像。 您会注意到,首先触发哪个事件并不重要,只有当两者都完成时,它才会通过。

您可以在返回位置后向表单添加提交函数。

这是一段对我有用的代码。

.HTML

<form id="form" action="" method="POST">

JavaScript

function getLocation() {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(showPosition);
    } else { 
        x.innerHTML = "Geolocation is not supported by this browser.";
    }
}
function showPosition(position) {
    x.innerHTML = "<input type=hidden name=lat id=lat value=" + 
        position.coords.latitude + "><input type=hidden name=lng id=lng value=" 
        + position.coords.longitude + ">";
    document.getElementById("form").submit();
}