Implementing an accordion in AngularJS and better understanding $scope - javascript

I am editing an already existing Angular webpage. In the app.js file, there are multiple controllers for each page. Here's their template:
JS:
app.controller("myCtrl", function($scope) {
$scope.useSettings({
Header: "header",
Title: "title",
mainImg: "main.png",
fields: [{
fieldText: "text",
},{
fieldImg: "pic.jpg",
},{
fieldAccordion:
//
},{
]
});
});
My goal is to have fieldAccordion work as an accordion for the data that I input there, just how all my fields work.
This is my Unordered List data type in the html file:
<div class="basic-page__field__undordered" ng-
if="field.fieldUnorderedList">
<ul class="field-list field-list--unordered">
<li ng-repeat="listItem in field.fieldUnorderedList">{{ listItem }}
</li>
</ul>
</div>
I can simply use it in the .JS file like this:
fieldUnorderedList: [
"item1",
"item2",
]
So I would like to find a similar way to use data for an accordion type.
Here is how I wrote it in the .html file:
<div class="basic-page__field__accordion" ng-if="field.fieldAccordion">
<ul class="field-list field-list--accordion">
<li ng-repeat="item in items" ng-click="accordion.current = item.name">
{{item.name}}
<ul ng-show="accordion.current == item.name">
<li ng-repeat="sub in item.sub">{{sub.name}}</li>
</ul>
</li>
</ul>
</div>
Now the issue that I'm having is getting it to work as simple as using
"fieldAccordion:" in my controller.
I have done some research and what I don't understand is this:
All my controllers have the same template with $scope.useSettings, followed by all the data such as fieldText, fieldImg, etc.
How would I add another $scope that deals with the accordion data type which I can use in the exact place that I want it to be?
Something like this:
$scope.accordion = {
current: null
};
$scope.items = [{
name: 'List 1',
sub: [{
name: 'Sub 1.1'
},{
name: 'Sub 1.2'
}]
},{
name: 'List 2',
sub: [{
name: 'Sub 2.1'
}]
},{
name: 'List 3',
sub: [{
name: 'Sub 3.1'
},{
name: 'Sub 3.2'
},{
name: 'Sub 3.3'
}]
}];
}]);
This is one of my biggest obstacles in getting to understand AngularJS. Since I am working on an already existing webpage, I don't know how to add multiple $scopes for one controllers and where to use them. Any help is appreciated.

Related

setting single element to hidden in vue js when mapped

kinda new to vue, I have mapped out some data from my initial data object in vue.js I am trying to hide and show only the items within that iteration of the mapping when the user selects the heading. I am using the isHidden prop in vue to hide and show my list items but when selecting any heading it shows all the tags instead of those associated with that specific header.
anyone know the proper way to do this? should I use some index or id from e.target? or should I give each list item a 'hidden' property and change it that way somehow?
here's my list that I mapped out
<div v-for="item in list">
<h4 v-on:click="viewItemsinCat()">{{item.category}}</h4>
<ul>
<li v-if="!isHidden" v-for="item in item.food">
{{item}}
</li>
</ul>
</div>
then I have my data like so:
data: {
list: [{
category: 'Baked goods',
food: ['bread', 'cookie', 'butter', 'powder']
}, {
category: 'meats',
food: ['chicken', 'turkey', 'beef']
}, {
category: 'fruits',
food: ['bannana', 'apple', 'pineapple']
}, {
category: 'canned goods',
food: ['tomatoes', 'green beans', 'corn']
}, {
category: 'veggies',
food: ['broccoli', 'celery', 'lettuce']
}, {
category: 'pantry',
food: ['broom', 'mop', 'dried beans']
}, ],
isHidden: true,
}
then I have my method to alter isHidden
viewItemsinCat: function(){
this.isHidden = false
},
Add a selected property to contain the currently selected item when the user clicks:
data() {
return {
selected: null,
list: [...]
}
}
<div v-for="item in list">
<h4 v-on:click="selected=item.category">{{item.category}}</h4>
<ul v-if="selected==item.category">
<li v-for="food in item.food">
{{ food }}
</li>
</ul>
</div>
Here's a demo

How can I use ng-repeat to iterate through arrays associated using dynamic keys

I am trying to use ng-repeat to iterate through an array of objects and use each objects ID to look up the data binded to a checklist model.
I have the following javascript object in a project I'm working on:
{
diagnosis: {
mainfractures: [
{
id: "metacarpal",
textinput_id: "metacarpal_text",
title: "5th Metacarpal",
},
{
id: "proximal_phalanx",
textinput_id: "proximal_phalanx_text",
title: "Proximal Phalanx",
},
{
id: "middle_phalanx",
textinput_id: "middle_phalanx_text",
title: "Middle Phalanx",
},
{
id: "distal_phalanx",
textinput_id: "distal_phalanx_text",
title: "Distal Phalanx",
},
{
id: "scaphoid_fracture",
textinput_id: "scaphoid_fracture_text",
title: "Scaphoid Fracture",
}
]
}}
Here is what I have for my checklist model. As the user selects a checkbox, a value is binded to the array associated with that fracture.
$scope.checklists = {
"diagnosis": {
metacarpal: [],
proximal_phalanx: [],
middle_phalanx: [],
distal_phalanx: [],
scaphoid_fracture: []
}
}
Checklist Image Example
Once a users makes a selection similar to the image above the the checklist model for metacarpal should look like this: metacarpal: ["head"]
What I'm trying to do is list each of the users selection in bulletpoint via fracture.id. I'm trying to accomplish it with this piece of code but it's only listed the fracture title so far. is it a problem with trying to interpolate fracture.id into ng-repeat?
<div ng-repeat="fracture in diagnosis.mainfractures">
<div > <!--ng-if="checklists['diagnosis'][fracture.id] > 0"-->
<h4>{{ fracture.title }}</h4>
<div class="row">
<ul type="disc">
<li ng-repeat="selection in checklists['diagnosis'][fracture.id]">
• {{ capitalize(selection) }}
</li>
</ul>
</div>
</div>
</div>
Based on your supplied code, I'd have to say your issue is actually due to JS syntax errors. You're missing commas after each object item and there is a random double quote here scaphoid_fracture"[].
$scope.checklists = {
"diagnosis": {
metacarpal: []
proximal_phalanx: []
middle_phalanx: []
distal_phalanx: []
scaphoid_fracture"[]
}
}
Here is a fully working jsfiddle
Adjusted the code a bit:
capitalize ->
uppercase(https://docs.angularjs.org/api/ng/filter/uppercase)
some syntax errors
But seems that access by dynamic object key inside ng-repeat works pretty correct
https://jsbin.com/rodecosoyo/1/edit?html,js,output
Angular Application
var app = angular.module('arrayid', []);
app.controller('arrayContainerCtrl', function($scope) {
$scope.diagnosis = {
mainfractures: [{
id: "metacarpal",
textinput_id: "metacarpal_text",
title: "5th Metacarpal",
}, {
id: "proximal_phalanx",
textinput_id: "proximal_phalanx_text",
title: "Proximal Phalanx",
}, {
id: "middle_phalanx",
textinput_id: "middle_phalanx_text",
title: "Middle Phalanx",
}, {
id: "distal_phalanx",
textinput_id: "distal_phalanx_text",
title: "Distal Phalanx",
}, {
id: "scaphoid_fracture",
textinput_id: "scaphoid_fracture_text",
title: "Scaphoid Fracture",
}]
};
$scope.checklists = {
"diagnosis": {
metacarpal: ['1', '2'],
proximal_phalanx: ['2', '3'],
middle_phalanx: ['3'],
distal_phalanx: ['4'],
scaphoid_fracture: ['5']
}
};
});
Markup:
<body ng-app='arrayid' ng-controller='arrayContainerCtrl'>
<div ng-repeat="fracture in diagnosis.mainfractures">
<h4>{{ fracture.title }}</h4>
<div class="row">
<ul type="disc">
<li ng-repeat="selection in checklists['diagnosis'][fracture.id]">
• {{ selection | uppercase }}
</li>
</ul>
</div>
</div>
</body>

Angular GroupBy using without ng-repeat

In AngularJS there is the groupBy method for ng-repeats. I'm using that to make a list of times a product with the same title is in the array I'm ng-repeating, and calculate the length and total price of it like this:
<li ng-repeat="(key, value) in products | groupBy: 'title'">
<span>{{value.length}} items</span>
<strong>{{ value[0].title }}</strong>
<tt>{{ (value[0].price*value.length) | currency: '$' }}</tt>
</li>
This works fine, but I wanna re-use that same calculation in the Controller. So I have an object/array like:
{
{
length: 10,
title: 'test 1',
price_total: 200.99,
},
{
length: 3,
title: 'test 2',
price_total: 3.99,
},
}
But I can't figure out how to use the same GroupBy kinda thing.
You can inject AnguarJS filters like this:
angular.module('myApp')
.controller('MyCtrl', function($filter, $scope) {
$scope.myCollection = [{
title: 'Wut',
text: 'Wat'
}, {
title: 'Que',
text: 'paso'
}]
$scope.grouped = $filter('groupBy')($scope.myCollection, 'title');
})
in order to get the same functionality that you would from a directive. Documentation here

Getting a a.foreach is not a function error

I am trying to build a multiselect list using angular js. I am getting a weird TypeError: a.foreach is not a function and I can’t seem to figure out when.
js :
var myAppModule = angular.module('multiselect', []);
myAppModule.controller("view", function ($scope) {
$scope.listA = {
values: [{
id: 1,
label: 'aLabel',
subItem: {
name: 'aSubItem'
}
}, {
id: 2,
label: 'bLabel',
subItem: {
name: 'bSubItem'
}
}],
selected: {
name: 'aSubItem'
}
};
})
html:
<select multiple ng-options="item.subItem as item.label for item in listA.values track by item.id" ng-model="listA.selected"></select>
I don’t know what I could be doing wrong. Am I casting something wrong ?
The problem is that since you have added the multiple attribute, the value of the select should be an array. So try something similar to this:
$scope.listA = {
values: [{
id: 1,
label: 'aLabel',
subItem: {
name: 'aSubItem'
}
}, {
id: 2,
label: 'bLabel',
subItem: {
name: 'bSubItem'
}
}],
selected: [{
name: 'aSubItem'
}]
};
You need not to track your values by id. it will do it by default.
<div ng-controller="Main">
<select multiple ng-options="item.subItem as item.label for item in listA.values" ng-model="listA.selected"></select>
</div>
JS Fiddle for your code (Fix):
http://jsfiddle.net/juag4okg/
I was having the same problem. It worked well by creating the static json object as answered above, but did not worked out when i tried to fetched the object or list from the server.
Then i realized my server was not sending the json object and i hadn't convert it to json as well. And when i converted it to json it worked perfectly fine.
So if you are having similar problem to display the select options (muliple or single) from the server side data this process might help you.
here is the link to angular angular.toJson() function.

Is it possible to create ng-grid's dynamically?

as part of one of my web projects I need multiple instances of ng-grid in a same app, being the user able to create dynamically as many grids as needed (Think of usual "Add New Grid..") button.
I've gone through the docs and implemented a prototype but I've found that the setup for the grid includes the hardcoded name of the variable containing the data, for example:
in the angular .js controller,
$scope.gridOptions = { data: 'myData' };
and in the html:
<div class="gridStyle" ng-grid="gridOptions">
I've tried using a variable instead, for example:
var mychart = [{...}, {...}]; // data rows
$scope.gridOptions = { data: $scope.mychart };
and
<div class="gridStyle" ng-grid="{{gridOptions}}">
but without success. All the examples I've found on the web use only one table so my question remains unanswered.
Any idea of how this could be resolved or is a major limitation of this grid system?
Thanks!
As usual, when you find yourself needing an arbitrary number of objects, you should think about putting them in a collection rather than giving them individual names. I've updated wayne's jsfiddle to use arrays and ng-repeat: http://jsfiddle.net/Th47J/
Make a grid for each option:
<div ng-repeat="option in gridOptions" class="gridStyle" ng-grid="option"></div>
Obviously if these are being created on the fly, you'll need to update the gridOptions array programmatically rather than having everything hard-coded. But if the data source is the only thing that is changing that's very easy.
Well I finally managed to do this. The key is that the data reference (myData[] in this case) can be generated dynamically (myData + '[' + myData.length + ']' for example), each time a new tab is added.
Of course it's up to you to keep sync between the tabs and the myData length.
The HTML:
<div id="myTabContent" class="tab-content">
<div class="tab-pane" ng-repeat="tab in tabs" id="{{tab.id}}">
<div class="gridStyle" ng-grid="{{tab.ref}}"></div>
</div>
</div>
The angular part:
$scope.tabs = [
{id: 0, title: 'a', contentId: '#0', data: 'lorem 1', ref:{data: 'myData[0]'}},
{id: 1, title: 'b', contentId: '#1', data: 'lorem 2', ref:{data: 'myData[1]'}},
{id: 2, title: 'c', contentId: '#2', data: 'lorem 3', ref:{data: 'myData[2]'}}
];
$scope.myData = [[
{name: "ryan1", surn: "smith1", address:"main square 1", phone:"000000001"},
{name: "ryan1", surn: "smith1", address:"main square 1", phone:"000000001"},
],
[{name: "ryan2", surn: "smith2", address:"main square 2", phone:"000000002"},
{name: "ryan2", surn: "smith2", address:"main square 2", phone:"000000002"},
],
[{name: "ryan3", surn: "smith3", address:"main square 3", phone:"000000003"},
{name: "ryan3", surn: "smith3", address:"main square 3", phone:"000000003"},
],
];

Categories

Resources