AngularJS - Form Validation

FormController, ng-show, ng-if, ng-model, ng-messages

HTML

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-messages.min.js"></script>
<h2>My AngularJS Form</h2>

<div ng-app="myApp">
  <form id="myForm" name="myForm" novalidate ng-controller="FormController" ng-submit="submitForm()">
  
    <div >
      <label for="firstName">First Name:</label>
      <input id="firstName" name="firstName" type="text" placeholder="First Name" ng-model="newUser.firstName" required />
      <span class="error-message" ng-show="showMessage(myForm.firstName)">Please complete this field.</span>
    </div>
   
    
    <div class="form-group">
    <button id="submitForm" name="submitForm" type="submit" class="btn btn-primary">Submit</button>
    </div>
  </form>
</div>

CSS

h2 {
  text-align: center;
}

form {
  border: 1px solid #ddd;
  margin: 0 auto;
  padding: 1em;
  width: 70vw;
}

input.ng-dirty.ng-invalid,
input.ng-invalid.ng-touched {
  border: 1px solid red;
}

.error-message {
  color: red;
  display: block;
}


/* Custom checkboxes
 * http://code.stephenmorley.org/html-and-css/styling-checkboxes-and-radio-buttons/#pureCSS
 */

.custom-checkbox input[type=checkbox] {
  width: 2em;
  margin: 0;
  padding: 0;
  font-size: 1em;
  opacity: 0;
}

.custom-checkbox input[type=checkbox] + label {
  display: inline-block;
  margin-left: -2em;
  line-height: 1.5em;
}

.custom-checkbox input[type=checkbox] + label > span {
  display: inline-block;
  width: 0.875em;
  height: 0.875em;
  margin: 0.25em 0.5em 0.25em 0.25em;
  border: 0.0625em solid rgb(192, 192, 192);
  border-radius: 0.25em;
  background: rgb(224, 224, 224);
  background-image: -moz-linear-gradient(rgb(240, 240, 240), rgb(224, 224, 224));
  background-image: -ms-linear-gradient(rgb(240, 240, 240), rgb(224, 224, 224));
  background-image: -o-linear-gradient(rgb(240, 240, 240), rgb(224, 224, 224));
  background-image: -webkit-linear-gradient(rgb(240, 240, 240), rgb(224, 224, 224));
  background-image: linear-gradient(rgb(240, 240, 240), rgb(224, 224, 224));
  vertical-align: bottom;
}

.custom-checkbox input[type=checkbox].ng-invalid.ng-dirty + label > span {
  border-color: red;
}

.custom-checkbox input[type=checkbox]:checked + label > span {
  background-image: -moz-linear-gradient(rgb(224, 224, 224), rgb(240, 240, 240));
  background-image: -ms-linear-gradient(rgb(224, 224, 224), rgb(240, 240, 240));
  background-image: -o-linear-gradient(rgb(224, 224, 224), rgb(240, 240, 240));
  background-image: -webkit-linear-gradient(rgb(224, 224, 224), rgb(240, 240, 240));
  background-image: linear-gradient(rgb(224, 224, 224), rgb(240, 240, 240));
  border: 0;
}

.custom-checkbox input[type=checkbox]:checked + label > span:before {
  content: '✓';
  display: block;
  width:...

JavaScript

var app = angular.module("myApp", ["ngMessages"]);
app.controller("FormController", ["$scope", function($scope) {
  $scope.newUser = {
    firstName: '',
    lastName: '',
    userEmail: '',
    acceptConds: false,
    subscribeNews: false
  };
  $scope.submitForm = function() {
    angular.forEach($scope.myForm.$error.required, function(field) {
      field.$setDirty();
    });
    
    if (!$scope.myForm.$valid) 
    {
     alert('sss2');
        $event.preventDefault();
       return;
   }
   
    alert('sss');
     return;
  };
  $scope.regularClick = function() {
    alert("OJO: Valida pero no hace Submit!");
  };
  $scope.showMessage = function(input) {
    var show = input.$invalid && (input.$dirty || input.$touched);
    return show;
  };
}]);