Pause the code execution

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • nathj
    Recognized Expert Contributor
    • May 2007
    • 937

    #1

    Pause the code execution

    Hi,

    I have a strange problem, my code is running too quickly. Allow me to explain (if I can).

    I am using the XMLHTTP object in order to query the database as a user completes the membership application form, basically I want to ensure that each username is unique.

    I have the code to check this and the XMLHTTP object is working fine. However, before the code finishes executing the next part of the function is run. this means that the array I have for storing if items are valid or not is being populated incorrectly.

    I only check the database if the first stage of validation returns true. At present I have a bit of a fudge in place in that I have added an alert box, as you can see in the code below, this seems to pause the code, which then results in the correct behaviour. Without this I get told that the username I entered is in the database but the system allows me to continue because the validation flag says true because the user name followed the regular expression in place.

    Here is the code
    [CODE=javascript]
    function writeResponse()
    {
    if (goXMLHTTP.read yState==4 || goXMLHTTP.ready State=="complet e")
    {
    // I did hav a line here testing status=200 but it didn't make any difference document.getEle mentById(gcItem ID).innerHTML=g oXMLHTTP.respon seText;
    // set glIsValid based on the return from the database
    glIsValid = goXMLHTTP.respo nseText.search(/warninglabel/i)>0? false:true;
    }
    }

    function GetXmlHttpObjec t()
    {
    if (window.XMLHttp Request)
    {
    goXMLHTTP=new XMLHttpRequest( )
    }
    else if (window.ActiveX Object)
    {
    goXMLHTTP=new ActiveXObject(" Microsoft.XMLHT TP")
    }
    if (goXMLHTTP==nul l)
    {
    alert ("Browser does not support HTTP Request")
    return
    }
    }


    function validateItem(pc ID,pcItem,pcDis play,pnType,plP opulateExtra,pn NumberOfItems,p lCheckDatabase, pnListItem)
    {
    var lcRegExp, llUseRegExp
    var lnItemsToValida te = 0
    glIsValid = false
    llUseRegExp = false
    switch (pnType)
    {
    case 1: // UK postcode
    pcItem = pcItem.toUpperC ase()
    lcRegExp = '^[A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA$'
    break;
    case 2: // email address
    lcRegExp = '^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*$'
    break;
    case 3: // number of set length - basic telephone number check
    lcRegExp = '^[0-9 ]{6,13}$'
    break;
    case 4: // password validation - alpha numeric characters 6-18 characters long
    lcRegExp = '^[A-Za-z0-9]{6,18}$'
    break;
    case 5: // username validation - alpha numeric characters 6-18 characters long
    lcRegExp = '^[A-Za-z0-9]{6,18}$'
    break;
    default: // all other validation items
    lcRegExp = '^[A-Za-z0-9 ]{2,30}$'
    break;
    }

    glIsValid = pcItem.match(lc RegExp)?true:fa lse;

    // set the display now
    if (plCheckDatabas e) // check the database
    {
    if(glIsValid) // only check the database if the item to check is valid from the first stage
    {
    GetXmlHttpObjec t() // sets the global variable goXMLHTTP
    gcItemID = pcID
    gcUrl = "../lib/datacheck.php?c heck=" + pnType +"&tocheck=' " + pcItem + "'"
    goXMLHTTP.onrea dystatechange=w riteResponse
    goXMLHTTP.open( "GET",gcUrl,tru e)
    goXMLHTTP.send( null)
    // update gaValidationLis t accordingly
    alert("Checking the database for availability" + '\n' + "Click 'OK' to continue") // this is used to simply prevent the code from running ahead of itself and explain the process to the user
    // it would be good if a better way could be established - THIS IS THE FUDGE
    setValidationLi st(pnListItem)
    }
    }
    else // set the display
    {
    document.getEle mentById(pcID). innerHTML = glIsValid? pcDisplay:"<spa n class='warningl abel'>" + pcDisplay + "</span>";
    // update gaValidationLis t accordingly
    setValidationLi st(pnListItem)
    }


    // structure to ensure that the form is only valid when it is valid
    for (lnItem in gaValidationLis t)
    {
    if (gaValidationLi st[lnItem] == false)
    {
    lnItemsToValida te++
    }
    }

    if (lnItemsToValid ate == 0)// everything is valid - let the user continue by setting the disabled property of an item
    {
    hideOrShowInput ("complete",fal se)
    }
    else // something is invalid, the user will be able to tell, they need to complete this before moving on
    {
    hideOrShowInput ("complete",tru e)
    }

    if (plPopulateExtr a)
    {
    populateExtra(l cSource, lcDestination, true, true)
    }
    }

    function setValidationLi st(pnListItem)
    {
    // gaValidationLis t is a global array - for the life of the page using it at least
    gaValidationLis t[pnListItem] = glIsValid
    }
    [/CODE]

    That's all the functions involved at this stage. The PHP file referenced there simply runs some data checks and writes the relevant response back to the screen, so if the item exists the label written to the screen will contain the string "warninglab el"

    Is there a better way of pausing the code? I tried setTimeout but that didn't have the desired results.

    Any suggestions at all will be welcome. Generally I am quite pleased with this form and the way it validates as the user types - the validateItem() function is called from the onchange event of the input boxes.

    Many thanks
    Nathan
  • pbmods
    Recognized Expert Expert
    • Apr 2007
    • 5821

    #2
    Heya, Nathan.

    Try calling setValidationLi st() directly inside of writeResponse() .

    See this thread for more info.

    Comment

    • nathj
      Recognized Expert Contributor
      • May 2007
      • 937

      #3
      Originally posted by pbmods
      Heya, Nathan.

      Try calling setValidationLi st() directly inside of writeResponse() .

      See this thread for more info.
      I have read the other thread, and felt a bit of a fool for forgetting what Asynchronous meant.

      The trouble I have with calling setValidationLi st() directly is that I can't pass parameters into the function from onreadystatecha nge.

      If I code cause the cde to pause for a bit, without the alert that would be perfect (if a bit of a fudge). Is there are any effective way of doing this?

      Alternatively is there a way of passing paramters into the function that is called from onreadystatecha nge? If there is then perhaps I can move my call to setValidationLi st() into writeResponse() . That way the code that sets the glIsValid variable will have executed by the time the setValidationLi st() function is called.

      Thanks for the help so far, I have already learnt a lot more about this sort of development.
      nathj

      Comment

      • pbmods
        Recognized Expert Expert
        • Apr 2007
        • 5821

        #4
        Heya, Nathan.

        Originally posted by nathj
        The trouble I have with calling setValidationLi st() directly is that I can't pass parameters into the function from onreadystatecha nge.
        See this article.

        Comment

        • nathj
          Recognized Expert Contributor
          • May 2007
          • 937

          #5
          Originally posted by pbmods
          Heya, Nathan.



          See this article.
          An excellent article, that has cleared a few things up for me.

          Unfortunately the code that checks the validation list array is still executing before the code called by onreadystatecha nge completes. It seems that the only way to the stop this is with an alert. It is a complete fudge I know, but I have learnt quite a lot through this process.

          While the alert works in that it appears to prevent subsequent code from executing until the user acts it does seem to reduce accessibility a bit. Is there a better way of causing the code to wait without relying on the user?

          Many thanks
          Nathan

          Comment

          • pbmods
            Recognized Expert Expert
            • Apr 2007
            • 5821

            #6
            Heya, Nathan.

            Originally posted by nathj
            While the alert works in that it appears to prevent subsequent code from executing until the user acts it does seem to reduce accessibility a bit. Is there a better way of causing the code to wait without relying on the user?
            [Un]fortunately, JavaScript has no sleep() function. The only way to delay execution is to use the setTimeout() function.

            Comment

            • nathj
              Recognized Expert Contributor
              • May 2007
              • 937

              #7
              Originally posted by pbmods
              Heya, Nathan.



              [Un]fortunately, JavaScript has no sleep() function. The only way to delay execution is to use the setTimeout() function.
              Hi pbmods,

              First, thanks for all the help so far.

              I tried to play around with the setTimeout() function and couldn't get this to work. What I tried was:
              [CODE=javascript]
              var lnTime = setTimeOut(setV alidationList(p nListItem), 3000);
              [/CODE]

              I must admit I didn't really understand what I was doing I was simply following some instructions I had seen some place on the web. I do prefer to understand why and how something works.

              Cheers
              Nathan

              Comment

              • pbmods
                Recognized Expert Expert
                • Apr 2007
                • 5821

                #8
                Heya, Nathan.

                Originally posted by nathj
                [CODE=javascript]
                var lnTime = setTimeOut(setV alidationList(p nListItem), 3000);
                [/CODE]

                I must admit I didn't really understand what I was doing I was simply following some instructions I had seen some place on the web. I do prefer to understand why and how something works.
                setTimeout() takes two arguments: An object to be evaluated and a number that represents the number of milliseconds to wait before evaluating the object.

                Since JavaScript will try to execute setValidationLi st(), you have to instead create an anonymous function and pass that to setTimeout():
                [code=javascript]
                var lnTime = setTimeOut(func tion() { setValidationLi st(pnListItem); }, 3000);

                // Or spaced out, if you prefer....
                var lnTime = setTimeOut(
                function() {
                setValidationLi st(pnListItem);
                },
                3000);
                [/code]

                After 3000 milliseconds, the browser will evaluate the function that you created, which executes setValidationLi st(). Note that this will only work properly if your AJAX call returns within 3 seconds.

                Comment

                • nathj
                  Recognized Expert Contributor
                  • May 2007
                  • 937

                  #9
                  Originally posted by pbmods
                  Heya, Nathan.



                  setTimeout() takes two arguments: An object to be evaluated and a number that represents the number of milliseconds to wait before evaluating the object.

                  Since JavaScript will try to execute setValidationLi st(), you have to instead create an anonymous function and pass that to setTimeout():
                  [code=javascript]
                  var lnTime = setTimeOut(func tion() { setValidationLi st(pnListItem); }, 3000);

                  // Or spaced out, if you prefer....
                  var lnTime = setTimeOut(
                  function() {
                  setValidationLi st(pnListItem);
                  },
                  3000);
                  [/code]

                  After 3000 milliseconds, the browser will evaluate the function that you created, which executes setValidationLi st(). Note that this will only work properly if your AJAX call returns within 3 seconds.
                  Hi pbmods,

                  I gotta say I really appreciate you taking the time to help. I have played around with this function, and thanks to your explanation i actually have a better understanding of what I am doing and how and why it should work.

                  I have spent some time messing around with this idea of delaying code execution and finally decided that I don't really like the idea. So, As I need to do something like that I figure user information is the best way forward, this leaves me with the alert to inform the user what is happening at this stage.

                  This solution still seems like a bit of a fudge to me but hopefully it wont look out of place when the site goes live (probably next year).

                  What do you think of this solution? I respect your opinion and if you woudl be good enough to spare the time to share it I'd really appreciate it.

                  Once again many thanks
                  Nathan

                  Comment

                  • pbmods
                    Recognized Expert Expert
                    • Apr 2007
                    • 5821

                    #10
                    Heya, Nathan.

                    The problem with delaying your code's execution (whether by using a timer or by using an alert) is that you don't really know when your AJAX call returns. Ideally, if you get a response sooner, you'll want to display the results sooner.

                    As you're aware, you can accomplish this by using http's onreadystatecha nge handler. But what if (as you mentioned) you need to pass extra arguments or call additional functions?

                    Check out your setTimeout call:[code=javascript]var lnTime = setTimeOut(
                    function() {
                    setValidationLi st(pnListItem);
                    },
                    3000);[/code]

                    You can use the same principle when you set goXMLHTTP.onrea dystatechange in validateItem() (line 68 in your OP):[code=javascript]goXMLHTTP.onrea dystatechange=f unction() {
                    writeResponse() ;
                    setValidationLi st(pnListItem);
                    };[/code]

                    Comment

                    • nathj
                      Recognized Expert Contributor
                      • May 2007
                      • 937

                      #11
                      Originally posted by pbmods
                      Heya, Nathan.

                      The problem with delaying your code's execution (whether by using a timer or by using an alert) is that you don't really know when your AJAX call returns. Ideally, if you get a response sooner, you'll want to display the results sooner.

                      As you're aware, you can accomplish this by using http's onreadystatecha nge handler. But what if (as you mentioned) you need to pass extra arguments or call additional functions?

                      Check out your setTimeout call:[code=javascript]var lnTime = setTimeOut(
                      function() {
                      setValidationLi st(pnListItem);
                      },
                      3000);[/code]

                      You can use the same principle when you set goXMLHTTP.onrea dystatechange in validateItem() (line 68 in your OP):[code=javascript]goXMLHTTP.onrea dystatechange=f unction() {
                      writeResponse() ;
                      setValidationLi st(pnListItem);
                      };[/code]
                      Thank you so much. I really appreciate this, you are truly a star! I have now got this to behave as I want it without any dodgy alerts or unecessary waiting around. This has made my day. I couldn't have done it without your help.

                      More importantly than it working is the fact that I know understand why it works. This is always my ultimate aim, so a real big thnkyou for that too.
                      Cheers
                      Nathan
                      Last edited by nathj; Jul 6 '07, 11:36 AM. Reason: further gratitude

                      Comment

                      • pbmods
                        Recognized Expert Expert
                        • Apr 2007
                        • 5821

                        #12
                        Heya, Nathan.

                        That's great to hear that you were able to get it working!

                        Good luck with your project, and if you ever need anything, post back anytime :)

                        Comment

                        Working...