ng-repeat on <tr> giving problems - angularjs

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

Related

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

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>

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>

How the value is passed inside the indexOf()?

In this code, the 'm' is written inside the indexOf function. But no where in the code the value is passed. I am not able to understand how this 'm' deleting the right item in ng-repeat. When i change 'm' to something else it is now working. I am new to AngularJS.
In the main.js file there is removeitem function, i am getting from where the value of 'm' is coming , it has,nt passed from anywhere. I tried removeing 'm' but it doesnt work, it deletes the last item.
var app = angular.module('myApp', []);
app.controller('cont', function($scope) {
$scope.invoice = {
number: 10,
tax: 14,
items: [{
description: "",
quentity: 10,
cost: 300
}],
};
$scope.currency_symbol = [{
name: 'Indian Rupee',
currency: '₹'
},
{
name: 'USD',
currency: '$'
},
{
name: 'Euro',
currency: '€'
}
];
$scope.addItem = function() {
$scope.invoice.items.push([{
description: "description",
quentity: 1,
cost: 1
}]);
}
$scope.removeItem = function(m) {
$scope.invoice.items.splice($scope.invoice.items.indexOf(m), 1);
}
$scope.subTotal = function() {
var total = 0.0;
angular.forEach($scope.invoice.items, function(item, key) {
total += item.quentity * item.cost;
});
return total;
};
$scope.calcuteTax = function() {
return (($scope.subTotal() * $scope.invoice.tax) / 100);
};
$scope.grandTotal = function() {
return ($scope.subTotal() + $scope.calcuteTax());
};
});
<head>
<title>Simple Invoicing - Built with AngularJS </title>
<meta charset='utf-8'>
<meta name="description" content="AngularJS and Angular Code Example for creating Invoices and Invoicing Application">
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/style.css">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js"></script>
</head>
<body ng-app="myApp" ng-controller="cont">
<div class="container" width="800px" id="invoice">
<div class="row">
<div class="col-xs-12 heading">
<strong>Billing System</strong>
</div>
</div>
</div>
<div class="main1">
<div="customer">
<select ng-init="currencySymbol=currency_symbol[0]" ng-model="currencySymbol" ng-options="currency.name+' '+currency.currency for currency in currency_symbol"></select>
</div>
</div>
<div class="main2">
<table border=1 width=100%>
<th></th>
<th>Description</th>
<th>Quantity</th>
<th>Cost{{' '+currencySymbol.currency}}</th>
<th>Total</th>
<tr ng-repeat="item in invoice.items">
<td text-align="center">
<a class="btn" href="" ng-click="removeItem()">
<strong>[x]</strong>
</a>
</td>
<td><input type="text" ng-model="item.description" placeholder="Description"></td>
<td><input type="number" ng-model="item.quentity" placeholder="10"></td>
<td><input type="number" ng-model="item.cost" placeholder="10"></td>
<td placeholder="0">{{item.quentity*item.cost}}</td>
</tr>
<tr>
<td text-align="center"><a class="btn" style="background-color:green;" href ng-click="addItem()">[+]</a></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td text-align="center"></td>
<td></td>
<td></td>
<td>Sub Total:</td>
<td>
<p>{{subTotal()}}</p>
</td>
</tr>
<tr>
<td text-align="center"></td>
<td></td>
<td></td>
<td>Tax:<input type="number" ng-model="invoice.tax"></td>
<td>
<p>{{calcuteTax()}}</p>
</td>
</tr>
<tr>
<td text-align="center"></td>
<td></td>
<td></td>
<td>Grand Total:</td>
<td>
<p>{{grandTotal()}}</p>
</td>
</tr>
</table>
</div>
</body>
How do i make the code delete the item on which i click ?
Add item as an argument to the removeItem function:
<tr ng-repeat="item in invoice.items">
<td text-align="center">
̶<̶a̶ ̶c̶l̶a̶s̶s̶=̶"̶b̶t̶n̶"̶ ̶h̶r̶e̶f̶=̶"̶"̶ ̶n̶g̶-̶c̶l̶i̶c̶k̶=̶"̶r̶e̶m̶o̶v̶e̶I̶t̶e̶m̶(̶)̶"̶>̶
<a class="btn" href="" ng-click="removeItem(item)">
<strong>[x]</strong>
</a>
</td>
$scope.removeItem = function(m) {
$scope.invoice.items.splice($scope.invoice.items.indexOf(m), 1);
}

Angularjs Inline Edit row not working

Angularjs Inline Edit row not working
When i click edit button all input field is enabled
also this not disabled
<span ng-show="edit != true">{{data.question}}</span>
<tr ng-repeat="data in Value ">
<td>
<span ng-show="edit != true">{{data.question}}</span>
<input ng-show="edit" type="text" ng-model="data.question" class="form-control" placeholder="Name">
</td>
<td>{{dataId.name}}</td>
<td><span id="{{data.id}}" ng-click="editUtterance(data.id)" class="glyphicon glyphicon-pencil edit"></span></td>
</tr>
$scope.edit = 'false';
console.log($scope.edit);
$scope.editUtterance = function(id){
alert(id);
$scope.edit = 'true';
console.log($scope.edit);
}
From what limited data and code you have provided in your question, I have put together a basic PLUNKER which gives you the edit and save functionality in line in a table cell.
The idea is to attach the edit flag (it's better if it's a boolean rather than a string) to each element in the array so we can track which row should be editable. If you set it to scope and use it like you have shown in the code, it will be applied to all rows and all of them will be editable even if your intent was for a single row.
#script.js
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function($scope) {
$scope.Value = [{
id: 1,
question: 'question 1',
name: 'name 1'
}, {
id: 2,
question: 'question 2',
name: 'name 2'
}, {
id: 3,
question: 'question 3',
name: 'name 3'
}]
$scope.editUtterance = function(data) {
alert(data.id);
data.edit = true;
console.log(data.edit);
}
$scope.save = function(data) {
data.edit = false;
}
});
Try this
angular.module('demo', ['ui.bootstrap']);
angular.module('demo').controller('DemoCtrl', DemoCtrl);
DemoCtrl.$inject = ['$scope', '$timeout'];
function DemoCtrl($scope, $timeout) {
$scope.Value = [{
id: 1,
question: "Ben"
}, {
id: 2,
question: "Sally"
}, {
id: 3,
question: "John"
}];
$scope.selected = {};
$scope.editContact = function(data) {
$scope.editing = true;
$scope.selected = angular.copy(data);
};
$scope.saveContact = function(id) {
$scope.editing = false;
$scope.Value[id] = angular.copy($scope.selected);
};
}
body {
margin: 20px;
}
#th-name,
#th-age {
width: 40%;
}
#th-actions {
width: 20%;
}
<!DOCTYPE html>
<html ng-app="demo">
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.1.3/ui-bootstrap-tpls.min.js"></script>
<script type="text/javascript" src="app.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css" />
<link rel="stylesheet" href="style.css" />
</head>
<body ng-controller="DemoCtrl">
<h3>ng-show/hide</h3>
<table class="table table-striped">
<thead>
<tr>
<th id="th-name">Question</th>
<th id="th-age">ID</th>
</tr>
</thead>
<tr ng-repeat="data in Value">
<td>
<span ng-show="edit != true">{{data.question}}</span>
<input ng-show="edit" type="text" ng-model="selected.question" class="form-control" placeholder="question">
</td>
<td>
<span ng-show="edit != true">{{data.id}}</span>
<input ng-show="edit" type="text" ng-model="selected.id" class="form-control" placeholder="ID">
</td>
<td>
<button ng-show="edit != true && editing != true" id="table-edit" ng-click="edit = true; editContact(data)"><i class="fa fa-fw fa-pencil"></i></button>
<button ng-show="edit" id="table-save" ng-click="edit = false; saveContact($index)"><i class="fa fa-fw fa-floppy-o"></i></button>
</td>
</tr>
</table>
</body>
</html>
$scope.editContact = function (data) {
debugger;
$scope.editing = true;
$scope.universityModel = angular.copy(data);
};
$scope.CancelEdit = function (event) {
$scope.editing = false;
event.preventDefault();
}
`
<tbody>
<tr ng-repeat="item in UniversityList track by $index">
<td>
<span ng-show="edit != true">{{item.ValueAr}}</span>
<input ng-show="edit" type="text" ng-model="universityModel.ValueAr" class="form-control" placeholder="ValueAr">
</td>
<td>
<span ng-show="edit != true">{{item.ValueEn}}</span>
<input ng-show="edit" type="text" ng-model="universityModel.ValueEn" class="form-control" placeholder="ValueEn">
</td>
<td class="text-center">
<button class="btn green" ng-show="edit != true && editing != true" id="table-edit" ng-click="edit = true; editContact(item)"><i class="fa fa-edit"></i></button>
<button class="btn red" ng-show="edit != true && editing != true" id="table-edit" ng-click="edit = true; DeleteUniversity(item.Id,$index )"><i class="fa fa-trash-o"></i></button>
<button class="btn blue" ng-show="edit" id="table-save" ng-click="edit = false; saveContact($index,$event,universityModel)"><i class="fa fa-fw fa-floppy-o"></i></button>
<button class="btn red" ng-show="edit" id="table-cancel" ng-click="edit = false; CancelEdit($event)"><i class="fa fa-close"></i></button>
<!--<a class="btn green" ng-click="toggleUniversityModal(item,true)"><i class="fa fa-edit"></i></a>
<a class="btn red" ng-click="DeleteUniversity(item.Id,$index )"><i class="fa fa-trash-o"></i></a>-->
</td>
</tr>
</tbody>

How to push JSON object to array using single AngularJS controller

Please guide me how do I push a new commodity object in the above loads object, by submiting a new form for commodity. The code I have tried is given below.
Note when I fill the form of commodity and submit to push in above json, it tells me undefined for loads.commodities.push
I have a complete sample JSON object (we call it loads), In which I have to push a commodity object. For new commodity I have an explicit form to add a new commodity details and push into existing loads object.
Loads Object:
{
"loadStops": [
{
"companyId": 148,
"companyCode": null,
"legalName": "Frontier WHSE",
"accessorialReason": null,
"commodities": [{
"id": 1,
"commodity": "Food",
"estWeight": 20000.00
}]
}
]
}
Display Table for viewing the loads data and Form to add New Commodity
<div ng-controller="FreightSaleCtrl">
<table>
<tr>
<th> Company Code </th> <th> Legal Name </th>
</tr>
<tr ng-repeat="theLoad in loads">
<td> {{theLoad.companyCode}} </td>
<td> {{theLoad.legalName}} </td>
</tr>
<tr>
<td colspan="2">
<table>
<tr>
<th> Commodity </th> <th> EstWeight </th>
</tr>
<tr ng-repeat="cmdty in theLoad.commodities">
<td> cmdty.commodity </td>
<td> cmdty.estWeight </td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<div>
<form ng-controller="FreightSaleCtrl">
<input type="text" ng-model="commodityForm.commodity"/>
<input type="text" ng-model="commodityForm.estWeight"/>
<input type="submit" value="Add New Commodity"/>
</form>
</div>
My AngularJS controller:
(function() {
'use strict';
angular.module('bootstrapApp').controller('FreightSaleCtrl', FreightSaleCtrl);
function FreightSaleCtrl($scope, $location, $http, $compile) {
$scope.loads[0].commodities.push( $scope.commodityForm );
}
});
My new commodity form that opens by clicking on the link given in the commodity table:**
<div class="modal fade" id="commoditiesModal" tabindex="-1" role="dialog"
aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<form ng-controller="FreightSaleCtrl" id="commodity-form" role="form" novalidate>
<div class="modal-content">
<div class="modal-header modal-lg">
<h5 class="modal-title" id="exampleModalLabel">
Add Commodity
<button type="button" class="close" data-dismiss="modal"
aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</h5>
</div>
<div class="modal-body">
<div class="row"> <!-- row-1 -->
<div class="col-sm-3"> <!-- [0, 0] -->
<fieldset class="form-group">
<label id="fieldTitle">Commodity</label>
<input type="text" class="form-control" placeholder="" required data-error="Commodity required">
<div class="help-block with-errors"></div>
</fieldset>
</div>
<div class="col-sm-3"> <!-- [0, 1] -->
<fieldset class="form-group">
<label id="fieldTitle">Est. Weight</label>
<input type="text" class="form-control" placeholder="" required data-error="Est. weight required">
<div class="help-block with-errors"></div>
</fieldset>
</div>
</div>
</div>
<div class="modal-footer">
<input type="reset" class="btn btn-warning btn-sm" value="Reset" />
<button type="button" class="btn btn-danger btn-sm" ng-click="clear()"
data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-default btn-sm">
<i class="fa fa-check-square-o"></i> Submit
</button>
</div>
</div>
</form>
</div>
</div>
The above form opens, when I click on this button: while the commodities displayed in the table:
The Commodity Form Modal itself
Every time the controller is specified, it will create new instance
of that controller So it should be kept inside one controller
theLoad.commodities cannot be accessed as it is ouside the
<tr ng-repeat="cmdty in theLoad.commodities">
<td> cmdty.commodity </td>
<td> cmdty.estWeight </td>
</tr>
One way to solve this is to have add input boxes inside the table - for each loads
<!DOCTYPE html>
<html>
<head>
<script data-require="jquery#3.0.0" data-semver="3.0.0" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
<link data-require="bootstrap#3.3.7" data-semver="3.3.7" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<script data-require="angular.js#1.6.6" data-semver="1.6.6" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>
<script src="https://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.min.js"></script>
<script>
(function() {
var app = angular.module("bootstrapApp", ['ui.bootstrap']);
app.component('modalComponent', {
templateUrl: 'myModalContent.html',
bindings: {
resolve: '<',
close: '&',
dismiss: '&'
},
controller: function($scope) {
var $ctrl = this;
$ctrl.$onInit = function() {
$scope.theLoad = $ctrl.resolve.currentLoad;
};
$scope.ok = function() {
$ctrl.close({
$value: $scope.theLoad
});
};
}
});
app.controller('FreightSaleCtrl', ['$scope', '$uibModal', function($scope, $uibModal) {
$scope.loads = [{
"companyId": 148,
"companyCode": 1234,
"legalName": "Frontier WHSE",
"accessorialReason": null,
"commodities": [{
"id": 1,
"commodity": "Food",
"estWeight": 20000.00
}, {
"id": 2,
"commodity": "Another",
"estWeight": 160000.00
}]
}, {
"companyId": 45,
"companyCode": 7879,
"legalName": "ASD froads",
"accessorialReason": null,
"commodities": [{
"id": 10,
"commodity": "Drinks",
"estWeight": 5600.00
}]
}];
$scope.openModal = function(load) {
var modalInstance = $uibModal.open({
animation: true,
component: 'modalComponent',
resolve: {
currentLoad: function() {
return load;
}
}
}).result.then(function(currentLoad) {
if (currentLoad) {
var maxValue = Math.max.apply(Math, currentLoad.commodities.map(function(o) {
return o.id;
}))
if (!maxValue) {
maxValue = 0;
}
currentLoad.newCommodity.id = maxValue + 1;
currentLoad.commodities.push(angular.copy(currentLoad.newCommodity));
currentLoad.newCommodity = undefined;
}
}, function() {
console.log('modal-component dismissed at: ' + new Date());
});
};
}]);
}());
</script>
<style></style>
</head>
<body ng-app="bootstrapApp">
<div ng-controller="FreightSaleCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title" id="modal-title">Add Commodity !</h3>
</div>
<div class="modal-body" id="modal-body">
<form name="testForm">
<div class="form-group" ng-class="{ 'has-error' : testForm.commodity.$invalid && !testForm.commodity.$pristine }">
<label>Commodity</label>
<input type="text" name="commodity" ng-model="theLoad.newCommodity.commodity" placeholder="Commodity" ng-minlength="3" ng-maxlength="8" required/>
<p ng-show="testForm.commodity.$error.required && !testForm.commodity.$pristine" class="help-block">commodity is required.</p>
<p ng-show="testForm.commodity.$error.minlength" class="help-block">commodity is too short.</p>
<p ng-show="testForm.commodity.$error.maxlength" class="help-block">commodity is too long.</p>
</div>
<div class="form-group" ng-class="{ 'has-error' : testForm.estWeight.$invalid && !testForm.estWeight.$pristine }">
<label>estWeight</label>
<input type="text" name="estWeight" ng-model="theLoad.newCommodity.estWeight" placeholder="EST Weight" ng-minlength="3" ng-maxlength="8" required/>
<p ng-show="testForm.estWeight.$error.required && !testForm.estWeight.$pristine" class="help-block">estWeight is required.</p>
<p ng-show="testForm.estWeight.$error.minlength" class="help-block">estWeight is too short.</p>
<p ng-show="testForm.estWeight.$error.maxlength" class="help-block">estWeight is too long.</p>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="ok()">OK</button>
<button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button>
</div>
</form>
</script>
<form name="commonForm">
<table class="table">
<tr>
<th> Company Code </th>
<th> Legal Name </th>
<th> Commodity </th>
<th> EstWeight </th>
</tr>
<tr ng-repeat="theLoad in loads">
<td> {{theLoad.companyCode}} </td>
<td> {{theLoad.legalName}} </td>
<td colspan="2">
<table class="table">
<tr ng-repeat="cmdty in theLoad.commodities track by cmdty.id">
<td>{{cmdty.id}} {{cmdty.commodity}} </td>
<td> {{cmdty.estWeight}} </td>
</tr>
<tr>
<td colspan="2">
<input class="pull-right" type="button" value="Add" ng-click="openModal(theLoad)" />
</td>
</tr>
</table>
</td>
</tr>
</table>
</form>
</div>
</body>
</html>

Resources