Getting controls of forms inside a directive - angularjs

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>

Related

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?

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

Scope not updating in link directive on ng-submit

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

Pass variable to directive that is restricted to attribute

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>

Why does `controllerAs` in JavaScript work but not `ng-controller=...as...` in HTML?

This works:
Plunker controllerAs in js
input-form.html
<form name="inputForm" ng-submit="inputForm.$valid && inputCtrl.emitData()" novalidate>
<textarea name="topic1Data" ng-model="inputCtrl.inputValues.topic1Data" rows="10" cols="30" required></textarea>
<button type="submit" class="btn btn-info btn-lg" ng-disabled="!inputForm.$valid">Compare</button>
</form>
inputForm.js
"use strict";
(function() {
var inputForm = angular.module('input-form', []);
inputForm.directive('inputForm', function() {
return {
restrict: 'E',
templateUrl: 'input-form.html',
scope: {data: "="},
controllerAs: 'inputCtrl',
bindToController: true,
controller: function() {
var inputCtrl = this;
inputCtrl.inputValues = {topic1Data: 123456789};
inputCtrl.emitData = function() {
inputCtrl.data = inputCtrl.inputValues.topic1Data;
};
}
};
});
})();
Source: https://stackoverflow.com/a/29558554/2848676
This doesn't work:
Plunker controller as in html
input-form.html
<form name="inputForm" ng-controller="InputController as inputCtrl" ng-submit="inputForm.$valid && inputCtrl.emitData()" novalidate>
<textarea name="topic1Data" ng-model="inputCtrl.inputValues.topic1Data" rows="10" cols="30" required></textarea>
<button type="submit" class="btn btn-info btn-lg" ng-disabled="!inputForm.$valid">Compare</button>
</form>
inputForm.js
"use strict";
(function() {
var inputForm = angular.module('input-form', []);
inputForm.directive('inputForm', function() {
return {
restrict: 'E',
templateUrl: 'input-form.html',
scope: {data: "="},
bindToController: true
};
});
inputForm.controller('InputController', function(){
var inputCtrl = this;
inputCtrl.inputValues = {topic1Data: 123456789};
inputCtrl.emitData = function() {
inputCtrl.data = inputCtrl.inputValues.topic1Data;
};
});
})();
I found an article by Pascal Precht that seemed to say the solution was bindToController but I'm using bindToController and it doesn't work still.
How come the controllerAs in the JavaScript works but not the ng-controller=...as... in HTML?
bindToController works with a controller defined on the directive definition object:
.directive("foo", function(){
return {
//..
bindToController: true,
controller: "FooCtrl",
controllerAs: "foo"
};
});
In other words, when $compile service runs and compiles/links the directives, it collects the directives and binds to a directive.controller object. That is the controller that "binds" to the isolate scope properties.
In your case, you assumed (incorrectly) that a controller defined in the template with ng-controller="FooCtrl as foo" would work in the same manner. There is no basis for that assumption and the article that you linked to never showed that as an option.
The template can instantiate numerous controllers, not to mention that a template could be loaded asynchronously (with templateUrl), so the bindToController was never meant to be used in such a manner.

Resources