2-way binding is lot when using $templateRequest - javascript

I have a template, which is loaded using $templateRequest. I have a textarea in the template. The textarea populates the value, that is set in the controller. But when I am trying to access the textarea in the controller method, it does not update the value.
Template
<div class="panel add-notes">
<div class="panel-body">
<textarea ng-model="quickNote" rows="5"/>
<button ng-click="saveNotes()">Add Note</button>
</div>
</div>
</div>
Method to load the template
$scope.displayPanel = function(templateName){
var templateURL = resourceURL+templateName+".html";
$templateRequest(templateURL).then(function(template) {
$compile($("#modalContent").html(template).contents())($scope);
},function() {
//ERROR HANDLER
});
};
Controller Method
$scope.saveNotes = function(){
console.log($scope.quickNote);
}
In the console log, the value of quickNote is displayed as undefined. Any resolution?

Related

Cannot interpolate vm.value in template - AngularJS

I am updating and modifying a project using Angular JS 1.2.25.
I have my controller where I have a value called vm.stageValue which is then called in template with an ng-if, so when the vm.stageValue increments it shows different containers. But whhen I define a value on the vm object that I want to interpolate on the template, eg a string that will be used and will not change on the template, I cannot seem to get it display.
This has makes me think I have not set up my controller correctly using the vm method.
It seems weird that I can use the ng-if and call function from the controller using ng-click on the template but I cannot interpolate a string or send it to another child component
Code is below, thank you in advance. Any help would be hugely appreciated
Controller
angular
.module('formModule')
.controller('NewBusinessFormCtrl', [
function() {
let vm = this;
// Methods used in controller
vm.methods = {
incrementStageValue: incrementStageValue,
decrementStageValue: decrementStageValue,
canIncrement: canIncrement,
canDecrement: canDecrement
};
//Initial stage values
vm.stageValue = 1;
vm.maxStageValue = 7;
// This is the string that I want to interpolate below
vm.contactFormCategory = 'New Business';
}
]);
Template of Controller
<div class="new_busines_cf" ng-controller="NewBusinessFormCtrl as vm">
<div class="form_wrapper">
<div ng-if="vm.stageValue == 1">
<input-text
class="form_input"
ng-model="ngModel"
input-text-label="This is the label">
</input-text>
// I want to send the vm.contactFormCategory into the component
// Value is sending but the component display 'vm.contactFormCategory'
// Not the value set in the controller
<form-headline
form-headline-sup-title="vm.contactFormCategory"
form-headline-text="This is a form headline text">
</form-headline>
</div>
// Trying to interpolate value here into template, but nothing display
{{vm.contactFormCategory}}
<div ng-if="vm.stageValue == 2">
<input-text
class="form_input"
ng-model="ngModel"
input-text-label="This is the label of stage 2">
</input-text>
<form-headline
form-headline-sup-title="vm.contactFormCategory"
form-headline-text="This is a form headline text">
</form-headline>
</div>
<button ng-click="vm.methods.incrementStageValue()">Increment Value</button>
<button ng-click="vm.methods.decrementStageValue()">decrement Value</button>
</div>
</div>
** Form Headline **
angular
.module('formModule')
.directive('formHeadline', function() {
return {
restrict: 'E',
templateUrl: '/partials/form/form-headline.component.html',
scope: {
formHeadlineText: '#',
formHeadlineSupTitle: '#'
},
link: function () {
}
};
});
Change your ng-if to
<div ng-if="vm.stageValue === '2'">

Angular: How can I call a controller function from an HTML view using ng-if or another Angular directive

My question is; how can I call a controller function from my view when a condition is met/equates to true, using ng-if or perhaps some other Angular directive?
Something like this:
<div ng-if="dataHasBeenLoaded == 'true'" ng-init="configureWordCloudGraph()"></div>
This is what I would like to achieve:
When my data has loaded and was retrieved via my API call, I would like to set a $scope variable ($scope.dataHasBeenLoaded = true;) to true. And when this $scope variable === true, it is evaluated in my DOM, and then calls a function configureWordCloudGraph() in my controller:
$scope.configureWordCloudGraph = function () {
if ($scope.dataHasBeenLoaded) {
var data = $scope.wordCloudData;
$scope.twitterProfileWords = WordCloud.setUpTags(data.words);
}
}
This is my view:
<div ng-controller="TwitterWordCloudController">
<div id="word">
<og-data-box heading="Most used words on Twitter" link="" uid="socialMentionsMeta" description="">
<div class="dataStatus" ng-show="!dataContent">{{dataStatus}}<og-loading-indicator></og-loading-indicator></div>
<div class="dataContent" ng-show="dataContent" ng-mouseover="showGraphTrainingInfo()">
<og-word-cloud words="twitterProfileWords"></og-word-cloud>
<div ng-if="dataHasBeenLoaded == 'true'" ng-init="configureWordCloudGraph()"></div>
</div>
</og-data-box>
</div>
</div>
Simple way can be to watch dataHasBeenLoaded and launch configureWordCloudGraph when true :
var deregister = $scope.$watch('dataHasBeenLoaded', function() {
if($scope.dataHasBeenLoaded) {
configureWordCloudGraph();
deregister();
}
})
As per the comment from selvassn, the way to call an Angular controller from an HTML view is as follows:
NOTE: I'll break it down in 3 parts of code; Just the HTML method call, the controller method, the complete HTML code including the controller method call.
Just the HTML Controller Method call code:
<div ng-if="dataHasBeenLoaded == 'true'" ng-init="configureWordCloudGraph()"></div>
Controller Method:
$scope.configureWordCloudGraph = function () {
if ($scope.dataHasBeenLoaded) {
var data = $scope.wordCloudData;
$scope.twitterProfileWords = WordCloud.setUpTags(data.words);
}
}
HTML view Controller Method call:
<div ng-controller="TwitterWordCloudController">
<div id="word">
<og-data-box heading="Most used words on Twitter" link="" uid="socialMentionsMeta" description="">
<div class="dataStatus" ng-show="!dataContent">{{dataStatus}}<og-loading-indicator></og-loading-indicator></div>
<div class="dataContent" ng-show="dataContent" ng-mouseover="showGraphTrainingInfo()">
<og-word-cloud words="twitterProfileWords"></og-word-cloud>
<div ng-if="dataHasBeenLoaded == 'true'" ng-init="configureWordCloudGraph()"></div>
</div>
</og-data-box>
</div>
</div>

Angular JS data binding in component is not working

I am using Angular JS 1.5.6 components to build dynamically a form. The hierarchy is the following : index.html calls component my-view which calls component my-form which calls unitary components like inputs and button.
The issue is that the data binding is not working because any modification in input components is not taken into account into my-view component.
Besides I have a weird behavior, each time I update input value, a call is made to view component function.
I have plunkered this, the submit button triggers console.log (so need to open firebug to see it in action).
Here is my index.html
<body ng-app="MyApp">
<my-view></my-view>
</body>
Here is myView.html
<div class="container">
<h2>With component myform</h2>
<my-form form-elements="
[{type:'input', label:'First name', placeholder:'Enter first name',model:$ctrl.userData.firstName, id:'firstName'},
{type:'input', label:'Last name', placeholder:'Enter last name',model:$ctrl.userData.lastName, id:'lastName'},
{type:'button', label:'Submit', click:$ctrl.click()}]"></my-form>
</div>
<div class="container">
<h2>Check data binding</h2>
<label>{{$ctrl.userData.firstName}}</label>
<label>{{$ctrl.userData.lastName}}</label>
</div>
Here is myView.js
(function() {
'use strict';
angular.module('MyApp').component('myView', {
templateUrl: 'myView.html',
controller: MyViewController,
bindings: {
viewFormElements: '<'
}
});
function MyViewController() {
this.userData = {
firstName: 'François',
lastName: 'Xavier'
};
function click() {
console.log("Hello " + this.userData.firstName + " " + this.userData.lastName);
}
this.click = click;
}
})();
I manage to solve my issue with 2 way binding and by putting form-element in an object instead of putting it directly in the view ($ctrl.formElements). It is on plunker.
myView.html
<div class="container">
<h2>With component myform</h2>
<my-form form-elements=$ctrl.formElements></my-form>
</div>
<div class="container">
<h2>Check data binding</h2>
<label>{{$ctrl.formElements}}</label><br />
</div>'

binding to controller object in Angular

I'm new to angular, trying to bind an an element's content into the controller's Scope to be able to use it within another function:
here is the scenario am working around:
I want the content of the <span> element {{y.facetName}} in
<span ng-model="columnFacetname">{{y.facetName}}</span>
to be sent to the controller an be put in the object $scope.columnFacetname in the controller
Here is a snippet of what I'm working on:
<div ng-repeat="y in x.facetArr|limitTo: limit track by $index ">
<div class="list_items panel-body ">
<button class="ButtonforAccordion" ng-click="ListClicktnColumnFilterfunc(); onServerSideButtonItemsRequested(ListClicktnColumnFilter, myOrderBy)">
<span>{{$index+1}}</span>
<span ng-model="columnFacetname">{{y.facetName}}</span>
<span>{{y.facetValue}}</span>
</button>
</div>
</div>
angular.module('mainModule').controller('MainCtrl', function($scope, $http) {
$scope.columnFacetname = "";
$scope.ListClicktnColumnFilter = "";
$scope.ListClicktnColumnFilterfunc = function() {
$scope.ListClicktnColumnFilter = "\":\'" + $scope.columnFacetname + "\'";
};
}
the problem is that the $scope.ListClicktnColumnFilter doesn't show the $scope.columnFacetname within it, meaning that the $scope.columnFacetname is not well-binded.
In your ng-click instead of calling two different function
ng-click="ListClicktnColumnFilterfunc(); onServerSideButtonItemsRequested(ListClicktnColumnFilter, myOrderBy)"
you can declare like this
ng-click="columnFacetname = y.facetName; onServerSideButtonItemsRequested(columnFacetname , myOrderBy)"
You are trying to pass that model to another function by assigning it to ListClicktnColumnFilter in your controller
By doing in this way, you can achieve the same thing.
I have done one plunker with sample array,
http://embed.plnkr.co/YIwRLWXEOeK8NmYmT6VK/preview
Hope this helps!

Can't access form values in a $modalInstance

I'm opening a $modalInstance in which user has to choose an option from radio inputs (values loaded dynamically) and return chosen value.
I have this function to open the $modalInstance:
$scope.openAddFriendGroup = function () {
var addFriendGroupModal = $modal.open({
templateUrl: "addFriendGroupModal.html",
controller: ModalAddFriendGroupCtrl,
resolve: {
myDetails: function () {
return $scope.info;
}
}
});
};
Then this is the $modalInstance controller:
var ModalAddFriendGroupCtrl = function ($scope, $modalInstance, myDetails, groupsSvc) {
$scope.addableFriends = [];
$scope.chosenFriend = null;
//here goes a function to retrieve value of $scope.addableFriends upon $modalInstance load
$scope.addFriend = function () {
$scope.recording = true;
groupsSvc.addFriend($scope.chosenFriend, myDetails).then(function (response) {
if(response.status && response.status == 200) {
$modalInstance.close($scope.userid);
}
}, function (err) {
$modalInstance.dismiss(err);
});
};
};
And this is addFriendGroupModal.html, the HTML for the modal itself:
<div id="add-friend-group-modal">
<div class="modal-header">
<h3 class="modal-title">Add friend</h3>
</div>
<div class="modal-body">
<form class="form" role="form" ng-hide="loading">
<div class="form-group">
<label class="control-label">Friend:</label>
<div class="radio" ng-repeat="thisFriend in addableFriends">
<label>
<input type="radio" id="friend{{thisFriend.id}}" name="chosenFriend" ng-model="$parent.chosenFriend" ng-value="thisFriend" /> {{thisFriend.name}} {{thisFriend.surname}}
</label>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="addFriend()">Add friend</button>
</div>
</div>
Now, the problem comes when I try to retrieve the value that has been selected in the radio buttons of the form in the modal. I can't seem to retrieve this value in $scope.addFriend. The value of $scope.chosenFriend stays at null and does not get updated when selecting a radio option.
What am I doing wrong?
$modal.open returns promise so try :
var addFriendGroupModal;
$modal.open({ ...})
.result.then(function(response){
addFriendGroupModal = response;
});
<input type="radio" id="friend{{thisFriend.id}}" name="chosenFriend" ng-model="$parent.chosenFriend" ng-value="thisFriend" /> {{thisFriend.name}} {{thisFriend.surname}}
in here your ng-model is $parent.chosenFriend so, why are you expecting $scope.chosenFriend to not be a null? change you ng-model property to $scope.chosenFriend.
Retrieved answer from a related question, by gertas
Angular-UI modals are using transclusion to attach modal content, which means any new scope entries made within modal are created in child scope. This happens with form directive.
This is known issue: https://github.com/angular-ui/bootstrap/issues/969
I proposed the quick workaround which works for me, with Angular 1.2.16:
<form name="$parent.userForm">
The userForm is created and available in modal's controller $scope. Thanks to scope inheritance userForm access stays untouched in the markup.
<div ng-class="{'has-error': userForm.email.$invalid}"}>
So, in my form I would have to set a name="$parent.friendForm" attribute to <form>, and then bind the radio button model to it, ng-model="friendForm.chosenFriend" to be able to read it from the modal scope at $scope.friendForm.chosenFriend.

Categories

Resources