After going through numerous solutions for the "closure" problem, I still can't find one that addresses my specific issue.
In the JavaScript code below, a JSON file is fetched and processed, followed by form validation based on the data.
The issue arises when submitting the form and running the validate function. Instead of seeing two errors as expected, only the error for the last field is displayed in the console.
This seems to be a closure problem, which has been consuming my entire day without a successful resolution. The code snippet with the click event at the end...
For now, I am only focusing on validating the minimum length rule.
// Fetch and store the json file
function loadJSON(callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', 'js/rules.json');
xobj.onreadystatechange = function () {
if (xobj.readyState == 4 && xobj.status == "200") {
// Using an anonymous callback due to asynchronous nature of .open method
callback(xobj.responseText);
}
};
xobj.send(null);
}
// Load the json...
loadJSON(response);
// Declare global variables...
var lookup = [], errors = [], i, e, id, lookupId, minLength;
function response(responseData) {
// Convert json data into objects
var rulesSet = JSON.parse(responseData);
// Iterate over objects
for (i = 0; i < rulesSet.length; i++) {
// Create a lookup for each object for future use
lookup[rulesSet[i].id] = rulesSet[i];
}
// Loop through form elements and store ids
// Validate the form
function validate(e) {
var elements = document.getElementsByTagName('input');
for (e = 0; e < elements.length; e++) {
id = elements[e].getAttribute('id');
lookupId = lookup[id].rules;
var rules;
// Process rules of the matched IDs
for (rules of lookupId){
// Check for min length rule
if(rules.name === 'min_length') {
minLength = rules.value.toString();
// Verify validity of the rule (existence of number)
if(isNaN(minLength) || minLength.length === 0){
// Log an error
// Check min length and report an error if invalid
} else if(!checkMinLength(minLength, id)) {
errors[errors.length] = id + " - You must enter more than " + minLength + " characters";
}
}
}
// If there are errors, display them
if (errors.length > 0) {
reportErrors(errors);
//e.preventDefault();
}
}
}
validate();
// Verify field length
function checkMinLength(minLength, id){
var val = document.getElementById(id).value;
if(val < minLength){
return false;
}
return true;
}
// Error reporting
function reportErrors(errors){
for (var i=0; i<errors.length; i++) {
var msg = errors[i];
}
console.log(msg);
}
$('#email-submit').on('click',function(e){
validate(e);
});
}
Below is the JSON content that is loaded...
[
{
"id": "search",
"rules": [
{
"name": "min_length",
"value": "5"
},
{
"name": "email"
}
]
},
{
"id": "phone-number",
"rules": [
{
"name": "min_length",
"value": 8
}
]
},
{
"id": "surname",
"rules": [
{
"name": "min_length",
"value": 10
}
]
}
]
Finally, here's the basic form that requires validation...
<form action="index.html" name="searchForm" id="search-form">
<label for="search">Email</label>
<input type="text" id="search" name="email" placeholder="Enter email">
<input type="text" id="phone-number" name="name" placeholder="Enter name">
<button type="submit" id="email-submit">Submit</button>
</form>