Reputation: 857
I am new to AngularJS and would like to create functionality for a login page similar to what you find here when you click the 'Forgot Password' link:
http://bootsnipp.com/snippets/featured/login-amp-password-reminder#comments
Is it best to use a directive, since this is behavioral, instead of a controller? I've tried quite a bit with creating a controller for it, but as I search for help on the subject I find that using a controller for this may not be the way to go. Here was my latest trials which was unsuccessful (the link does nothing when clicked):
on controller side in a js file:
angular.module('mean.users')
.controller('SwitcherCtrl', ['$document',
function($document) {
$document.ready(function () {
$document.getElementById('olvidado').click(function (e) {
e.preventDefault();
$document.getElementById('form-olvidado').toggle('500');
});
$document.getElementById('acceso').click(function (e) {
e.preventDefault();
$document.getElementById('form-olvidado').toggle('500');
});
});
}
])
on html side, I included ng-controller="SwitcherCtrl" where necessary.
Upvotes: 6
Views: 19089
Reputation: 12181
JQuery approach is completely incompatible with AngularJS. DOM Manipulation is only allowed in directives in the link function otherwise it is a very bad practice. Try to start from scratch and forget about JQuery. The magic of AngularJS happens with 2-way bindings.
You could use a directive, with a login controller and a factory/service to hold the username and password and send it to the database. For this login there is definitely no need for JQuery at all. You can check this question here: AngularJS- Login and Authentication in each route and controller
edit: In your question above, it is not a directive instead of a controller. A directive can have a controller that is applied to a specific scope. You could do the same thing with both but depends how many times you will reuse this login snippet - I guess you won't need it but I believe it is still good practice to make one.
edit 2: if you havent' read this one, please do it! I believe you will answer most of your questions about the two different (opposite I would say) technologies. "Thinking in AngularJS" if I have a jQuery background? Also since I came from Jquery background too, I followed these four resources in order and now I can make most of the things I want:
Introduction to Angular.js in 50 Examples (part 1) https://www.youtube.com/watch?v=TRrL5j3MIvo
Introduction to Angular.js in 50 Examples (part 2) https://www.youtube.com/watch?v=6J08m1H2BME
Free Interactive AngularJS learning for Beginners https://www.codeschool.com/courses/shaping-up-with-angular-js
More AngularJS resources by topic egghead.io https://egghead.io/technologies/angularjs
edit 3: Since I saw good interest in my answer I decided to expand it with what to avoid/best practices so the code is more testable, maintainable and easier to migrate to Angular 2:
5 Guidelines For Avoiding Scope Soup in Angular http://www.technofattie.com/2014/03/21/five-guidelines-for-avoiding-scope-soup-in-angular.html
No $scope soup, bindToController in AngularJS https://toddmotto.com/no-scope-soup-bind-to-controller-angularjs/
Angular JS - you probably shouldn't use $watch in your controllers. http://www.benlesh.com/2013/10/title.html
11 Tips to Improve AngularJS Performance http://www.alexkras.com/11-tips-to-improve-angularjs-performance/
Upvotes: 8
Reputation: 857
Thanks to everyone who answered. They kicked off this thing moving in the right direction and I was able to improve upon it to come to the exact answer shown below.
The HTML:
<div ng-controller="SwitcherCtrl">
<div data-fold-toggle="active">
<form id="login">
<input type="email" ng-model="email" required="">
<input type="password" ng-model="password" required="">
<button type="submit">Login</button>
<a ng-click="active=!active">Forgot your password?</a>
</form>
</div>
<div data-fold-toggle="active" style="display: none;">
<form id="forgotpw">
<input type="email" ng-model="email" required="">
<button type="submit">Reset Password</button>
<a ng-click="active=!active">Account Access</a>
</form>
</div>
</div>
The Controller & Directive:
.controller('SwitcherCtrl', function($scope) {
$scope.active = true;
})
.directive('foldToggle', function() {
return {
restrict: 'A',
scope:{
isOpen: '=foldToggle'
},
link: function(scope, element) {
scope.$watch('isOpen', function(newVal,oldVal){
if(newVal !== oldVal){
element.toggle(200);
}
});
}
};
});
Upvotes: 1
Reputation: 1877
You can try this out, it uses directives and html. Whether the login or forgot username shows is tied to the state of a scope variable in the directives link function.
<div ng-app="myApp">
<div my-auth>
<div ng-show="active">
<form name="login">
<input type="email" ng-model="email" placeholder="[email protected]" required />
<input type="password" ng-model="passwd" required />
<button ng-disabled="!login.$valid">Login</button>
</form>
<a href="#" ng-click="toggle()">forgot password?</a>
</div>
<div ng-show="!active">
<form name="forgot">
<input type="email" ng-model="email" placeholder="[email protected]" required />
<button ng-disabled="!forgot.$valid">Reset Password</button>
</form>
<a href="#" ng-click="toggle()">access</a>
</div>
</div>
</div>
The directive
angular.module('myApp', [])
.directive('myAuth', function(){
return {
link: function(scope, elem, attr){
scope.active = true;
scope.toggle = function(){
scope.active = !scope.active;
};
}
};
});
Upvotes: 3