How to access value from one controller to the other using scope? - angularjs

I have two controllers: One with controls - textarea and button. And another that takes the value of the text from the textarea and then displays it. I am able push the value of the textarea into an array. But I cant access the array in another directive so that it wud display the value.
I am new to angular scopes.
First Controller:
This directive has its own controller.
angular.module('myApp')
.controller('listController', ['$scope','$compile','$http', function($scope, $compile, $http){
'ngInject';
var vm =this;
console.log("in addmectrl");
$scope.tasks=[];
$scope.cardarr =[];
vm.addme = function(){
$scope.tasks.push({title: vm.title, cardarr: []}); //pushes in to an array
}
}])
.directive('addListControls', function() {
return {
restrict: 'E', // Element directive'
controller: 'listController as listctrl2',
scope: { tasks: "#",
cardarr: "#"},
template: `
<textarea ng-model= "listctrl2.title" placeholder ="Add a List"
id="input" style = "position:absolute">
</textarea>
<button id="controlbutton" class ="btn btn success"
style = "position:absolute"
ng-click="listctrl2.addme()">Save
</button>
<img id ="remove" src ="remove.png"
ng-click ="listctrl2.removeinput()">`,
};
});
This directive accesses the parent controller.
Display the text in this template---
angular.module('myApp')
.directive('listWrapperTitlebox', function() {
return {
restrict: 'E', // Element directive
template: `
<b class ="card1" id ="cardtitle">{{task.title}}</b>
<a class ="card1" tabindex="0" data-trigger ="focus"
data-toggle="popover"
ng-click = "ctrl.listpopover($index)" >...</a>`
};
});

Related

How to pass a value from one controller to another controller? -angularjs

I am getting a value from a function in controller1. I want to set this value to controller2's directive's template. I am confused on how to use scope in this to achieve the same.
Html
<body ng-app = "myApp" ng-controller="parentcontroller as ctrl">
<div class ="boardcanvas" style ="overflow-x:auto;">
<div id = "board">
<list-wrapper ng-repeat="task in ctrl.tasks track by $index" class ="listwrapper" id = "listwrapper"></list-wrapper>
<add-list-controls class = "controls" tasks ="ctrl.tasks" ng-show ="ctrl.listcontrolarea"></add-list-controls>
</div>
</div>
</body>
Controller1 and its Directive:
angular.module('myApp')
.controller('listController', ['$scope','$compile','$http', function($scope, $compile, $http){
'ngInject';
$scope.tasks=[];
$scope.cardarr =[];
vm.addme = function(){
console.log(vm);
console.log($scope.tasks);
$scope.tasks.push({title: $scope.title, cardarr: []});
}
}])
.directive('addListControls', function() {
return {
restrict: 'E', // Element directive'
controller: 'listController as listctrl2',
scope: { tasks: "=",
cardarr: "="},
template: `<textarea ng-model= "listctrl2.title" placeholder ="Add a List" id="input" style = "position:absolute"></textarea>
<button id="controlbutton" class ="btn btn success" style = "position:absolute" ng-click="listctrl2.addme()">Save
</button>`,
};
});
Controller2 and its Directive:
.controller('listWrapperController', ['$scope','$compile','$http', function($scope, $compile, $http){
'ngInject';
$scope.tasks=[];
}])
.directive('listWrapper', function() {
return {
restrict: 'E', // Element directive
scope:{
tasks: '='
},
controller: 'listWrapperController as listctrl',
template: `<div id="titlebox">
<b class ="card1" tasks="listctrl.task" id ="cardtitle">
{{task.title}} // set the value from controller1 here
</b>
</div> `
};
});
You are initalizing the $scope.tasks array on both controllersand this override the original $scope.task reference (ctrl.tasks) that is set by directive definititon.
Try comment or initialize only if undefined
$scope.tasks= $scope.tasks || [];
$scope.cardarr = $scope.cardarr || [];
The listWrapper directive must be changed andd translate the ng-repeat to its template:
HTML
<list-wrapper tasks="ctrl.tasks"></list-wrapper>
listWrapper directive
(...)
.directive('listWrapper', function() {
return {
restrict: 'E', // Element directive
scope:{
tasks: '='
},
controller: 'listWrapperController as listctrl',
template:
`<div id="titlebox" ng-repeat="task in tasks track by $index" class ="listwrapper" id = "listwrapper">
<b class ="card1" id ="cardtitle">
{{task.title}} // set the value from controller1 here
</b>
</div> `
};
});

How to access ng-model value in directive?

I created a directive for google map auto-complete. everything is working fine, but the problem is when I need to access the value of input and re-set it. it doesn't work. Here is code:
<div controller='mainCtr'>
<span click='reset(destination)'>Reset</span>
<div class='floatleft' style='width:30%;margin-right:40px;'>
<smart-Googlemaps locationgoogle='destination.From'></smart-Googlemaps>
<label>From</label>
</div>
</div>
In the directive:
angular.module('ecom').directive('smartGooglemaps', function() {
return {
restrict:'E',
replace:false,
// transclude:true,
scope: {
locationgoogle: '='
},
templateUrl: 'components/directives/autocomplete/googlemap-search.html',
link: function($scope, elm, attrs){
var autocomplete = new google.maps.places.Autocomplete($(elm).find("#google_places_ac")[0], {});
google.maps.event.addListener(autocomplete, 'place_changed', function() {
var place = autocomplete.getPlace();
// $scope.location = place.geometry.location.lat() + ',' + place.geometry.location.lng();
// console.log(place);
$scope.locationgoogle = {};
$scope.locationgoogle.formatted_address = place.formatted_address;
$scope.locationgoogle.loglat = place.geometry.location;
$scope.locationgoogle.locationText = $scope.locationText;
$scope.$apply();
});
}
}
})
Here is html for directive:
<input id="google_places_ac" placeholder="Please enter a location" name="google_places_ac" type="text" class="input-block-level" ng-model='locationText'/>
The directive works fine, I create a isolated scope(locationgoogle) to pass the information I need to parent controller(mainCtr), now in the mainCtr I have a function calld reset(), after I click this,I need to clean up the input make it empty. How Can I do it?
One way to access the value of the model in your directive from a parent controller is to put that on the isolate scope too and use the two-way binding flag = like you've done with the locationgoogle property. Try this:
DEMO
html
<body ng-controller="MainCtrl">
<button ng-click="reset()">Reset</button>
<smart-googlemaps location-text="locationText"></smart-googlemaps>
</body>
js
app.controller('MainCtrl', function($scope) {
// need to define model in parent and pass to directive
$scope.locationText = {
value: ''
};
$scope.reset = function(){
$scope.locationText.value = '';
}
});
app.directive('smartGooglemaps', function() {
return {
restrict:'E',
replace:false,
// transclude:true,
scope: {
locationgoogle: '=',
locationText: '='
},
// ng-model="locationText.value"
template: '<input id="google_places_ac" placeholder="Please enter a location" name="google_places_ac" type="text" class="input-block-level" ng-model="locationText.value"/>',
link: function($scope, elm, attrs){
// implement directive googlemaps logic, set text value etc.
$scope.locationText.value = 'foo';
}
}
})

Angular - understanding directive isolated scope method

take a look at the following code:
html:
<body ng-app="myApp">
<div ng-controller="MainController">
<input type="button" ng-click="talk()" value="outside directive" />
<div my-element>
<input type="button" ng-click="talk()" value="inside directive" />
</div>
</div>
</body>
js:
var app = angular.module('myApp', []);
app.controller('MainController', function($scope){
$scope.talk = function() {
alert('HELLO1');
}
});
app.directive('myElement', function(){
return {
restrict: 'EA',
scope: {},
controller: function($scope) {
$scope.talk = function() {
alert('HELLO2');
}
}
};
});
as you can see, there's a controller, which nests a directive.
there are 2 buttons, one in controller level (outside of directive), and one is inside the directive my-element.
the main controller defines a scope method talk, the nested directive controller also defines a method - talk - but keep in mind that directive has isolated scope (i'd expect that talk method won't be inherited into directive's scope).
both buttons result an alert of 'HELLO 1', while i expected the second button (inside directive) to alert 'HELLO 2' as defined in directive controller, but it doesn't - WHY?
what am i missing here? how could i get a result when the second button will alert 'HELLO 2' but with the same method name ("talk") ?
thanks all
If you want the inner content to use the directive scope, you need to use manual transclusion:
app.directive('myElement', function(){
return {
restrict: 'EA',
scope: {},
transclude: true,
link: function(scope, element, attr, ctrl, transclude) {
transclude(scope, function(clone, scope) {
element.append(clone);
});
},
controller: function($scope) {
$scope.talk = function() {
alert('HELLO2');
}
}
};
});
By default, transcluded content uses a sibling of the directive scope. I actually don't know how angular handles DOM content for directives that don't use transclude (which is what makes this an interesting question), but I would assume from the behavior you are seeing that those elements use the directive's parent scope by default.
This will work for you
<body ng-app="myApp">
<div ng-controller="MainController">
<input type="button" ng-click="talk()" value="outside directive" />
<div my-element></div>
</div>
</body>
app.directive('myElement', function(){
return {
restrict: 'A',
template: '<input type="button" ng-click="talk()" value="inside directive">',
replace: true,
scope: {},
controller: function($scope) {
$scope.talk = function() {
alert('HELLO2');
}
}
};
});

Using custom directive with isolated scope, in a modal

I use a custom directive to get places from Google API. This directive works like a charm in a controller. But when I want to use it inside a modal, it doesn't work any more. It's a question of scope, but I can't figure out what's exactly happened. Any idea ?
My directive :
'use strict';
angular.module('app').directive('googleplace', function() {
return {
require: 'ngModel',
scope: {
ngModel: '=',
details: '=?'
},
link: function(scope, element, attrs, model) {
var options;
options = {
types: ['address'],
componentRestrictions: {}
};
scope.gPlace = new google.maps.places.Autocomplete(element[0], options);
google.maps.event.addListener(scope.gPlace, 'place_changed', function() {
scope.$apply(function() {
scope.details = scope.gPlace.getPlace();
if (scope.details.name) {
element.val(scope.details.name);
model.$setViewValue(scope.details.name);
element.bind('blur', function(value) {
if (value.currentTarget.value !== '') {
element.val(scope.details.name);
}
});
}
});
});
}
};
});
My modal controller :
modalInstance = $modal.open
templateUrl: "modal.html"
controller: ($scope, $modalInstance) ->
$scope.$watch 'placeDetails', ->
_.forEach $scope.placeDetails.address_components, (val, key) ->
$scope.myaddress = val.short_name + ' ' if val.types[0] is 'street_number'
return
And finally, my html :
<div class="modal-body">
<div>
<input type="text" placeholder="Start typing" ng-model="address" details="placeDetails" googleplace />
</div>
<div>
<input type="text" ng-model="myaddress">
</div>
</div>
I should have the ng-model="address" populated with the result of the call to Google Place API, and the ng-model="myaddress" populated by the $watch, but nothing happens.
Here is my plunkr http://plnkr.co/edit/iEAooKgfUUfxoBWm8mgw?p=preview
Click on "Open modal" causes the error : Cannot read property 'address_components' of undefined
working demo
According to how to create modal in angularjs
Extra things that i added :
1 : New Controller for modal
2 : Blur function that fires on property change Instead of $watch

AngularJS - How do I access the form defined inside a templateUrl in my directive?

I am attempting to access the form inside my directive for validation purposes, so I'd like access to $setPristine, however, I can't seem to figure out how to get the form if it's created using a templateUrl.
I have a plunker detailing the issue here: http://plnkr.co/edit/Sp53xzdTbYxL6DAue1uV?p=preview
I'm getting an error:
Controller 'form', required by directive 'testDirective', can't be found!
Here is the relevant Plunker code:
.js:
var app = angular.module("myApp", []);
app.directive("testDirective", function() {
return {
restrict: 'E',
scope: {},
templateUrl: "formTemplate.html",
require: "^form", // <-- doesn't work
link: function (scope, element, attrs, ctrl) {
console.log(ctrl);
scope.open = function() {
// Would like to have access to the form here
// ctrl.$setPristine();
}
},
controller: function($scope) {
$scope.firstName = "Mark";
$scope.save = function(form) {
console.log(form);
}
}
}
})
formTemplate.html:
<form name="testForm" ng-click="save(testForm)">
<input type="text" ng-model="firstName" />
<br>
<input type="submit" value="Save" />
</form>
How can I attach the form in formTemplate.html to the isolated scope of my directive?
http://plnkr.co/edit/41hhRPKoIsZ9C8Y9Yi87?p=preview
Try this in your directive:
var form1 = element.find('form').eq(0);
formCtrl = form1.controller('form');
console.log(formCtrl);
this should grab the controller for the form.

Resources