Can angular directives call themselves? - javascript

I have some sample data in JSON format:
{
"menus" : [
{"name" : "Item 1", "children" : [
{"name" : "Item 1.1", "url" : "http://www.website.com1/1"},
{"name" : "Item 1.2", "url" : "http://www.website.com1/2"},
{"name" : "Item 1.3", "children": [
{"name" : "Item 1.3.1", "url" : "http://www.website.com1/3/1"},
{"name" : "Item 1.3.2", "url" : "http://www.website.com1/3/2"},
{"name" : "Item 1.3.3", "url" : "http://www.website.com1/3/3"}
]}
]},
{"name" : "Item 2", "children": [
{"name" : "Item 2.1", "url" : "http://www.website.com2/1"},
{"name" : "Item 2.2", "url" : "http://www.website.com2/2"},
{"name" : "Item 2.3", "url" : "http://www.website.com2/3"}
]},
{"name" : "Item 3", "url" : "http://www.website.com3"}
]
}
I want to build a menu tree that matches the stucture of the JSON. So I made a directive:
app.directive('menuItem',
function(){
return {
restrict : "E",
scope: { data : '='},
replace:true,
templateUrl: 'directives/menu-item.html'
};
});
I add the directive to my HTML and it works great for the first layer:
<menu-item data="menu.data.menus"></menu-item>
What I want to happen is that if model the directive is using has a 'children' property, I want it to build a new node using the same template as itself:
<ul class="menu-items" ng-repeat="item in data">
<li class="menu-item">
<div>{{item.name}}</div>
<div ng-if="item.children.length">
<!-- when I add this line I get problems -->
<menu-item data="item.children"></menu-item>
</div>
</li>
</ul>
I get the following error:
Error: [$rootScope:inprog]
http://errors.angularjs.org/1.3.0-beta.13/$rootScope/inprog?p0=%24digest
Question is, how can I get the desired functionality, and how should I think about what's going on to understand this better?
Fiddle to come...

Ok Thanks. Yes this was in fact the same issue adressed in How to handle recursive rendering of data using AngularJS
For this particular case, it would be important to mention that in it's present formulation the template would need to use "ng-init" to properly recurse.
<ul class="menu-items" ng-repeat="item in data">
<li class="menu-item">
<div>{{item.name}}</div>
<div ng-include="'directives/menu-item.html'" ng-init="data = item.children" class="submenu-item"></div>
</li>
</ul>

Related

Add new element to array with setState

How to add new element to array with setState
I have this data
this.state = {
items : [
{ "id" : "324", "parent" : "qqqq", "text" : "Simple root node" },
{ "id" : "24", "parent" : "dwdw", "text" : "Root node" },
{ "id" : "55", "parent" : "ajson2", "text" : "Ch" },
{ "id" : "9866", "parent" : "ajson2", "text" : "oiiojio" },
]
}
I'm mapping the data
{this.state.items.sort((a,b) => a.newID < b.newID).map((item)=>
<ul>
<li key={item.id}><span>ID: </span>{item.id} <span>parent: </span>{item.parent} <span>text: </span>{item.text}</li>
</ul>
)}
and then I'm sorting the data by newID That I need to create it with setState
this.setState(prevState=>({newData: [...prevState.items, this.props.account.info]}));
How can I create new element with this.props.account.info add somthing like i++ I don't know actually
this.props.account.info It's adding data like
{ "id" : "324", "parent" : "qqqq", "text" : "Simple root node" }
So I need to add an element inside this will be like
{ "newID": "1", "id" : "324", "parent" : "qqqq", "text" : "Simple root node" }
So if you want to add "newID" field in the object, there is a way to do this using object spread operator.
{...this.props.account.info, "newID":"1"}
This will give you a new object with the "newID" field added with "1" as its value associated with it.
This is a shorthand for this:
Object.assign({}, this.props.account.info, {"newID": "1"});

Polymer: Passing array to property via markup

I have created an element which has an array property 'icon-buttons'. I can pass the array using javascript but when I pass it in the markup itself, it does not work.
Property:
iconButtons: {
type: Array,//tried Object as well
value: function() { return []; }
}
Usage:
<my-card heading="Demo 2" icon-buttons='[
{"name" : "edit", "icon" : "icons:create", "click" : "toggleMode();", "disabled" : false},
{"name" : "close", "icon" : "icons:clear", "click" : "alert(''close'');", "disabled" : false},
{"name" : "maximize", "icon" : "icons:fullscreen", "click" : "alert(''maximize'');", "disabled" : false},
{"name" : "more", "icon" : "icons:more-vert", "click" : "alert(''more'');", "disabled" : true}
]'>
<div class="card-content">
<list mode="edit"></list>
</div>
<div class="card-actions">
<paper-button>Hello</paper-button>
<paper-button>Bye</paper-button>
</div>
</my-card>
I have passed a JSON object similarly for another element. But this one with Array does not work.
What is wrong in this?
a1626 is right, use \" instead of '' in your alerts
... "click": "alert(\"close\");", ...

AngularJS showing value based on id

How can I change data based on id that is passed from json file.
JSON:
{
"hotels": [
{
"id" : 1,
"name": "some hotel 1",
"category" : [{
"id" : 1,
"hotel_id" : 1,
"name" : "Cat name 1",
"bnb" : "yes",
"simple" : "yes"
}]
},
{
"id" : 2,
"name": "some hotel 2",
"category" : [{
"id" : 1,
"hotel_id" : 2,
"name" : "Cat name 1",
"bnb" : "yes",
"simple" : "yes"
}]
}
]
}
in my html I have ng-repeat like:
<p>Hotel names</p>
<ul>
<li ng-repeat="hotel in list.hotels">
{{hotel.name}}
<ul class="thumbnails">
<p>Category</p>
<li ng-repeat="cat in hotel.category">
{{cat.name}}
</li>
</ul>
</li>
</ul>
So this will show all what I have in that json file and I'm trying to limit it to show only data for one hotel (I know that I can do it with something like {{hotel[0].name}}) but there must be better approach, and also how can I use some kind of a switch by pressing the button to show data from hotel with id 1 to hotel with id 2 in the same div and vice versa?
Thank you.
You could use ng-repeat to create the links to display the hotel based on the click like in the following demo or in this fiddle.
For the categories you can use another ng-repeat (not added in the demo).
angular.module('demoApp', [])
.controller('mainController', MainController);
function MainController() {
this.hotels = [
{
"id" : 1,
"name": "some hotel 1",
"category" : [{
"id" : 1,
"hotel_id" : 1,
"name" : "Cat name 1",
"bnb" : "yes",
"simple" : "yes"
}]
},
{
"id" : 2,
"name": "some hotel 2",
"category" : [{
"id" : 1,
"hotel_id" : 2,
"name" : "Cat name 1",
"bnb" : "yes",
"simple" : "yes"
}]
}
];
this.selectedHotel = this.hotels[0];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demoApp" ng-controller="mainController as mainCtrl">
{{hotel.name}}
<div>
Hotel name: {{mainCtrl.selectedHotel.name}}
Category: {{mainCtrl.selectedHotel.category}}
</div>
</div>
To answer your question, notice ng-if added
<p>Hotel names</p>
<ul>
<li ng-repeat="hotel in list.hotels">
{{hotel.name}}
<ul class="thumbnails">
<p>Category</p>
<li ng-repeat="cat in hotel.categories" ng-if="cat.id == yourid">
{{cat.name}}
</li>
</ul>
</li>
</ul>
You can change yourid by using the current controller. And as other people suggest, you shouldn't use ng-repeat if you want to display only one element

How to show JSON as formatted view in html

I need to view JSON in my html page as formatted view. JSON come from database. I need to show it nut in Formatted view.
Just like
{
"crews": [{
"items": [
{
"year" : "2013",
"boat" : "Blue",
"position" : "1",
"name" : "Patrick Close",
"college" : "Pembroke",
"weight" : "14st 2lbs"
}, {
"year" : "2013",
"boat" : "Blue",
"position" : "2",
"name" : "Geordie Macleod",
"college" : "Christ Church",
"weight" : "13st 10lbs"
}]
}]
}
Anyone have any idea or suggestion ? or any resource that may help.
Edited: I want to create a JSON parser. User input different json and can view in formatted view.
Try JSON.stringify(data), its a Javascript function. Hope it might help.
Refer: Detail Explaination
If you are using PHP then use json_encode
Refer: json_encode manual
Since your are using angular-js, you can simply load your JSON feed from your controller then use the ng-repeat function to iterate over the items into your view page. Here down a sample where of how your HTML view can look like and you may need to style and build the blocks as per your needs:
<span>items:</span>
<span>[</span>
<br/>
<div class="item" ng-repeat="item in items">
<span>{</span><br/>
<span class="field">year : {{item.year}}</span><br/>
<span class="field">boat : {{item.boat}}</span><br/>
<span class="field">position : {{item.position}}</span><br/>
<span>}</span>
</div>
You can find a working sample in this JSFiddle.
First: your remote JSON is invalid: it's missing an ending bracket for crews.
It should be like this:
{
"crews": [{
"items": [
{
"year" : "2013",
"boat" : "Blue",
"position" : "1",
"name" : "Patrick Close",
"college" : "Pembroke",
"weight" : "14st 2lbs"
}, {
"year" : "2013",
"boat" : "Blue",
"position" : "2",
"name" : "Geordie Macleod",
"college" : "Christ Church",
"weight" : "13st 10lbs"
}]
}] // Missing this bracket
}
You didn't mention if your JSON is remote or not. I'm assuming not, so I'll use a local JavaScript var with eval function in this sample code.
<script type="text/javascript">
var content = {
"crews": [{
"items": [
{
"year" : "2013",
"boat" : "Blue",
"position" : "1",
"name" : "Patrick Close",
"college" : "Pembroke",
"weight" : "14st 2lbs"
}, {
"year" : "2013",
"boat" : "Blue",
"position" : "2",
"name" : "Geordie Macleod",
"college" : "Christ Church",
"weight" : "13st 10lbs"
}]
}]
};
var json = eval(content);
for (c in json.crews) {
var crew = json.crews[c];
for (i in crew.items) {
var item = crew.items[i];
console.log(item.year);
console.log(item.boat);
console.log(item.position);
console.log(item.name);
}
}
</script>
I'm using console.log to output, so you'll be able to see data only if you open the browser console:

jstree get data after update

I pass some json data in jstree and then I update the tree.
For example my initial data is
[
{ "id" : "demo_root_1", "text" : "Root 1", "children" : true, "type" : "root" },
{ "id" : "demo_root_2", "text" : "Root 2", "type" : "root" }
]
I update it a little (simple rename). "Root 1" becomes "UPDATED". How can I get the updated version of my data in json format like below?
[
{ "id" : "demo_root_1", "text" : "UPDATED", "children" : true, "type" : "root" },
{ "id" : "demo_root_2", "text" : "Root 2", "type" : "root" }
]
Okay..so basically if you want to refresh the tree with the updated data, then after the updation code, call the jstree callback:
$(tree).jstree('refresh');
This will refresh the tree with the new json data.
let me know in case of further issues.

Categories

Resources