开发者

How to make PHP function run after javascript ends?

I have two PHP functions - one that builds a html form and another that handles it when it's submitted.

I want to add to the html a javascript onClick function that sends one of the form's fields to an external API (Google Maps) and saves the reply in a hidden field in the form so that the handling PHP function will get that data as well.

My question is - how do I make sure the handling PHP function only fires after the onClick function 开发者_StackOverflow社区has finished?

Or maybe I can't and I have to use ajax?


You'll need 2 events to accomplish this.

  1. the onClick event for your button that executes the google map request and saves the data into the local form
  2. an onSubmit event for your form. You will use this event to see if the form is submittable. Basically, check to make sure that your google map request has been run and has completed before allowing the form to submit.

Example:

<script>
var googleMapsDone = false;
$('#gmap_button').click(function(event)
{
    doGoogleMapThing(function()//callback from googlemaps
    {
        //save data to local form for processing by script once posted
        googleMapsDone = true;
    });
});

$('#form').submit(function(event)
{
    //check to see if we did our google maps stuff, and that its done
    if (false == googleMapsDone)
    {
        event.preventDefault();
        return false;
    }
});
</script>

With that code, any time the user is waiting for google maps and clicks submit, nothing will happen. They would have to wait on the response from GMaps, THEN click submit. This is okay for some things, but if you're trying to do background requests to GMaps that require no user input/interaction/feedback (maybe getting Long/Lat of their address when they submit a form), then you can modify the code a bit to post when you get the response. An example of that would be:

<script>
var googleMapsDone = false, submitWaiting = false;
$('#gmap_button').click(function(event)
{
    doGoogleMapThing(function()//callback from googlemaps
    {
        //save data to local form for processing by script once posted
        googleMapsDone = true;

        /* check to see if submitWaiting is TRUE.  If it is, automatically
           post the form when we get the response.
        */
        if (submitWaiting)
        {
            $('#form').submit();
        }
    });
});

$('#form').submit(function(event)
{
    //check to see if we did our google maps stuff, and that its done
    if (false == googleMapsDone)
    {
        event.preventDefault();

        /* set our submitWaiting flag which we will use in our clalback
           so when we get our google maps response, we post our form right
           away
        */
        submitWaiting = true;

        /* You might want to display a modal or some other kind of notification
           that the form post is 'working' or 'processing' so when the user
           clicks it and doesn't see anything happening, they don't bail
           or click it 800 times out of frustration
        */

        return false;
    }
});
</script>

edit: I realize my comment below on how this works are...hard to understand, so let me explain here, then show an alternative.

  1. User fills out form
  2. User clicks button to do stuff on google maps (example was written before I knew the scope/context of the GMaps request, so that's why it's done this way)
  3. If user then clicks 'submit' before the GMap request is complete, we CANCEL the submit and set a flag submitWaiting
  4. GMaps request returns, and executes our callback. Our callback knows how to look for submitWaiting and if it is set to true it submits the form

An alternative to this, instead of requiring user interaction for the GMaps request you could change the event to an onChange event for the input box of the address, or you can do it all via the submit button/event, like so:

<script>    
$('#form').submit(function(event)
{
    //lets look up our user's address!
    doGoogleMapThing(function()//callback from googlemaps
    {
        //do stuff with your inputs, or whatever

        $('#form').submit();
    });

    event.preventDefault();
    return false;
});
</script>

edit note: the examples above assumes you're using jquery, and that your google map API request is done via javascript

If your google map api request is not using the google maps javascript library, this is STILL possible, just requires you to make a "proxy" script to the API via a php script on your local domain. (Browser restrictions). It'd be something like THIS:

<script>
function doGoogleMapThing(callback_when_done)
{
    $.post("/path/to/proxy/script.php", { data: to, post: to_server }, function(response)
    {
        //check & parse response
        callback_when_done(/* Data needed to populate form */);
    });
}
</script>

note: both of these examples assume jquery usage. because...well..why wouldn't you.

Below is an implementation of your exact script. I changed it a bit to use jquery, because it makes things a bit less painful.

<script type=”text/javascript” 
    src=”http://maps.google.com/maps/api/js?sensor=false”></script>
<script type="text/javascript" 
    src="http://code.jquery.com/jquery-1.6.min.js"></script>

<script type=”text/javascript”>    
function codeAddress(callback)
{
    var address = $('#address').val();

    geocoder.geocode( { 'address': address}, function(results, status)
    {
        if (status == google.maps.GeocoderStatus.OK)
        {
             $('#latitude').val( results[0].geometry.location.latitude );
             $('#longitude').val( results[0].geometry.location.longitude );

             if (typeof callback != 'undefined') //call the callback.
             {
                 callback(true);
             }
        }
    });

    /* Just in case google returns a bad response or doesn't return at all
       we need to add a timeout that will call the callback after 10 seconds
       just so we make sure our user doesn't hang.
    */
    setTimeout(function(){
        callback(false); //pass false indicating no/invalid response
    }, 10000); //10000ms = 10s
}


/* We are using the reallySubmit variable as a flag here, to know when we finish
   our call to google maps and that we want to really submit our form.

   we have to do this because the form.submit() call fires the form's submit event
   again, and we end up going into an infinite loop.

   an alternative to this would be to bind your form processing to the form's submit
   button's click event. that should also pick up any presses of the enter key, also.
   the solution below also works.
*/
var reallySubmit = false;
$('#form').submit(function(event)
{
    if (false == reallySubmit)
    {
        //lets look up our user's address!
        codeAddress(function(success)//callback from googlemaps
        {
            reallySubmit = true;  
            $('#form').submit();
        });

        event.preventDefault();
        return false;
    }
});
</script>


This is fundamentally impossible - PHP runs on the server, JavaScript runs on the client. You will indeed need to use Ajax.


You can have a hidden IFRAME element where you load a php document as soon as your javascript ends. Simple, but effective (as long as your php document comes from the same URL).


AJAX is a must I am afraid. You need to redirect the user to a page with the script.

Once the server has run the PHP to generate the HTML, then sent it to the browser, there is no way to run it again, or indeed run anything from the server, without making a request to the server. That is the nature of a server side scripting language, of which PHP is.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜