Using a loop in JavaScript to validate credit card information by cycling through the form field names and identifying any errors

Embarking on a challenge for a course. Required to perform credit card validation according to these specific guidelines:

You are establishing your own credit card company. You have devised a new method to validate credit cards using a straightforward function named validateCreditCard, which returns true or false.

These are the criteria for a valid number:

- The number must consist of 16 digits, all of which must be numbers - There must be at least two different represented digits (none of them can be identical) - The final digit should be even - The sum of all the digits should exceed 16

The following credit card numbers are deemed valid:

9999-9999-8888-0000

6666-6666-6666-1666

However, the following credit card numbers are considered invalid:

  • a923-3211-9c01-1112 due to invalid characters
  • 4444-4444-4444-4444 because there's only one type of number
  • 1111-1111-1111-1110 as the sum is less than 16
  • 6666-6666-6666-6661 with an odd final number

You will need to design a web form that permits users to input credit card numbers and instantly validate whether the credit card is valid upon any alterations, providing feedback to the user accordingly.

Tip: Before validating the input credit card number, eliminate the dashes from the input string (refer to split() and join() methods).

Extra Credit (5 points): Enhance your credit card scheme further! Specify the rules and identify some numbers that pass or fail. Suggestions: incorporate an expiration date check and explore the Luhn Algorithm for inspiration.

Below is the HTML code:

<!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 />
           ...
           ...
         </form>
    </body>
</html>

As for the JavaScript (the code is outdated):

/**
* 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 attempting to devise a loop utilising i instead of creating numerous variables to reference the various form fields like creditCard1...2...3 etc.

An error I'm encountering reads as follows:

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 more effective approach to address this issue?

With the revised code, I'm now facing a new error:

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

Answer №1

The issue you're encountering arises from the fact that document.newForm.creditCard does not exist. When attempting to retrieve [1] from it, an error occurs. Fortunately, there are a few approaches to addressing this:

One option is to utilize bracket notation for access. While I assume this was your initial intention, there was a slight oversight - the correct syntax should be

document.newForm["creditCard" + i]
. Note the use of quotes around creditCard - since you require a string and "creditCard" + i will yield "creditCard1", "creditCard2", and so forth.

Another approach entails employing DOM lookup methods. One convenient method in this scenario is likely getElementById(). The corresponding syntax would be

document.getElementById("creditCard" + i)
- following the same principle as before, where you construct strings like "creditCard1", "creditCard2", and beyond to fetch elements. Consequently, the lines
document.getElementById("creditCard[i]").style.color = "green";
and
document.getElementById("creditCard[i]").style.color = "red";
must also adhere to this rule.

Alternatively, aside from direct ID-based identification, you can employ other DOM search techniques based on diverse parameters. For instance, by assigning a class to each input tag as demonstrated:

<input type = "text" class = "creditCard" ... />
, you could leverage getElementsByClassName() (noting the plural - elements). This function returns a collection of matching elements, permitting iteration through them via a for loop like so:

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

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the procedure for placing an item into a vacant area in react-dnd?

Looking to create a drag and drop list using react-dnd. Manage to put together an example: visit codesandbox example here Currently facing one issue: Unable to drop an item into an empty section. If trying to move image1 to the first or third group, un ...

Ways to incorporate sass:math into your vue.config.js file

While using vue-cli with Vue 2.6 and sass 1.49, I encountered errors in the console related to simple division calculations: Deprecation Warning: Using / for division outside of calc() is deprecated and will be removed in Dart Sass 2.0.0. I attempted to ...

retrieve content within an iframe via ajax

I currently have an iframe set up on the server side like this: <iframe frameborder="0" runat="server" style="width: 100%; height: 700px; background-color: #bacad3;" id="I1" name="I1" src="Page.aspx"></iframe> and I update the content dynamic ...

Seamless scrolling experience achieved after implementing a header that appears when scrolling up

My goal is to create a header with the following functionalities: Initially displays with a transparent background Upon scrolling down the page by 25px, it will dynamically add the header--maroon class to the header, which alters the background color and ...

Troubleshooting Error: Heroku, mLab, and Node.js - Application Issue with Mongoose

As a beginner in the world of Node.js and Heroku, I am attempting to host my first application on Heroku but encountering deployment issues. To guide me through this process, I have been following a tutorial which can be found here: https://scotch.io/tutor ...

Exploring data-toggle elements using jQuery

I am faced with the challenge of dynamically constructing a form using jQuery. The form includes a checkbox list of items that I am creating in the following manner: function initializeForm() { var html = ''; var items = GetItems(); for ( ...

Issue encountered in Babel version 6 with the transform-es2015-classes plugin in loose mode, causing a SyntaxError when using async/await

After updating to the latest version of Babel v6, I encountered an issue with the transform-es2015-classes plugin in loose mode (https://github.com/bkonkle/babel-preset-es2015-loose/blob/master/index.js#L8) causing problems with async/await functions. Here ...

Ways to apply Position Fixed to a particular Div element and subsequently eliminate that class while scrolling

Check out my current Jsfiddle project here I am working on a task that involves adding a class to a specific div when scrolling and then removing that class. Below is the JavaScript code I have written for this functionality: var targetDiv = $(".mainwra ...

Is there a way to flip a figure that is flipped upside down?

I'm currently working on creating a map using a json file to go from d3.js to Three.js. However, when the map is displayed, it appears upside down. I'm wondering if there is a way to flip it so that it displays correctly. As a newcomer to d3 and ...

Issue persisting Firebase data

I am currently exploring Firebase and attempting to save the user object (specifically the user's email) into the database using the .then() method after executing firebase.auth().createUserWithEmailAndPassword(email, password) However, I encountered ...

exploring the use of background threads in jQuery and JavaScript

Here's an interesting scenario to consider... As I work on my Java web project, utilizing AJAX to store large amounts of data in a database using a separate thread. Everything seems to be functioning as expected. However, something has me puzzled... ...

Creating a VSCode extension using Vue: Step-by-step guide

I'm looking to develop a VSCode extension with Vue utilizing the VSCode webview. However, when attempting to import the compiled index.html into my extension, I consistently receive a prompt to enable JavaScript. Is there a solution for integrating Vu ...

Is it better to use Asynchronous or Synchronous request with XMLHttpRequest in the Firefox Extension for handling multiple requests

As a newcomer to developing Firefox Add-Ons, my initial project involves calling an external API in two steps: Step 1) Retrieve data from the API. Step 2) Use the data retrieved in Step 1 to make another call to the same API for additional information. ...

Creating a tab component using vanilla javascript

I am facing an issue with my tab component in plain JavaScript. The content displays correctly in debug mode, but after compilation, it does not show up on the browser. Additionally, when I select a tab, the 'activeNav' class is applied to indica ...

Add items to a new array with a property set to true, if they are present in the original array

Could someone assist me with the following situation? I need an array of strings. A function is required to map the array of strings, assigning each element a name and key, while also adding another object "checked: false". Another function should take t ...

The Jodit editor is appearing incorrectly

Encountering an issue with the jodit wysiwyg editor or any similar plugin editor while working within a Bootstrap tab. When adding an editor to the tab content, the display is incorrect upon selecting the tab (displayed at a fraction of the height and miss ...

identifying HTTP requests originating from an embedded iframe

I have a unique scenario where there is an iframe on my page that calls a URL from a different domain. Occasionally, this URL will tunnel to a different URL than the one I specified. Unfortunately, due to cross-domain restrictions, I am unable to view the ...

How to disable the onChange event in PrimeNG p-dropdown?

I'm currently utilizing PrimeNG's dropdown component. Each option in the list includes an icon that, when clicked, should trigger a specific method. Additionally, I need to execute another method when the onChange event of the dropdown is trigger ...

What is the best method for converting this API into a JavaScript object?

My goal is to retrieve data from this API: and store it in a JavaScript variable so that when I log the variable inside the browser console, I will see a tree structure related to the API. To better illustrate what I mean, here's an image of the desi ...

Using expect() within the .then() function when writing Jasmine unit tests for AngularJS

I'm currently struggling with the .then() function while trying to implement Jasmine unit testing. Here is the code that's giving me trouble: describe("getBuilding", function () { it("checks getBuilding", function () { var id_building = 4; ...