Validate Input fields only on submit angularjs - angularjs

I am trying to show a Validation Summary, a Div on top of the page with all the Validation error messages in angularjs, on form submit.
I am using the below logic to show/ hide the top div with validation messages,
<div class="alert alert-error" ng-show="submitted && myForm.$invalid">
</div>
I am setting the variable submitted to true on save button click. It's working Okay the first time, but after the first submission, if enter the value for the input field(required field) and clear it, it's kicking off the validation(the top div shows).
Is there a way to show the validation div, only on the submit of the form and not when the user clears the input field ?
UPDATE
$scope.save = function (myForm) {
$scope.submitted = true;
if (myForm.$invalid) {
return;
}
$scope.submitted = false;
}
Thanks !

Hmm one way to do it would be to watch the FormController's property $dirty and $setPristine() method, and use a variable hasError to show the error or not.
See this plunker as an example
JAVASCRIPT
controller('AppController', ['$scope', function($scope) {
$scope.hasError = false;
$scope.$watch('theForm.$dirty', function() {
$scope.hasError = false;
$scope.theForm.$setPristine();
});
$scope.save = function() {
$scope.hasError = $scope.theForm.$invalid;
if($scope.hasError) {
// perform error routine
} else {
// perform save routine
}
};
}]);
HTML
<body ng-controller="AppController">
<div class="error" ng-show="hasError">This is an error</div>
<form name="theForm" ng-submit="save()" novalidate>
<input type="text" name="text1" ng-model="text1" required>
<input type="text" name="text2" ng-model="text2" required>
<button type="submit">Submit</button>
</form>
</body>

Make sure you are setting submitted to false upon display of your validation div else it'll show up after each additional validation call.
$scope.save = function (myForm) {
$scope.submitted = true;
if (myForm.$invalid) {
$scope.submitted = false;
return;
}
}

Related

onclick button get the value of selected (checkbox) value

<div class="chks" ng-repeat="request in pendingRequest">
<input type="checkbox" name="chk" ng-model="pendingRequest" id="chk1" ng-click="pendingUser(request.user_id)">
<label for="chk1">{{request.first_name}} {{request.last_name}}</label>
</div>
<button type="button" ng-click="checkVal()" class="btn btn-default next-step"><span class="next-step">Resend Linking Request</span></button>
var selectUser = '';
$scope.pendingUser = function(user) {
selectUser = user;
}
$scope.checkVal = function() {
if (selectUser) {
alert(selectUser);
} else {
alert("CheckBox is not checked.");
}
}
How can I check on click checkVal button function has user_id.
on bases checkbox click get the user_id in Angularjs.
Use an array to push the value entries from the checkbox.
$scope.nameSelected= [];
Give a single value for the checkbox. I'm assuming that to be the first name.
$scope.getAllSelected = function(){
angular.forEach($scope.first_name,function(key,value){
if(key)
$scope.nameSelected.push(value)
});
console.log($scope.nameSelected)
}
Remove the unwanted ng-click from the checkbox input entry. getAllSelected can be done in the ng-click on the submit button you've there.
<div class="chks" ng-repeat="request in pendingRequest">
<input type="checkbox" name="chk" ng-model="pendingRequest" id="chk1" ng-click="pendingUser(request.user_id)">
<label for="chk1">{{request.first_name}} {{request.last_name}}
</label>
</div>
Why would you ng-repeat over the same model than your checkbox is ? Can you provide a plunker or something.
$scope.checkVal = function(){
if (selectUser) {
alert(selectUser);
} else {
alert("CheckBox is not checked.");
}
}
The selectUser is undefined there, is it supposed to be a single user (and you should pass it in params then), or the whole array pendingRequest ?
If you want to check if each request is selected then you could just bind your checkbox to request.selected and return in the check request.selected
Which would be something like that :
$scope.checkVal = function(){
angular.forEach($scope.pendingRequest, function(request) {
if (request.selected)
alert(request)
else
alert("Not selected")
})
}

Issue which showing the image

What am I trying?
On button clicking showing the progress bar and hiding the button that was clicked.
Problem
Button is not hiding and image is not showing. I inspected the element and I can confirm that the image is given correct url.
My AngularJs Html is below
<form ng-submit="doLogin();" novalidate name='loginForm'>
<input type="text" name="EmailAddress" ng-model="credentials.EmailAddress" required/>
<button type="submit" ng-disabled="loginForm.$invalid" ng-show="{{RegisterShow}}">
Login
</button>
<img ng-src="{{imgProcessingPath}}" ng-show="{{imgProcessingShow}}">
</form>
Controller is below
myApp.controller('LoginController', ['$scope',
function($scope) {
$scope.imgProcessingPath = appUrl + "Images/ajax-loader.gif";
$scope.imgProcessingShow = false;
$scope.RegisterShow = true;
angular.extend($scope, {
doLogin: function() {
$scope.imgProcessingShow = true;
$scope.RegisterShow = false;
var data = {
"EmailAddress": $scope.credentials.EmailAddress
};
userModel.doLogin(data).then(function(response) {
$scope.imgProcessingShow = false;
$scope.RegisterShow = true;
},function(response) {
$scope.imgProcessingShow = false;
$scope.RegisterShow = true;
});
}
});
}
]);
Am I missing anything?
try removing the curly braces for ng-show in html file!
ng-show="RegisterShow"
alternatively you can also use
ng-if="RegisterShow"
ng-show should not have an expression, it acts like model variable,
Change it as,
<button type="submit" ng-disabled="loginForm.$invalid" ng-show="RegisterShow">
also
<img ng-src="{{imgProcessingPath}}" ng-show="imgProcessingShow">
I am posting this as an answer as I don't have the rep to comment.
Remove the brackets inside ng-show.
<img ng-src="{{imgProcessingPath}}" ng-show="imgProcessingShow">

Angular remote form not displaying error

I have created an angular form that displays input validation errors received from the server. My solution works fine except for one small issue.
If I submit the form with no value, after the page loads, I am receiving the correct response from my server i.e. 422, but the validation error is not displayed. If I then start typing a value in the input the validation error flashes and disappears.
I am almost certain that it has something to do with my directive, but I'm not sure how to fix it. This is my current directive code:
var appServices = angular.module('webFrontendApp.directives', []);
appServices.directive('serverError', function(){
return {
restrict: 'A',
require: '?ngModel',
link: function(scope,element,attrs,ctrl){
element.on('change keyup', function(){
scope.$apply(function(){
ctrl.$setValidity('server', true);
});
});
}
};
});
I think the issue is with the element.on('change keyup'.... section of this code. That's why the error message flashes when I start typing. Also when I change this to 'change' instead of 'change keyup', the error message is displayed permanently when I start typing.
Does anybody have an idea of how I can display the error message even if I did not type any value into the input before submitting it the first time?
UPDATE AS PER COMMENT
Here is my form:
<form ng-submit="create(memberData)" name="form" novalidate>
<div class = "row form-group" ng-class = "{ 'has-error' : form.email.$dirty && form.email.$invalid }">
<input type="text" ng-model="memberData.email" placeholder="janedoe#mail.com" name="email" class="col-xs-12 form-control" server-error>
<span class="errors" ng-show="form.email.$dirty && form.email.$invalid">
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
<span ng-show="form.email.$error.server">{{errors.email}}</span>
</span>
</div>
<div class="row">
<button type="submit" class="btn btn-danger col-xs-12">Join Private Beta</button>
</div>
</form>
And my controller:
$scope.memberData = {};
$scope.create = function() {
var error, success;
$scope.errors = {};
success = function() {
$scope.memberData = {};
};
error = function(result) {
angular.forEach(result.data.errors, function(errors, field) {
$scope.form[field].$setValidity('server', false);
$scope.errors[field] = errors.join(', ');
});
};
BetaMember.save({ beta_member: { email: $scope.memberData.email || "" }}).$promise.then(success, error);
};
Since the form itself doesn't have a $setValidity method, because doens't have an ng-model, and assuming that the server error is not referred to a single field ( in this case a $setValidity method is preferred ), I think that the simplest solution could be this one:
Create a form with some random validation ( this one simply needs at least the username ) and a div that can display a custom server error.
<div ng-controller="AppCtrl">
<form novalidate name="createForm">
<div class="inputWrap">
<input ng-model="name" name="name" type="text" required placeholder="John Doe">
<span ng-if="createForm.name.$dirty && createForm.name.$invalid">
Some kind of error!
</span>
</div>
<div ng-if="serverError">
{{ serverError.message }}
</div>
<input
value="Join Private Beta"
ng-disabled="createForm.$invalid || serverError"
ng-click="create()"
type="button">
</form>
</div>
Then in your controller you can add the create method that deal with YourService ( should return a promise ) and if the response is failure you can create a simple object with a custom server error message inside which will also be usefull to disable the form button, if you need.
var AppCtrl = function($scope, YourService){
// Properties
// Shared Properties
// Methods
function initCtrl(){}
// Shared Methods
$scope.create = function(){
YourService.makeCall().then(function(response){
// Success!
// Reset the custom error
$scope.serverError = null;
}, function(error){
// Do your http call and then if there's an error
// create the serverError object with a message
$scope.serverError = {
message : 'Some error message'
};
})
};
// Events
// Init controller
initCtrl();
};
AppCtrl.$inject = [
'$scope',
'YourService'
];
app.controller('AppCtrl', AppCtrl);
I mean it's very simple snippet here, I just wanted to bring an example. Nothing to complex, but you can scale this to something more.
It seems that there was an extremely simple workaround. Since I had the filter form.email.$dirty in my view, the error would not be displayed if the user clicked submit without clicking on the form first.
After removing form.email.$dirty and only having form.email.$invalid, it works perfectly. I think this is sufficient in my case, as this validation is dependant on a server response and will not be triggered before the form is submitted. The error object is also cleared up in my controller ensuring that the page does not load an error when it's first loaded.

ngDisabled validation not working

I'm trying to add a single disabled="disabled" to a button, to block the element while the it is creating a server requests, however, for some reason the documentations information is not working for me, so my case is:
HTML:
<button ng-disabled="isDisable" ng-click="submit()">Submit</button>
JS (into my controller):
$scope.isDisable = false;
$scope.submit = function() {
$scope.isDisable = true;
//$http request....
something.sucess(function(data) {
$scope.isDisable = false;
};
};
for some reason my logic is not working.
Any ideas?
You don't need the {{}} as it's not an expression.
<button ng-disabled="isDisable" ng-click="submit()">Submit</button>
EDIT
If this is a form then on the form tag do ..
<form name="aForm" novalidate ng-submit="submit()">
then submit button
<button type="submit" ng-disabled="isDisable">Submit</button>

$dirty not working as expected when the input type is "file"

Am quite new to AngularJS. The issue is i have a form with two fields- name and profile pic as shown in the code below. I am using ng-upload (https://github.com/twilson63/ngUpload). I want the 'Save' button to work only if either field is dirty and the upload isn't happening currently so that multiple post requests are not triggered on the user clicking on the 'Save' button. But looks like, $dirty works fine with the 'name' field but not with the 'profile pic' field. Am i just missing something? How to go about it keeping it as simple as possible for a beginner of AngularJS. Any help would be appreciated.
//Code
<form id='picUpload' name='picUpload' ng-upload-before-submit="validate()" method='post' data-ng-upload-loading="submittingForm()" action={{getUrl()}} data-ng-upload='responseCallback(content)' enctype="multipart/form-data">
<input type="text" name="name" data-ng-model="user.name" maxlength="15" id="user_screen_name" required>
<input type="file" name="profilePic" data-ng-model="user.profilePic" accept="image/*">
<div class="form-actions">
<button type="submit" class="btn primary-btn" id="settings_save" data-ng-disabled="!(picUpload.name.$dirty|| picUpload.profilePic.$dirty) || formUploading">Save changes</button>
</div>
</form>
//In my JS code
$scope.submittingForm = function(){
$scope.formUploading = true;
}
Regards!
I made a directive ng-file-dirty
.directive('ngFileDirty', function(){
return {
require : '^form',
transclude : true,
link : function($scope, elm, attrs, formCtrl){
elm.on('change', function(){
formCtrl.$setDirty();
$scope.$apply();
});
}
}
})
I haven't used ng-upload before, but you can use onchange event of input element. onchange event is fired whenever user selects a file.
<input type="file" onchange="angular.element(this).scope().fileNameChanged(this)" />
Javascript :
var app = angular.module('MainApp', []);
app.controller('MainCtrl', function($scope)
{
$scope.inputContainsFile = false;
$scope.fileNameChanged = function(element)
{
if(element.files.length > 0)
$scope.inputContainsFile = true;
else
$scope.inputContainsFile = false;
}
});
So now you can check if inputContainsFile variable is true along with dirty check of name field

Resources