angularjs make json message sortable - javascript

Here is the Json message:
{"title": {"default":"hello 3", "position":[2,12,0]},
"description":{"default":"description hello 3", "position":[1,12,0]},
"option": [{"default":"1","position":[3,12,0]}, {"default":"2", "position":[0,12,0]}]
},
I am new to angularjs, I am trying to load the json message in ascending order according to the position first element by angularjs and print them in html. ("0" means load firstly, so on so far. )
Could someone help me on that? Thanks in advance!

Take a look at this
Working demo
html
<div ng-controller="MyCtrl">
<ul ng-repeat="value in data">Default:{{value.title.default}}
<li ng-repeat="pos1 in value.title.position|orderBy:orderByValue">{{pos1}}</li>Default:{{value.description.default}}
<li ng-repeat="pos2 in value.description.position|orderBy:orderByValue">{{pos2}}</li>
<li ng-repeat="val in value.option">Default:{{value.option[$index].default}}
<div ng-repeat="pos3 in val.position|orderBy:orderByValue">{{pos3}}</div>
</li>
</ul>
</div>
script
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function ($scope) {
$scope.orderByValue = function (value) {
return value;
};
$scope.data = [{
"title": {
"default": "hello 3",
"position": [2, 12, 0]
},
"description": {
"default": "description hello 3",
"position": [1, 12, 0]
},
"option": [{
"default": "1",
"position": [3, 12, 0]
}, {
"default": "2",
"position": [0, 12, 0]
}]
}];
});

Related

Angular js set default tab with ng-repeat in array object

I want to show last object of each tab in default tab. Now my interface is like this: tab[0] last object is {"id": 8, "status": 1}, tab[1] last object is {"id": 8, "status": 1} but it is wrong. I want it to look like this: tab[0] last object is {"id": 5, "status": 0}, tab[1]last object is{"id": 8, "status": 1}`.
Image of my wrong interface: [1]: https://i.stack.imgur.com/MhvKX.png
My json data like this:
[
{
"tab":[
[
{"id": 1, "status": 1},
{"id": 2, "status": 1},
{"id": 3, "status": 1},
],
[
{"id": 4, "status": 1},
],
[
{"id": 5, "status": 0}
]
]
},
{
"tab":[
[
{"id": 6, "status": 1},
{ "id": 7, "status": 1},
],
[
{"id": 8, "status": 1}
]
]
},
];
My js:
for(let i = 0; i < $scope.data.length; i++) {
for(let j = 0; j < $scope.data[i].tab.length; j++) {
$scope.selecttab = $scope.data[i].tab[j];
}
}
$scope.getTab = function(obj) {
$scope.selecttab = obj;
};
My html
<div ng-repeat="obj in data">
<ul class="nav nav-tabs">
<li ng-class="{ active: selecttab == obj1 }" ng-repeat="obj1 in obj.tab track by $index">
<a href ng-click="getTab(obj1)">{{ $index }}</a>
</li>
</ul>
<div class="tab-content" ng-repeat="obj1 in selecttab">
ID: {{obj1.id}}<br>
Status : {{obj1.status}}
</div>
</div>
Can someone please help in identifying what am i doing wrong?
You have to correct your last tab selection logic.
Since selectedTab is specific to each node in your data array, I parsed the array and added a selectedTab property to each data node which holds its first.
Working fiddle
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope) {
$scope.data = [
{
"tab": [
[{ "id": 1, "status": 1 }, { "id": 2, "status": 1 }, { "id": 3, "status": 1 }],
[{ "id": 4, "status": 1 }],
[{ "id": 5, "status": 0 }]
]
},
{
"tab": [
[{ "id": 6, "status": 1 }, { "id": 7, "status": 1 }],
[{ "id": 8, "status": 1 }]
]
},
];
for (let i = 0; i < $scope.data.length; i++) {
$scope.data[i].selectedTab = $scope.data[i].tab[$scope.data[i].tab.length - 1];
}
$scope.setSelectedTab = function (node, tab) {
tab.selectedTab = node;
};
});
.active {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="obj in data">
<ul class="nav nav-tabs">
<li ng-class="{ active: obj1[0] && obj.selectedTab == obj1 }" ng-repeat="obj1 in obj.tab track by $index">
<a href ng-click="setSelectedTab(obj1, obj)">{{ $index }} </a>
</li>
</ul>
<div class="tab-content" ng-repeat="tab in obj.selectedTab track by $index">
ID: {{tab.id}}<br>
Status : {{tab.status}}
</div>
</div>
</div>

Parse a list of heading in a document to a sorted tree

I'm trying to parse a list of headings (h1, h2, etc.) to obtain the table of content in a well structured javascript variable (kinda like a tree).
Here's the structure of my document:
<div id="content">
<h1>The content</h1>blah
<h2 class="show-in-toc">Test 1</h2>
<h3 class="show-in-toc">Test 1.1</h3>
<h3 class="show-in-toc">Test 1.2</h3>
<h4 class="show-in-toc">Test 1.2.1</h4>
<h4 class="show-in-toc">Test 1.2.2</h4>
<h2 class="show-in-toc">Test 2</h2>
<h3 class="show-in-toc">Test 2.1</h3>
<h4 class="show-in-toc">Test 2.1.1</h4>
<h3 class="show-in-toc">Test 2.2</h3>
</div>
And here's what I'm trying to get:
[
{"text": "Test 1","level": 2, "children": [
{"text": "Test 1.1","level": 3,"children": []},
{"text": "Test 1.2", "level": 3, "children": [
{"text": "Test 1.2.1", "level": 4, "children": []},
{"text": "Test 1.2.2", "level": 4, "children": []}
]}
]},
{"text": "Test 2", "level": 2, "children": [
{"text": "Test 2.1", "level": 3, "children": [
{"text": "Test 2.1.1", "level": 4, "children": []}
]},
{"text": "Test 2.2", "level": 3, "children": []}
]}
]
I'm guessing the function should be recursive and would look like this:
headings = $('.show-in-toc:header'); // Maybe .toArray() ?
toc = generateToc(headings, 2); // With 2 being the starting level
I tried to inspire an algorithm from this subject but I didn't get any result (they're directly putting the result into a dom element).
Have you any suggestion to guide me? Thank you in advance
I finally managed to do the algorithm I wanted, thank to the comments that gave me a bit of a hint. Here's the result on a JSFiddle, I'll explain it and comment it later even though it's pretty simple to understand.
function headerTagToObject(tag, level) {
tag = $(tag);
return {
'title': tag.text(),
'level': level,
'children': []
}
}
function generateToc(level, filter = undefined, initial_parent = undefined, parent = undefined) {
var result, tags;
result = [];
if (parent) {
tags = $(parent).nextUntil('h' + (level - 1), 'h' + level).filter(filter);
} else {
if (initial_parent) {
tags = $(initial_parent).find('h' + level).filter(filter);
} else {
tags = $('h' + level).filter(filter);
}
}
tags.each(function(i, tag) {
var tagResult;
tagResult = headerTagToObject(tag, level);
tagResult['children'] = generateToc(level + 1, filter, initial_parent, tag);
result.push(tagResult);
});
return result;
}
// Usage
result = generateToc(2, '.show-in-toc', '#content');

Angular ngrepeat not showing any data from an array of objects

I was wondering what I am doing wrong with angular as the ngrepeat is not displaying the data.
I have a fiddle here
http://jsfiddle.net/e0e7dee5/
<div ng-controller="MyCtrl">
<div class="container-fluid">
<div ng-repeat="u in utilities.all">
{{u.name}}
</div>
</div>
</div>
Above should be right?
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
//var utilities = this;
var utilities = {};
utilities.all = [{ .... }]; // this is my data it is in the fiddle
console.log(utilities.all); // this displays array of objects
}
You should change var utilities = {}; to $scope.utilities = {};
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
//var utilities = this;
$scope.utilities = {};
$scope.utilities.all =
[{
"programId": 1062,
"name": "Atlantic City Electric",
"utilityTypeName": "Electric",
"programName": "Test Program 24",
"rate": 0.0775,
"term": 12,
"serviceReference": false,
"accountNumberTypeName": "Account Number",
"accountNumberLength": 10,
"msf": 4.95,
"etf": 100,
"unitOfMeasureName": "KwH",
"meterNumberLength": null,
"zip": "85281",
"$$hashKey": "object:325"
}, {
"programId": 1063,
"name": "Atlantic City Electric",
"utilityTypeName": "Electric",
"programName": "Test Program 12",
"rate": 0.0875,
"term": 24,
"serviceReference": false,
"accountNumberTypeName": "Account Number",
"accountNumberLength": 10,
"msf": 5.95,
"etf": 150,
"unitOfMeasureName": "KwH",
"meterNumberLength": null,
"zip": "85281",
"$$hashKey": "object:326"
}, {
"programId": 1064,
"name": "Atlantic City Electric",
"utilityTypeName": "Gas",
"programName": "Test Gas Program 12",
"rate": 0.555,
"term": 12,
"serviceReference": false,
"accountNumberTypeName": "Account Number",
"accountNumberLength": 10,
"msf": 1,
"etf": 10,
"unitOfMeasureName": "Therm",
"meterNumberLength": 5,
"zip": "85281",
"$$hashKey": "object:333"
}];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<div class="container-fluid" ng-repeat="u in utilities.all">
<div>
{{u.name}}
</div>
</div>
</div>

Angular.js : ng-repeat OrderBy fails to order values

I am using Angular.JS to retrieve data from an object array passed from the server. Each object has an ID, a name and a position identifier that is used to order the objects in a table.
However, orderBy does not work: here is an example output by showing the positions.
Here is the code of list.js :
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
});
and the JADE page:
doctype html
html
head
title Angular.js Test Page
link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css')
script(src='/javascripts/angular.min.js')
script(src='/javascripts/list.js')
body(ng-app='myApp', ng-controller='myCtrl' ng-init='list= #{JSON.stringify(list)}')
.col-lg-3
table.table.table-bordered
thead
tr
th User List
tfoot(ng-repeat="item in list | orderBy: 'position' track by item.position")
tr
td {{item.position}}
Here is the list that gets passed:
"list": [
{
"position": 5,
"name": "Item 1",
"id": 205690
},
{
"position": 9,
"name": "Item 2",
"id": 15540
},
{
"position": 12,
"name": "Item 3",
"id": 360640
},
{
"position": 27,
"name": "Item 4",
"id": 325470
},
{
"position": 7,
"name": "Item 5",
"id": 271670
},
{
"id": 72850,
"name": "Item 6",
"position": 9196
},
{
"id": 15080,
"name": "Item 7",
"position": 6863
},
{
"id": 242550,
"name": "Item 8",
"position": 6864
},
{
"id": 207490,
"name": "Item 9",
"position": 6865
},
{
"id": 15060,
"name": "Item 10",
"position": 6862
}
]
By all sources I checked, the ng-repeat syntax is correct.
Result is the same if I track by id, or remove track by; if I use OrderBy: '-position', position 9196 is put at the bottom (after '5').
Firefox console shows no warning or error at all!
Everything seems fine, so I am confused about what is going on. Can someone help?
Thanks.
Did you try to use tbody instead of tfoot ?
<div ng-app="myApp" ng-controller="myCtrl">
<table>
<thead>
<tr><td></td></tr>
</thead>
<tbody>
<tr ng-repeat="item in list | orderBy:'position' track by item.position">
<td>{{item.position}}</td></tr>
</tbody>
</table>
</div>
I did it in the JSFiddle and it works ...
maybe the problem is with your angular version.
my code works perfect when its on angularjs 1.2.1 and doesn't work on angularjs 1.0.3. see it for your self on this fiddle
<div ng-app>
<div ng-controller="ClickToEditCtrl">
<ul>
<li ng-repeat="item in test track by item.id">
{{item.name}}
</li>
</ul>
</div>
</div>
$scope.list = [
{
"position": 5,
"name": "Item 1",
"id": 205690
},
{
"position": 9,
"name": "Item 2",
"id": 15540
},
{
"position": 12,
"name": "Item 3",
"id": 360640
},
{
"position": 27,
"name": "Item 4",
"id": 325470
}
];
http://jsfiddle.net/Miqe/wqgkst7d/1/

Json Data Handling using AngularJS

I have a new case, where I need help. I want to have 9 buttons and a panel that displays the movie details, depending on which one has been clicked. So say if I clicked 'Transformers', the transformers detail should appear in the panel. Then if I were to click 'Fury', the panel detail would change to the Fury details. I need this data to be in a JSON file. I've looked, how to do this and struggle to understand how I would go about doing this. Here's what I've got so far.
JS:
var app = angular.module("myApp", []);
app.controller('MainController', ['$scope', function ($scope) {
}])
JSON:
{
"movie": [
{
"id": 1,
"name": "Star Wars The Phantom Menace",
"format": "DVD",
"rate": 4,
"price": 2
},
{
"id": 2,
"name": "Star Wars A New Hope",
"format": "DVD",
"rate": 6,
"price": 4
},
{
"id": 3,
"name": "Transformers",
"format": "Blu-Ray",
"rate": 7,
"price": 3
},
{
"id": 4,
"name": "Transformers Dark of the Moon",
"format": "Blu-Ray",
"rate": 6,
"price": 5
}
]}
HTML:
<body ng-controller="MainController" ng-app="myApp">
<h1 style="text-align:center">Garrett's Rentals</h1>
<div ng-repeat="movie in movies">
<button>{{movie.name}}</button>
</div>
<div class="panel">
<h3>You have selected:</h3>
<p>{{movie.name}}</p>
<p>{{movie.format}}</p>
<p>{{movie.rate}}</p>
<p>{{movie.price}}</p>
</div>
</body>
use
var app = angular.module("myApp", []);
app.controller('MainController', ['$scope', function ($scope) {
var json={
"movie": [
{
"id": 1,
"name": "Star Wars The Phantom Menace",
"format": "DVD",
"rate": 4,
"price": 2
},
{
"id": 2,
"name": "Star Wars A New Hope",
"format": "DVD",
"rate": 6,
"price": 4
},
{
"id": 3,
"name": "Transformers",
"format": "Blu-Ray",
"rate": 7,
"price": 3
},
{
"id": 4,
"name": "Transformers Dark of the Moon",
"format": "Blu-Ray",
"rate": 6,
"price": 5
}
]};
console.log(json);
$scope.movies=json.movie;
console.log($scope.movie);
}]);
HTML
<body ng-controller="MainController" ng-app="myApp">
<h1 style="text-align:center">Garrett's Rentals</h1>
<div ng-repeat="movie in movies">
<button>{{movie.name}}</button>
</div>
<div class="panel">
<h3>You have selected:</h3>
<p>{{movie.name}}</p>
<p>{{movie.format}}</p>
<p>{{movie.rate}}</p>
<p>{{movie.price}}</p>
</div>
</body>
Fiddle for support:http://jsfiddle.net/sXkjc/993/
Use ng-click directive on button to set current selected movie like follwing.
var app = angular.module("myApp", []);
app.controller('MainController', ['$scope', function ($scope) {
$scope.movies= movies; //here movies is your json object
$scope.selectedMovie=$scope.movies[0]; // assume that first movie is selected default
}])
HTML
<div ng-repeat="movie in movies">
<button ng-click="selectedMovie=movie">{{movie.name}}</button>
</div>
<div class="panel">
<h3>You have selected:</h3>
<p>{{selectedMovie.name}}</p>
<p>{{selectedMovie.format}}</p>
<p>{{selectedMovie.rate}}</p>
<p>{{selectedMovie.price}}</p>
</div>
JS
angular.module('myApp', [])
.controller('MainController',['$scope','$http',function($scope,$http){
$scope.contents=null;
$http.get('URL TO JSON').then(function(resp){
console.log('Success', resp);
$scope.contents=resp.data;
},
function(err){
console.error('ERR',err);
})
}]);
HTML
<body ng-controller="MainController" ng-app="myApp">
<h1 style="text-align:center">Garrett's Rentals</h1>
<div ng-repeat="movie in movies">
<button>{{movie.name}}</button>
</div>
<div class="panel">
<h3>You have selected:</h3>
<p>{{movie.name}}</p>
<p>{{movie.format}}</p>
<p>{{movie.rate}}</p>
<p>{{movie.price}}</p>
</div>
Controller Code:
var app = angular.module("myApp", []);
app.controller('MainController', ['$scope', function ($scope) {
$scope.movies = {
movie: [
{
id: 1,
name: "Star Wars The Phantom Menace",
format: "DVD",
rate: 4,
price: 2
},
{
id: 2,
name: "Star Wars A New Hope",
format: "DVD",
rate: 6,
price: 4
},
{
id: 3,
name: "Transformers",
format: "Blu-Ray",
rate: 7,
price: 3
},
{
id: 4,
name: "Transformers Dark of the Moon",
format: "Blu-Ray",
rate: 6,
price: 5
}
]}
$scope.setMovie = function(movie) {
$scope.currentMovie = movie;
}
}])
HTML:
<html ng-app="myApp">
<head>
<link rel="stylesheet" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainController" >
<h1 style="text-align:center">Garrett's Rentals</h1>
<div ng-repeat="movie in movies.movie">
<button ng-click = "setMovie(movie)">{{movie.name}}</button>
</div>
<div class="panel">
<h3>You have selected:</h3>
<p>{{currentMovie.name}}</p>
<p>{{currentMovie.format}}</p>
<p>{{currentMovie.rate}}</p>
<p>{{currentMovie.price}}</p>
</div>
</body>
</html>
http://plnkr.co/edit/0f5bbaS38GCIjGtCfLmy?p=preview
I have given a working example of your requirements see http://plnkr.co/edit/uQLqB3CfSUlETQEcpsS5?p=preview
Change the html to
<div ng-repeat="movie in movies">
<button ng-click="selectedMovie(movie)">{{movie.name}}</button>
</div>
<div class="panel">
<h3>You have selected:</h3>
<p>{{movie.name}}</p>
<p>{{movie.format}}</p>
<p>{{movie.rate}}</p>
<p>{{movie.price}}</p>
</div>
javascript to
myApp.controller('MainController', ['$scope', function($scope) {
var data = {
"movie": [
{
"id": 1,
"name": "Star Wars The Phantom Menace",
"format": "DVD",
"rate": 4,
"price": 2
},
{
"id": 2,
"name": "Star Wars A New Hope",
"format": "DVD",
"rate": 6,
"price": 4
},
{
"id": 3,
"name": "Transformers",
"format": "Blu-Ray",
"rate": 7,
"price": 3
},
{
"id": 4,
"name": "Transformers Dark of the Moon",
"format": "Blu-Ray",
"rate": 6,
"price": 5
}
]};
$scope.movies = data.movie;
$scope.selectedMovie = function(movie){
$scope.movie = movie;
}
}]);
All you need to do is define the movies object inside your controller in order for the movies to be displayed in your front-end. Embedding the movies JSON directly in your controller would look something like this:
app.controller('MainController', ['$scope', function ($scope) {
$scope.movies1 =
[{
"id": 1,
"name": "Star Wars The Phantom Menace",
"format": "DVD",
"rate": 4,
"price": 2
},
{
"id": 2,
"name": "Star Wars A New Hope",
"format": "DVD",
"rate": 6,
"price": 4
},
{
"id": 3,
"name": "Transformers",
"format": "Blu-Ray",
"rate": 7,
"price": 3
},
{
"id": 4,
"name": "Transformers Dark of the Moon",
"format": "Blu-Ray",
"rate": 6,
"price": 5
}];
}]);
Note that I have removed the movie property from inside the movies object and converted movies to an array instead, so that ng-repeat will work properly.
If instead you need to have the movies JSON as a separate file you can load that file using the $http service as #KuZon noted.
$http.get('movies.json').then(function(json) {
$scope.movies1 = json.data.movie;
});
In this case I have left the movie attribute inside the JSON object, and used it to select the array to store in $scope.movies1.
You can see both approaches in this Plunkr
Finally, don't forget to use ng-click on your buttons to actually select the movie. Something like the following:
<button ng-click="selectMovie1(movie)">{{movie.name}}</button>
and in your controller:
$scope.selectMovie1 = function(movie) {
$scope.movie1 = movie
}

Categories