How to bring dynamicaly scope in view - angularjs

In my controller I have this code:
$scope.lists = [{
listName: 'list1'
}, {
listName: 'list2'
}];
angular.forEach($scope.lists, function(item) {
var listName = item.listName;
$scope[listName] = [{
Name: 'Stefan'
}, {
Name: 'Stefan'
}, {
Name: 'Stefan'
}, {
Name: 'Stefan'
}];
});
The Input from lists cames from a webservice, so the values (list1 and list2) can be different each time i reload the app. I can also more then 2 items in lists.
How can I show the value from $scope[listName] in an ng-repat section in my view?
Thanks for your Help.
Stefan.

You might try something like this:
(function() {
angular.module("myApp", []).controller("controller", ["$scope",
function($scope) {
$scope.lists = [{
listName: "list1"
}, {
listName: "list2"
}];
angular.forEach($scope.lists, function(item) {
var listName = item.listName;
$scope[listName] = [{
Name: "Stefan"
}, {
Name: "Stefan"
}, {
Name: "Stefan"
}, {
Name: "Stefan"
}];
$scope.results = $scope[listName];
});
}
]);
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div data-ng-app="myApp">
<div data-ng-controller="controller">
<ul>
<li data-ng-repeat="item in results">{{item.Name}}</li>
</ul>
</div>
</div>

Related

Angular recursive directive to represent tree structure needs adding file list

I have been attempting to update this directive to add fileList into the tree structure, but I was not successful. The original works fine (https://embed.plnkr.co/plunk/JgQu3r), but it considers directories only. In my data structure any directory can have a fileList, as well as any number of nested directoryList and so on.
function MainController($scope) {
$scope.menu = [{
name: 'one',
directoryList: [{
name: 'one'
}, {
name: 'two'
}],
fileList: ['one.pdf', 'two.pdf', 'three.pdf']
},
{
name: 'two',
directoryList: [{
name: 'one',
directoryList: [{
name: 'one'
}],
fileList: ['one.pdf', 'two.pdf', 'three.pdf', 'four.pdf']
}]
},
{
name: 'three'
}
];
}
function myMenu() {
return {
scope: {
myMenu: '=myMenu'
},
template: '<li ng-repeat="item in myMenu"><my-menu-item></my-menu-item></li>',
link: function(scope, elem) {}
}
}
function myMenuItem($compile) {
return {
template: '<a href ng-bind="item.name" ng-click="show($event)"></a>',
link: function(scope, element) {
if (angular.isArray(scope.item.menu)) {
element.append($compile('<ul ng-if="collapsed" my-menu="item.menu"></ul>')(scope));
}
scope.show = function($event) {
scope.collapsed = !scope.collapsed;
}
}
}
}
angular.module('app', [])
.controller('MainController', MainController)
.directive('myMenu', myMenu)
.directive('myMenuItem', myMenuItem);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.14/angular.js"></script>
<body ng-app="app" ng-controller="MainController">
<ul my-menu="menu">
</ul>
</body>
You need to distinguish between files and folders. Just treat the folders like you treat it in your example, and treat your files separately. The following snippet works, but I recommend that you take a minute to think about why and how it works.
function MainController($scope) {
$scope.menu = [{
name: 'one',
directoryList: [{
name: 'one'
}, {
name: 'two'
}],
fileList: ['one.pdf', 'two.pdf', 'three.pdf']
},
{
name: 'two',
directoryList: [{
name: 'one',
directoryList: [{
name: 'one'
}],
fileList: ['one.pdf', 'two.pdf', 'three.pdf', 'four.pdf']
}]
},
{
name: 'three'
}
];
}
function myMenu() {
return {
scope: {
myMenu: '=myMenu'
},
template: '<li ng-repeat="item in myMenu"><my-menu-item></my-menu-item></li>',
link: function(scope, elem) {}
}
}
function myMenuItem($compile) {
return {
template: `
<a href ng-bind="item.name" ng-click="show($event)"></a>
`,
link: function(scope, element) {
if (angular.isArray(scope.item.directoryList)) {
element.append($compile('<ul ng-if="!collapsed" my-menu="item.directoryList"></ul>')(scope));
}
if (angular.isArray(scope.item.fileList)) {
element.append($compile(`
<ul ng-if="item.fileList && !collapsed">
<li ng-repeat="file in item.fileList">{{file}}</li>
</ul>
`)(scope));
}
scope.collapsed = true;
scope.show = function($event) {
scope.collapsed = !scope.collapsed;
}
}
}
}
angular.module('app', [])
.controller('MainController', MainController)
.directive('myMenu', myMenu)
.directive('myMenuItem', myMenuItem);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.14/angular.js"></script>
<body ng-app="app" ng-controller="MainController">
<ul my-menu="menu">
</ul>
</body>

How to access element from an array of objects returned from node in Angular?

I'm getting an array of objects in my $http.get request. I am doing the following:
$http.get("/showdata").then(function (response) {
var thedata = response.data.category;
console.log(thedata);
$scope.alldata = response.data;
if (thedata === "school") {
$scope.category = "SchoolBC";
} else {
$scope.category = "Not School";
}
});
How can i check something in the response and set the $scope accordingly?
What I get in return is:
[
{
id: "123456",
category: "school",
title: "first test"
},
{
id: "789012",
category: "home",
title: "second test"
}
]
In the frontend I have:
<ul ng-repeat = "mydata in alldata">
<li>{{mydata.title}}<p>{{category}}</p></li>
</ul>
Updated the answer based on comments and edit of your question. Loop through objects in array and override object property according to condition:
var app = angular.module("app", []);
app.controller("ctrl", function($scope) {
var thedata = [
{
id: "123456",
category: "school",
title: "first test"
},
{
id: "789012",
category: "home",
title: "second test"
},
{
id: "789012",
category: ['home', 'school', 'primary', 'pre-primary', 'test', 'test1', 'test2' ],
title: "third test"
}
];
function overrideObjectValue(data) {
angular.forEach(data , function(value, key){
if(typeof value.category === 'object') {
if ($.inArray('school', value.category)) {
data[key].category = "SchoolBC";
} else {
data[key].category = "Not School";
}
} else {
if (value.category === "school") {
data[key].category = "SchoolBC";
} else {
data[key].category = "Not School";
}
}
});
return data;
}
$scope.alldata = overrideObjectValue(thedata);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<ul ng-repeat = "mydata in alldata">
<li>{{mydata.title}}<p>{{mydata.category}}</p></li>
</ul>
</div>

ng-click does not call function in mdDialog

I am a little new to AngularJS but I cannot figure out why the ng-click here will not call th addingSt() function, I wonder if it has something to do with the fact that it is being called from a mdDialog. Thanks for your help.
Heres my html for the mdDialog:
<md-dialog aria-label="Send Email">
<md-dialog-content>
<h3>Issue Details</h3>
<h4>Description</h4>
<md-input-container>
<label>Add description:</label>
<textarea class="form-control input-lg" style="width: 500px; height:100px;"></textarea>
</md-input-container>
<h3>Sub-tasks:</h3>
<md-list-item ng-repeat=" subtask in subtasks">
<p>{{subtask.content}}</p>
<md-checkbox aria-label="blarg" class="md-secondary" style="padding-right:60px;" ng-click="removeSubTask(subtask,$index)"></md-checkbox>
<md-list-item ng-if="addingTask === true"> <input ng-if="addingTask===true" ng-model="task.content" aria-label="blarg" placeholder="Add Subtask Here"></input>
</md-dialog-content>
<md-dialog-actions>
<md-button ng-show="addingTask === false" ng-click="addingSt()" class="btn btn-primary">
Add Sub-Task
</md-button>
<md-button ng-show="addingTask === true" ng-click="addingSt()" class="btn btn-primary">
cancel
</md-button>
<md-button ng-show="addingTask === true" ng-click="addSubTask()" class="btn btn-primary">
Submit
</md-button>
<md-button ng-click="closeDialog()" class="btn btn-primary">
Close
</md-button>
Here's the controller for the parent of the above mdDialog, (the controller for the mdDialog is nested inside it and works fine for all functions accept the addingSt() function)
var app = angular.module('epr')
app.controller('adminMainCtr',[ '$scope','$mdDialog',function($scope, $mdDialog) {
$scope.issues = [
{ name: 'Blizzard', img: 'img/100-0.jpeg', WardMessage: true, index:0, subtasks:[{content:"Shovel Sister Pensioner's Driveway "},
{content:"Clear downed trees at the Bush's home "}]},
{ name: 'Tornado', img: 'img/100-1.jpeg', WardMessage: false, index:1, subtasks:[{content:"",index:0}] },
{ name: 'Peterson Family Car Crash', img: 'img/100-2.jpeg', WardMessage: false, index:2, subtasks:[{content:"",index:0}] },
{ name: 'Flood', img: 'img/100-2.jpeg', WardMessage: false, index:3, subtasks:[{content:"",index:0}] },
{ name: 'School Shooting', img: 'img/100-2.jpeg', WardMessage: false, index:4, subtasks:[{content:"",index:0}] }
];
$scope.goToIssue = function(issue, event) {
var parentEl = angular.element(document.body);
$mdDialog.show({
//parent: parentEl,
templateUrl:'views/issue.html',
locals: {
items: $scope.items,
issue: issue
},
controller: DialogController
});
function DialogController($scope, $mdDialog) {
$scope.subtasks = issue.subtasks;
$scope.addingTask = false;
$scope.task={content:""};
$scope.closeDialog = function() {
console.log($scope.addingTask);
$mdDialog.hide();
}
$scope.removeSubTask = function(subtask,index){
$scope.subtasks.splice(index,1);
}
}
$scope.addSubTask = function() {
console.log("here");
}
$scope.addingSt = function() {
if($scope.addingTask === false) {
console.log($scope.addingTask);
$scope.addingTask = true;
return;
}
if($scope.addingTask === true) {
$scope.addingTask = false;
return;
}
}
}
}]);
Any help that you can lend me would be very appreciated!!!
You messed with the HTML and angylar code.
Errors found:
1) angular module initialization.
var app = angular.module('MyApp', ['ngMaterial'])
2) You placed some function outside the DialogController
3) md-list-item HTML has no end tags.
Created working Plunkr here. https://plnkr.co/edit/Sl1WzLMCd8sW34Agj6g0?p=preview . Hope it will solve your problem.
(function() {
'use strict';
var app = angular.module('MyApp', ['ngMaterial'])
app.controller('adminMainCtr', ['$scope', '$mdDialog', function($scope, $mdDialog) {
$scope.issues = [{
name: 'Blizzard',
img: 'img/100-0.jpeg',
WardMessage: true,
index: 0,
subtasks: [{
content: "Shovel Sister Pensioner's Driveway "
}, {
content: "Clear downed trees at the Bush's home "
}]
}, {
name: 'Tornado',
img: 'img/100-1.jpeg',
WardMessage: false,
index: 1,
subtasks: [{
content: "",
index: 0
}]
}, {
name: 'Peterson Family Car Crash',
img: 'img/100-2.jpeg',
WardMessage: false,
index: 2,
subtasks: [{
content: "",
index: 0
}]
}, {
name: 'Flood',
img: 'img/100-2.jpeg',
WardMessage: false,
index: 3,
subtasks: [{
content: "",
index: 0
}]
}, {
name: 'School Shooting',
img: 'img/100-2.jpeg',
WardMessage: false,
index: 4,
subtasks: [{
content: "",
index: 0
}]
}];
$scope.goToIssue = function(issue, event) {
var parentEl = angular.element(document.body);
$mdDialog.show({
templateUrl: 'mddialog.html',
locals: {
message: {
items: $scope.items,
issue: issue
}
},
controller: DialogController
});
}
function DialogController($scope, $mdDialog, message) {
console.log(message)
//$scope.subtasks = message.issue.subtasks;
$scope.addingTask = false;
$scope.task = {
content: ""
};
$scope.closeDialog = function() {
console.log($scope.addingTask);
$mdDialog.hide();
}
$scope.removeSubTask = function(subtask, index) {
$scope.subtasks.splice(index, 1);
}
$scope.addSubTask = function() {
console.log("here");
}
$scope.addingSt = function() {
if ($scope.addingTask === false) {
console.log($scope.addingTask);
$scope.addingTask = true;
return;
}
if ($scope.addingTask === true) {
$scope.addingTask = false;
return;
}
}
}
}]);
})();

Angular custom filter into javascript only

I have some checkboxes and a list. I have made a custom filter to filter the results of that list according to the checkbox that is selected.
The problem is that I plan to have quite a lot of these checkboxes filtering the results so I would like to move all aspects of the filtering into the javascript. I have seen that this is possible by adding it into the controller but I have not been able to. Could someone point me in the right direction?
Here is the fiddle: http://jsfiddle.net/webgremlin/qpyngzu8/
html
<div ng-app="someApp">
<div ng-controller="checkboxCtrl">
<label ng-repeat="tree in trees">
{{ tree.name }}
<input type="checkbox" ng-model="tree.selected"/>
</label>
</div>
<hr />
<div ng-controller="listCtrl">
<ul>
<li ng-repeat="item in listItems | filterByCategory : trees">
{{ item.name }}
</li>
</ul>
</div>
</div>
js
var someApp = angular.module('someApp', []);
someApp.factory('checkboxFactory', function() {
var checkboxFactory = [
{ name: 'item 1', item: 1 },
{ name: 'item 2', item: 2 },
{ name: 'item 3', item: 3 }
];
return checkboxFactory;
});
someApp.factory('listFactory', function() {
var listFactory = [
{ name: 'list item 01', item: 1 },
{ name: 'list item 02', item: 2 },
{ name: 'list item 03', item: 3 },
{ name: 'list item 04', item: 1 },
{ name: 'list item 05', item: 2 },
{ name: 'list item 06', item: 3 },
{ name: 'list item 07', item: 1 },
{ name: 'list item 08', item: 2 },
{ name: 'list item 09', item: 3 },
{ name: 'list item 10', item: 1 }
];
return listFactory;
});
someApp.filter('filterByCategory', function() {
return function(input, trees) {
console.log(input, trees);
var ret =[];
for (var i in input){
var match = false;
for (var j in trees){
if (trees[j].selected && trees[j].item == input[i].item){
ret.push(input[i]);
}
}
}
if (ret.length > 0){
return ret;
} else {
return input;
}
};
})
someApp.controller('checkboxCtrl', ['$scope','checkboxFactory',
function($scope, checkboxFactory) {
$scope.trees = checkboxFactory;
}]);
someApp.controller('listCtrl', ['$scope','checkboxFactory','listFactory',
function($scope, checkboxFactory,listFactory) {
$scope.trees = checkboxFactory;
$scope.listItems = listFactory;
console.log($scope.listItems);
}]);
You can do that. Just use the $filter provider to look up your filterByCategory filter in your controller and apply it that way:
Fiddle here:
http://jsfiddle.net/smaye81/gp4qg257/2/

Angular JS - How can i animate on model change?

i'm trying to do a nice fadeout+fadein transition when the currentVertical changes.
in knockout it was so simple but i can't figure it out here. please help.
the following code displays a UL list which is "bound" to a pricings array in the $scope.currentVertical when an LI element is clicked, the $scope.currentVertical is changed and the UL list updates accordingly. This works fine, but i would like the entire #container div to fade out and fadein when $scope.currentVertical is changed. Please help...
My html:
<body>
<h1>Pricing Poll</h1>
<div ng-controller="VerticalsController">
<div id="container">
<h2>{{currentVertical.title}}</h2>
<ul>
<li ng-repeat="pricing in currentVertical.pricings">
<a ng-click="currentVertical.selectPricing(pricing)">{{pricing.name}}</a>
</li>
</ul>
</div>
</div>
</body>
my javascript:
function VerticalsController($scope) {
$scope.verticals = [
{
title:'internet',
pricings: [
{
name: 'netvision',
monthly: 23
},
{
name: 'hot',
monthly: 33
},
{
name: '012',
monthly: 28
}
]
},
{
title:'cellular',
pricings: [
{
name: 'cellcom',
monthly: 20
},
{
name: 'pelephone',
monthly: 30
},
{
name: 'orange',
monthly: 25
}
]
},
{
title:'banks',
pricings: [
{
name: 'leumi',
monthly: 20
},
{
name: 'poalim',
monthly: 30
},
{
name: 'benleumi',
monthly: 25
}
]
}];
$scope.selected = [
];
$scope.currentIndex = 0;
$scope.currentVertical = $scope.verticals[0];
$scope.selectPricing = function(pricing) {
$scope.selected.push(pricing);
$scope.currentIndex++;
$scope.currentVertical = $scope.verticals[$scope.currentIndex];
};
/*$scope.remaining = function() {
var count = 0;
angular.forEach($scope.todos, function(todo) {
count += todo.done ? 0 : 1;
});
return count;
};*/
}
You have to use custom or create directives to start advanced DOM manipulation like animations.
Here's a fiddle with the animation you requested, I use the visible variable on scope to trigger fading and the $timeout service to only change the selectedItem when fadeOut, it could be improved to pass a timeout and a callback as a directive option...
Fiddle: http://jsfiddle.net/g/Bs66R/1/
JS:
function VerticalsController($scope, $timeout) {
$scope.verticals = [{
title:'internet',
pricings: [{
name: 'netvision',
monthly: 23
},
{
name: 'hot',
monthly: 33
},
{
name: '012',
monthly: 28
}]
},
{
title:'cellular',
pricings: [{
name: 'cellcom',
monthly: 20
},
{
name: 'pelephone',
monthly: 30
},
{
name: 'orange',
monthly: 25
}]
},
{
title:'banks',
pricings: [{
name: 'leumi',
monthly: 20
},
{
name: 'poalim',
monthly: 30
},
{
name: 'benleumi',
monthly: 25
}]
}];
$scope.selected = [
];
$scope.currentIndex = 0;
$scope.currentVertical = $scope.verticals[0];
$scope.selectPricing = function(pricing) {
$scope.selected.push(pricing);
$scope.currentIndex++;
$scope.visible = false;
$timeout(function(){
$scope.currentVertical = $scope.verticals[$scope.currentIndex];
$scope.visible = true;
}, 1000);
};
$scope.visible = true;
}
var fadeToggleDirective = function() {
return {
link: function(scope, element, attrs) {
scope.$watch(attrs.uiFadeToggle, function(val, oldVal) {
if(val === oldVal) return; // Skip inital call
// console.log('change');
element[val ? 'fadeIn' : 'fadeOut'](1000);
});
}
}
}
angular.module('app', []).controller('VerticalsController', VerticalsController).directive('uiFadeToggle', fadeToggleDirective);
angular.bootstrap(document.body, ['app']); angular.bootstrap(document.body, ['app']);
HTML:
<h1>Pricing Poll</h1>
<div ng-controller="VerticalsController">
<div id="container" ui-fade-toggle="visible">
<h2>{{currentVertical.title}}</h2>
<ul>
<li ng-repeat="pricing in currentVertical.pricings">
<a ng-click="selectPricing(pricing)">{{pricing.name}}</a>
</li>
</ul>
</div>
</div>
I recommend you use the new ngAnimate directive provided in the AngularJS Core.
Read more here

Resources