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?
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>
Why are the user inputted values not duplicating when a user types into an input?
The user input works and duplicates when the HTML is separate from a custom directive template as shown below and in this fiddle: http://jsfiddle.net/Lvc0u55v/7069/ .
<div ng-controller="LeaseTemplateController">
<div class="leasespecial">
<div class="firstsec">
<div class="percNumber">
<h1 id="perId" ng-repeat="bb in percent_id">{{bb.value}}</h1>
</div>
</div>
<h2>Lease Special Template</h2>
<form>
<div class="form-group" ng-repeat="cc in percent_id">
<div class="input-group">
<input class="form-control input" type="text" placeholder="Enter Percent" ng-model="cc.value">
</div>
</div>
</form>
</div>
<script>
var myApp = angular.module('myApp', []);
myApp.controller('LeaseTemplateController', ['$scope', function($scope) {
//Lease Special Template
$scope.percent_id = [{
value: '20'
}];
}]);
</script>
However, instead I'm trying to insert it using two different directive templates as shown in this fiddle: http://jsfiddle.net/Lvc0u55v/7068/
<div lease-text-directive>
</div>
<div lease-input-directive>
</div>
<script>
var myApp = angular.module('myApp', []);
myApp.controller('LeaseTemplateController', ['$scope', function($scope) {
//Lease Special Template
$scope.percent_id = [{
value: '20'
}];
}]);
myApp.directive('leaseTextDirective', function() {
return {
restrict: 'A',
template: '<div class="leasespecial" ng-controller="LeaseTemplateController">\
<div class="firstsec">\
<div class="percNumber">\
<h1 id="perId" ng-repeat="bb in percent_id">{{bb.value}}</h1>\
</div>\
</div>'
};
});
myApp.directive('leaseInputDirective', function() {
return {
restrict: 'A',
template: '<h2>Lease Special Template</h2>\
<form ng-controller="LeaseTemplateController">\
<div class="form-group" ng-repeat="cc in percent_id">\
<div class="input-group">\
<input class="form-control input" type="text" placeholder="Enter Percent" ng-model="cc.value">\
</div>\
</div>\
</form>'
};
});
</script>
Why are the values not duplicating over in the second example and would you suggest a better practice than this?
I believe your experiencing the separation of scopes. Your directives have a different scope than your controller so it knows nothing. Try injecting your rootscope or scope like myApp.directive('leaseInputDirective', function($rootScope, $scope)
got it working now
var myApp = angular.module('myApp', []);
myApp.controller('LeaseTemplateController', function($scope,$rootScope) {
//Lease Special Template
$rootScope.percent_id = [{
value: '20'
}];
});
myApp.directive('leaseTextDirective', function() {
return {
restrict: 'E',
replace: true, // Replace with the template below
transclude: true, // we want to insert custom content inside the directive
template: '<div class="leasespecial" ng-controller="LeaseTemplateController">\
<div class="firstsec">\
<div class="percNumber">\
<h1 id="perId" ng-repeat="bb in percent_id">{{bb.value}}</h1>\
</div>\
</div>'
};
});
myApp.directive('leaseInputDirective', function() {
return {
restrict: 'E',
replace: true, // Replace with the template below
transclude: true, // we want to insert custom content inside the directive
template: '<div><h2>Lease Special Template</h2>\
<form ng-controller="LeaseTemplateController">\
<div class="form-group" ng-repeat="cc in percent_id">\
<div class="input-group">\
<input class="form-control input" type="text" placeholder="Enter Percent" ng-model="cc.value">\
</div>\
</div>\
</form></div>'
};
});
<lease-text-directive>
</lease-text-directive>
<!-- leaseTextDirective -->
<lease-input-directive>
</lease-input-directive>
This is my directive code:
'use strict';
demo.directive('myModal', function($parse) {
return {
restrict: 'A',
transclude: true,
scope: '#',
template: '<div ng-transclude><h4>Please enter value</h4></div>'
}
});
Usage is as follows:
<!-- myModal directive -->
<div my-modal>
<input type="text" ng-model="myTest" />
<input type="button" ng-click="getMyTest()" value="Get Value" />
</div>
And my main controller, which wraps the whole application, includes this:
demo.controller('MainCtrl', function($scope) {
$scope.getMyTest = function(){
alert($scope.myTest);
}
});
Any ideas why can't I access myTest?
JsFiddle: http://jsfiddle.net/sZZEt/679/
You should use the dot-notation:
demo.controller('MainCtrl', function($scope) {
$scope.data = {};
$scope.getMyTest = function(){
alert($scope.data.myTest);
}
});
and
<div my-modal>
<input type="text" ng-model="data.myTest" />
<input type="button" ng-click="getMyTest()" value="Get Value" />
</div>
JSFIDDLE
Transclusion creates a child scope, that's why you should use the dot-notation for ng-model.
try this. add directive to model element.
<div>
<input my-modal type="text" ng-model="myTest" />
<input type="button" ng-click="getMyTest()" value="Get Value" />
</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)"