Search code examples
javascriptdom-eventsglobal-variables

Global variables have wrong value after functions exit


I am building a registration form and have trouble with the JavaScript part that enables the submit button when the user name is available, the password is sufficiently complex and the confirm password matches the first password. For some reason passwordStrong is always false and passwordsMatch is always undefined.

userNameAvailable = false
passwordStrong = false
passwordsMatch = false
submitButton = null;

function checkAvailability(name, avalabilityDiv)
{
    if(name.length == 0)//this happens when a name is entered but backspaced OR the shift key is pressed (and nothing else)
    {
        avalabilityDiv.innerHTML = "Please enter a name"
        userNameAvailable = false
    }
    else
    {
        var xmlhttp, responseText
        if(window.XMLHttpRequest)
        {// code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp=new XMLHttpRequest();
        }
        else
        {// code for IE6, IE5
            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
        }
        xmlhttp.onreadystatechange=function()
        {
            if(xmlhttp.readyState == 4 && xmlhttp.status == 200)
            {
                responseText = xmlhttp.responseText;
                avalabilityDiv.innerHTML = responseText//responseText is the property of XMLHttpRequest object that holds server's response
                if(responseText == "available")
                    userNameAvailable = true
                else
                    userNameAvailable = false
            }
        }
        xmlhttp.open("GET", "process.php?pName="+name,true);
        xmlhttp.send();
    }
}

/*
Checks if password contains at least two characters from at least two categories: letter, number, other
sets passwordStrong true if does, otherwise false
*/
function passwordStrength(pass, strengthDiv)
{
    if(pass.length < 8)//check passwords length
    {
        strengthDiv.innerHTML = "too short!"
        //passwordStrong = false
        return
    }
    var group = [0, 0, 0, 0]
    for(i = 0, c = pass.charAt(0); i < pass.length; ++i, c = pass.charAt(i))
        group[typeOfChar(c)]++

    var result = 0
    for(var i = 0; i < group.length; i++)
        if(group[i] >= 2)
            result++

    if(result >= 2)
    {
        var passwordStrong = true
        strengthDiv.innerHTML = "Good."
        alert("passwordStrong: "+passwordStrong)
    }
    else
    {
        //var passwordStrong = false
        strengthDiv.innerHTML = "too simple!"
    }
}

/*used by isPasswordStrong()*/
function typeOfChar(c)
{
    var ascii = c.charCodeAt(0)

    if(ascii >= 48 && ascii <= 57)//is a digit
        return 0
    else if(ascii >= 65 && ascii <= 90)//is upper case letter
        return 1
    else if(ascii >= 97 && ascii <= 122)//is lower case letter
        return 2
    else//is other character(e.g. grammar character)
        return 3
}

/*
Checks to see if confirmation password is same as first password
sets passwordsMatch true if same, otherwise false
*/
function matchPasswords(first, second, matchDiv)
{
    matchDiv.innerHTML = "first: "+first.value+" second: "+second.value+"<br />"+userNameAvailable+" "+passwordStrong+" "+passwordsMatch+" done"
    if(first.value == second.value)
        var passwordsMatch = true
    else
        var passwordsMatch = false
}

/*This always shows that passwordStrong is false*/
function output()
{
    alert("From output() passwordStrong: "+passwordStrong)
}

function toggleSubmit()
{
    alert("here1 passwordStrong: "+passwordStrong)
    if(submitButton == null)//may be cached
        submitButton = document.getElementById("submit")
    if(userNameAvailable && passwordStrong && passwordsMatch)
        submitButton.disabled = false
    else
        submitButton.disabled = true
}

Even if the HTML "Good." is displayed by passwordStrength() after the function has exited the variable passwordStrong becomes false. Why?

I'm not using JQuery.

EDIT: yea it fixed it. How did you guys know? All of my trouble shooting techniques did not turn up this source.


Solution

  • Get rid of the var keyword when you reference those variables inside your functions.

    By using var, you're making local variables with the same names as the relatively-global ones, so the global variables are "shadowed".