Scope not updating in link directive on ng-submit - angularjs

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

Related

Getting controls of forms inside a directive

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>

Plug a user directive to form.$valid

I have a simple directive:
myDirective.html:
<div class="my-directive" ng-class="{'on':status,'off':!status}" ng-click="onClick()">
click me
</div>
myDirective.js:
app.directive('myDirective', function () {
return {
restrict: 'E',
templateUrl: 'myDirective.html',
controller: ['$scope', function ($scope) {
$scope.onClick = function () {
$scope.status = !$scope.status;
}
}]
}
});
I have a ng-form and I'm using this directive as a field of the form:
<ng-form name="frm">
<div class="form-field">
<input type="text" required ng-model="v1" />
</div>
<div class="form-field">
<my-directive status="v2" />
</div>
<input type="button" ng-disabled="!frm.$valid" value="save" />
</ng-form>
Live example in: JsFiddle.
When I set some text in the input frm.$valid turn to true automatically.
I want to apply to my-directive the same effect. Lets say...
Consider my-directive as valid only when status is true.
And if my-directive is invalid the form should be invalid too.
Can I set this effect in my-directive? And how can I do it?

changes in directive scope variables don't update the parent scope variables. Angular Js 1.5

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>

Directive not loading

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');}
}
}
]);
})();

How to have access to directive scope value from my main controller

Web API file Upload with AngularJS - https://code.msdn.microsoft.com/AngularJS-with-Web-API-22f62a6e#content
This tutorial upload selected files to the server but there is no way to get the selected filename exception from a directive,
Please, i need a way to get the filename of the selected file from the directive scope, so that i can use it in another controller
This is the focus area
(function () {
'use strict';
angular
.module('app.photo')
.directive('egPhotoUploader', egPhotoUploader);
egPhotoUploader.$inject = ['appInfo','photoManager'];
function egPhotoUploader(appInfo, photoManager) {
var directive = {
link: link,
restrict: 'E',
templateUrl: 'app/photo/egPhotoUploader.html',
scope: true
};
return directive;
function link(scope, element, attrs) {
scope.hasFiles = false;
scope.photos = [];
scope.upload = photoManager.upload;
scope.appStatus = appInfo.status;
scope.photoManagerStatus = photoManager.status;
}
}
})();
The Directive Template
<form name="newPhotosForm" role="form" enctype="multipart/form-data" ng-disabled="appStatus.busy || photoManagerStatus.uploading">
<div class="form-group" ng-hide="hasFiles">
<label for="newPhotos">select and upload new photos</label>
<input type="file" id="newPhotos" class="uploadFile" accept="image/*" eg-files="photos" has-files="hasFiles" multiple>
</div>
<div class="form-group" ng-show="hasFiles && !photoManagerStatus.uploading">
<div>
File Name:{{photos[0].name}}
</div>
<input class="btn btn-primary" type="button" eg-upload="upload(photos)" value="upload">
<input class="btn btn-warning" type="reset" value="cancel" />
</div>
From my main controller, i want to have access to the directive scope
{{vm.photos[0].name}}
function link(scope, element, attrs) {
scope.hasFiles = false;
scope.photos = [];
scope.upload = photoManager.upload;
scope.appStatus = appInfo.status;
scope.photoManagerStatus = photoManager.status;
}
// This is scope that i need in the main controller, please how can i get it out.
scope.photos = [];

Resources