var app = angular.module('snc', []);
app.controller('contactForm', function($scope, $http) {
$scope.user = {};
$scope.submitForm = function() {
$http({
method: 'POST',
url: 'php-form/form.php',
data: $scope.user,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.success(function(data) {
console.log(data);
if (!data.success) {
if ($scope.errorName = data.errors.name) {
$(".alert-set").removeClass('alert-danger');
$(".alert-set").removeClass('alert-success');
$(".alert-set").fadeIn(1000);
$(".alert-set").removeClass("hide");
$(".alert-set").fadeOut(5000);
$(".alert-set").addClass('alert-warning');
$(".Message-txt").text(data.errors.name);
} else if ($scope.errorMobile = data.errors.mobile) {
$(".alert-set").removeClass('alert-danger');
$(".alert-set").removeClass('alert-success');
$(".alert-set").fadeIn(1000);
$(".alert-set").removeClass("hide");
$(".alert-set").fadeOut(5000);
$(".alert-set").addClass('alert-warning');
$(".Message-txt").text(data.errors.mobile);
} else if (data.errors.email == 'fail') {
$(".alert-set").removeClass('alert-danger');
$(".alert-set").removeClass('alert-success');
$(".alert-set").fadeIn(1000);
$(".alert-set").removeClass("hide");
$(".alert-set").fadeOut(5000);
$(".alert-set").addClass('alert-warning');
$(".Message-txt").text('Sorry, Failed to send E-mail.');
} else {
$(".alert-set").removeClass('alert-warning');
$(".alert-set").removeClass('alert-success');
$(".alert-set").fadeIn(1000);
$(".alert-set").removeClass("hide");
$(".alert-set").fadeOut(5000);
$(".alert-set").addClass('alert-dnager');
$(".Message-txt").text('somthing went wrong please try again.');
}
} else {
$(".alert-set").removeClass('alert-danger');
$(".alert-set").removeClass('alert-warning');
$(".alert-set").fadeIn(1000);
$(".alert-set").removeClass("hide");
$(".alert-set").fadeOut(5000);
$(".alert-set").addClass('alert-success');
$(".Message-txt").text(data.message);
this.submitForm = {};
}
});
};
});
<form name="queryForm" ng-submit="submitForm()" novalidate>
<div class="form-group">
<label for="Name">Name:<span class="text-danger">*</span></label>
<input type="text" class="form-control" ng-model="user.name" id="name" placeholder="Enter Your Name">
</div>
<div class="form-group">
<label for="Mobile">Mobile:<span class="text-danger">*</span></label>
<input type="number" class="form-control" ng-model="user.mobile" id="mobile" placeholder="Enter Your Mobile Number">
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" class="form-control" ng-model="user.email" id="email" placeholder="Enter Your Email">
</div>
<div class="form-group">
<label for="Message">Message:</label>
<textarea type="text" class="form-control" ng-model="user.message" id="name" placeholder="Enter Your Message" rows="4"></textarea>
</div>
<button type="submit" class="btn btn-snc">Submit</button>
<div class="alert alert-dismissible alert-set">
<strong class='Message-txt'></strong>
</div>
</form>
I have a simple contact form it has to send query data to php page and I want to disable button and change button text after submitting form and also full form reset after submit. I tried but I always get some type of angular error. Can you help me to solve it and if you are a Angular Developer then can you please check this form and let me know if I need to change something.
To reset the form, you could use something like:
(Mind: you've got two name ID. An ID should be UNIQ on your page).
function onSubmit()
{
$('#submit_button').text('Loading…');
resetForm();
}
function resetForm()
{
for(let id of ['name','mobile','email', 'message'])
{
$("#"+id).val('');
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form name="queryForm" ng-submit="submitForm()" novalidate>
<div class="form-group">
<label for="Name">Name:<span class="text-danger">*</span></label>
<input type="text" class="form-control" ng-model="user.name" id="name" placeholder="Enter Your Name">
</div>
<div class="form-group">
<label for="Mobile">Mobile:<span class="text-danger">*</span></label>
<input type="number" class="form-control" ng-model="user.mobile" id="mobile" placeholder="Enter Your Mobile Number">
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" class="form-control" ng-model="user.email" id="email" placeholder="Enter Your Email" value="some text">
</div>
<div class="form-group">
<label for="Message">Message:</label>
<textarea type="text" class="form-control" ng-model="user.message" id="message" placeholder="Enter Your Message" rows="4">Some text</textarea>
</div>
<button id="submit_button" type="button" class="btn btn-snc" onclick="onSubmit()">RESET FORM</button>
<div class="alert alert-dismissible alert-set">
<strong class='Message-txt'></strong>
</div>
</form>
An assignation is not a comparison:
$scope.errorName = data.errors.name ;
… is an assignation which means: put the data.errors.name into the $scope.errorName variable.
$scope.errorName == data.errors.name
… is a comparison which means: data.errors.name is equal to $scope.errorName.
If you use an assignation instead of a comparison, the result will always be true as long as the value is true-like.
So:
if ( a = 1 ) { /* always true */ }
if ( a == 1 ) { /* true only if `a` is equal to 1 */
if ( a === 1 ) { /* true only if `a` is strictly equal to 1 */
if ( a = "false" ) { /* always true (a string not empty is true) */ }
if ( a == "false" ) { /* true only if `a` is equal to "false" */
if ( a === "false" ) { /* true only if `a` is strictly equal to "false" */
The strictly above means of the same type. For instance:
1 == "1" // => true
1 === "1" // => not true. The Former is a Number, the latter is
// a String.
You should avoid the typo like:
$(".alert-set").addClass('alert-dnager');
To avoid it, try to keep your code as clean as possible. You'll be able to avoid a lot of errors, you'll have a better understanding of your code, and other people can help you more efficiency.
Your if error statement could become:
.success(function(data) {
console.log(data);
if ( false === data.success) {
// Typo error avoiding: NOT plain-text USE variables
let alertClass = '.alert-set';
let errMessage = '' ;
// Reduce the amount of code
$(alertClass)
.addClass('alert-warning')
.removeClass('alert-success')
.fadeIn(1000)
.removeClass("hide")
.fadeOut(5000)
.removeClass('alert-danger') ;
// Treat only what you have to treat
// You could use a lambda function, too:
// let errMessage = function(val){ return ... }(actual value);
if ( $scope.errorName == data.errors.name )
{
errMessage = data.errors.name ;
}
else if ( $scope.errorMobile == data.errors.mobile )
{
errMessage = data.errors.mobile ;
}
else if (data.errors.email == 'fail')
{
errMessage = 'Sorry, Failed to send E-mail.';
}
else {
errMessage = 'somthing went wrong please try again.' ;
}
// Only one action
$(".Message-txt").text(errMessage) ;
Now we can work ;-).
Keep in mind that we don't want to help you if your code is not clean and if we can't understand at a first glance what's going on.
I'm developing a small AngularJs and ASP.net MVC based web application with MongoDb database. And one of it's task is to register yourself if not an already a member. And after successfully submitting data from client side to the server, the user should be redirected to another page.So Data get saved in the database after the submission but It's does not seem to trigger the success function of Angular part where i try to redirect to the other page.
I have attached the image showing non-triggering part of the code highlighting in yellow.
How can i resolve this ? Any help would be appreciated.
[HttpPost]
public JsonResult RegisterUser(User user)
{
mongoClient = new MongoClient();
var db = mongoClient.GetDatabase(Database);
userList = db.GetCollection<User>("user");
var result = userList.AsQueryable().Where(a => a.UserName.Equals(user.UserName)).SingleOrDefault();
user.IsActive = true;
user.UserType = "Visitor";
string message = "";
if (result == null)
{
var seralizedUser = JsonConvert.SerializeObject(userList);
userList.InsertOne(user);
//var seralizedUser = new JavaScriptSerializer().Serialize(userList);
message = "Success";
//return Json(seralizedUser, JsonRequestBehavior.AllowGet);
return Json(new
{
redirectUrl = Url.Action("VisitorChatPanel", "Visitor", ""),
isRedirect = true
});
// return new JsonResult { Data = message, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
else
{
message = "Failed";
//var seralizedUser = new JavaScriptSerializer().Serialize(userList);
var seralizedUser = JsonConvert.SerializeObject(userList);
// return Json(seralizedUser, JsonRequestBehavior.AllowGet);
return Json(new
{
redirectUrl = Url.Action("VisitorChatPanel", "Visitor", ""),
isRedirect = false
});
}
}
angular.module('MyApp', [])
.controller('VisitorRegistrationController', function ($scope, RegistrationService) {
$scope.SubmitText = "Save";
$scope.IsFormValid = false;
$scope.Submitted = false;
$scope.Message = '';
$scope.User = {
UserName: '',
Password: '',
Email: '',
FirstName: '',
LastName: '',
IsActive: false,
UserType: 'Visitor'
};
//validates form on client side
$scope.$watch('f1.$valid', function (newValue) {
$scope.isFormValid = newValue;
});
//Save Data
$scope.SaveData = function (data) {
if ($scope.SubmitText == 'Save') {
$scope.Submitted = true;
$scope.Message = '';
if ($scope.isFormValid) {
// $scope.SubmitText = 'Please Wait...';
$scope.User = data;
alert('data : ' + $scope.User.FirstName);
RegistrationService.SaveFormData($scope.User).then(function (d) {
alert(d);
if (d == 'Success') {
//have to clear form here
ClearForm();
}
$scope.SubmitText = "Save";
});
}
else {
$scope.Message = '';
}
}
}
//Clear Form
function ClearForm() {
$scope.User = {};
$scope.f1.$setPristine(); //here f1 is form name
$scope.Submitted = false;
}
}).factory('RegistrationService', function ($http, $q) {
var fac = {};
fac.SaveFormData = function (data) {
//alert('$http : ' + $http);
var defer = $q.defer();
alert('q : ' + $q);
$http({
url: '/Visitor/RegisterUser',
method: 'POST',
data: JSON.stringify(data),
headers: {'content-type' : 'application/json'}
}).success(function (d) {
// Success callback
alert('Successfully registered !');
if (d.isRedirect) {
window.location.href = d.redirectUrl;
}
defer.resolve(d);
}).error(function (e) {
//Failed Callback
alert('Error!');
// defer.reject(e);
});
return defer.promise;
//return 'Successfull';
}
return fac;
});
;
#{
ViewBag.Title = "VisitorRegistrationForm";
}
<style>
body {
margin-top: 50px;
}
input {
max-width: 300px;
}
.error {
color: red;
}
</style>
<h2>Visitor Registration Form</h2>
<div class="panel panel-info" style="margin-left:30px;margin-right:500px;">
<div ng-controller="VisitorRegistrationController" class="panel-body">
<form novalidate name="f1" ng-submit="SaveData(User)" class="form-horizontal">
<div class="form-group">
<label class="text text-info col-md-offset-2">First Name : </label>
<input type="text" ng-model="User.FirstName" class="form-control col-md-offset-2" name="uFirstName" ng-class="Submitted?'ng-dirty':''" required autofocus />
<span class="error col-md-offset-2" ng-show="(f1.uFirstName.$dirty || Submitted) && f1.uFirstName.$error.required">FirstName required!</span>
</div>
<div class="form-group">
<label class="text text-info col-md-offset-2">Last Name : </label>
<input type="text" ng-model="User.LastName" class="form-control col-md-offset-2" name="uLastName" ng-class="Submitted?'ng-dirty':''" required autofocus />
<span class="error col-md-offset-2" ng-show="(f1.uLastName.$dirty || Submitted) && f1.uLastName.$error.required">LastName required!</span>
</div>
<div class="form-group">
<label class="text text-info col-md-offset-2">Email : </label>
<input type="email" ng-model="User.Email" class="form-control col-md-offset-2" name="uEmail" ng-class="Submitted?'ng-dirty':''" />
<span class="error col-md-offset-2" ng-show="(f1.uEmail.$dirty || Submitted) && f1.uEmail.$error.required">Email required</span>
<span class="error col-md-offset-2" ng-show="(f1.uEmail.$dirty || Submitted) && f1.uEmail.$error.email">Email not valid!</span>
</div>
<div class="form-group">
<label class="text text-info col-md-offset-2">UserName : </label>
<input type="text" ng-model="User.UserName" class="form-control col-md-offset-2" name="uUserName" ng-class="Submitted?'ng-dirty':''" required />
<span class="error col-md-offset-2" ng-show="(f1.uUserName.$dirty || Submitted) && f1.uUserName.$error.required">UserName required!</span>
</div>
<div class="form-group">
<label class="text text-info col-md-offset-2">Password : </label>
<input type="password" ng-model="User.Password" class="form-control col-md-offset-2" name="uPassword" ng-class="Submitted?'ng-dirty':''" required />
<span class="error col-md-offset-2" ng-show="(f1.uPassword.$dirty || Submitted) && f1.uPassword.$error.required">Password required!</span>
</div>
<div class="form-group">
<label></label>
<input type="submit" class="btn btn-success col-md-offset-2" value="{{SubmitText}}" />
</div>
</form>
</div>
</div>
I have faced with the unclear situation when I try to setValidity() inside my own directive.
It set opposite value than expression when, expression return false, and undefined when returned return true.
So my Angular code:
<script>
var userForm = angular.module("userForm", []);
userForm.directive('isEquals', function () {
return {
// element must have ng-model attribute.
require: 'ngModel',
scope: {
otherFieldValue: "=isEquals"
},
link: function (scope, elem, attr, ctrl) {
ctrl.$validators.isEquals = function (modelValue) {
console.log("otherFieldValue: " + scope.otherFieldValue);
console.log("modelValue: " + modelValue);
valid = (modelValue === scope.otherFieldValue);
ctrl.$setValidity('isEquals', valid);
console.log("valid: " + valid);
//Q1: is it in fact userForm.confirmPassword.$error.isEquals?
console.log("isEquals: " + ctrl.$error.isEquals);
console.log("modelValue: " + modelValue);
console.log("");
return modelValue;
};
scope.$watch("otherFieldValue", function () {
ctrl.$validate();
});
}
};
});
userForm.controller("userFormController", function ($scope, $http) {
});
</script>
and my html code:
<div ng-app="userForm">
<form name="userForm" modelAttribute="userForm" ng-controller="userFormController" ng-submit="createUser()" novalidate>
<div class="row">
<input id="password" name="password" path="password" type="password" placeholder="Password" minlength="5" maxlength="60" ng-model="user.password" required/>
<br>
<span ng-show="userForm.password.$dirty && userForm.password.$error.required">Password field is required.<br></span>
<span ng-show="userForm.password.$dirty && userForm.password.$error.minlength || userForm.password.$error.maxlength">Password field must have size from 5 to 60 symbols.<br></span>
</div>
<div class="row">
<input id="confirmPassword" name="confirmPassword" path="confirmPassword" type="password" placeholder="Confirm Password" minlength="5" maxlength="60" ng-model="user.confirmPassword" equals-to="user.password" required/>
<br>
<span ng-show="userForm.confirmPassword.$dirty && userForm.confirmPassword.$error.required">Confirm Password field is required.<br></span>
<span ng-show="userForm.confirmPassword.$dirty && userForm.confirmPassword.$error.minlength || userForm.confirmPassword.$error.maxlength">Confirm Password field must have size from 5 to 60 symbols.<br></span>
<span id="m1" ng-show="userForm.confirmPassword.$dirty && !userForm.confirmPassword.$error.equalsTo">Passwords are not same.<br></span>
</div>
<div class="row">
<input id="submit" type="submit" ng-submit="createUser()" value="Sign Up"/>
</div>
</form>
</div>
But when I enter passwords i have the next situations (I will sign "Passwords are not same." AS m1) :
//1) valid!=equalsTo, m1 visible. Have to be valid===equalsTo===false, m1 visible.
otherFieldValue: teste
modelValue: undefined
valid: false
equalsTo: true
modelValue: undefined
//2) valid!=equalsTo, equalsTo undefined. Have to be valid===equalsTo===true. m1 still visible, but has not to be.
otherFieldValue: teste
modelValue: teste
valid: true
equalsTo: undefined
modelValue: teste
I will appreciate any help, propositions, link and especially explanations. Thanks in advance.
EDIT: OK. Accidentally, I figured out that it is because the directive's name and ctrl.$validators.isEquals have the same names. What is the problem with that, can someone explain?
Here I created sample file for validation, which is working fine...
But My requirement is I need to do some modification on that while validating. Error message need to show in auto tooltip. It needs to be shown automatically when there is error and hide automatically once error cleared. Until error clear popup need to be stay.
If it is possible without jquery or else with jquery also fine.
var app = angular.module('myapp', ['UserValidation']);
myappCtrl = function($scope) {
$scope.formAllGood = function () {
return ($scope.usernameGood && $scope.passwordGood && $scope.passwordCGood)
}
}
angular.module('UserValidation', []).directive('validUsername', function () {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function (viewValue) {
// Any way to read the results of a "required" angular validator here?
var isBlank = viewValue === ''
var invalidChars = !isBlank && !/^[A-z0-9]+$/.test(viewValue)
var invalidLen = !isBlank && !invalidChars && (viewValue.length < 5 || viewValue.length > 20)
ctrl.$setValidity('isBlank', !isBlank)
ctrl.$setValidity('invalidChars', !invalidChars)
ctrl.$setValidity('invalidLen', !invalidLen)
scope.usernameGood = !isBlank && !invalidChars && !invalidLen
})
}
}
}).directive('validPassword', function () {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function (viewValue) {
var isBlank = viewValue === ''
var invalidLen = !isBlank && (viewValue.length < 8 || viewValue.length > 20)
var isWeak = !isBlank && !invalidLen && !/(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z])/.test(viewValue)
ctrl.$setValidity('isBlank', !isBlank)
ctrl.$setValidity('isWeak', !isWeak)
ctrl.$setValidity('invalidLen', !invalidLen)
scope.passwordGood = !isBlank && !isWeak && !invalidLen
})
}
}
}).directive('validPasswordC', function () {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function (viewValue, $scope) {
var isBlank = viewValue === ''
var noMatch = viewValue != scope.myform.password.$viewValue
ctrl.$setValidity('isBlank', !isBlank)
ctrl.$setValidity('noMatch', !noMatch)
scope.passwordCGood = !isBlank && !noMatch
})
}
}
})
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.2/css/bootstrap-combined.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myapp">
<form name="myform" class="form form-horizontal" ng-controller="myappCtrl" novalidate>
<legend>Angular User Validation with Bootstrap Decorations</legend>
<div class="control-group" ng-class="{error:!myform.username.$valid}">
<label for="inputUsername" class="control-label">Username:</label>
<div class="controls">
<input type="text" id="inputUsername" name="username" ng-model="username" valid-username />
<div class="help-inline">
<span ng-show="!!myform.username.$error.isBlank">Username Required.</span>
<span ng-show="!!myform.username.$error.invalidChars">Username must contain letters & spaces only.</span>
<span ng-show="!!myform.username.$error.invalidLen">Username must be 5-20 characters.</span>
</div>
</div>
</div>
<div class="control-group" ng-class="{error:!myform.password.$valid}">
<label for="inputPassword" class="control-label">Password:</label>
<div class="controls">
<input type="text" id="inputPassword" name="password" ng-model="password" valid-password />
<div class="help-inline">
<span ng-show="!!myform.password.$error.isBlank">Password Required.</span>
<span ng-show="!!myform.password.$error.isWeak">Must contain one upper & lower case letter and a non-letter (number or symbol.)</span>
<span ng-show="!!myform.password.$error.invalidLen">Must be 8-20 characters.</span>
</div>
</div>
</div>
<div class="control-group" ng-class="{error:!myform.password_c.$valid}">
<label for="password_c" class="control-label">Confirm Password:</label>
<div class="controls">
<input type="text" id="password_c" name="password_c" ng-model="password_c" valid-password-c />
<div class="help-inline">
<span ng-show="!!myform.password_c.$error.isBlank">Confirmation Required.</span>
<span ng-show="!!myform.password_c.$error.noMatch">Passwords don't match.</span>
</div>
</div>
</div>
<div class="form-actions" ng-show="formAllGood()">
<input type="submit" class="btn btn-primary" value="Submit" />
</div>
</form></div>
Yes it is possible to show/hide popover on any event. Following code depicts a validate function for numbers using popover.
JSFiddle.
function validate(el) {
var regex = /^\d+$/g;
var valid = regex.test(el.value);
if (!valid) {
// Check if popover is already visible to handle flicker effect.
if ($("#txtInput").next('div.popover').length == 0) {
$('#txtInput').popover({
placement: 'bottom',
content: 'This is not a valid entry'
}).popover('show');
}
} else {
$('#txtInput').popover('hide');
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<input type="text" id="txtInput" onkeyup="validate(this)">
References:
Check visibility
Documentation.
Best solution is to use Parsley.js
Why Parsley :
Validation Event can be customized (onsubmit , onkeyup , or any other event )
Validation Style can be customized
Validation message will automatically disappear , once input satisfies conditions
Check their examples
I have a form which need to show validation error messages if clicked submit.
Here is a working plunker
<form name="frmRegister" ng-submit="register();" novalidate>
<div>
<input placeholder="First Name" name="first_name" type="text" ng-model="user.firstName" required />
<span ng-show="frmRegister.first_name.$dirty && frmRegister.first_name.$error.required">First Name is required</span>
</div>
<div>
<input placeholder="Last Name" name="last_name" type="text" ng-model="user.lastName" required />
<span ng-show="frmRegister.last_name.$dirty && frmRegister.last_name.$error.required">Last Name is required</span>
</div>
<div>
<input placeholder="Email" name="email" type="email" ng-model="user.email" required />
<span ng-show="frmRegister.email.$dirty && frmRegister.email.$error.required">Email is required.</span>
<span ng-show="frmRegister.email.$dirty && frmRegister.email.$error.email">Invalid Email address.</span>
</div>
<input type="submit" value="Save" />
<span ng-show="registered">YOU ARE NOW REGISTERED USER</span>
</form>
Validation works normally when user start making changes. But it doesn't show any error messages If clicked submit without entering anything.
Any thought of achieving this?. Or in other way how can I make each input field $dirty when clicks the Submit button
I found this fiddle http://jsfiddle.net/thomporter/ANxmv/2/ which does a nifty trick to cause control validation.
Basically it declares a scope member submitted and sets it true when you click submit. The model error binding use this extra expression to show the error message like
submitted && form.email.$error.required
UPDATE
As pointed out in #Hafez's comment (give him some upvotes!), the Angular 1.3+ solution is simply:
form.$submitted && form.email.$error.required
Since I'm using Bootstrap 3, I use a directive:
(see plunkr)
var ValidSubmit = ['$parse', function ($parse) {
return {
compile: function compile(tElement, tAttrs, transclude) {
return {
post: function postLink(scope, element, iAttrs, controller) {
var form = element.controller('form');
form.$submitted = false;
var fn = $parse(iAttrs.validSubmit);
element.on('submit', function(event) {
scope.$apply(function() {
element.addClass('ng-submitted');
form.$submitted = true;
if(form.$valid) {
fn(scope, {$event:event});
}
});
});
scope.$watch(function() { return form.$valid}, function(isValid) {
if(form.$submitted == false) return;
if(isValid) {
element.removeClass('has-error').addClass('has-success');
} else {
element.removeClass('has-success');
element.addClass('has-error');
}
});
}
}
}
}
}]
app.directive('validSubmit', ValidSubmit);
and then in my HTML:
<form class="form-horizontal" role="form" name="form" novalidate valid-submit="connect()">
<div class="form-group">
<div class="input-group col col-sm-11 col-sm-offset-1">
<span class="input-group-addon input-large"><i class="glyphicon glyphicon-envelope"></i></span>
<input class="input-large form-control" type="email" id="email" placeholder="Email" name="email" ng-model="email" required="required">
</div>
<p class="col-sm-offset-3 help-block error" ng-show="form.$submitted && form.email.$error.required">please enter your email</p>
<p class="col-sm-offset-3 help-block error" ng-show="form.$submitted && form.email.$error.email">please enter a valid email</p>
</div>
</form>
UPDATED
In my latest project, I use Ionic so I have the following, which automatically puts .valid or .invalid on the input-item's:
.directive('input', ['$timeout', function ($timeout) {
function findParent(element, selector) {
selector = selector || 'item';
var parent = element.parent();
while (parent && parent.length) {
parent = angular.element(parent);
if (parent.hasClass(selector)) {
break;
}
parent = parent && parent.parent && parent.parent();
}
return parent;
}
return {
restrict: 'E',
require: ['?^ngModel', '^form'],
priority: 1,
link: function (scope, element, attrs, ctrls) {
var ngModelCtrl = ctrls[0];
var form = ctrls[1];
if (!ngModelCtrl || form.$name !== 'form' || attrs.type === 'radio' || attrs.type === 'checkbox') {
return;
}
function setValidClass() {
var parent = findParent(element);
if (parent && parent.toggleClass) {
parent.addClass('validated');
parent.toggleClass('valid', ngModelCtrl.$valid && (ngModelCtrl.$dirty || form.$submitted));
parent.toggleClass('invalid', ngModelCtrl.$invalid && (ngModelCtrl.$dirty || form.$submitted));
$timeout(angular.noop);
}
}
scope.$watch(function () {
return form.$submitted;
}, function (b, a) {
setValidClass();
});
var before = void 0;
var update = function () {
before = element.val().trim();
ngModelCtrl.$setViewValue(before);
ngModelCtrl.$render();
setValidClass();
};
element
.on('focus', function (e) {
if (ngModelCtrl.$pristine) {
element.removeClass('$blurred');
}
})
.on('blur', function (e) {
if (ngModelCtrl.$dirty) {
setValidClass();
element.addClass('$blurred');
}
}).on('change', function (e) {
if (form.$submitted || element.hasClass('$blurred')) {
setValidClass();
}
}).on('paste', function (e) {
if (form.$submitted || element.hasClass('$blurred')) {
setValidClass();
}
})
;
}
};
}])
and then in the HTML:
<form name='form' novalidate="novalidate" ng-submit="auth.signin(form, vm)">
<label class="item item-input item-floating-label">
<span class="input-label">Email</span>
<input type="email" placeholder="Email" ng-model="vm.email" autofocus="true" required
>
</label>
<button ng-if="!posting" type="submit" class="item button-block item-balanced item-icon-right call-to-action">Login<i class="icon ion-chevron-right"></i>
</button>
and in the controller:
self.signin = function (form, data) {
if (!form.$valid) return;
Authentication.emailLogin(data)
//...
so, now, in the CSS, you can do stuff like:
.item.valid::before{
float: right;
font-family: "Ionicons";
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
text-rendering: auto;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #66cc33;
margin-right: 8px;
font-size: 24px;
content: "\f122";
}
.item.invalid::before{
float: right;
font-family: "Ionicons";
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
text-rendering: auto;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #ef4e3a;
margin-right: 8px;
font-size: 24px;
content: "\f12a";
/*
border-left: solid 2px #ef4e3a !important;
border-right: solid 2px #ef4e3a !important;
*/
}
MUCH SIMPLER!
I also had the same issue, I solved the problem by adding a ng-submit which sets the variable submitted to true.
<form name="form" ng-submit="submitted = true" novalidate>
<div>
<span ng-if="submitted && form.email.$error.email">invalid email address</span>
<span ng-if="submitted && form.email.$error.required">required</span>
<label>email</label>
<input type="email" name="email" ng-model="user.email" required>
</div>
<div>
<span ng-if="submitted && form.name.$error.required">required</span>
<label>name</label>
<input type="text" name="name" ng-model="user.name" required>
</div>
<button ng-click="form.$valid && save(user)">Save</button>
</form>
I like the idea of using $submitted, I think I've to upgrade Angular to 1.3 ;)
I can come up with 2 ways to achieve it.
The first one is to remove novalidate to enable the browser's validation.
Second, you can disable the save button when the form is not valid like this
<input ng-disabled="!frmRegister.$valid" type="submit" value="Save" />
Hope it helps.
There are two simple & elegant ways to do it.
Pure CSS:
After first form submission, despite the form validity, Angular will add a ng-submitted class to all form elements inside the form just submitted.
We can use .ng-submitted to controller our element via CSS.
if you want to display an error text only when user have submitted e.g.
.error { display: none }
.ng-submitted .error {
display: block;
}
Using a value from Scope:
After first form submission, despite the form validity, Angular will set [your form name].$submitted to true. Thus, we can use that value to control elements.
<div ng-show="yourFormName.$submitted">error message</div>
<form name="yourFormName"></form>
My solution with bootstrap 3
http://jsfiddle.net/rimian/epxrbzn9/
<form class="form" name="form" ng-app novalidate>
<div class="form-group">
<input name="first_name"
type="text"
class="form-control"
ng-model="first_name"
placeholder="First Name"
required />
</div>
<div class="form-group">
<input name="last_name"
type="text"
class="form-control"
ng-model="last_name"
placeholder="Last Name"
required />
</div>
<button
type="submit"
class="btn btn-primary btn-large"
ng-click="submitted=true">
Submit
</button>
<div ng-show="submitted && form.$invalid" class="alert alert-danger">
<div ng-show="form.first_name.$error.required">
First Name is Required
</div>
<div ng-show="form.last_name.$error.required">
Last Name is Required
</div>
</div>
</form>
You only need to check if the form is dirty and valid before submitting it. Checkout the following code.
<form name="frmRegister" data-ng-submit="frmRegister.$valid && frmRegister.$dirty ? register() : return false;" novalidate>
And also you can disable your submit button with the following change:
<input type="submit" value="Save" data-ng-disable="frmRegister.$invalid || !frmRegister.$dirty" />
This should help for your initial
http://jsfiddle.net/LRD5x/30/ A simple solution.
HTML
<form ng-submit="sendForm($event)" ng-class={submitted:submitted}>
JS
$scope.sendForm = function($event) {
$event.preventDefault()
$scope.submitted = true
};
CSS
.submitted input.ng-invalid:not(:focus) {
background-color: #FA787E;
}
input.ng-invalid ~ .alert{
display:none;
}
.submitted input.ng-invalid ~ .alert{
display:block;
}
I like the solution from realcrowd the best.
HTML:
<form role="form" id="form" name="form" autocomplete="off" novalidate rc-submit="signup()">
<div class="form-group" ng-class="{'has-error': rc.form.hasError(form.firstName)}">
<label for="firstName">Your First Name</label>
<input type="text" id="firstName" name="firstName" class="form-control input-sm" placeholder="First Name" ng-maxlength="40" required="required" ng-model="owner.name.first"/>
<div class="help-block" ng-show="rc.form.hasError(form.firstName)">{{rc.form.getErrMsg(form.firstName)}}</div>
</div>
</form>
javascript:
//define custom submit directive
var rcSubmitDirective = {
'rcSubmit': ['$parse', function ($parse) {
return {
restrict: 'A',
require: ['rcSubmit', '?form'],
controller: ['$scope', function ($scope) {
this.attempted = false;
var formController = null;
this.setAttempted = function() {
this.attempted = true;
};
this.setFormController = function(controller) {
formController = controller;
};
this.hasError = function (fieldModelController) {
if (!formController) return false;
if (fieldModelController) {
return fieldModelController.$invalid && this.attempted;
} else {
return formController && formController.$invalid && this.attempted;
}
};
this.getErrMsg=function(ctrl){
var e=ctrl.$error;
var errMsg;
if (e.required){
errMsg='Please enter a value';
}
return errMsg;
}
}],
compile: function(cElement, cAttributes, transclude) {
return {
pre: function(scope, formElement, attributes, controllers) {
var submitController = controllers[0];
var formController = (controllers.length > 1) ? controllers[1] : null;
submitController.setFormController(formController);
scope.rc = scope.rc || {};
scope.rc[attributes.name] = submitController;
},
post: function(scope, formElement, attributes, controllers) {
var submitController = controllers[0];
var formController = (controllers.length > 1) ? controllers[1] : null;
var fn = $parse(attributes.rcSubmit);
formElement.bind('submit', function (event) {
submitController.setAttempted();
if (!scope.$$phase) scope.$apply();
if (!formController.$valid) return false;
scope.$apply(function() {
fn(scope, {$event:event});
});
});
}
};
}
};
}]
};
app.directive(rcSubmitDirective);
A complete solution to the validate form with angularjs.
HTML is as follows.
<div ng-app="areaApp" ng-controller="addCtrler">
<form class="form-horizontal" name="fareainfo">
<div class="form-group">
<label for="input-areaname" class="col-sm-2 control-label">Area Name : </label>
<div class="col-sm-4">
<input type="text" class="form-control" name="name" id="input-areaname" ng-model="Area.Name" placeholder="" required>
<span class="text-danger" ng-show="(fareainfo.$submitted || fareainfo.name.$dirty) && fareainfo.name.$error.required"> Field is required</span>
</div>
</div>
<div class="col-sm-12">
<button type="button" class="btn btn-primary pull-right" ng-click="submitAreaInfo()">Submit</button>
</div>
</form>
</div>
AngularJS App and Controller is as follows
var areaApp = angular.module('areaApp', []);
areaApp.controller('addCtrler', function ($scope) {
$scope.submitAreaInfo = function () {
if ($scope.fareainfo.$valid) {
//after Form is Valid
} else {
$scope.fareainfo.$setSubmitted();
}
};
});
Important Code Segments
ng-app="areaApp" ng-controller="addCtrler"
Defines the angular app and controller
ng-show="(fareainfo.$submitted || fareainfo.name.$dirty) && fareainfo.name.$error.required"
Above condition ensure that whenever a user first sees the form there's no any validation error on the screen and after a user does changes to the form it ensure that validation message show on the screen. .name. is the name attribute of the input element.
$scope.fareainfo.$valid
Above code, segment check whether the form is valid whenever a user submits the form.
$scope.fareainfo.$setSubmitted();
Above code, segment ensures that all validation messages are displayed on the screen whenever a user submits the form without doing anything.
// This worked for me.
<form name="myForm" class="css-form" novalidate ng-submit="Save(myForm.$invalid)">
<input type="text" name="uName" ng-model="User.Name" required/>
<span ng-show="User.submitted && myForm.uName.$error.required">Name is required.</span>
<input ng-click="User.submitted=true" ng-disabled="User.submitted && tForm.$invalid" type="submit" value="Save" />
</form>
// in controller
$scope.Save(invalid)
{
if(invalid) return;
// save form
}
G45,
I faced same issue , i have created one directive , please check below hope it may be helpful
Directive :
app.directive('formSubmitValidation', function () {
return {
require: 'form',
compile: function (tElem, tAttr) {
tElem.data('augmented', true);
return function (scope, elem, attr, form) {
elem.on('submit', function ($event) {
scope.$broadcast('form:submit', form);
if (!form.$valid) {
$event.preventDefault();
}
scope.$apply(function () {
scope.submitted = true;
});
});
}
}
};
})
HTML :
<form name="loginForm" class="c-form-login" action="" method="POST" novalidate="novalidate" form-submit-validation="">
<div class="form-group">
<input type="email" class="form-control c-square c-theme input-lg" placeholder="Email" ng-model="_username" name="_username" required>
<span class="glyphicon glyphicon-user form-control-feedback c-font-grey"></span>
<span ng-show="submitted || loginForm._username.$dirty && loginForm._username.$invalid">
<span ng-show="loginForm._username.$invalid" class="error">Please enter a valid email.</span>
</span>
</div>
<button type="submit" class="pull-right btn btn-lg c-theme-btn c-btn-square c-btn-uppercase c-btn-bold">Login</button>
</form>
Try this code:
<INPUT TYPE="submit" VALUE="Save" onClick="validateTester()">
This funvtion will validate your result
function validateTester() {
var flag = true
var Tester = document.forms.Tester
if (Tester.line1.value!="JavaScript") {
alert("First box must say 'JavaScript'!")
flag = false
}
if (Tester.line2.value!="Kit") {
alert("Second box must say 'Kit'!")
flag = false
}
if (flag) {
alert("Form is valid! Submitting form...")
document.forms.Tester.submit()
}
}