want to display names separated by comma - angularjs

here is the program for display book details.everything is working perfect but i dont know how to display authorname separated by comma(,).I want to display author name separated by comma(,) in home page.the third line is error.that I want to fix and display authornames.
home.html
<script type="text/ng-template" id="display">
<td>{{book.title}}</td>
errorline: <td>{{book.authorname}}</td>(Here i want to display author names separated by comma(,))
<td>{{book.price}}</td>
<td>
<i class="material-icons"><button type="button" data-ng-click="editBook(book)">create</button></i>
</td>
<td><i class="material-icons"><button type="button" data-ng-click="deleteBook(book)">delete_forever</button></i></td>
</script>
controllers.js
$scope.online_bookauthors= 'data/bookauthors.js';
$scope.loadbookauthorscadentials= function (file) {
$http.get(file)
.then(function (result) {
$scope.bookauthorsresult=result;
$scope.bookauthorslist=$scope.bookauthorsresult.data.bookauthorsdetails;
})
}
$scope.loadbookauthorscadentials($scope.online_bookauthors);
bookauthors.js
{
"bookauthors": {
"Id": 1,
"name": "Book Author Details"
},
"bookauthorsdetails": [{
"bookid": 1,
"title": "War and piece",
"price": 100,
"authors": [{
"authorid": 1,
"authorname": "Tolstoy"
}, {
"authorid": 2,
"authorname": "Herman melville"
}]
}, {
"bookid": 2,
"title": "moby Dick",
"price": 200,
"authors": [{
"authorid": 1,
"authorname": "Tolstoy"
}, {
"authorid": 2,
"authorname": "Herman melville"
}, {
"authorid": 3,
"authorname": "Jane Austen"
}]
}],
"selected": {}
}

<div ng-repeat="author in book.authors">{{ ($index !== book.authors.length-1) ? author.authorname+',' : author.authorname }}</div>

Related

angular comparing two array values using ngIf else to show button

I am working on two arrays with ngIf else condition , I got two array values from two tables posts[post_id, user_id, description], likes[post_id, user_id, like_status, like_id].Here i need to compare post_id, user_id and like_status='like' if they are equal then condition true show success button else false default button.
I am already tried but its not working so please help to compare two arrays in using ngIf else .
<div class="container" *ngFor="let post of posts; let i = index">
<h6> {{post.description}} </h6>
<div class="container" style="border: 0px solid #ada5a5; ">
<div class="row">
<!--like button-->
<div class=" col-4">
<div *ngIf="(postLikes.indexOf(user_id) > -1) && (post.post_id == postLikes.post_id) && (postLikes.like_status == 'like'); else default">
<button type="button" class="btn btn-success" (click)=likeSubmit(post.user_id,post.post_id)>Liked</button><p>liked</p>
</div>
<ng-template #default>
<button type="button" class="btn btn-secondary" (click)=likeSubmit(post.user_id,post.post_id)>Like</button><p>like</p>
</ng-template>
</div>
</div>
</div>
</div>
// two tables data
posts: any[] =
[{
"post_id": 4,
"user_id": 2,
"description": " Hi How are you ",
"created_date": "2019-01-28T12:30:49.000Z"
}, {
"post_id": 5,
"user_id": 2,
"description": " Working a Fine ",
"created_date": "2019-01-28T12:31:20.000Z"
}, {
"post_id": 6,
"user_id": 2,
"description": " Hi How are you ......",
"created_date": "2019-01-28T12:32:15.000Z"
}, {
"post_id": 7,
"user_id": 2,
"description": " 4th test post",
"created_date": "2019-01-29T07:10:37.000Z"
}, {
"post_id": 9,
"user_id": 2,
"description": " 5th test post",
"created_date": "2019-01-31T11:17:31.000Z"
}, {
"post_id": 10,
"user_id": 2,
"description": " 6th test post",
"created_date": "2019-01-31T12:03:54.000Z"
}, {
"post_id": 11,
"user_id": 2,
"description": " 7th post post",
"created_date": "2019-02-08T05:50:02.000Z"
}, {
"post_id": 12,
"user_id": 2,
"description": " 8th test post ",
"created_date": "2019-02-08T06:08:01.000Z"
}];
postLikes:any[] =[{
"post_id": 4,
"user_id": 2,
"like_status": "unlike",
"like_id": 10
}, {
"post_id": 5,
"user_id": 2,
"like_status": "like",
"like_id": 9
}, {
"post_id": 6,
"user_id": 2,
"like_status": "like",
"like_id": 8
}, {
"post_id": 7,
"user_id": 2,
"like_status": "like",
"like_id": 7
}, {
"post_id": 9,
"user_id": 2,
"like_status": "like",
"like_id": 11
}];
post_id: any;
user_id:Number = 2;
// likes: Like[];
like_id: number | null ;
like_status: string;
Please try my StackBlitz code once and correct the error
https://stackblitz.com/edit/angular-wddupe?file=src%2Fapp%2Fapp.component.ts
I have updated code, please find changes
https://stackblitz.com/edit/angular-yjcpfk?file=src/app/app.component.html
Hope this helps you.
There is a problem with postlikes condition in html you compare string with array
Ngfor for postlikes array is remaining
I recommend you to do this in typescript using find keyword to compare and pass that result on posts objects like boolean from that it shows and hide your button
One way to do this
Create a public method in your component as
public isPostLikedByUser(postID: any, userID: any){
// This is actually matching the criteria exactly as you have described in question RETURN true or false
return this.postLikes.findIndex((i) => i.post_id == postID && i.user_id == userID && i.like_status == 'like') > -1;
}
Now call this method in your view as
<div *ngIf="isPostLikedByUser(post.post_id, post.user_id); else otherTest">
I have updated you stackblitz example as well. I hope this helps.
https://stackblitz.com/edit/angular-wddupe?embed=1&file=src/app/app.component.html

Dynamic form using AngularJS, multiple values binding

I am looking for a best approach to convert a static form to an angular dynamic form. I am not sure how to bind multiple values to the same answer.
The static page is available at: https://jsfiddle.net/hvuq5h46/
<div ng-repeat="i in items">
<select ng-model="i.answer" ng-options="o.id as o.title for o in i.answersAvailable" ng-visible="y.TYPE = 'SINGLE'"></select>
<input type="checkbox" ng-model="i.answer" ng-visible="y.TYPE = 'MULTIPLE'" />
</div>
The JSON file
[
{
"id": 1,
"title": "Are you a student?",
"type": "SINGLE",
"answersAvailable": [
{
"id": 1,
"title": "Yes"
},
{
"id": 2,
"title": "No"
}
],
"answer": [
1
]
},
{
"id": 2,
"title": "Would you like to be an astronaut?",
"type": "SINGLE",
"answersAvailable": [
{
"id": 4,
"title": "Yes"
},
{
"id": 5,
"title": "No"
},
{
"id": 6,
"title": "I am not sure"
}
],
"answer": [
4
]
},
{
"id": 3,
"title": "What is your favourite planet?",
"type": "MULTIPLE",
"answersAvailable": [
{
"id": 7,
"title": "Earth"
},
{
"id": 8,
"title": "Mars"
},
{
"id": 9,
"title": "Jupiter"
}
],
"answer": [
7,
8
]
}
]
Things would be much simpler if you can use a multiple select, but I understand it might be difficult for user to interact (consider something like md-select, which transforms multiple select into a list of checkbox for you)
Multiple select:
<select multiple
ng-model="i.answer"
ng-options="o.id as o.title for o in i.answersAvailable"
ng-if="i.type == 'MULTIPLE'"></select>
Anyway it is completely ok to use HTML checkbox. To do that we would need to bind checkbox model into the data as usual, and then update the answer array simultaneously.
ng-model="o.selected"
ng-change="updateAnswer(i)"
Also, we'll need to copy existing data to model during init.
ng-init="initMultiple(i)"
Working code:
angular.module('test', []).controller('Test', Test);
function Test($scope) {
$scope.items = [{
"id": 1,
"title": "Are you a student?",
"type": "SINGLE",
"answersAvailable": [{
"id": 1,
"title": "Yes"
},
{
"id": 2,
"title": "No"
}
],
"answer": [
1
]
},
{
"id": 2,
"title": "Would you like to be an astronaut?",
"type": "SINGLE",
"answersAvailable": [{
"id": 4,
"title": "Yes"
},
{
"id": 5,
"title": "No"
},
{
"id": 6,
"title": "I am not sure"
}
],
"answer": [
4
]
},
{
"id": 3,
"title": "What is your favourite planet?",
"type": "MULTIPLE",
"answersAvailable": [{
"id": 7,
"title": "Earth"
},
{
"id": 8,
"title": "Mars"
},
{
"id": 9,
"title": "Jupiter"
}
],
"answer": [
7,
8
]
}
]
$scope.initMultiple = function(item) {
item.answersAvailable.forEach(function(option) {
option.selected = item.answer.indexOf(option.id) != -1;
});
}
$scope.updateAnswer = function(item) {
item.answer = item.answersAvailable.filter(function(option) {
return option.selected;
})
.map(function(option) {
return option.id;
});
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<div ng-app='test' ng-controller='Test'>
<div ng-repeat="i in items">
<select ng-model="i.answer[0]"
ng-options="o.id as o.title for o in i.answersAvailable"
ng-if="i.type == 'SINGLE'"></select>
<label ng-repeat="o in i.answersAvailable"
ng-if="i.type == 'MULTIPLE'"
ng-init="initMultiple(i)">
<input type="checkbox"
ng-model="o.selected"
ng-change="updateAnswer(i)" /> {{o.title}}
</label>
<div>{{i.answer}}</div>
</div>
</div>
Based on my experience, I will make a separation as two Angular models (or usually called services) for the form questions and another one which will collect the answers and eventually will be passed to the backend for further processing. This will provide me a flexibility to maintain both logic and presentation.
var myModule = angular.module('myModule', []);
myModule.factory('QuestionsFormService', function() {
var _question1;
var _question2;
var _question3;
function init(data){
//questions initiation
}
return init;
});
var myModule = angular.module('myModule', []);
myModule.factory('FormDataService', function() {
var _dataAnswer = {}
function init(){
//data initialization
}
function insertData(key, value){
_dataAnswer[key] = value
}
return init;
});
From the example of service models above, you need to make these available to your presentation through the Angular controller with Dependency Injection.
myModule.controller("MyCtrl", function($scope, FormDataService, QuestionsFormService) {
$scope.form_questions = QuestionsFormService.init();
$scope.form_answers = FormDataService.init()
//further logic to make these available on your view on your convenience
});
What you write on the HTML page as an Angular view is already close enough. You only need to change the binding to two models as I propose above. Thank you.

Show JSON data as selected in Select AngularJS

I don' have a lot of knowledge about AngularJS. I have a JSON with all the data and first I created a select and according to the selected option I show some data or others according to the value, which are the IDs in the json
JSON
$scope.players = [
{
"player": {
"info": {
"position": "D",
"shirtNum": 4,
"positionInfo": "Centre/Right Central Defender"
},
"nationalTeam": {
"isoCode": "BE",
"country": "Belgium",
"demonym": "Belgian"
},
"age": "27 years 139 days",
"name": {
"first": "Toby",
"last": "Alderweireld"
},
"id": 4916,
"currentTeam": {
"name": "Tottenham Hotspur",
"teamType": "FIRST",
"shortName": "Spurs",
"id": 21
}
},
"stats": [
{
"name": "goals",
"value": 5
},
{
"name": "losses",
"value": 20
},
{
"name": "wins",
"value": 48
},
{
"name": "draws",
"value": 23
},
{
"name": "fwd_pass",
"value": 1533
},
{
"name": "goal_assist",
"value": 2
},
{
"name": "appearances",
"value": 80
},
{
"name": "mins_played",
"value": 6953
},
{
"name": "backward_pass",
"value": 308
}
]
},
...];
HTML
<select id="select-players" ng-model="Jugador" ng-options="jugador as (jugador.player.name.first + ' ' + jugador.player.name.last) for jugador in players track by jugador.player.id " ng-change="show()">
<option value="">Select a player...</option>
</select>
And I want to show the details of the player
<div class="content-player">
<div class="img-team"><span class="img-escudo"><img src="img/tottenham.png" /></span></div>
<p class="name-player">{{jugador.player.name.first}} {{jugador.player.name.last}} <span class="pos-player">{{jugador.info.positionInfo}}</span></p>
<div class="cont-desc-player">
<div class="desc-player">
<span class="txt-estadistics">{{jugador.stats.name}}</span>
<span class="num-estadistics">{{jugador.stats.value}}</span>
</div>
<div class="desc-player separador">
<span class="txt-estadistics">{{jugador.info.positionInfo}}</span>
<span class="num-estadistics">{{jugador.stats.value}}</span>
</div>
<div class="desc-player separador">
<span class="txt-estadistics">{{jugador.info.positionInfo}}</span>
<span class="num-estadistics">{{jugador.stats.value}}</span>
</div>
<div class="desc-player separador">
<span class="txt-estadistics">{{jugador.info.positionInfo}}</span>
<span class="num-estadistics">{{jugador.stats.value}}</span>
</div>
<div class="desc-player separador">
<span class="txt-estadistics">{{jugador.info.positionInfo}}</span>
<span class="num-estadistics">{{jugador.stats.value}}</span>
</div>
</div>
</div>
I don't know if I need to create in the controller one switch or using only if and else if is good and how can call it in HTML to show the details.
Thanks
You are using the iterated current object jugador in place of using the Model name Jugador. Try using Jugador.player.name.first instead of jugador.player.name.first and it should work fine if rest of the things are ok.
I also don't see the need of ng-change="show()" in your case. Model changes automatically as you change the select value and you can use it.
You use the iterated object name jugador while doing ng-repeat.

Complicated sorting with tabs in ng-repeat?

I have the following JSON object:
$scope.projects = [
{
"_id": "58ab1cb6edf5430e9014e2bc",
"name": "Project 1",
"issues": [
{
"status": 0,
"name": "Hart Cummings"
},
{
"status": 1,
"name": "Kinney Leach"
},
{
"status": 2,
"name": "Blake Mclaughlin"
}
]
},
{
"_id": "58ab1cb6d87456482e0eec4a",
"name": "Project 2",
"issues": [
{
"status": 0,
"name": "Vargas Gordon"
},
{
"status": 1,
"name": "Bobbie Church"
},
{
"status": 2,
"name": "Pennington Fry"
}
]
},
{
"_id": "58ab1cb6d87456482e0eec4a",
"name": "Project 3",
"issues": [
{
"status": 0,
"name": "WWWWW"
},
{
"status": 1,
"name": "SFSF"
},
{
"status": 2,
"name": "Pennington Fry"
}
]
}
];
I use ng-repeat to display this object in template:
<div ng-app="app">
<div ng-controller="TodoListController">
<div ng-repeat="project in projects">
<br>
<br>
<div><b> {{project.name}}</b></div>
<div class="tabs">
<div style="display:inline" ng-click="sort(1, $index);">Active</div> |
<div style="display:inline" ng-click="sort(0, $index);">Deactivated</div>
</div>
_____________________________________
<div ng-repeat="issue in project.issues | filter: (filterObject.index | filterObject.status)">
<div>{{issue.name}}</div>
</div>
</div>
</div>
</div>
So, as you can see I have two nested ng-repeat.
Issue is:
When I click on any tab and call method sort() I need to sort issue in project.issues by status field.
This is real sample that I want to reach.
https://jsfiddle.net/at6kw67g/
Problem is in this code:
<div ng-repeat="issue in project.issues | filter:filterObject.index : {status : filterObject.status}">
Since the links should sort the issues of a specific project, you should pass the project as argument to your sort() function.
And JavaScript arrays have a sort() method, so just use it.
Since one link should sort issues in ascanding order, and the other one in descending order, you should also pass this information to your sort() function.
So it boils down to
$scope.sortIssuesByStatus = function(project, descending) {
project.issues.sort(function(issue1, issue2) {
var result = issue1.status - issue2.status;
if (descending) {
result = -result;
}
return result;
});
}
and
<div ng-repeat="project in projects">
<div class="tabs">
<button ng-click="sortIssuesByStatus(project, true)">Active</button>
<button ng-click="sortIssuesByStatus(project, false)">Deactivated</button>
</div>
<div ng-repeat="issue in project.issues">
<div>{{issue.name}} - {{ issue.status }}</div>
</div>
</div>
Here's a plunkr implementing it.

Angularjs Dynamic Text Fields and multiply two field

Hi I have a Json Like this
[
{
"id": 1,
"name": "Furniture & Fixture",
"choices": [
{
"req_goods": "",
"qty": "10",
"rate": "",
"total": ""
}
]
},
{
"id": 2,
"name": "Miscellaneous Property",
"choices": [
{
"req_goods": "",
"qty": "",
"rate": "",
"total": ""
}
]
},
{
"id": 3,
"name": "Office Equipment",
"choices": [
{
"req_goods": "",
"qty": "",
"rate": "",
"total": ""
}
]
}
]
here choices are my dynamic fields user can add as much choices as they want, my add/remove js is like this
$scope.addNewChoice = function(id){
$scope.capital_budgets[id].choices.push({});
};
$scope.removeChoice = function(parent_id,id) {
$scope.capital_budgets[parent_id].choices.splice(id,1);
};
my html
<div ng-repeat="cb in capital_budgets">
<div><b><% $index+1 %> <% cb.name %></b></div>
<div ng-repeat="choice in cb.choices">
<input type="text" ng-model="choice.req_goods">
<input type="text" ng-model="choice.qty">
<input type="text" ng-model="choice.rate">
<input type="text" ng-model="choice.total">
<button type="button" ng-hide="$first" ng-click="removeChoice($parent.$index,$index)">-</button>
</div>
<button type="button" ng-click="addNewChoice($index)">+</button>
</div>
Now I want to calculate the total(qty*rate) of each added choices whenever they put qty and rate and put it in total field please help
One way to accomplish this would be to create a method in your controller to do the calculation and then just call it on a change of qty or rate.
controller:
$scope.updateTotal = function(choice) {
if(!choice.qty || !choice.rate) {
choice.total = 0;
} else {
choice.total = choice.qty * choice.rate;
}
};
html:
<input type="text" ng-model="choice.qty" ng-change="updateTotal(choice)">
<input type="text" ng-model="choice.rate" ng-change="updateTotal(choice)">

Resources