1

this is my first post so apologies if I get anything wrong, just let me know.

I am trying to have an external javascript file that has functions which will be able to be reused. For instance, when I have a text field and want to validate it, I want to be able to pass over three arguments (value to check, field description and min length allowed)

At the top of my HTML (above head tag) I have my script tag: <script src="checkInputs.js"></script>

So far, I have a form. The form has these two fields (omitted some code):

<form name="join" action="createUser.php" onsubmit="return initDetails()" method="post">
<label> Choose a username: </label> <input type="text" name="username" maxlength=20><br>
<div id="uname" style="display: none; font-family:arial;color:red;font-size:12px;"></div>

The submit of the form calls the following function (I know it is calling it correctly):

    function initDetails() {
    alert("inside initDetails");
    var unamev=document.forms["join"]["username"].value;
    var pass=true;
    var usernameCheck = [];
    usernameCheck.push(checkTextField(unamev, 5, "username"));
    alert("check variables");
    alert(usernameCheck['Pass']);
    alert(usernameCheck['Error']);
    alert("check variables finished");
        if (usernameCheck['Pass']=="True"){
            alert("We pass");
            document.getElementById('uname').style.display = 'none';
        }
        else{
            alert("We fail");
            pass=false; 
            document.getElementById('uname').style.display = 'block';
            document.getElementById("uname").innerHTML = usernameCheck['Error'];
        }
    return pass;
}

So the above is responsible for grabbing the username, call calling checkTextField with my three values, and storing the returned items in an array. These are used to see if the test passed or failed, and populating the error message and displaying the hidden block with that error, and finally returning true or false to the submit.

So now for the external js file, I have the following:

    function checkTextField(fieldInput, maxLength, fieldDescription) {
alert("Inside checkInputs.js ")
var errmsg = ""; 
    if (fieldInput.length < maxLength ){
            pass=false;
            errmsg = "<li> The " + fieldDescription + " must be larger than 5 characters </li>";
        if (fieldInput == null  || fieldInput == ""){
            pass=false;
            errmsg = "<li> The " + fieldDescription + " cannot be empty </li>";     
        }
        return {'Pass': "False", 'Error': errmsg};
    }
    else{
        return {'Pass': "True", 'Error' : ""};  
    }

}

I used to have something very similar inside the HTML file that worked, but to avoid duplicated code, I wanted to have a framework of sorts to handle these. Now it could very well be that I am making a simple syntax schoolboy error, but I am trying to get up to scratch with Javascript, its not too good.

UPDATE

I have updated the code based on a number of suggestions posted here. It now calls the external file, and the following alerts:

        alert(usernameCheck['Pass']);
    alert(usernameCheck['Error']);

Both alerts are undefined....

paulLowden
  • 11
  • 2
  • 4
    The title might want to be a tad more descriptive. – Dave Newton Feb 04 '14 at 20:34
  • 1
    And the actual question: what works? What doesn't? What's in the JS console? Etc. Actual details. – Dave Newton Feb 04 '14 at 20:35
  • Thanks for the quick reply, well I have alerts in all parts and none are firing, the form just submits, so I assume it is syntax somewhere.... – paulLowden Feb 04 '14 at 20:35
  • Your first script looks like a javascript, if so there lot of syntax errors. At first, if you want to create an array in JavaScript you should use `var usernameCheck = [];` than `usernameCheck.push(checkTextField(unamev, 5, "username"));` – Givi Feb 04 '14 at 20:38
  • 1
    `if usernameCheck[0] = "Pass" {` is an assignment, not a boolean expression, which would be `==` – Dave Newton Feb 04 '14 at 20:39
  • Of course! Stupid me! – paulLowden Feb 04 '14 at 20:39
  • 1
    Also, correct syntax of if statement is `if (expression) { }` you should wrap your expression with parentheses. – Givi Feb 04 '14 at 20:42
  • Givi, many thanks! You have helped me get much further on this issue. Couldn't have done it without you! – paulLowden Feb 04 '14 at 20:54

2 Answers2

0

You need to prevent the default event action. The easiest way would be to set up the event handler not on the form tag but in a script using addEventListener(). The first argument to the given event handler callback (which basically should do what your initDetails function does) is the event object:

var form = document.forms['join'];
form.addEventListener( 'submit', function( event ) {

    // prevent the default submit action
    event.preventDefault();

    // do your checks, e.g.
    var usernameCheck = checkTextField( form.['username'].value, 5, 'username' );
    // …

    if( usernameCheck === 'Pass' ) {

        // finally submit the form
        form.submit();

    }

}, false );

See also:

Other changes I've done here are also mentioned in the comments above. For example using === for comparison or not pushing a value to an array, but assigning it to a simple variable (a = b;).

UPDATE: To solve the problem with multiple return values, you should read the answer of »theUtherSide« again. Just return an object.

feeela
  • 29,399
  • 7
  • 59
  • 71
  • Yes but if I return False to the submit, the submit action will not execute. So an action listener is not really necessary is it? – paulLowden Feb 04 '14 at 20:47
  • http://stackoverflow.com/questions/4924036/return-false-on-addeventlistener-submit-still-submits-the-form If the form action is canceled by a `return false;` depends on the browser, I guess. See also: http://stackoverflow.com/questions/18971284/event-preventdefault-vs-return-false-no-jquery – feeela Feb 04 '14 at 20:51
0

I think your validation function is not getting called because of this line:

var usernameCheck[] = checkTextField(unamev, 5, "username");

Should be:

var usernameCheck = checkTextField(unamev, 5, "username");

If you want to declare the variable first, you could do:

var usernameCheck = [];
(You could also give it a size this way.)

An additional tip for the design of your framework:

A more scalable strategy might be to have your function return an object, rather than an array.

This way you could have it return named values, and your implementation wouldn't break if the array changes, and you don't have to worry about the size.

For example, instead of: return ["Fail", errmsg];

Do: return {'Pass': true, 'msg': errmsg};

Then, in the implementation: usernameCheck[1];

Becomes: usernameCheck['msg'];

theUtherSide
  • 3,338
  • 4
  • 36
  • 35
  • Yes, I should use an object I agree. I want to try the basics first, get it working, and improve gradually. Plus one for the framework tip (If I had a +15 rep!) – paulLowden Feb 04 '14 at 20:58