简体   繁体   中英

Validating Credit Card in JavaScript, using loop to cycle through form field names, getting error

Working on a problem for a class. Need to do credit card validation per these instructions:

You're starting your own credit card business. You've come up with a new way to validate credit cards with a simple function called validateCreditCard that returns true or false.

Here are the rules for a valid number:

Number must be 16 digits, all of them must be numbers You must have at least two different digits represented (all of the digits cannot be the same) The final digit must be even The sum of all the digits must be greater than 16

The following credit card numbers are valid:

9999-9999-8888-0000

6666-6666-6666-1666

The following credit card numbers are invalid:

  • a923-3211-9c01-1112 invalid characters
  • 4444-4444-4444-4444 only one type of number
  • 1111-1111-1111-1110 sum less than 16
  • 6666-6666-6666-6661 odd final number

You will need to create a web form that allows your users to enter credit card numbers and on change, validate if the credit card is valid and display a message to the user accordingly.

Hint: Remove the dashes from the input string before checking if the input credit card number is valid. (check out split() and join() methods.

5 points extra: Return an object indicating whether the credit card is valid, and if not, what the error is { valid: true, number: 'a923-3211-9c01-1112' } { valid: false, number: 'a923-3211-9c01-1112', error: 'wrong_length' }

And display it appropriately.

5 points extra: Make your credit card scheme even more advanced! What are the rules, and what are some numbers that pass or fail? Ideas: check expiration date! Check out the Luhn Algorithm (Links to an external site.)Links to an external site. for inspiration.

Here's my html:

<!DOCTYPE>
<html>
    <head>
        <title>Credit Card Validation</title>
        <!--Lisa Hergert's Extra Credit 1-->
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
        <script src="extraCredit.js"></script>
    </head>
    <body>
        <form name = "newForm">
            <label for = "creditCard1">Card Number</label>
            <input type = "text" name = "creditCard1" id = "creditCard1" placeholder = "XXXX-XXXX-YYYY-AAAA"
            onChange = "validateCreditCard()" /><br />
            <label for = "creditCard2">Card Number</label>
            <input type = "text" name = "creditCard2" id = "creditCard2" placeholder = "XXXX-XXXX-YYYY-AAAA"
            onChange = "validateCreditCard()" /><br />
            <label for = "creditCard3">Card Number</label>
            <input type = "text" name = "creditCard3" id = "creditCard3" placeholder = "XXXX-XXXX-YYYY-AAAA"
            onChange = "validateCreditCard()" /><br />
            <label for = "creditCard4">Card Number</label>
            <input type = "text" name = "creditCard4" id = "creditCard4" placeholder = "XXXX-XXXX-YYYY-AAAA"
            onChange = "validateCreditCard()" /><br />
            <label for = "creditCard5">Card Number</label>
            <input type = "text" name = "creditCard5" id = "creditCard5" placeholder = "XXXX-XXXX-YYYY-AAAA"
            onChange = "validateCreditCard()" /><br />
            <label for = "creditCard6">Card Number</label>
            <input type = "text" name = "creditCard3" id = "creditCard3" placeholder = "XXXX-XXXX-YYYY-AAAA"
            onChange = "validateCreditCard()" /><br />
        </form>
    </body>
</html>

Here's my javascript (the code is undated):

/**
* validCardNumber tests that Credit Card Number is XXXX-XXXX-YYYY-AAAA
* X, Y and A must only be digits
*/

    function validateCreditCard () {
    for (var i = 1; i < 7; i++) {
        var cardNumber = document.getElementById("creditCard" + i);

        var pattern = new RegExp("[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{3}[24680]{1}");
        var res = pattern.test(cardNumber);

        if (res) {
            document.getElementById("message").style.color = 'green';
            document.getElementById("message").innerHTML = "Card Number is Valid";
            document.getElementById("creditCard" + i).style.color = "green";
        } else {
            document.getElementById("message").style.color = 'red';
            document.getElementById("message").innerHTML = "Card Number is NOT valid";
            document.getElementById("cardCard" + i).style.color = 'red';
        }
    }
}

I am trying to create a loop with i so that instead of doing a long list of variables to use to reference the different form fields: creditCard1...2...3 etc.

I am getting this error:

extraCredit.js:10 Uncaught TypeError: Cannot read property '1' of undefined
    at validateCreditCard (extraCredit.js:10)
    at HTMLInputElement.onchange (creditCardValidation.html:13)

Is there a better way to do this?

Getting new error with the updated code:

extraCredit.js:22 Uncaught TypeError: Cannot read property 'style' of null
    at validateCreditCard (extraCredit.js:22)
    at HTMLInputElement.onchange (creditCardValidation.html:14)

The error you are getting is because document.newForm.creditCard does not exist. Trying to get [1] from it then fails with the error message. There are a couple of ways to go around this:

Use brackets notation to access it. I assume this was your intention but you missed it by a bit - the proper syuntax is document.newForm["creditCard" + i] . note the quotes around creditCard - you need a string and "creditCard" + i will generate "creditCard1" , "creditCard2" , etc.

Use the DOM lookup methods. In this case, the easiest one is probably getElementById() - the syntax would be document.getElementById("creditCard" + i) - the idea is the same as before - you need to create the strings "creditCard1" , "creditCard2" and so on and look up the elements based on that. You would need to change the lines document.getElementById("creditCard[i]").style.color = "green"; and document.getElementById("creditCard[i]").style.color = "red"; to also follow this rule.

For reference, there is also another way to find these elements instead of directly by ID. You can use other DOM search methods and base them on different things. For example, if you add a class to each of the input tags like so <input type = "text" class = "creditCard" ... /> then you would be able to use getElementsByClassName() (note the plural - element s ). This will return a list of all elements that match and you can iterate over it using a for loop again, eg

var creditCardInputs = document.getElementsByClassName("creditCard");

for (var i = 0; i < creditCardInputs.length; i++) { //note that you start at zero instead of one
    var creditCardNumber = creditCardInputs[i].value; 
    /* process this number further */
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM