Node list can't find the value

26 Views Asked by At

I have been creating some form elements like name, age, address and also I have to add blocks for the achievements, skills, projects and education, but I have an issue while dealing with jQuery repeaters, it's just a made a node list to fill it with multi-values information like achievement or skills but the DevTools shows up this error:

Uncaught TypeError: Cannot read properties of undefined (reading 'value')

and here is an exp:

this is a simple form elements and a multi-values element

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
    <title>EXP</title>
    <meta name='viewport' content='width=device-width, initial-scale=1'>
</head>
<body>
    <section id="about-user" class="">
        <div class="container">
            <div class="about-data">
                <form action="" class="cv-form" id="cv-form">
                    <!-- if i deal with a static data like personal information i font have a problem-->
                    <div class="cv-form-blk">
                        <div class="cv-form-row-title">
                            <h3>about user</h3>
                        </div>
                        <div class="cv-form-row cv-form-row-about">
                            <div class="form-elem">
                                <label for="" class="form-label">firstname</label>
                                <input type="text" name="firstname" class="form-control firstname" id="" onkeyup="generateCV()">
                            </div>
                        </div>
                        <div class="form-elem">
                            <label for="" class="form-label">firstname</label>
                            <input type="text" name="firstname" class="form-control firstname" id="" onkeyup="generateCV()">
                        </div>
                        <div class="form-elem">
                            <label for="" class="form-label">address</label>
                            <input type="text" name="address" class="form-control address" id="" onkeyup="generateCV()">
                        </div>
                        <div class="form-elem">
                            <label for="" class="form-label">age</label>
                            <input type="text" name="age" class="form-control age" id="" onkeyup="generateCV()">
                        </div>
                    </div>
                    <div class="cv-form-blk">
                        <div class="cv-form-row-title">
                            <h3>Achievements</h3>
                        </div>
                        <div class="row-separator repeater">
                            <div class="repeater" data-repeater-list="group-a">
                                <div data-repeater-item>
                                    <div class="cv-form-row cv-form-row-acheivement">
                                        <div class="form-elem">
                                            <label for="" class="form-label">Title</label>
                                            <input type="text" name="acheiv-title" class="form-control acheiv-title" id="" onkeyup="generateCV()">
                                            <span class="form-text"></span>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            
                        </div>
                    </div>
                </form>
            </div>
        </div>   
    </section>

    <!-- jquery cdn -->
    <script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" crossorigin="anonymous"></script>
    <!-- jquery repeater -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.repeater/1.2.1/jquery.repeater.js" integrity="sha512-bZAXvpVfp1+9AUHQzekEZaXclsgSlAeEnMJ6LfFAvjqYUVZfcuVXeQoN5LhD7Uw0Jy4NCY9q3kbdEXbwhZUmUQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <!-- custom js -->
    <script type="text/javascript" src="exp.js"></script>
</body>
</html>

and this the generator function

const strRegex = /^[a-aA-Z\s]*$/; // containing only letters


const mainForm = document.getElementById('cv-form');

// user input elemnts 
let firstnameElem = mainForm.firstname,
    addressElem = mainForm.address,
    ageElem = mainForm.age;


const validType = {
    TEXT: 'text',
    EMAIL: 'email',
}

// first value is for attributes and seconde one passes the nodelists
const addValues = (attrs, ...nodeLists) => {
    let elemsAttrCount = nodeLists.length;
    let elemsDataCount = nodeLists[0].length;
    let tempDataArr = [];

    //first loop deals with the no of repeaters value
    for(let i = 0; i<elemsDataCount; i++ ){
        let dataObj = {}; // creating an empty obj to fill the data
        //second loop fetches the data for each repeaters value or attributes
        for (let j = 0; j < elemsAttrCount; i++ ) {
            /* setting the key name for the obj and fill it with data , 
            which is the expectable thing*/
            dataObj[`${attrs[j]}`] = nodeLists[j][i].value; // but in this part exact the node list can't find a value
        }
        tempDataArr.push(dataObj);
    }
    return tempDataArr;
}

const getUserInputs = () => {
    // achievements
    let achievementsTitleElem = document.querySelectorAll('.acheiv-title');   

    console.log(addValues(['achiev-title'],achievementsTitleElem));

    // event listeners for validation
    firstnameElem.addEventListener('keyup', (e) => validateFormData(e.target, validType.TEXT, 'First name'));
    addressElem.addEventListener('keyup', (e) => validateFormData(e.target, validType.TEXT, 'last name'));
    ageElem.addEventListener('keyup', (e) => validateFormData(e.target, validType.ANY, 'designation'));
    achievementsTitleElem.forEach(item => item.addEventListener('keyup' ,(e) => validateFormData(e.target, validType.TEXT ,'Title')));


    return {
        firstname: firstnameElem.value,
        address: addressElem.value,
        age: ageElem.value,
        acheivements: addValues(['acheiv-title'],achievementsTitleElem)
        
    }
}

function validateFormData(elem, elemType, elemName) {
    // checking for text string and non empty string
    if (elemType == validType.TEXT) {
        if (!strRegex.test(elem.value) || elem.value.trim().length == 0) {
            addErrMsg(elem, elemName);
        }
        else{
            removeErrMsg(elem);
        }
    }
}

// adding the invalid text
function addErrMsg(formElem, formElemName){
    formElem.nextElementSibling.innerHTML = '${formElemName} is invalid !';
}

//removing the invalid text
 function removeErrMsg(formElem){
    formElem.nextElementSibling.innerHTML = "";
 }

const generateCV = () => {
    let userData = getUserInputs();
}

I tried also to test the element without "addVlues( )" if it's returning something but it shows me 1 and with out any reference to the element, also when tried ".values" instead of ".length" it shows no error but the values are undefined

const getUserInputs = () => {
    // achievements
    let achievementsTitleElem = document.querySelectorAll('.acheiv-title');   

    console.log(achievementsTitleElem.length);


/*
    // event listeners for validation
    firstnameElem.addEventListener('keyup', (e) => validateFormData(e.target, validType.TEXT, 'First name'));
    addressElem.addEventListener('keyup', (e) => validateFormData(e.target, validType.TEXT, 'last name'));
    ageElem.addEventListener('keyup', (e) => validateFormData(e.target, validType.ANY, 'designation'));
    achievementsTitleElem.forEach(item => item.addEventListener('keyup' ,(e) => validateFormData(e.target, validType.TEXT ,'Title')));

*/
    return {
        firstname: firstnameElem.value,
        address: addressElem.value,
        age: ageElem.value,
       // acheivements: addValues(['acheiv-title'],achievementsTitleElem)
        
    }
}
0

There are 0 best solutions below