2
\$\begingroup\$

Currently trying to learn to add in some validations, but only run 2nd validation after the 1st one is fully done and has no errors.

Just want to hear reviews regarding my current logic in my data validation.

  • 1st Validation checks for empty fields
  • 2nd Validation (only to work after 1st validation is done) checks if value equals to 10. If yes, then prompt with bootstrap message, to submit current data or go back.

 <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">

<div class="container mt-4">

    
    <hr>

    <h3>Form:</h3>
    <form id="form" class="mt-4 mb-4" action="/reports_send/21-TEMP-01a" method="POST">

        <div style="border: 1px solid black; padding: 40px; border-radius: 25px;">
        <div class="container mt-4">
            <div id="errors" class="mt-4 alert alert-danger" style="visibility: hidden">
                <h4>Please complete all required fields</h4>
            </div>
        </div>

            <h4>Select Room</h4>
            <div id="RoomSelect">
                <select id="RoomMenu" class="form-control mb-4"> 
                    {{!-- Drying Room 1 --}}
                    <option value="dry-1">Drying Room 1</option>
                    {{!-- Drying Room 2 --}}
                    <option value="dry-2">Drying Room 2</option>
                    {{!-- Dry Store--}}
                    <option value="dry-3">Dry Store</option>
                </select>
            </div>
            
            <div id="RoomInputs">

                {{!-- Drying Room 1 --}}
                <div class="form-group" id="dry-1">
                    {{!-- Title --}}
                    <h4>Drying Room 1</h4>

                    {{!-- All temperatures --}}
                    <div class="temperatures">
                     
                        <label>Temperature °C - <strong>Actual</strong></label>
                        <input type="number" class="form-control" name="actual-temp-1">

                      
                        <label>Temperature °C - <strong>Minimum</strong></label>
                        <input type="number" class="form-control" name="min-temp-1">

                    
                        <label>Temperature °C - <strong>Maximum</strong></label>
                        <input type="number" class="form-control" name="max-temp-1">
                    </div>
                    <br>
                    <br>
                    {{!-- All humidity --}}
                    <div class="humidity">
                         
                        <label>Relative Humidity - <strong>Actual</strong></label>
                        <input type="number" class="form-control" name="actual-humid-1">
                        
                        <label>Relative Humidity - <strong>Minimum</strong></label>
                        <input type="number" class="form-control" name="min-humid-1">
                         
                        <label>Relative Humidity - <strong>Maximum</strong></label>
                        <input type="number" class="form-control" name="max-humid-1">
                    </div>
                </div>


                {{!-- Drying Room 2 --}}
                <div class="form-group" id="dry-2">
                    {{!-- Title --}}
                    <h4>Drying Room 2</h4>

                    {{!-- All temperatures --}}
                    <div class="temperatures">
                       
                        <label>Temperature °C - <strong>Actual</strong></label>
                        <input type="number" class="form-control" name="actual-temp-2">

                       
                        <label>Temperature °C - <strong>Minimum</strong></label>
                        <input type="number" class="form-control" name="min-temp-2">

                       
                        <label>Temperature °C - <strong>Maximum</strong></label>
                        <input type="number" class="form-control" name="max-temp-2">
                    </div>
                    <br>
                    <br>
                    {{!-- All humidity --}}
                    <div class="humidity">
                         
                        <label>Relative Humidity - <strong>Actual</strong></label>
                        <input type="number" class="form-control" name="actual-humid-2">
                        
                        <label>Relative Humidity - <strong>Minimum</strong></label>
                        <input type="number" class="form-control" name="min-humid-2">
                         
                        <label>Relative Humidity - <strong>Maximum</strong></label>
                        <input type="number" class="form-control" name="max-humid-2">
                    </div>
                </div>

                {{!-- Dry Store --}}
                <div class="form-group" id="dry-3">
                    {{!-- Title --}}
                    <h4>Dry Store</h4>

                    {{!-- All temperatures --}}
                    <div class="temperatures">
                        
                        <label>Temperature °C - <strong>Actual</strong></label>
                        <input type="number" class="form-control" name="actual-temp-3">

                        
                        <label>Temperature °C - <strong>Minimum</strong></label>
                        <input type="number" class="form-control" name="min-temp-3">

                        
                        <label>Temperature °C - <strong>Maximum</strong></label>
                        <input type="number" class="form-control" name="max-temp-3">
                    </div>
                    <br>
                    <br>
                    {{!-- All humidity --}}
                    <div class="humidity">
                         
                        <label>Relative Humidity - <strong>Actual</strong></label>
                        <input type="number" class="form-control" name="actual-humid-3">
                         
                        <label>Relative Humidity - <strong>Minimum</strong></label>
                        <input type="number" class="form-control" name="min-humid-3">
                         
                        <label>Relative Humidity - <strong>Maximum</strong></label>
                        <input type="number" class="form-control" name="max-humid-3">
                    </div>
                </div>

                <button id="submit-btn" class="btn btn-primary">Submit</button>
            </div>
            
        </div>
    </form>

</div>


{{!-- Errors --}}

<div id="myModal" class="modal" tabindex="-1" role="dialog">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Targets not met</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <p>Some temperatures or humidity values have not met their targets</p>
        <p>- Re-check or continue submitting current data.</p>
      </div>
      <div class="modal-footer">
        <button id="submit-email" type="button" class="btn btn-primary">Submit</button>
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
      </div>
    </div>
  </div>
</div>

<script>

// Store DOM Strings
var DOMStrings = {
    room_options: '#RoomMenu'
};

// On selected option, show specific div element
showActiveElement = () => {
    

    for(const option of document.querySelector(DOMStrings.room_options).options) {
        document.querySelector(`#${option.value}`).style.display = "none";
    }

    if(document.querySelector(DOMStrings.room_options).value === 'dry-1') {
        document.querySelector('#dry-1').style.display = "block";
    } else if (document.querySelector(DOMStrings.room_options).value === 'dry-2') {
        document.querySelector('#dry-2').style.display = "block";
    } else if (document.querySelector(DOMStrings.room_options).value === 'dry-3') {
        document.querySelector('#dry-3').style.display = "block";
    }

}



// Show selected div element from options
document.querySelector(DOMStrings.room_options).addEventListener('change', () => {
    showActiveElement();
});



// Validate data
document.getElementById("form").addEventListener("submit", (e) => {
        
    const inputs = document.querySelectorAll('#form input');
    
    let bool = true;
    
    // Event listener activated after user submits the form
    inputs.forEach((item) => {
        if(item.value === "") {
            bool = false;
            e.preventDefault();
            item.style.borderColor = 'red';
            item.placeholder = "Required";
            document.getElementById('errors').style.visibility = "visible";
            
        } else {
            item.style.borderColor = '#fff';
        }

        // On input - add event listener
        item.addEventListener("input", (event) => {
            if(item.value === "") {
                e.preventDefault();
                item.style.borderColor = 'red';
                item.placeholder = "Required";
            } else {
                item.style.borderColor = '#fff';
            }
        });
    });

    if(bool == true) {
        for (var i = 0; i < inputs.length; i++) {
            if(inputs[i].name.startsWith("actual-temp") || inputs[i].name.startsWith("min-temp") || inputs[i].name.startsWith("max-temp")) {
                validateActualTemp(parseFloat(inputs[i].value), inputs[i], e);
            }

        }
    }
    
});

    



function validateActualTemp(value, item, e) {
    if(value === '10') {
        e.preventDefault();
        item.style.backgroundColor = 'red';
        $("#myModal").modal();
    }
}

document.getElementById('submit-email').addEventListener('click', () => {
    const form = document.getElementById('form');
    form.submit();
});


// On load
window.onload = () => {
    showActiveElement();
}


</script>

\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

I think that, in the form submit event listener, you want to check if every input has a value different that an empty string.

You can check if every item of an array satisfies the return function expression, for example:

["a", "b", "c"].every(str => str !== "") // true
["", "b", "c"].every(str => str !== "") // false

Also, you can check if some item of an array satisfies the function expression:

["", "b", "c"].some(str => str === "") // true
["a", "b", "c"].some(str => str === "") // false

But inputs is a NodeList and has not an every and some methods, which are Array methods. By other hand, a NodeList is an object that can be accessed by index and have a length propertie, that is, is an array-like object.

When you have a case like this, you can reuse native implemented functions with Function.prototype.call, like this:

const inputs = document.querySelectorAll('#form input');
const isEmpty = [].some.call(inputs, e => e.value === "");

But, in this case, Array.prototype.empty returns a Boolean, and you will need the empty inputs to style after.

You can use Array.prototype.filter, which return an array with every elements that satisfies the return function expression, for example:

[1, 2, 3, 4, 5].filter(n => n > 3) // [ 4, 5 ]

In your case, maybe you can check the filtered inputs length:

const inputs = document.querySelectorAll('#form input');
const empty = [].filter.call(inputs, e => e.value === "");

if(empty.length === 0) {
  // there's no empty inputs, continue with the validation
} else {
  // here you can style the empty inputs
}

Conclusion: you can reuse native implemented Array methods that solves your problem in array-like objects

Useful link

\$\endgroup\$
3
  • \$\begingroup\$ On the last code - how do you style specific input that is empty? \$\endgroup\$ Sep 24, 2020 at 13:56
  • 1
    \$\begingroup\$ If there's empty inputs, they will be in empty array; I would make a CSS class to style invalid input and just do a forEach through empty adding this class \$\endgroup\$ Sep 24, 2020 at 15:17
  • \$\begingroup\$ Similar to how it is explained in this SO answer a CSS pseudo class selector - e.g. :valid combined with :not() - could likely eliminate the need for a loop \$\endgroup\$ Mar 12, 2022 at 3:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.