0

Hi I am new to JavaScript and AJAX.

The idea for this page is that when the user clicks the appropriate area in an image in a map it calls a JavaScript function myFunction1 when the entry in 'field_X' is '0' - this function then updates 'field_X' to be '1' through AJAX ('field_X' starts with a '0' entry).

Then when the user next clicks the same area in the map myFunction2 is called because the entry in 'field_X' is now '1' - and this then updates 'field_X' to be '2'.

And so on...

The AJAX call works fine and updates 'field_X' correctly when the appropriate function is called individually.

However the problem is (with the code as I have it) when the user clicks the map all 3 functions are called in succession straight away (and 'field_X' becomes '3'). I am not sure how to pause this between functions and wait for the next click by the user.

I have abbreviated the code in the functions as best I can as the functions do other things as well. Any help would be appreciated.

PHP user page

<?php function request_data(){select field_X from TABLE_X; }  
$q = request_data(); ?>  

<map>  
<area onclick= <?php    
    if ($q == '0') {?>"myFunction1();" <?php }  
    if ($q == '1') {?>"myFunction2();" <?php }  
    if ($q == '2') {?>"myFunction3();" <?php }   
    if ($q == '3') { ...and so on... }   
?> />  
</map>  

JavaScript page

<script>   
//JavaScript  
function myFunction1() { update_1(); }  
function myFunction2() { update_2(); }  
function myFunction3() { update_3(); }  

//AJAX - abbreviated  
function update_1(){ update TABLE_X set field_X = (1); }  
function update_2(){ update TABLE_X set field_X = (2); }  
function update_3(){ update TABLE_X set field_X = (3); }  
</script>   
TedtheBear
  • 59
  • 6
  • 2
    share your markup and click event handler registration – Arun P Johny Apr 05 '13 at 03:50
  • Are these `update_X()` functions are server side or client side? – Praveen Kumar Purushothaman Apr 05 '13 at 04:03
  • 2
    Set a global loading variable that prevents them from clicking the other spots until the ajax completes. – John V. Apr 05 '13 at 04:12
  • The request_data() function is PHP server side and the others are in a JavaScript page. The AJAX functions call functions that update the database and these are in a PHP page. – TedtheBear Apr 05 '13 at 04:58
  • 1
    please post the _full_ JS code, your probably calling all functions in succession, because you're not taking the _asynchronous_ nature of ajax calls into account: use the `onreadystatechange` callback to call bind the next handler – Elias Van Ootegem Apr 05 '13 at 07:27
  • Thanks @EliasVanOotegem for your help. Yes I did get some real help from some responses in my other posts and I have noted the gratitude in my responses but the tick does not always appear on the comment that was useful (am I missing something). Getting the question right is harder than it looks and sometimes no answers are posted probably because of this. I will go back and see if I can do this on those posts :) – TedtheBear Apr 05 '13 at 12:37
  • Thanks @JohnVanDeWeghe yes this seems like what I am looking for - i will get into this in the morning and get back to you, thanks, Ted – TedtheBear Apr 05 '13 at 12:38

1 Answers1

2

You can't pause JS's execution, not really... There are some hacky ways to do it, but they make for terrible code, so there really is no point in learning them. I would, as suggested by some in the comments use a global (or even better: a closure) variable. Here's a basic setup I would use in your case:

//server side, instead of echoing function1() etc...
echo 'var funcNumber = ';
switch($q)
{
    case 0: echo 1; break;
    case 1: echo 2; break;
    //and so on
}
echo ';';
//or better yet
echo 'var funcNumber  = '.($q + 1).';';

Then, in JS

//var funcNmber = 1; ===> makes it a global var, which is not recommended
window.onload = function()
{
    var funcNmber = 1;//echo here if possible
    var handler = function(e)
    {//assign to var, you'll see why
        var ajax = nex XMLHttpRequest(),
        that = this, //this points to the clicked element, reference it by var that
        queryString = 'field=' + funcNumber;
        //your basic setup
        //followed by this piece of magic:
        this.onclick = null;//unbind handler
        ajax.onreadystatechange = function()
        {
            if (this.readyState === 4 && this.status === 200)
            {//call complete
                funcNumber++;//increment
                that.onclick = handler;//rebind event handler, that's why we named it
            }
        };
    };
    document.getElementById('areaId').onclick = handler;//bind handler
};

Of course, this code needs a lot of work, still. If you want a X-browser XHTTP object, for example:

var getXHR = function()
{
    try
    {
        return new XMLHttpRequest();
    }
    catch (error)
    {
        try
        {
            return new ActiveXObject('Msxml2.XMLHTTP');
        }
        catch(error)
        {
            try
            {
                return new ActiveXObject('Microsoft.XMLHTTP');
            }
            catch(error)
            {
                throw new Error('no Ajax support?');
            }
        }
    }
};

Also, since we're on X-browser stuff, note that window.onload can cause memory leaks, which are quite easy to avoid if you understand the way event delegation and closures work. Since you're relatively new to JS, I suspect you may want to read up on that... it is well worth it!

Community
  • 1
  • 1
Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
  • Thanks again @EliasVanOotegem for your help. I will have a go at this in morning - but yes this seems like the bit of the puzzle I have been missing. Many thanks, Ted – TedtheBear Apr 05 '13 at 12:40