-2
\$\begingroup\$

Introduction

So i am building a SPA with AngularJS. The application provides a large number of <input> elements and can be seen as a huge form.

However, i am not using an actual <form> element because of the applications architecture. Once everything is filled, all of the data will be submitted by a single button, though.

This has lead to the problem that i can not use Angular's build-in form validation. I was forced to write my own implementation.

The issue

What follows is my approach to validate the stuff. Everything works fine for me and gets the job done. Nevertheless, i would like to hear the opinions of some advanced or maybe even professional colleagues on how good or bad said approach is and where it could be improved.

HTML


This is a snippet from the applications 'form'. To maintain better readability, i've stripped out the ng-model attributes.

<div>
    <label for="searchClient">Kundennummer</label>
    <input validate-string type="text" id="searchClient">

    <label for="recName">Name*</label>
    <input validate-string type="text" id="recName">                 
 </div>

As you can see, validation is triggered via a directive restricted to attribute.

The directive


app.directive('validateString',function(){
  return{
    restrict: 'A',
    link: function(scope, element){
        var el = angular.element(element);
        el.attr('valid','nope');

        element.bind('input',function(){
            if (element[0].value !== ""){
                el.removeAttr('valid');
            }
            else{el.attr('valid','false');}
        })
    }
  }
});

The directive sets a default attribute of valid="false" to every element the directive is attached to. If an input is made, the attribute is removed. Once everything is done and the user decides to submit, a validation function will fire:

validate()


Shipment.prototype.validate = function(){
   var inputs = $document.find('input');
   var inValidElements = 0;

   for (var i = 0; i<inputs.length;i++){

     if(inputs[i].attributes.valid !== undefined && inputs[i].attributes.valid !== ""){
         inValidElements++;
     }
   }

     console.log(inValidElements); // Here we can handle those invalidElements
    };

validate() will look up all <input> elements on the page and set a default number of invalid elements of zero. Then, it will take each of those elements, check whether or not it has an attribute of valid and if so, increment the invalidElements counter. At this point, further handling of those elements would be possible.

Conclusion

Would you appreciate this approach of validating a pseudo-form?

\$\endgroup\$
2
\$\begingroup\$

While your code works, I would have structured it differently. I would suggest reading this question on StackOverflow.

In your position, I'd have written a directive to place on the outer container that holds all of the inputs, and I would have made your validate function a part of the directive itself. By doing this, you might be able to avoid looking for elements that have a specific class set; you could simply use the values of the datamodel to determine that. I would probably use an object to hold key/value pairs, and use the input ID as the key (with the validity value as the object).

I don't have sample code at the moment (and it seems that, for this site, sample code is essential to a good answer) but I'll try to mock something up tomorrow, perhaps.

\$\endgroup\$
  • \$\begingroup\$ Thank you very much so far, i will try to implement your concept. Nevertheless, i would appreciate a sample, as you suggested. \$\endgroup\$ – Wottensprels Jul 6 '13 at 8:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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