Error with binding text input - angularjs

i have this strange thing that happens in my application every time it starts, but first the code
HTML
<form ng-submit="login()" class="login">
<input type="text" ng-model="data.username" placeholder="username" value="username" class="form-control" popover="inserisci qui il tuo username" popover-trigger="focus" popover-placement="right"></input><br>
<input type="password" ng-model="data.password" placeholder="password" value="password" class="form-control" popover="inserisci qua la tua password" popover-trigger="focus" popover-placement="right"><br>
<input class="btn-primary btn-lg" type="submit" value="Login">
JS
var loginCtrl=function($scope,$http,$modalInstance,$state){
$scope.data = {username : '',password:''};
var data=$scope.data;
$scope.login=function(){
$http.post(server[0]+someurl,{name:data.username,password:data.password})
.then(function (response) {
var status=response.status;
loggedOk=true;
$state.go('home',{username:data.username,logged:status});
$modalInstance.close();
},
function(response){
var status=response.status;
alert(status);
logged=false;});
};
this is clearly a little login app. My problem is that when i start the app and the text area is all ready filled with a user and a password saved before, if i press login, the post request send empty params.
Strangely if i delete a letter from the two params and i rewrite it everything goes ok, any idea why?

I think your main issue is that your bindings are not to your data object. Change ng-model="username" to ng-model="data.username", and do the same for password. That should make everything bound up correctly for login.

Related

Submit login with AngularJS

I want to avoid using <form> so instead of
<form action="./login" method="post">
<input type="text" placeholder="Username" name="username">
<input type="password" placeholder="Password" name="password">
<input type="submit" value="Login">
</form>
I want to use something like
<input type="text" placeholder="Nombre de usuario" data-ng-model="username">
<input type="password" placeholder="ContraseƱa" data-ng-model="password">
<a data-ng-click="doLogin()">Login</a>
And in controller:
$scope.doLogin=function(){
var url = '/login?username=' + $scope.username + '&password=' + $scope.password;
$http.post(url).then(function(msg){
console.log(msg);
});
}
The request is sent to Spring framework and work perfectly when I use form,but when I use Angular to perform same action it gives me an error POST http://localhost:8080/login?username=admin&password=admin 404 (Not Found)
What changes I have to do? I would like to have the perfectly the same functionality of submit, as on wrong credentials Spring framework redirects me on another view.
I think that you should not delete the form but change it to a pure angularjs form with a ngSubmit attribute (be sure to delete the action attribute).
Like this :
<form method="post" ng-submit="doLogin()">
<input type="text" placeholder="Username" name="username">
<input type="password" placeholder="Password" name="password">
<input type="submit" value="Login">
</form>
Then, in your js controller, your http call is a post call with parameters passed like a get call (param1=value1&param2=...), change your call to pass login parameters in post.
$scope.doLogin=function(){
var url = '/login';
$http.post(url, {username: $scope.username, password: $scope.password}).then(function(msg){
console.log(msg);
});
}
This way, your angularjs form will behave the same way than your previous code.

AngularJS: ngModel with ngSwitch, cannot watch?

I'm trying to make a very simple signup form, which is supposed to work in 2 steps.
I ask the user for his email in the first step
in the second step, I ask the user for the other details (step == 2).
The template is simple;
<div class="input-group layout-container" ng-switch on="step">
<!-- Login -->
<img src="images/yeoman.png">
<p>{{msg}}</p>
<form name="signup">
<input type="text" class="form-control login" placeholder="firstname" ng-model="firstname" ng-switch-when="2">
<input type="text" class="form-control login" placeholder="lastname"ng-model="lastname" ng-switch-when="2">
<input type="email" class="form-control login" placeholder="email" ng-model="email" ng-switch-when="1" required>
<span class="error" ng-show="signup.input.$error.required">Cannot be blank</span>
<span class="error" ng-show="signup.input.$error.email">Not a valid email</span>
<input type="password" class="form-control login" placeholder="password" ng-model="pass" ng-switch-when="2"> <br/><br/>
<div class="btn-container">
<button class="btn btn-primary" ng-click="next()">Next</button>
</div>
</form>
</div>
As you can see, there's some basic validation going on as well, and I assign the value of the email to a model I call email.
And the controller goes like this:
.controller('SignupCtrl', function ($scope) {
$scope.msg = "First, your email";
$scope.step = 1;
$scope.email = ''; // this still doesn't help
$scope.$watch('email', function (now, then, scope) {
console.log('email change', now, then);
});
$scope.next = function () {
$scope.step = Math.min($scope.step + 1, 2);
};
})
The problem is this: the $watch on 'email' doesn't ever trigger at all. Where's this going wrong?
I agree with #miqid, that ng-switch creates a new scope implicitly. All the value changes of <input> are actually happened in this isolated child scope. Its parent, where you are doing $watch, will NOT be notified. That's the reason why you cannot watch the variable changes. This is a common pitfall to angular users.
LT;DR simply change any ng-model="foo" to ng-model="$parent.foo" in your ng-switch block.
Here is a working jsfiddle (of just the part you have a problem with): demo
function ctrl($scope) {
$scope.items = ['one','two'];
$scope.selection = 'two';
$scope.data = {email:''};
$scope.$watch('data.email', function (now, then, scope) {
console.log('email change', now, then);
});
}
Note that it will only trigger the watch if the email is valid if the input is type="email".
Edit: updated for use with ng-switch.
Explanation: As noted by miqid, when you use primitives, child scopes have no access to parent scope variables, but when they're objects angular creates a reference in the child scopes.

Translated form validation in AngularJS

What's the easiest way of changing the default error messages in form validation provided by Angular to another language?
If I'm not mistaken, you think about html5 validation.
Something like this:
<b>HTML5 validation</b>
<form>
First name:
<input type="text" name="firstName" required="" />
<br />
Last name:
<input type="text" name="lastName" required="" />
<br />
<input type="submit" value="Submit" />
</form>
If user click on the Submit button he will see:
I think that this error comment you cannot change because it depends on the user browser/computer settings.
Maybe you should try to use angularjs validation (first add to form novalidate to switch off HTML5 validation):
HTML
<div ng-controller="PersonController">
<b>AngularJS validation</b>
<form novalidate name="myForm">
First name:
<input type="text" name="firstName" ng-model="newPerson.firstName" required="" />
<span style="color: red" ng-show="myForm.firstName.$dirty && myForm.firstName.$invalid">First name is required</span>
<br />
Last name:
<input type="text" name="lastName" ng-model="newPerson.lastName" required="" />
<span style="color: red" ng-show="myForm.lastName.$dirty && myForm.lastName.$invalid">Last name is required</span>
<br />
<button ng-click="resetPerson()">Reset</button>
<button ng-click="addPerson()" ng-disabled="myForm.$invalid">Save</button>
</form>
</div>
JavaScript
var myApp = angular.module('myApp', []);
myApp.controller('PersonController', ['$scope',
function($scope) {
var emptyPerson = {
firstName: null,
lastName: null
};
$scope.addPerson = function() {
alert('New person added ' + $scope.newPerson.firstName + ' ' + $scope.newPerson.lastName);
$scope.resetAdvert();
};
$scope.resetPerson = function() {
$scope.newPerson = angular.copy(emptyPerson);
// I don't know why not work in plunker
//$scope.myForm.$setPristine();
};
$scope.resetPerson();
}
]);
If user fill the field and erase he will see the error info:
The submit button will be disabled if user don't fill the required fields.
Plunker example
Why don't you try something easy for a change... :) Well here is my Angular-Validation. I made a project on Github and I think you can't be simpler than that...and yes I also support translation localization, those are saved into an external JSON file:
<!-- example 1 -->
<label for="input1">Simle Integer</label>
<input type="text" name="input1" validation="integer|required" ng-model="form1.input1" />
<span class="validation text-danger"></span>
<!-- example 2 -->
<label for="input2">Alphanumeric + Exact(3) + required</label>
<input type="text" name="input2" validation="alpha|exact_len:3|required" ng-model="form1.input2" />
<span class="validation text-danger"></span>
JSON external file for translation locales
// English version, JSON file (en.json)
{
"INVALID_ALPHA": "May only contain letters. ",
"INVALID_ALPHA_SPACE": "May only contain letters and spaces. ",
...
}
// French version, JSON file (fr.json)
{
"INVALID_ALPHA": "Ne doit contenir que des lettres. ",
"INVALID_ALPHA_SPACE": "Ne doit contenir que des lettres et espaces. ",
...
}
On top of supporting multiple translations, the directive is so crazy simple for validation, that you'll just love it. I can define whatever amount of validation rules (already 25+ type of validators available) under 1 attribute. validation="min_len:2|max_len:10|required|integer" and the error message will always be displayed in the following <span> isn't it beautiful? I think so too hehe... 1 line of code for your input, 1 line of code for the error display, can you beat that? oh and I even support your custom Regex if you want to add. Another bonus, I also support whichever trigger event you want, most common are probably onblur and onkeyup. I really added all the imaginable features I wanted into 1 crazy simple directive.
No more clustered Form with 10 lines of code for 1 input (sorry but always found that ridiculous) when the only little piece you need is 2 lines of code, nothing more, even for an input of 5 validators on it. And no worries about the form not becoming invalid, I took care of that as well, it's all handled the good "Angular" way.
Take a look at my Github project Angular-Validation... I'm sure you'll love it =)
DEMO
Added a live demo on Plunker

Clearing all inputs and restoring .ng-pristine on click

It's still the first day of me using AngularJS after inheriting the project from a fellow developer. I was wondering, I have a login/registration form on my interface that is hidden once the items/form is submitted. Now once the user has submitted is there a correct or proper way to clear the form of it's entries and restore the .ng-pristine class on the items. The reason for this is should the user choose to log out and then login again (or another user wishes to register) the form is populated and has the validation css applied to it already. I don't want this, I would want everything to be empty and no CSS applied.
I can do this in JavaScript (obviously) however with AngularJS being a different approach I was wondering if I should approach this issue another way rather than loop through the form items and append a class to each item whilst clearing it's value.
This an example of one of my forms
<form name="signupForm" novalidate ng-submit="register(user)">
<div><label for="email">email:</label><input type="email" id="email" name="email" required ng-model="user.email" ng-minlength=4></div>
<div><label for="userName">Username:</label><input type="text" name="userName" id="userName" ng-model="user.userName" required ng-pattern="/^[A-Za-z0-9 \-_.]*$/" ng-minlength=4></div>
<div><label for="firstName">Vorname:</label><input type="text" name="firstName" id="firstName" ng-model="user.firstName" required ng-pattern="/^[A-Za-z \-_.]*$/" ng-minlength=3></div>
<div><label for="lastName">Nachname:</label><input type="text" name="lastName" id="lastName" ng-model="user.lastName" required ng-pattern="/^[A-Za-z \-_.]*$/" ng-minlength=4></div>
<div><label for="password1">Passwort:</label><input type="password" name="password1" id="password1" ng-model="user.password1" required ng-minlength=4></div>
<div><label for="password2">Passwort wiederholen:</label><input type="password" name="password2" id="password2" ng-model="user.password2" valid-password2 ng-minlength=4 pw-check="password1"></div>
... and so on
Many thanks
The form will appear in the correct scope under its name, i.e. $scope.signupForm. Additionally the object populating the form is $scope.user. In your controller, do:
$scope.user = {}; // or new User() if it is your case
$scope.signupForm.$setPristine();
In case $scope.signupForm is undefined, put a controller directly on the form, and place the code above (and anything else applicable) inside this new controller:
<form name="signupForm" novalidate ng-submit="register(user)"
ng-controller="NewCtrl">
(This may happen due to scope nesting under your original controller.)
Just refer to this post :
Reset form to pristine state (AngularJS 1.0.x)
In the main question you got reference to issues and pull request on AngularJS. In resume you have to use $setPristine() method to your form.
Hope it helps !
var app = angular.module('App', []);
app.controller('formController', function($scope, $document){
$scope.Clear = function(){
angular.forEach(angular.element($document[0].querySelectorAll('input[type=text], input[type=email], input[type=password]')), function (elem, index) {
elem.value = '';
/*
Just extra do something
elem.parent().parent().removeClass('has-error has-success');
elem.parent().parent().children().find('span').removeClass('glyphicon-exclamation-sign glyphicon-ok');
*/
});
$scope.myForm.$setPristine();
}
});
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>
</head>
<body ng-app="App">
<div ng-controller="formController">
<form name="myForm">
<input type="text" name="FirstName" ng-model="FN"/> <br>
<input type="text" name="LastName"/>
<br>
<input type="text" name="UserName"/>
<br>
<input type="password" name="Password"/>
</form>
<button ng-click="Clear()">Clear</button>
</div>
</body>
</html>
Here is my Example, it worked for me i am using angularjs 1.6

Angular JS Forms submit not sending model data

In the following example, message is undefined when I display it in the controller after the event is fired. Why?
<form>
<input type="text" ng-model="message.Title" />
<textarea ng-model="message.Content"></textarea>
<input type="submit" value="Send Message" ng-click="sendMessage(message)" />
</form>
Controller:
$scope.sendMessage = function(message) {
console.log(message);
}
My code seems identical to the documentation here except my controller manages the entire "page" not just the form.
Wow nevermind, apparently when you submit with blank values it doesn't even create the object.
I see you've found your problem, but I'd like to propose a solution to prevent your problem anyway:
<form name="messageForm" ng-submit="sendMessage(message)">
<input type="text" ng-model="message.Title" required/>
<span ng-show="messageForm.title.$error.required && messageForm.title.$dirty">required</span><br/>
<textarea ng-model="message.Content"></textarea>
<input type="submit" value="Send Message" ng-disabled="messageForm.$invalid" />
</form>
The above will make the Title required, display an error message, and disable your submit button if the form isn't valid.

Resources