how to group array and read using knockout.js data-bind: with - arrays

I am trying to group an array
[{ "Name": "test1", "Other": "Junk" },
{ "Name": "test1", "Other": "Junk2" },
{ "Name": "test2", "Other": "Pile" }]
I am using the following method to group by property.
var groupBy = function (xs, key) {
return xs.reduce(function (rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
My output from this is, "test1": {children info}, "test2": {one child info}
I am using knockout.js to pass this info to a modal, to which i am using data-bind="with: results"
I am just not sure how to display the results as
test1 - (2) *count/length of test1
test2 - (1) *count/length of test2
I have tried using data-bind="foreach: $parent", this doesn't seem to work. I have also tried setting the object, to a parent called UnpackedItems, then using foreach on UnpackedItems.. this doesn't work either.
<div class="modal fade" id="myModal" data-bind="with: TheseUnpackedItems" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Unpacked Items</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="modal-body">
<table style="margin: auto;" class="table">
<tbody data-bind="foreach: UnpackedItems">
<tr>
<td>
<p class="form-control-static" data-bind="text: Name"></p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
self.ShowUnpacked = function(vm) {
var groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
const Property = "Name";
const GroupedUnpackedItems = groupBy(vm.UnpackedItems, Property);
var test = JSON.stringify(GroupedUnpackedItems);
var m = { "UnpackedItems": GroupedUnpackedItems }
self.TheseUnpackedItems(vm);
}
I am not getting any errors, however, no data actually shows up.

UnpackedItems is an object. So, you can't use foreach bindings. You could loop through the keys of the object using Object.keys()
<tbody data-bind="foreach: Object.keys(UnpackedItems)">
<tr>
<td>
<p class="form-control-static" data-bind="text: $data"></p>
</td>
</tr>
</tbody>
Here's a working snippet:
const groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
function viewModel() {
const self = this;
const UnpackedItems=[{Name:"test1",Other:"Junk"},{Name:"test1",Other:"Junk2"},{Name:"test2",Other:"Pile"}],
Property = "Name",
GroupedUnpackedItems = groupBy(UnpackedItems, Property),
m = { "UnpackedItems": GroupedUnpackedItems }
self.TheseUnpackedItems = ko.observable(m);
}
ko.applyBindings(new viewModel)
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div id="myModal" data-bind="with: TheseUnpackedItems">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Unpacked Items</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="modal-body">
<table style="margin: auto;" class="table">
<tbody data-bind="foreach: Object.keys(UnpackedItems)">
<tr>
<td>
<p class="form-control-static" data-bind="text: $data"></p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>

Related

How can I minus the quantity from list table in VueJS?

Good day everyone! Can you help me how can I minus the quantity of list table by using the quantity of cart table? In my console.log when I add more than one item to the cart and click the minus button the quantity of each row are the become the same. The quantity from the list table are not the same. How can I get the right result of each quantity in my cart table? I want to display the right answer in the bottom of the cart table. Here’s my jsfiddle -->
https://jsfiddle.net/2zx9vy3n/20/
minusFromListToCart : function() {
for(var index = 0; index < this.selects.length; index++) {
this.total = parseInt(this.select_quantity) - parseInt(this.input_quantity);
console.log(this.total);
}
}
I appreciate your try, but unfortunately there are many small mistakes, like
repeating same product goes separately instead adding to previous,
you need computed method to get remaining counts
reset you count for next product adding in cart
minus quantity from relative product count instantly.
Note : add all validation like what if there is not product available etc.
var app = new Vue({
el: '#app',
data: {
selects: [],
carts : [{
id: null, name: null, cat: null, quantity : null
}],
lists: [
{ id: 1, name: 'Book', cat: 'Category 1', quantity : 50},
{ id: 2, name: 'Notebook', cat: 'Category 2', quantity : 60},
{ id: 3, name: 'Pencil', cat: 'Category 3', quantity : 70}
],
select_id : "",
select_name : "",
select_cat : "",
input_quantity : "",
select_quantity : "",
total : 0
},
computed:{
remainingQuantity : function() {
var total_qty = 0;
var selected_qty = 0;
for(let i in this.lists){
total_qty += this.lists[i].quantity;
}
return total_qty;
}
},
methods : {
retrieveList : function(id, name, cat, quantity) {
this.input_quantity =1;
this.select_id = id;
this.select_name = name;
this.select_cat = cat;
this.select_quantity = quantity;
//console.log(this.select_quantity);
},
addToCart : function() {
if(!this.input_quantity){
return false;
}
this.carts.id = this.select_id;
this.carts.name = this.select_name;
this.carts.cat = this.select_cat;
this.carts.quantity = parseInt(this.input_quantity);
console.log(this.carts.quantity);
var selected_index = this.selects.map((e)=>e.id).indexOf(this.select_id);
if(selected_index > -1){
this.selects[selected_index].quantity += parseInt(this.input_quantity);
}else{
this.selects.push({...this.carts});
}
var lists_index = this.lists.map((e)=>e.id).indexOf(this.select_id);
if(lists_index > -1){
this.lists[lists_index].quantity -= parseInt(this.input_quantity);
}
}
}
});
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">
</script>
</head>
<body>
<div id="app">
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Category</th>
<th>Quantity</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr v-for="(list, index) in lists">
<td>{{list.id}}</td>
<td>{{list.name}}</td>
<td>{{list.cat}}</td>
<td>{{list.quantity}}</td>
<td>
<button #click="retrieveList(list.id, list.name, list.cat, list.quantity)" data-toggle="modal" data-target="#myModal">Add to cart</button>
</td>
</tr>
</tbody>
</table>
<table border="1" class="mt-4">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Category</th>
<th>Quantity</th>
</tr>
</thead>
<tbody>
<tr v-for="(select, index) in selects">
<td>{{select.id}}</td>
<td>{{select.name}}</td>
<td>{{select.cat}}</td>
<td>{{select.quantity}}</td>
</tr>
</tbody>
</table>
<p>Final Quantity : {{remainingQuantity}}</p>
<div class="modal fade" id="myModal" class="text-dark" tabindex="1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Add Transaction</h4>
<button type="button" class="close" data-dismiss="modal"></button>
</div>
<div class="modal-body mx-auto" id="modal-less-input">
<label for="input_quantity">Quantity</label>
<div class="input-group form-group">
<input type="number" class="form-control col-sm-12" id="input_quantity" v-model="input_quantity" name="input_quantity" placeholder="Enter Quantity" autofocus required>
</div>
</div>
<div class="modal-footer">
<button #click.prevent="addToCart()" type="button" class="btn btn-success" data-dismiss="modal"><i class="far fa-save"> </i> Add to Cart</button>
</div>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>

Angular 2 bootstrap modal pass data

I am newbie on angular 2. I am trying to do simple crud operations. However I have problem with using bootstrap modal. The code below, opens bootstrapmodal but I can't send selected movie on DeleteMovie() method.
<div style="margin: 20px">
<h2>Movies List</h2>
<input type="button" Value="Add Movie" class="btn btn-primary" (click)="AddMovie()"/>
<hr/>
<div class="row">
<div class="col-md-12">
<table class="table table-bordered">
<thead>
<tr>
<th>Movie Name</th>
<th>Genre</th>
<th>Edit</th>
<th>Delete</th>
<th>Delete2</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let mv of movies">
<td>{{mv.MovieName}}</td>
<td>{{mv.MovieGenre}}</td>
<td><a routerLink="/movies/{{mv.movieID}}"><i class="glyphicon glyphicon-edit"></i></a></td>
<td><i class="glyphicon glyphicon-remove clickable" (click)="removeMovie(mv)"></i></td>
<td><i class="glyphicon glyphicon-remove clickable" data-toggle="modal" data-target="#myModal2" data-id="{{mv.MovieName}}" (click)="SelectMovie(mv)"></i></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="modal fade" id="myModal2" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="myModalLabel">Delete Record</h4>
</div>
<div class="modal-body">
Do you want to delete {{selectedMovie.MovieName}}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" (click)="removeMovieV2(selectedMovie)" data-dismiss="modal">Delete</button>
</div>
</div>
</div>
</div>
#Component({
selector: 'movies2',
templateUrl: '/templates/movies.component.html',
providers: [MoviesService]
})
export class MoviesComponent implements OnInit {
isLoading = true;
movies: any = [];
selectedMovie:any={};
constructor(private _moviesService: MoviesService, private router: Router, private notificationService: NotificationService) {
}
ngOnInit() {
this.GetMovies();
}
AddMovie() {
this.router.navigate(['/newmovie']);
}
GetMovies() {
this._moviesService.getMovies().subscribe(p => {
this.movies = p;
});
}
SelectMovie(mv: any) {
this.selectedMovie = mv;
}
removeMovieV2(val: any) {
this._moviesService.deleteMovie(val).subscribe(res => {
this.notificationService.printSuccessMessage(val.MovieName + ' has been deleted.');
this.GetMovies();
}, error => {
this.notificationService.printErrorMessage(error);
});
}
}
I think you need to use attribute binding instead of property binding for boostrap to get the value
attr.data-id="{{mv.MovieName}}"
(only for strings)
or
[attr.data-id]="mv.MovieName"
(also supports objects)

ng-repeat on <tr> giving problems

html code:
<head>
<title>Angular Accordion</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="dcrlistingHosted.js"></script>
</head>
<body ng-app="myApp" ng-controller="dcrlistingCtrl">
<div class="container-fluid">
<div class="row">
<div class="col-sm-4 hidden-xs" >
<ul class="list-group text-center" style="cursor:pointer; border-bottom:6px solid #3184a1">
<li class="list-group-item contactHeader" style="cursor:default; background-color:#3184a1; color:white;">{{contact}}</li>
<div style="cursor:pointer;" ng-repeat="con in contacts" class="text-center">
<div ng-click="toggleGroup(con)"
ng-class="{active: isGroupShown(con)}" class="list-group-item" style="background-color:#28aadc; border-bottom:1px solid white; border-top:1px solid white; color:white;">
{{con.patch}}<span class="badge">{{con.contact.length}}</span>
</div>
<div >
<div ng-repeat="cell in con.contact" ng-show="isGroupShown(con)" class="panel-collapse cell list-group-item" style="background-color:grey; color:white;" ng-click="transferEachContact('contacts','tableArray',cell.id)">
{{cell.name}}
</div>
</div>
</div>
</ul>
</div>
<div class="col-sm-8">
<div class="col-sm-12 hidden-xs toggleArea">
<button type="button" class="btn btn-primary " ng-click="doctors()"><b>Doctor</b></button>
<button type="button" class="btn btn-primary " ng-click="pharmacists()" ><b>Pharmacist</b></button>
<button type="button" class="btn btn-primary " ng-click="stockists()" ><b>Stockist</b></button>
<div style="display:inline; float:right;">
<input autocomplete="off" type="text" maxlength="50" placeholder="Search Doctor" min-length="4" typeahead-editable="false">
<button type="button" class="btn btn-info glyphicon glyphicon-search"><b>Search</b></button>
</div>
</div>
<div class="col-lg-12">
<div id="no-more-tables" class="doctors">
<table class="table table-striped table-bordered table-hover table-condensed cf">
<thead class="text-center cf" style="background-color:#3184a1; color:white;" >
<tr>
<th>Name</th>
<th class="hidden-xs">Speciality</th>
<th class="hidden-xs">class</th>
<th>patch</th>
<th class="hidden-xs">type</th>
<th>Edit</th>
<th>Delete</th></tr>
</thead>
<tbody data-link="row" class="rowlink">
<div class="contacts" ng-repeat="delt in delitems" >
<tr ng-repeat=" del in delt.contact" ng-click="transferEachContact('tableArray','contacts',del.id)">
<td>{{del.name}}</td>
<td class="hidden-xs">{{del.Speciality}}</td>
<td class="rowlink-skip hidden-xs">{{del.class}}</td>
<td data-title="patch:">{{del.patch}}</td>
<td class="hidden-xs">{{del.type}}</td>
<td data-title="Edit:"><span class="glyphicon glyphicon-plus"></span></td>
<td data-title="Delete:"><span class="glyphicon glyphicon-remove"></span></td>
</tr>
</tr>
</tbody>
</table>
<div ng-repeat="delitems in tableArray" >
patch:{{delitems.patch}}
<hr>
<div ng-repeat="del in delitems.contact">
<p ng-click="transferEachContact('tableArray','contacts',del.id)" ng-show="del.name.length"> name:{{del.name}}</p>
</div>
<hr>
<hr>
</div>
</div>
</div>
</div>
</div>
</body>
angular js code:
var appModule =angular.module("myApp", []);
appModule.controller("dcrlistingCtrl", function($scope) {
$scope.toggleGroup = function(group) {
if ($scope.isGroupShown(group)) {
$scope.shownGroup = null;
} else {
$scope.shownGroup = group;
}
};
$scope.isGroupShown = function(group) {
return $scope.shownGroup === group;
};
$scope.contact="Doctors";
$scope.contacts=
[
{ "patch":"BARIJPUR",
"contact":
[
{"id":"1","patch":"BARIJPUR","name":"RAMA SENA","Speciality":"consulting physician","class":"gold","type":"doctor"},
{"id":"2","patch":"BARIJPUR","name":"SMRITI IRANI","Speciality":"consulting physician","class":"gold","type":"doctor"},
{"id":"3","patch":"BARIJPUR","name":"JAGDISH NAIR","Speciality":"consulting physician","class":"gold","type":"doctor"}
]
},
{
"patch":"RATANGHAR",
"contact":
[
{"id":"4","patch":"RATANGHAR","name":"ASHISH NAIK","Speciality":"consulting physician","class":"gold","type":"doctor"},
{"id":"5","patch":"RATANGHAR","name":"SMRITI IRANI","Speciality":"consulting physician","class":"gold","type":"doctor"},
{"id":"6","patch":"RATANGHAR","name":"SAIRAJ NAIK","Speciality":"consulting physician","class":"gold","type":"doctor"}
]
},
{
"patch":"BHIRJ",
"contact":
[
{"id":"7","patch":"BHIRJ","name":"RATAN PANDEY","Speciality":"consulting physician","class":"gold","type":"doctor"},
{"id":"8","patch":"BHIRJ","name":"RAMAN SHIVOLKAR","Speciality":"consulting physician","class":"gold","type":"doctor"}
]
}
];
$scope.doctors = function() {
$scope.contact="Doctors";
$scope.contacts=[];
$scope.contacts=
[
{ "patch":"BARIJPUR",
"contact":
[
{"id":"1","patch":"BARIJPUR","name":"RAMA SENA","Speciality":"consulting physician","class":"gold","type":"doctor"},
{"id":"2","patch":"BARIJPUR","name":"SMRITI IRANI","Speciality":"consulting physician","class":"gold","type":"doctor"},
{"id":"3","patch":"BARIJPUR","name":"JAGDISH NAIR","Speciality":"consulting physician","class":"gold","type":"doctor"}
]
},
{
"patch":"RATANGHAR",
"contact":
[
{"id":"4","patch":"RATANGHAR","name":"ASHISH NAIK","Speciality":"consulting physician","class":"gold","type":"doctor"},
{"id":"5","patch":"RATANGHAR","name":"SMRITI IRANI","Speciality":"consulting physician","class":"gold","type":"doctor"},
{"id":"6","patch":"RATANGHAR","name":"SAIRAJ NAIK","Speciality":"consulting physician","class":"gold","type":"doctor"}
]
},
{
"patch":"BHIRJ",
"contact":
[
{"id":"7","patch":"BHIRJ","name":"RATAN PANDEY","Speciality":"consulting physician","class":"gold","type":"doctor"},
{"id":"8","patch":"BHIRJ","name":"RAMAN SHIVOLKAR","Speciality":"consulting physician","class":"gold","type":"doctor"}
]
}
];
};
$scope.pharmacists = function() {
$scope.contact="pharmacists";
$scope.contacts=[];
$scope.contacts=
[
{"patch":"DRAMAPUR","id":"4", "contact":["RYAN DCOSTA", "SIDDESH NAIK","ARVIND CHARI"]},
{"patch":"MAHALSA", "id":"5" ,"contact":["TANVI REDKAR", "PRIYANKA BANDODKAR", "GIRISH MATARBHOG"]}
];
};
$scope.stockists = function() {
$scope.contact="stockists";
$scope.contacts=[];
$scope.contacts=
[
{"patch":"SRIJAN","id":"6", "contact":["SHILPA NAIK", "ARBAAZ SHAIK","NAZEEF SHAIK"]},
{"patch":"KHANCHAR","id":"7", "contact":["AVESH NAIK", "MELROY FERNANDES", "BRIAN DIAS"]},
{"patch":"TRINSAL","id":"8","contact":["MEENAKSHI TIWARI", "GAURAV TIWARI"]}
];
};
//following function takes parameter of a existing function and makes a call to it (variable value as a function name can be archieved with the following //function)
$scope.callFunction = function (name){
if(angular.isFunction($scope[name]))
$scope[name]();
alert(name);
};
$scope.tableArray=
[
{"patch":"BARIJPUR",
"contact":[]
},
{"patch":"BHIRJ",
"contact":[]
},
{"patch":"RATANGHAR",
"contact":[]
}
];
//delete whole object which is inside an object and append to respective patch in array
$scope.transferEachContact= function(sourceArray,destArray,contactId)
{
//following for loop is to track each object inside array (depth=array[i])
for (i = 0; i < $scope.$eval(sourceArray).length; i++)
{
//following for loop is to track each object one more step inside array (depth=array[i].array[j])
for(j = 0; j < $scope.$eval(sourceArray)[i].contact.length; j++)
{
//checking is done on id which is unique! if id's match than that object is shifted to destination array under respective patch!
if ($scope.$eval(sourceArray)[i].contact[j].id && $scope.$eval(sourceArray)[i].contact[j].id === contactId)
{
//following loop is on the destination array (depth=array[k])
for(k = 0; k < $scope.$eval(destArray).length; k++)
{
//following checks where source array patch and dest array patch match and puts that object under the respective patch, ERADICATS NEED FOR RESPECTIVE ORDERED STORING OF PATCH IN ORDER IN DESTINATION ARRAY
if($scope.$eval(sourceArray)[i].patch == $scope.$eval(destArray)[k].patch)
{
[].push.apply($scope.$eval(destArray)[k].contact, $scope.$eval(sourceArray)[i].contact.splice(j, 1));
break;
}
}
}
}
}
};
});
the problem is that the ng-repeat on the <tr> is not happening! No data is shown when I click and transfer data from doctors array to tableArray
following is the image of the output:
here is the code:
Name
Speciality
class
patch
type
Edit
Delete
<tbody data-link="row" class="rowlink" ng-repeat="delitems in tableArray" ng-show="delitems.patch.length">
<tr ng-repeat=" del in delitems.contact" ng-show="del.name.length">
<div >
<td>{{del.name}}</td>
<td class="hidden-xs">{{del.Speciality}}</td>
<td class="hidden-xs">{{del.class}}</td>
<td data-title="patch:">{{del.patch}}</td>
<td class="hidden-xs">{{del.type}}</td>
<td data-title="Edit:"><span class="glyphicon glyphicon-plus"></span></td>
<td data-title="Delete:" ><span class="glyphicon glyphicon-remove" ng-click="transferEachContact('tableArray','contacts',del.id)"></span></td>
</div>
</tr>
</tbody>
</table>
the mistake i did was while using the ng-repeat in the wrong tags! and plus i could use ng-repeat on tag

How to delete data inside the list using bootstrap modal?

I just want to delete the data inside the table using bootstrap modal, but it seems so hard to find the right way how to do this, here's my sample code. Inside my modal I have an href code that use to delete the data
, it is working outside the modal. I just want to know any solution make this working. thanks.
var app = angular.module('app', ['ui.bootstrap']);
var student = [{
name: 'Andrew'
}, {
name: 'Butler'
}, {
name: 'Cameron'
}, {
name: 'Delo'
}, {
name: 'Emman'
}, {
name: 'Ferbs'
}];
app.filter('startFrom', function() {
return function(input, start) {
if (input) {
start = +start; //parse to int
return input.slice(start);
}
return [];
}
});
app.controller('customersCtrl', function($scope, $timeout) {
$scope.list = student;
$scope.currentPage = 1; //current page
$scope.entryLimit = 10; //max no of items to display in a page
$scope.filteredItems = $scope.list.length; //Initially for no filter
$scope.totalItems = $scope.list.length;
$scope.setPage = function(pageNo) {
$scope.currentPage = pageNo;
};
$scope.filter = function() {
$timeout(function() {
$scope.filteredItems = $scope.filtered.length;
}, 10);
};
$scope.sort_by = function(predicate) {
$scope.predicate = predicate;
$scope.reverse = !$scope.reverse;
};
});
app.filter('startsWithA', function() {
return function(items, letter) {
console.log(items, letter)
var filtered = [];
var letterMatch = new RegExp(letter, 'i');
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (letterMatch.test(item.name.substring(0, 1))) {
filtered.push(item);
}
}
console.log(filtered);
return filtered;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.10.0/ui-bootstrap-tpls.js"></script>
<div ng-app="app">
<div class="container" ng-controller="customersCtrl">
<div class="row">
<div class="col-12">
<h2 id="titleHead"><center>Student List</center></h2>
</div>
<div class="option-panel">
<div class="col-sm-3 col-md-3 pull-right">
<form class="navbar-form">
<div class="input-group">
<input type="text" ng-model="search" ng-click="filter()" placeholder="Search student" class="form-control" placeholder="Search" name="search">
</div>
</form>
</div>
</div>
<div class="nav navbar-default">
<div class="tab-panel">
<nav>
<ul>
<li class="active" name="active"><a ng-click="letter = '[AB]'">A-B</a>
</li>
<li class="active" name="active"><a ng-click="letter = '[CD]'">C-D</a>
</li>
<li class="active" name="active"><a ng-click="letter = '[EF]'">E-F</a>
</li>
</ul>
</nav>
</div>
</div>
<div id="no-more-tables">
<table class="col-md-12 table-bordered table-condensed cf" ng-show="filteredItems > 0">
<thead class="cf">
<tr>
<th>
<center>Name
<a ng-click="sort_by('first_name');"></a>
</center>
</th>
</tr>
</thead>
<tbody color="#">
<tr ng-repeat="data in filtered = (list | filter:search |orderBy : predicate :reverse) | startFrom:(currentPage-1)*entryLimit |startsWithA:letter |limitTo:entryLimit ">
<td data-title="Name" class="text-center">{{data.name}} <a type="button" class="btn btn-xs btn-primary" style="width: 40%;" href="#" data-toggle="modal" data-target="#myModal" >Delete</a>
</td>
</tr>
</tbody>
</table>
<div class="col-md-12" ng-show="filteredItems == 0">
<div class="col-md-12">
<center>
<h4>No results found</h4>
</center>
</div>
</div>
<div class="col-md-12" ng-show="filteredItems > 0">
<center>
<div pagination="" page="currentPage" on-select-page="setPage(page)" boundary-links="true" total-items="filteredItems" items-per-page="entryLimit" class="pagination-small" previous-text="«" next-text="»"></div>
</center>
</div>
<div id="myModal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Delete Student</h4>
</div>
<div class="modal-body">
<p>Do you want to delete this student?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">No</button>
<button type="button" class="btn btn-primary" href="<?php echo base_url(); ?>index.php/students/edit/studentform/{{data.id}}" >Yes</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
First I would suggest using $http service, or similar, for removing a record. Also, You'll notice that I made a change to the way your controller was organized by using the controller as syntax, and assigning everything to the controller, and not to the scope. That way you can pass on the controllers scope to directives and such more easily.
The idea is that you preserve an ID of the selected item, so that you can use it later on when you trigger the server delete action.
This can be done in many different ways, this is just one of the ways.
Hope this helps.
var app = angular.module('app', ['ui.bootstrap']);
var student = [{
id: 0,
name: 'Andrew'
}, {
id: 1,
name: 'Butler'
}, {
id: 2,
name: 'Cameron'
}, {
id: 3,
name: 'Delo'
}, {
id: 4,
name: 'Emman'
}, {
id: 5,
name: 'Ferbs'
}];
app.filter('startFrom', function() {
return function(input, start) {
if (input) {
start = +start; //parse to int
return input.slice(start);
}
return [];
}
});
app.controller('customersCtrl', function($http, $timeout) {
var vm = this,
itemId = null;
/**
* Store a selected item's ID
* #param id
*/
vm.getItemId = function (id) {
itemId = id;
};
/**
* Remove the selected item from the list
*/
vm.deleteItemFunction = function () {
console.log('remove', itemId);
// And then something like this
$http.delete('/students/edit/studentform/' + itemId).success(function () {
console.log('successfully removed');
});
};
vm.list = student;
vm.currentPage = 1; //current page
vm.entryLimit = 10; //max no of items to display in a page
vm.filteredItems = vm.list.length; //Initially for no filter
vm.totalItems = vm.list.length;
vm.setPage = function(pageNo) {
vm.currentPage = pageNo;
};
vm.filter = function() {
$timeout(function() {
vm.filteredItems = vm.filtered.length;
}, 10);
};
vm.sort_by = function(predicate) {
vm.predicate = predicate;
vm.reverse = !vm.reverse;
};
});
app.filter('startsWithA', function() {
return function(items, letter) {
console.log(items, letter)
var filtered = [];
var letterMatch = new RegExp(letter, 'i');
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (letterMatch.test(item.name.substring(0, 1))) {
filtered.push(item);
}
}
console.log(filtered);
return filtered;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.10.0/ui-bootstrap-tpls.js"></script>
<div ng-app="app">
<div class="container" ng-controller="customersCtrl as customer">
<div class="row">
<div class="col-12">
<h2 id="titleHead"><center>Student List</center></h2>
</div>
<div class="option-panel">
<div class="col-sm-3 col-md-3 pull-right">
<form class="navbar-form">
<div class="input-group">
<input type="text" ng-model="search" ng-click="customer.filter()" placeholder="Search student" class="form-control" placeholder="Search" name="search">
</div>
</form>
</div>
</div>
<div class="nav navbar-default">
<div class="tab-panel">
<nav>
<ul>
<li class="active" name="active"><a ng-click="letter = '[AB]'">A-B</a>
</li>
<li class="active" name="active"><a ng-click="letter = '[CD]'">C-D</a>
</li>
<li class="active" name="active"><a ng-click="letter = '[EF]'">E-F</a>
</li>
</ul>
</nav>
</div>
</div>
<div id="no-more-tables">
<table class="col-md-12 table-bordered table-condensed cf" ng-show="customer.filteredItems > 0">
<thead class="cf">
<tr>
<th>
<center>Name
<a ng-click="customer.sort_by('first_name');"></a>
</center>
</th>
</tr>
</thead>
<tbody color="#">
<tr ng-repeat="data in filtered = (customer.list | filter:search |orderBy : customer.predicate : customer.reverse) | startFrom:(customer.currentPage-1)* customer.entryLimit |startsWithA:letter |limitTo: customer.entryLimit ">
<td data-title="Name" class="text-center">
{{data.name}}
<a type="button" class="btn btn-xs btn-primary" style="width: 40%;" href="#" ng-click="customer.getItemId(data.id)" data-toggle="modal" data-target="#myModal">Delete</a>
</td>
</tr>
</tbody>
</table>
<div class="col-md-12" ng-show="customer.filteredItems == 0">
<div class="col-md-12">
<center>
<h4>No results found</h4>
</center>
</div>
</div>
<div class="col-md-12" ng-show="customer.filteredItems > 0">
<center>
<div pagination="" page="customer.currentPage" on-select-page="customer.setPage(page)" boundary-links="true" total-items="customer.filteredItems" items-per-page="customer.entryLimit" class="pagination-small" previous-text="«" next-text="»"></div>
</center>
</div>
<div id="myModal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Delete Student</h4>
</div>
<div class="modal-body">
<p>Do you want to delete this student?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">No</button>
<button type="button" class="btn btn-primary" ng-click="customer.deleteItemFunction()">Yes</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

Adding fields dynamically to JSON array in angular js

I've got two JSON arrays, one for headers and the other for data. I'm handling the headers, and I'm now displaying the data using ng-repeat. working fine. but, i want to add the data dynamically to $scope.data from the view. i've created a button in the last row of the table as 'add row' clicking on it, will fill the last row with input box each for a column. Further from here i'm not finding ways to proceed...since i'm new in angular js.
Please help me.
HTML code and JS is pasted below.
'use strict';
angular.module('mean.system').controller('IndexController', ['$scope', '$http', 'Global','$window',
function($scope, $http,$window) {
$scope.header = [{'field':'first_name', 'displayName':'First name','type':'required'},{'field':'last_name', 'displayName':'Last Name','type':'required'},{'field':'email','displayName':'Email Address','type':'required'}];
$scope.headerAll=[{'field':'first_name', 'displayName':'First name','type':'required'},{'field':'last_name', 'displayName':'Last Name','type':'required'},{'field':'email', 'displayName':'Email','type':'required'},{'field':'isMarried', 'displayName':'marital Status','type':'optional'},{'field':'nick_name', 'displayName':'Nick Name','type':'optional'}]
$scope.optional = [];
$scope.data=[{'first_name':'ruth','last_name':'vick','email':'ruthvick#gmail.com','isMarried':'no','nick_name':'ruthu'},{'first_name':'rahul','last_name':'kumar','email':'rahul#gmail.com','isMarried':'no','nick_name':'rahul'},{'first_name':'vicky','last_name':'gupta','email':'vicky#gmail.com','isMarried':'no','nick_name':'vicky'}]
$scope.headerAll.forEach(function(result){
if (result.type === 'optional') {
$scope.optional.push(result);
}
});
console.log($scope.optional);
$scope.addColumn = function(field){
/*$scope.toPush = {'field':'marital', 'displayName':'married','type':'required'};
$scope.header.push($scope.toPush);*/
$scope.optional.forEach(function(result){
if (result.field === field) {
$scope.header.push(result);
}
});
};
$scope. deleteColumn = function(field,index){
console.log(index);
$scope.optional.forEach(function(result){
console.log(result.field);
if (result.field === field) {
$scope.header.splice(index,1);
}
});
};
$scope.toPoint = function(index){
$scope.index = index;
console.log($scope.index);
};
$scope. editColumn = function(currentField,fieldToEdit,index){
$scope.header.splice($scope.index,1);
$scope.headerAll.forEach(function(result){
if(result.field === fieldToEdit){
$scope.header.splice($scope.index,0,result);
}
});
};
$scope.showAddBtn = 'true';
$scope.addRowButton = function(){
$scope.showInput = 'true';
$scope.showAddBtn = 'false';
};
$scope.cancel = function(){
$scope.showInput = 'false';
$scope.showAddBtn = 'true';
};
$scope.addRow = function(){
$scope.headerAll.forEach(function(result){
var x= result.field;
console.log(x);
$scope.rowObj = {
x : x
};
console.log($scope.rowObj);
});
};
}
]);
<div>
<table class="table table-bordered table-hover">
<thead class="wrapper">
<tr>
<th ng-repeat="data in header">
<div class="col-md-9">{{data.displayName}}</div>
<div class="col-md-1">
<button href="" ng-click="deleteColumn(data.field,$index)"><span class=" glyphicon glyphicon-trash pull-right"> </span></button>
</div>
<div class="dropdown col-md-1" >
<button class="glyphicon glyphicon-pencil dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" ng-click = "toPoint($index);">
<span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1" ng-repeat="optionalHeader in optional">
<li role="presentation" ng-repeat="dataEdit in headerAll"><a role="menuitem" tabindex="-1" href="" ng-click="editColumn(data.field,dataEdit.field,$index)">{{dataEdit.displayName}}</a></li>
</ul>
</div>
</th>
<th><div class="dropdown" >
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown">
Add Columns
<span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1" ng-repeat="optionalHeader in optional">
<li role="presentation" ng-repeat="optionalHeader in optional"><a role="menuitem" tabindex="-1" href="" ng-click="addColumn(optionalHeader.field)">{{optionalHeader.displayName}}</a></li>
</ul>
</div>
</th>
</tr>
</thead>
<tbody >
<tr class="active" ng-repeat="row in data">
<td ng-repeat="fields in headerAll">
{{row.fields.field}}
</td>
</tr>
<tr>
<td ng-repeat="fields in header">
<input type="text" ng-show="showInput" ng-model="input"></input>
</td>
<td>
<a href="" style="color:#63822E" ng-click="addRow()">
<h5 ng-show= "showInput"><span class="glyphicon glyphicon-ok" ></span></h5>
</a>
<a href="" style="color:#63822E">
<h5 ng-show= "showInput" ng-click="cancel()"><span class="glyphicon glyphicon-remove" ></span></h5>
</a>
<a href= "" style="color:#63822E" ng-click = "addRowButton()" ng-show = 'showAddBtn'>
<h5 ><span class="glyphicon glyphicon-plus-sign"></span>
Add a new row
</h5>
</a>
</td>
</tr>
</tbody>
</table>
</div>
i want what ever i type in the input box to be pushed in the $scope.data with the corresponding header taken from $scope.headerAll;
Thanks.
Here is an example where every update to the <input> fields directly updates the new object in the data array. The save button only hides the <input> fields. I think a better way is to validate the data in a save function and only push it when the data is correct. Therefore I didn't remove the following lines
//$scope.newObject = {};
//Maybe some validation
//$scope.data.push($scope.newObject);
HTML
<div ng-app ng-controller="Controller">
<table>
<tr>
<th ng-repeat="header in headers">{{header.name}}</th>
</tr>
<tr ng-repeat="row in data">
<td>{{row.firstname}}</td>
<td>{{row.lastname}}</td>
<td>{{row.gender}}</td>
</tr>
<tr ng-show="creatingObject">
<td ng-repeat="header in headers">
<input type="text" ng-model="newObject[header.field]">
</td>
</tr>
<tr>
<td></td>
<td><button ng-show="creatingObject" ng-click="saveRow()">Save</button></td>
<td><button ng-hide="creatingObject" ng-click="addRow()">Add Row</button></td>
</tr>
</table>
</div>
Controller
function Controller($scope) {
$scope.headers = [{ 'field': 'firstname', 'name': 'Firstname' },
{ 'field': 'lastname', 'name': 'Lastname' },
{ 'field': 'gender', 'name': 'Gender' }];
$scope.creatingObject = false;
$scope.data = [{'firstname': 'john', 'lastname': 'Doe', 'gender': 'male'} ];
$scope.addRow = function() {
//$scope.newObject = {};
var length = $scope.data.push({});
$scope.newObject = $scope.data[length - 1] ;
$scope.creatingObject = true;
}
$scope.saveRow = function() {
//Maybe some validation
//$scope.data.push($scope.newObject);
$scope.creatingObject = false;
}
}
Hope that helps.

Resources