I`m having some problem with my directive.
The js files for the directive and the controller are included in index.html and the path is correct.
No errors are given in the console, but my tag doesn`t render. Any help would be apreciated.
Here are some of my code
loginForm.js
(function () {
angular
.module('sysConApp')
.directive('loginForm', [
function () {
return {
restrict: 'E',
scope: {},
templateUrl: 'scripts/directives/loginForm/view/loginFormView.html',
controller: 'LoginFormController',
replace: 'true'
}
}
]);
});
loginFormController.js
angular.module('sysConApp')
.controller('LoginFormController', ['$scope', '$state', 'AuthService', 'userProfile',
function ($scope, $state, AuthService, userProfile) {/*Some codes*/}]);
loginFormView.html
<form class="loginForm">
<img class="login-logo"
src="data:image/png;base64,i..." alt="Logo SysCon">
<input id="inputEmail"
type="email"
class="form-control"
placeholder="E-mail"
ng-model="username"
required
autofocus>
<input type="password"
id="inputPassword"
ng-model="password"
class="form-control"
placeholder="Senha"
required>
<span ng-show="loginError && loginForm.$invalid"
class="label label-danger">
<b>Erro ao realizar login.</b> Favor tente novamente.
</span>
<button class="btn btn-lg btn-block btn-signin"
ng-disabled="loginForm.$invalid"
ng-class="{'btn-default':loginForm.$invalid,'btn-success':loginForm.$valid}"
ng-click="logIn()"
type="submit">
Log in
</button>
</form>
login.html
<div class="card card-container">
<login-form></login-form>
</div>
The problem with your code is that your IIFE isn't being invoked ever, you created the function but never called it.
You have this:
(function() {
//...
});
And you must change it to:
(function() {
//...
})();
Full code:
(function() {
angular
.module('sysConApp')
.directive('loginForm', [
function() {
return {
restrict: 'E',
scope: {},
templateUrl: 'scripts/directives/loginForm/view/loginFormView.html',
controller: 'LoginFormController',
replace: true,
link: function(){console.log('whoray');}
}
}
]);
})();
Related
I'm working on an AngularJS app and created two forms inside a directive. I want to reset both form's $submitted by $setSubmitted(false), however, the problem is that I cannot get two controls at the same time inside the directive controller.
Referred to this solution How to handle multiple forms present in a single page using AngularJS. However, the solution is for a controller, not for a directive.
(function () {
'use strict';
angular
.module('app')
.directive('multiForms', multiForms);
function multiForms() {
return {
restrict: "A",
scope: {
},
controller: function ($scope) {
$scope.functions = {
submit1: submit1,
submit2: submit2,
resetForms: resetForms
};
function resetForms() {
$scope.form1.$setSubmitted(false);
$scope.form2.$setSubmitted(false);
}
},
replace: false,
templateUrl: 'pathToTheHtml.html'
}
}
})();
<div>
<form name="form1" ng-submit="functions.submit1()">
<ng-form name="form1">
<input type="text" ng-model="text1">
<button type="submit">Submit1</button>
</ng-form>
</form>
<form name="form-2" ng-submit="functions.submit2()">
<ng-form name="form2">
<input type="text" ng-model="text2">
<button type="submit">Submit2</button>
</ng-form>
</form>
<button ng-click="functions.resetForms()"></button>
</div>
The expected results is to set $submitted value to false for both form1 and form2. The actual result is both $scope.form1 and $scope.form2 are undefined.
I was playing around and this actually worked. I added vm and binded with the view.
(function () {
'use strict';
angular
.module('app')
.directive('multiForms', multiForms);
function multiForms() {
return {
restrict: "A",
scope: {
},
controller: function ($scope) {
const vm = this;
vm.functions = {
submit1: submit1,
submit2: submit2,
resetForms: resetForms
};
function resetForms() {
vm.form1.$setPristine();
vm.form2.$setPristine();
}
},
controllerAs: 'vm',
bindToController: true,
replace: false,
templateUrl: 'pathToTheHtml.html'
}
}
})();
<div>
<form name="vm.form1" ng-submit="vm.functions.submit1()">
<ng-form name="form1">
<input type="text" ng-model="vm.data.text1">
<button type="submit">Submit1</button>
</ng-form>
</form>
<form name="vm.form-2" ng-submit="vm.functions.submit2()">
<ng-form name="form2">
<input type="text" ng-model="vm.data.text2">
<button type="submit">Submit2</button>
</ng-form>
</form>
<button ng-click="vm.functions.resetForms()"></button>
</div>
This is my controller
function commentController($stateParams, commentFactory, $rootScope){
const ctrl = this;
ctrl.comment = {};
ctrl.decision = {};
ctrl.$onInit = function(){
ctrl.decision.replyVisible = false;
}
export {commentController}
This is my component
import {commentController} from './comment.controller'
export const commentComponent = 'commentComponent'
export const commentComponentOptions = {
bindings: {
post: '<'
},
templateUrl: 'blog/src/app/components/post/comment/comment.html',
controller: ['$stateParams', 'commentFactory', '$rootScope', commentController],
controllerAs: 'cm'
}
This is my directive
function showReply(){
return {
restrict: 'A',
scope: {
collapsed: '<'
},
link: function(scope, element, attrs){
element.on('click', ()=>{
console.log(`Trying to hide ${scope.collapsed}`);
scope.collapsed = true
console.log(`Trying to hide ${scope.collapsed}`);
})
}
}
}
function hideReply(){
return {
restrict: 'A',
scope: {
collapsed: '<'
},
link: function(scope, element, attrs){
element.on('click', ()=>{
scope.collapsed = false;
console.log(`Trying to hide scope.replyVisible is ${scope.collapsed}`);
})
}
}
}
export {showReply, hideReply}
This is my html
<div class="comment_wrapper">
<div class="comment" ng-repeat="comment in cm.post.comments">
<h3>{{comment.author.name}}</h3>
<p ng-bind-html="comment.comment"></p>
<button show-reply collapsed="cm.decision.replyVisible">Reply</button>
<div class="reply_wrapper" ng-show="cm.decision.replyVisible">
<label for="name">Name</label>
<input type="text" id="name" ng-model="cm.comment.author.name">
<label for="email">Email</label>
<input type="text" id="email" ng-model="cm.comment.author.email">
<label for="comment">Comment</label>
<textarea name="" id="comment" cols="10" rows="5" ng-model="cm.comment.comment"></textarea>
<button ng-click="cm.reply(comment._id)">Submit</button> <button hide-reply collapsed="cm.decision.replyVisible">Cancel</button>
</div>
</div>
</div>
And this is my module
import angular from 'angular'
import {showReply, hideReply} from './comment.directive'
import {commentFactory, commentFactoryFunc} from './comment.factory'
import {commentComponent, commentComponentOptions} from './comment.component'
export const comment = angular.module('comment', [uiRouter])
.factory(commentFactory, ['$http', commentFactoryFunc])
.component(commentComponent, commentComponentOptions)
.directive('showReply', showReply)
.directive('hideReply', hideReply)
.name
Here's what I am trying to do, in my html, I want to show the reply form when someone clicks on the reply button. And since there are multiple comments for with each having a reply form, I can't use the regular ng-click.
The changes made to the scope.collapsed don't get reflected on cm.decision.replyVisible
How do I make this work? I have always been confused about accessing parent controller variables from a directive.
You should use comment.decision.replyVisible instead of cm.decision.replyVisible
HTML
<div class="comment_wrapper">
<div class="comment" ng-repeat="comment in cm.post.comments">
<h3>{{comment.author.name}}</h3>
<p ng-bind-html="comment.comment"></p>
<button show-reply
collapsed="comment.decision.replyVisible">Reply</button>
<div class="reply_wrapper" ng-show="comment.decision.replyVisible">
<label for="name">Name</label>
<input type="text" id="name" ng-model="cm.comment.author.name">
<label for="email">Email</label>
<input type="text" id="email" ng-model="cm.comment.author.email">
<label for="comment">Comment</label>
<textarea name="" id="comment" cols="10" rows="5" ng-model="cm.comment.comment"></textarea>
<button ng-click="cm.reply(comment._id)">Submit</button> <button hide-reply collapsed="cm.decision.replyVisible">Cancel</button>
</div>
</div>
</div>
I can't get the scope object to update on submit. The submit function is called, but the console shows the object does not update. I have tried most similar problem-solutions I have found.
The directive (inside index.html):
<div d-header-login class="header-login"></div>
The directive HTML:
<div class="container_header-login">
<div data-ng-if="!login.opLogin">
<form ng-submit="submit()">
<input type="text" ng-model="username" placeholder="username/email" />
<input type="text" ng-model="scope.password" placeholder="password" />
<br />
<input type="submit" class="btn btn-primary" value="Login"/>
</form>
Register
Forgot password
</div>
<div data-ng-if="login.opLogin">
<!--{{login.opLogin}}-->
Logged in as
</div>
</div>
The directive js
var mHeaderLogin = angular.module('app.directives.mHeaderLogin', ['mMain'])// mMain-dependent due to factory call
.directive('dHeaderLogin', fHeaderLogin);
function fHeaderLogin() {
return {
restrict: 'A',
//replace: true,
scope: {
username: '='
}, //isolate scope
templateUrl: 'app/directives/header-Login/header-Login.html',
controller: function ($scope, simpleFactory) {
$scope.users = simpleFactory.getUsers();
$scope.username = "test";
},
link: function (scope, element, attrs) {
scope.login = { opLogin: false };
scope.submit = function () {
console.log(scope.username);
console.log("fSubmit");
}
}
}
}
The log will show "test"; not what I wrote in the input box
I want on-click event from directive invoke some function from my controller. But for some reason it doesn't work. I want my datepicker to expand when I event is fired. Could you please help me to investigate what is wrong my in my current build?
app.js
app.directive('myDatepicker', function() {
return {
restrict: 'E',
scope :{
model:'=model',
minDate:'=minDate',
isOpened:'=isOpened',
openFunction: '&'
},
templateUrl: 'templates/datepicker/datepicker.html',
link: function(scope, elm, attrs) {
}
};
});
app.controller('FlightDatePickerController', function ($scope) {
$scope.openFunction = function($event, isDepart) {
$event.preventDefault();
$event.stopPropagation();
$scope.departureOpened = true;
};
};
datepicker.html
<fieldset>
<pre>{{model}}</pre>
<div class='input-group'>
<input type="text" class="form-control" datepicker-popup ng-model="{{model}}" min-date="{{minDate}}" is-open="{{isOpened}}" datepicker-options="dateOptions" ng-required="true" close-text="Close" />
<span ng-click='openFunction({event:event}, {isDepart:isDepart})' class="btn btn-default input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</fieldset>
index.html
<div ng-controller="FlightDatePickerController">
<div class="col-md-2">
<my-datepicker model="departureDate" minDate="minDateDeparture" isOpened="departureOpened" open-function="openFunction($event, isDepart)"></my-datepicker>
</div>
</div>
You can add a controller attribute to your directive, in order to bind some function to your template.
In your case, you can do :
Directive
app.directive('myDatepicker', function() {
return {
restrict: 'E',
scope :{
model:'=model',
minDate:'=minDate',
isOpened:'=isOpened'
},
templateUrl: 'templates/datepicker/datepicker.html',
controller: 'FlightDatePickerController'
};
});
Datepicker.html
<div ng-controller="FlightDatePickerController">
<div class="col-md-2">
<my-datepicker model="departureDate" minDate="minDateDeparture" isOpened="departureOpened"></my-datepicker>
</div>
</div>
Your overall implementation is correct, but you made couple of mistakes.
ng-click should be like adding parameter in JSON like structure.
ng-click='openFunction({event:$event, isDepart:isDepart})'
& then your directive element should have
open-function="openFunction($event, isDepart)"
I have this directive:
.directive('myDate', ['$timeout', '$rootScope', '$locale',
function ($timeout, $rootScope, $locale) {
'use strict';
return {
restrict: 'A',
scope: {
customDate: '='
},
// the rest part of directive...
};
}
]);
I know how to pass a variable to directive that is restricted to element. But that approach doesn't work when the directive is given as attribute:
<div class="input-group date" my-date custom-date="testDate">
<input type="text" class="form-control" ng-model="dateFrom" />
</div>
Where:
scope.testDate= new Date('2015-01-13')
How can I get it work?
For the most part, your code should work. Here is a working plunker for the rest. There were just a few small issues with the OP. In the controller, the property that is bound to the directive attribute must be of the same name (scope.date should have been scope.testDate) etc.
The controller:
app.controller('Ctrl', function($scope) {
$scope.testDate = new Date('2015-01-13')
});
The directive:
app.directive('myDate', ['$timeout', '$rootScope',
function ($timeout, $rootScope) {
'use strict';
return {
restrict: 'A',
scope: {
customDate: '='
},
link(scope) {
console.log(scope.customDate);
}
};
}
]);
The HTML:
<body ng-app="myApp">
<div ng-controller="Ctrl">
<div class="input-group date" my-date custom-date="testDate">
<input type="text" class="form-control" ng-model="dateFrom" />
</div>
</div>
</body>