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

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"},
],
];

Related

vue: can v-html be inside a js array?

I have a js file containing array and objects. I need to style some properties from these arrays. For example
myArray= [
{
id: 1,
name: 'honda',
description: 'to buy the latest car, click here'
},
{
id: 2,
name: 'tesla',
description: 'to buy the latest car, click here'
}
]
Let's say I want to style the description property so that I can bind a link there.
I figure that the way to do it is to use raw html. But in my case, I'm going to include it to my array. Is this possible? I have tried to search this question everywhere but there's no explanation for this case. Thank you so much.
You can use any html styled code in your Array such as below.
myArray= [
{
id: 1,
name: 'honda',
description: 'to buy the latest car, click here'
},
{
id: 2,
name: 'tesla',
description: 'to buy the latest car, click here'
}
]
And in your templete you would use: like
...
<div v-for="car in myArray" :key="car.id">
<p v-html="car.description"></p>
</div>
Check out this code.
Check out this codepen.
You can check out the vuejs documentation for more info.

Angular 7 nested for using parent value as index for child

Is it possible to do this in Angular 2+?
let's say I have the following objects:
myParent = [{id: 1, code: 'code1', title: 'parentTitle1'}, {id: 2, code: 'code2', title: 'parentTitle2'}];
myChild = {code1: [{id: 1, title: 'childTitle1'}, {id: 2, title: 'childTitle2'}], code2: [{id: 4, title: 'childTitle1'}]
I wanna Iterate the first one and then display the items of the second one, using the 'code' value of the parent object as index:
<h3 *ngFor="let parent of myParent">{{parent .title}}
<br>
<span *ngFor="let child of myChild[parent.code]"> {{child.title}} </span>
<br>
</h3>
I'm not getting any error on the console, but the child 'for' is not displaying anything. I used to do this on AngularJS but not sure if it's possible to do it in NG7
Check this stackblitz. Is this not working for you?
I tried with these data:
myParent = [{id: 1, code: 'code1', title: 'parentTitle1'}, {id: 2, code: 'code2', title: 'parentTitle2'}];
myChild = {code1: [{id: 1, title: 'childTitle1'}, {id: 2, title: 'childTitle2'}], code2: [{id: 4, title: 'childTitle1'}]};
And the html
<h3 *ngFor="let parent of myParent">{{parent .title}}
<br>
<span *ngFor="let child of myChild[parent.code]"> {{child.title}} </span>
<br>
</h3>
The stackblitz is working as you intended. Can you share some more code, as it seems like the data might not match.

Implementing an accordion in AngularJS and better understanding $scope

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.

How do I show an unknown length nested array without crashing the browser?

I have an huge array organized sort of like this:
[{ name: 'name1',
nodes: []},
{ name: 'name2',
nodes: [
{ name: 'name21',
nodes: [
{ name: 'name211',
nodes: []},
{ name: 'name212',
nodes: []}]
}]
},
{ name: 'name3',
nodes: [...] },
{...}
]
and it goes on...
I tried to use something like this:
<script type='text/ng-template', id='categoryTree'>
<p ng-if='!node.nodes'> {{node.name}} </p>
<details ng-if='node.nodes'>
<summary><b> {{node.name}}</b></summary>
<ul>
<span ng-repeat="node in node.nodes" ng-include="'categoryTree'"></span>
</details>
</script>
<div>
<ul>
<span ng-repeat="node in objArray" ng-include="'categoryTree'"></span>
</div>
This gives me what I want in terms of showing all the nested array in a tree format. The problem is that it seems to be caught in an infinite loop for when I look at the Task Manager, the RAM used starts increasing and only stops when Chrome crashes.
Does anybody know how could I get around with that? Or even if I have a better way to do this tree view?
Angular does not really handle recursive directives - by default
But there's a solution:
https://github.com/marklagendijk/angular-recursion
What you need actually is to temporarily remove the nested element when rendering the parent.

Creating a Grouped Select in Ember.js

It's relatively easy to create a select in Ember.js using Ember.Select.
The question is, how do I make this into a grouped select, using an optgroup. I don't think this is built in, but I'm guessing it's possible with some modifications to the template.
This is natively supported by Ember now, but there are a few gotchas. In 1.4.0, the following solution works...
Here's the example data:
foos: Ember.A([{value: 'foo', label: 'Foo', group: 'Foos'}, {value: 'bar', label: 'Bar', group: 'Bars'}, {value: 'bar2', label: 'Bar2', group: 'Bars'}, {value: 'foo2', label: 'Foo2', group: 'Foos'}])
Here's the view helper:
{{view Ember.Select content=controller.foos optionLabelPath='content.label' optionValuePath='content.value' optionGroupPath='group'}}
If, you just do the above you will get a select list that looks like this:
The only way I could get around this was to sort the array first by the grouped field:
foos: Ember.A([{value: 'foo', label: 'Foo', group: 'Foos'}, {value: 'bar', label: 'Bar', group: 'Bars'}, {value: 'bar2', label: 'Bar2', group: 'Bars'}, {value: 'foo2', label: 'Foo2', group: 'Foos'}]).sortBy("group")
Here's the solution that I came up with. https://gist.github.com/3297425
I had to make two collections. One grouped and the other just content so that the proper option can be selected.
groupedServiceCodes = [Ember.Object.create({label: 'Label for optgroup', content: Ember.A()}), …]
And then flatten the content from groupedServiceCodes down to maintain order for the select:
flattenedServiceCodes = [].concat(object.get('content'), …)
This is a bit of a hack, and I think Ember is wanting for a better solution, but this works for me. I would love to hear thoughts on improving this.
The answers here are a bit outdated. Ember now supports grouping of stuff. Imagine you have:
App.SomeController = Ember.Controller.extend({
content: [{value: 'foo', label: 'Foo', group: 'Foos'}, {value: 'bar', label: 'Bar', group: 'Bars'}]
})
You can then do
Ember.Select contentBinding='content' optionLabelPath='content.label' optionValuePath='content.value' optionGroupPath='group'
Notice that optionGroupPath does not do content.path, just path
Ember.Select does not support optgroups, but you can extend Ember.Select to do so by providing a new template for it and a new template for options. I've done this to support chosen.js selects within Ember.
Ember now supports this out of the box. Refer to this git pull request https://github.com/emberjs/ember.js/pull/2465

Categories

Resources