• Programming
  • 28
  • 0

Validation Checker

Validation Checker

This is a post about my custom validation checker that saves me alot of time. If you’ve ever built a project and have to dummy check fields are filled out. The task can become tedious. It’s something that needs to be done, but takes alot of time whether you’re writing a custom js script for each input or creating a class and attaching that on error, it can get time consuming.

One day, when starting a project for work, I decided to make my life easier at the start. I decided to write one script and be able to check for ALL the validation I could need (of course this was for the admin portion). So I wrote my script validationChecker.js. To start, lets look how I call it.

//This is called at the top of my page with forms needing validation or in my case I put it in the main Admin page on my Laravel application
<script src="{{ asset('js/validationChecker.js') }}"></script>
//This is called at the bottom to check the form
<script>
    $('form').on('submit', function(e) {
        var form = this;
        let checker = new validationChecker(form);
        if (checker) {
            if (checker.includes(false)) {
                return false;
            } else {
                return true;
            }
        }
    });
</script>

Now I know what you’re thinking.. Ok, how does this make my life simpler? Well that’s the hard part. After you put that code on the page you then do all of your input fields.

 <div class="form-group row">
    <label class="col-12" for="example-text-input">SENDGRID TEMPLATE ID</label>
      <div class="col-md-9">
        <input type="text" class="form-control" id="example-text-input" name="mc_api_id" placeholder="9050" value="{{$data->mc_api_id ?? ""}}">
 <div class="form-text text-muted">Enter Message Central Mailing ID</div>
        </div>
 </div>

So you’ll have to forgive the sloppiness, but here is an example of a regular text input field. This is what it looks like.

Soooo… Where is the validation check? Anyone that comes to a page with this and no custom js or something with “required” on the input field would make them wonder where the validation was coming from. And thats where I think the magic starts happening. The validationChecker.js file we added to the top of the Admin section handles all the validation. When we say

let checker = new validationChecker(form);

And then check whether or not it includes false in the array or if its all true. Help us to stop the submission of the form (if there’s a false returned). So what’s inside this validationChecker.js that could make things simpler? How do we pass in input fields into the checker? Let’s find out.

class validationChecker{

 message = "";
 classType = "";

//function needed... for some reason putting it above the constructor allows us to access it across the class
    //before, we couldn't
    /**
     * @param item - actual input field
     * @param message - message to display
     * @param classtype - class name to add to the item 
     * 
     */
    showResult = function(item, message, classtype){
        item.className += ' '+classtype;
        item.nextElementSibling.innerHTML = message;
        item.nextElementSibling.className += ' '+classtype;
        return true;
    }

    constructor(form){
        var input = form.getElementsByTagName('input');
        var select = form.getElementsByTagName('select');
        var newArr = [...input, ...select];
        let self = this;
        let arr = [];
            newArr.forEach((item, index) => {
                var required = item.getAttribute('name');
                if(required !== null && required !== ""){
                    if(required.includes('options[')){
                        required = required.replace("options['", "");
                        required = required.replace("']", "");
                    }
                    var req = this[required];
                    if(typeof req == "function"){
                        arr.push(req(item, self));
                    }
                }
            })
            return arr;
            
    }

Let’s break this down. First we declare some variables message, and classType, we’ll use these later. Next we have a function which accepts 3 parameters, item, message and classtype. This will also be used later. Finally we have the constructor which accepts the form parameter. This comes from the script we put in the Admin head.

var form = this;
let checker = new validationChecker(form);

Basically without going through too much detail, this will take all the input and select fields and loop through them on submit. And we then use the NAME of the input field to check against a function. My example above this code (input field) had the name mc_api_id. So, lets see if there’s a function in the validationChecker.

    mc_api_id(item, self){
       
        if(item.value.length < 3){
            self.showResult(item, "MC API ID cannot be empty or must be valid", "error");
            return false;
        }
        else{
            var data = {
                mcapi_id: item.value
            }
            item.classList.remove('error');
            item.nextElementSibling.classList.remove('error');
            return true;
          
        }
    }

There’s the function above. So we pass through item, the input field, and self which deals with this class. In this function we check if then item.value.length is < 3 (because at the time I just needed it to be longer than 3 characters). If it is less than 3, we call the showResult function which then changes the input (item), the message and the classtype. In my css I have error to change all the fields to red.

.text-muted.error{
    color: red !important;
    border-color: red;
    -moz-transition: all 1s ease-in;
    /* WebKit */
    -webkit-transition: all 1s ease-in;
    /* Opera */
    -o-transition: all 1s ease-in;
    /* Standard */
    transition: all 1s ease-in;
  }
  .form-control.error{
    border-color: red;
    -moz-transition: all 1s ease-in;
    /* WebKit */
    -webkit-transition: all 1s ease-in;
    /* Opera */
    -o-transition: all 1s ease-in;
    /* Standard */
    transition: all 1s ease-in;
  }

This helps show some slow animation to red when the error class is shown.

Ok ok, not impressed yet? Fine, how about if we do a select dropdown? Would that be impressive enough? So the name of the select dropdown is primary_listname below.

<div class="form-group row">
  <label class="col-12" for="example-select">PRIMARY LISTNAME</label>
    <div class="col-md-9">
<select class="form-control" id="example-select" name="primary_listname">
       <option value="0">Please select</option>
          @foreach($listname as $list)
            <option value="{{$list->id}}" {{(isset($data->primary_listname_id) && $data->primary_listname_id == $list->id) ? 'selected="selected"' : ""}}>
{{$list->listcode}}
</option>
          @endforeach
</select>
 <div class="form-text text-muted"></div>
      </div>
</div>

So, lets see if we can’t find it in the validationChecker.js….

primary_listname(item, self){
        if(item.value == 0){
            self.showResult(item, "Please select an option", "error");
            return false;
        }
        else{
            item.classList.remove('error');
            item.nextElementSibling.classList.remove('error');
            return true;
        }
    }

Tada! And there we have handled error checking on a dropdown. We get the item.value and check to see if it’s equal to 0 (which is the first dropdown item “Please Select”) and returns an error if it is (false means it failed). Still not impressed? Ok, you’re hard to impress. What about a conditional. You know, a “if a checkbox is checked, then there needs to be a value” how can I handle that?

<div class="form-group row">
                                <label class="col-3">COREG</label>
                                <div class="col-9">
                                    <div class="custom-control custom-checkbox mb-5">
                                        <input class="custom-control-input" type="checkbox" name="coreg" id="coreg-checkbox" value="1" {{isset($coreg) ? "checked='checked'" : ""}}>
                                        <label class="custom-control-label" for="example-checkbox1">True</label>
                                    </div>
                                </div>
                            </div>

<div class="form-group row">
                                <label class="col-12" for="example-select">COREG LISTNAME</label>
                                <div class="col-md-9">
                                    <select class="form-control" id="example-select" name="coreg_primary_listname">
                                        <option value="0">Please select</option>
                                        @foreach($listname as $list)
                                        <option value="{{$list->id}}" {{(isset($coreg->listname_id) && $coreg->listname_id == $list->id) ? 'selected="selected"' : ""}}>{{$list->listcode}}</option>
                                        @endforeach
                                    </select>
                                    <div class="form-text text-muted"></div>
                                </div>
                            </div>

So in this code above, if the checkbox with the name “coreg” is checked, then the dropdown with name “coreg_primary_listname” needs to have a selection. Let’s check the validationChecker.

coreg(item, self){
        if(item.value == 1 && item.checked == true){
            self.coreg_checked = true;
         }
         else{
             self.coreg_checked = false;
             return true;
         }
    }
coreg_primary_listname(item, self){
        if(item.value == 0 && self.coreg_checked){
            self.showResult(item, "Please select an option", "error");
            return false;
        }
        else{
            item.classList.remove('error');
            item.nextElementSibling.classList.remove('error');
            return true;
        }
    }

And just like that, we have the conditional checked and validation met. And all of this checking stops the form submission from our code at the very top which checks on form submission. If we return false at all we return false and the form can’t submit. Here’s a video to check it out in action!

Leave a Reply

Your email address will not be published. Required fields are marked *