Duplicating table fails in angularJS - javascript

My code is like this
<body>
<div>
<table ng-app='myApp' ng-controller="MainCtrl">
<thead>
</thead>
<tbody ng-repeat="prdElement in palletElement">
<tr><td>{{prdElement.name}}</td></tr>
<tr ng-repeat="data in prdElement.Data">
<td>
{{data.itemId}}
</td>
<td>
{{data.shipmentId}}
</td>
<td>
{{data.itemCode}}
</td>
<td>
{{data.description}}
</td>
<td>
{{data.handlingUnit}}
</td>
<td>
{{data.weight}}
</td>
<td>
{{data.class}}
</td>
<td>
{{data.lenght}}
</td>
<td>
{{data.width}}
</td>
<td>
{{data.height}}
</td>
<td>
{{data.flag}}
</td>
<td>
<input type="text" ng-model="data.quantity" placeholder=" Code" required />
</td>
</tr>
<tr>
<td>
<button ng-click="newPalletItem( prdElement,$event)">Submit</button>
</td>
</tr>
</tbody>
</table>
</div>
(function () {
angular.module('myApp', []).controller('MainCtrl', function ($scope) {
var counter = 0;
$scope.palletElement =
[{
name: 'Pallet 1',
Data:[{
name:'item 1' ,
itemId: '284307',
shipmentId: 'eb44f690-c97a-40e3-be2a-0449559e171a',
itemCode: '',
description: 'Bicycle parts - frame',
quantity: '31',
handlingUnit: 'CTN',
weight: '613.04',
class:'',
lenght: '102',
width: '42',
height: '61',
flag:'P'
}, {
name: 'item 2',
itemId: '284308',
shipmentId: 'eb44f690-c97a-40e3-be2a-0449559e171a',
itemCode: '',
description: 'Bicycle parts - fork',
quantity: '22',
handlingUnit: 'CTN',
weight: '242.99',
class: '',
lenght: '75',
width: '34',
height: '18',
flag: 'P'
}]
}]
$scope.newPalletItem = function (palletElement, $event) {
counter++;
angular.forEach(palletElement, function (value, key) {
palletElement.push(palletElement);
});
}
});
}());
on the last button click I am trying to duplicate entire tbody, but its not working. does any one have any idea?
Fiddle

Just Change $scope.newPalletItem function To:
$scope.newPalletItem = function (palletElement, $event) {
counter++;
$scope.palletElement.push(palletElement);
}
SEE DEMO

Related

Component template should contain exactly one root element nuxt

I'm not sure what could be the issue here but I'm using nuxt to make a SPA app. and I'm getting an error from an already compiled piece of code I got from codepen. link to codepen
https://codepen.io/jjelic/pen/yevNLZ?editors=1010
When I try this code my my nuxt app I get an error.
I've added a file called monitor.vue in pages folder and added the html and js like so
Is this root element error common as I have never encountered it before with html and how can I avoid?
Vue.filter('currencyDisplay', {
// model -> view
read: function(val) {
if (val > 0) {
return accounting.formatMoney(val, "$", 2, ".", ",");
}
},
// view -> model
write: function(val, oldVal) {
return accounting.unformat(val, ",");
}
});
Vue.directive('sortable', {
twoWay: true,
deep: true,
bind: function() {
var that = this;
var options = {
draggable: Object.keys(this.modifiers)[0]
};
this.sortable = Sortable.create(this.el, options);
console.log('sortable bound!')
this.sortable.option("onUpdate", function(e) {
that.value.splice(e.newIndex, 0, that.value.splice(e.oldIndex, 1)[0]);
});
this.onUpdate = function(value) {
that.value = value;
}
},
update: function(value) {
this.onUpdate(value);
}
});
var vm = new Vue({
el: '#app',
data: {
rows: [
//initial data
{
qty: 5,
description: "Something",
price: 55.20,
tax: 10
},
{
qty: 2,
description: "Something else",
price: 1255.20,
tax: 20
},
],
total: 0,
grandtotal: 0,
taxtotal: 0,
delivery: 40
},
computed: {
total: function() {
var t = 0;
$.each(this.rows, function(i, e) {
t += accounting.unformat(e.total, ",");
});
return t;
},
taxtotal: function() {
var tt = 0;
$.each(this.rows, function(i, e) {
tt += accounting.unformat(e.tax_amount, ",");
});
return tt;
}
},
methods: {
addRow: function(index) {
try {
this.rows.splice(index + 1, 0, {});
} catch (e) {
console.log(e);
}
},
removeRow: function(index) {
this.rows.splice(index, 1);
},
getData: function() {
$.ajax({
context: this,
type: "POST",
data: {
rows: this.rows,
total: this.total,
delivery: this.delivery,
taxtotal: this.taxtotal,
grandtotal: this.grandtotal,
},
url: "/api/data"
});
}
}
});
<template>
<div class="panel-body" id="app">
<table class="table table-hover">
<thead>
<tr>
<th style="width: 20px;">No.</th>
<th>Description</th>
<th style="width: 80px;">Qty</th>
<th style="width: 130px;" class="text-right">Price</th>
<th style="width: 90px;">Tax</th>
<th style="width: 130px;">Total</th>
<th style="width: 130px;"></th>
</tr>
</thead>
<tbody v-sortable.tr="rows">
<tr v-for="row in rows" track-by="$index">
<td>
{{ $index +1 }}
</td>
<td>
<input class="form-control" v-model="row.description" />
</td>
<td>
<input class="form-control" v-model="row.qty" number />
</td>
<td>
<input class="form-control text-right" v-model="row.price | currencyDisplay" number data-type="currency" />
</td>
<td>
<select class="form-control" v-model="row.tax">
<option value="0">0%</option>
<option value="10">10%</option>
<option value="20">20%</option>
</select>
</td>
<td>
<input class="form-control text-right" :value="row.qty * row.price | currencyDisplay" v-model="row.total | currencyDisplay"
number readonly />
<input type="hidden" :value="row.qty * row.price * row.tax / 100" v-model="row.tax_amount | currencyDisplay"
number />
</td>
<td>
<button class="btn btn-primary btn-xs" #click="addRow($index)">add row</button>
<button class="btn btn-danger btn-xs" #click="removeRow($index)">remove row</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" class="text-right">TAX</td>
<td colspan="1" class="text-right">{{ taxtotal | currencyDisplay }}</td>
<td></td>
</tr>
<tr>
<td colspan="5" class="text-right">TOTAL</td>
<td colspan="1" class="text-right">{{ total | currencyDisplay }}</td>
<td></td>
</tr>
<tr>
<td colspan="5" class="text-right">DELIVERY</td>
<td colspan="1" class="text-right"><input class="form-control text-right" v-model="delivery | currencyDisplay"
number /></td>
<td></td>
</tr>
<tr>
<td colspan="5" class="text-right"><strong>GRANDTOTAL</strong></td>
<td colspan="1" class="text-right"><strong>{{ grandtotal = total + delivery | currencyDisplay }}</strong></td>
<td></td>
</tr>
</tfoot>
</table>
<button #click="getData()">SUBMIT DATA</button>
<pre>{{ $data | json }}</pre>
</div>
</template>
This problem is actually a very simple problem. I don't know vue, but the render method has the same limits of react's one: every component must have only one root element in its template.
This means that a situation like this isn't accepted:
<template>
<div></div>
<div></div>
</template>
But like this is correct:
<template>
<div></div>
</template>
This means that surely, somehow in the code you didn't show us, you're putting two elements as root of your template

ng-table header select all check box

I am using ng-table for display data. i am using below code to do select all checkboxe. that select all check box insert using text/ng-template. if i use select all checkbox outside the ng-table, all functions work. but inside the ng-table with text/ng-template , functions not working.
$scope.selectAll = function() {
angular.forEach($scope.invoiceApprovalList, function(invoiceApproval) {
invoiceApproval.checkboxItem= $scope.selectedAll;
});
};
// use the array "every" function to test if ALL items are checked
$scope.checkIfAllSelected = function() {
$scope.selectedAll = $scope.invoiceApprovalList.every(function(invoiceApproval) {
return invoiceApproval.checkboxItem == true;
})
};
<script type="text/ng-template" id="all.html">
<input type="checkbox" ng-model="selectedAll" ng-click="selectAll()" />
</script>
<table ng-table="invoicetableParams" ng-show="invoicetableParams!=null" class="table scroll table-condensed table-bordered table-striped table-scroll" id="in-app">
<tbody>
<tr ng-repeat="invoiceApproval in $data">
<td header="'all.html'" class="row-center" style="width:20%">
<input class="myCheckBox" ng-model="invoiceApproval.checkboxItem" type="checkbox" ng-click="checkIfAllSelected()"/></td>
<td data-title="'Customer Name'" style="width:20%" filter="{'customerName':'text'}" sortable="'customerName'" class="row-center">
<div class="row-center">{{invoiceApproval.customerName}}</div>
</td>
<td data-title="'Invoice Number'" style="width:20%" sortable="'invoiceNumber'" class="row-center">
<div class="row-center">{{invoiceApproval.invoiceNumber}}</div>
</td>
<td data-title="'Invoice Date'" style="width:20%" class="row-center">
<div class="row-center">{{invoiceApproval.invoiceDate | date}}</div>
</td>
<!-- <td data-title="'Action'" class="row-center" style="text-align:right">
<button type="button" class="btn grid-btn row-view sm-btn" ng-click="loadCustomerInvoicePDFviewPDF(invoiceApproval.customerInvoiceHeaderID,1)">
<span class="glyphicon glyphicon-list"></span> Preview
</button>
</td> -->
</tr>
</tbody>
</table>
It does work as expected. Unfortunately you didn't show enough code to reproduce your problem. Please compare your solution and ensure your using ng-include in the right way:
View
<div ng-controller="MyCtrl">
<table ng-table="invoicetableParams" ng-show="invoicetableParams!=null" class="table scroll table-condensed table-bordered table-striped table-scroll" id="in-app">
<tbody>
<tr ng-repeat="invoiceApproval in data">
<td ng-include="'all.html'"></td>
<td data-title="'Customer Name'" style="width:20%" filter="{'customerName':'text'}" sortable="'customerName'" class="row-center">
<div class="row-center"> {{invoiceApproval.customerName}}</div>
</td>
<td data-title="'Invoice Number'" style="width:20%" sortable="'invoiceNumber'" class="row-center">
<div class="row-center">{{invoiceApproval.invoiceNumber}}</div>
</td>
<td data-title="'Invoice Date'" style="width:20%" class="row-center">
<div class="row-center">{{invoiceApproval.invoiceDate | date}}</div>
</td>
</tr>
</tbody>
</table>
</div>
<script type="text/ng-template" id="all.html">
<input type="checkbox" ng-model="invoiceApproval.checkboxItem" ng-click="selectAll()" />
</script>
AngularJS application
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function($scope) {
$scope.selectAll = function() {
$scope.data.forEach(function(invoiceApproval) {
return invoiceApproval.checkboxItem = true;
});
}
$scope.invoicetableParams = true;
$scope.data = [{
checkboxItem: false,
customerName: 'test name 1',
invoiceNumber: 'test name 1',
invoiceDate: new Date()
},
{
checkboxItem: false,
customerName: 'test name 2',
invoiceNumber: 'test name 2',
invoiceDate: new Date()
},
{
checkboxItem: false,
customerName: 'test name 3',
invoiceNumber: 'test name 3',
invoiceDate: new Date()
},
{
checkboxItem: false,
customerName: 'test name 4',
invoiceNumber: 'test name 4',
invoiceDate: new Date()
}
];
});
> demo fiddle

How do I filter and structure this JSON?

I have a array of json objects known as events, which has fields like eventId, eventName and most importantly dateofevent.
[{event1}, {event2}, {event3}];
I need to iterate over this array of events and filter out the events that are on the same day. To obtain a new object like this.
"days": [
{
"date": "11-05-2015",
"events": [
{"eventId": 1, ...},
{"eventId": 2, ...},
{"eventId": 3, ...},
{"eventId": 4, ...},
]
},
How can I do this efficiently with Javascript or Angular?
You can create a new object with the dates as keys, and the values are arrays that contain the events.
After you have the date => events map, convert it to array in the structure you want.
Assuming the original data is in a variable called "events":
var events = [{event 1}, {event 2}...];
var daysMap = {};
var days = [];
events.map(function(event) {
if (days[event.dateofevent] === undefined) {
days[event.dateofevent] = [];
}
days[event.dateofevent].push(event);
});
for (var day in daysMap) {
days.push({
date: day,
events: daysMap[day]
});
}
HTML
<div ng-app>
<span class="bold">Demonstrating filtering and sorting using Angular JS</span>
<br /><br />
<div ng-controller="ShoppingCartCtrl">
<div>Sort by:
<select ng-model="sortExpression">
<option value="Name">Name</option>
<option value="Price">Price</option>
<option value="Quantity">Quantity</option>
</select>
</div>
<br />
<div><strong>Filter Results</strong></div>
<table>
<tr>
<td>By Any: </td>
<td><input type="text" ng-model="search.$" /></td>
</tr>
<tr>
<td>By Name: </td>
<td><input type="text" ng-model="search.Name" /></td>
</tr>
<tr>
<td>By Price: </td>
<td><input type="text" ng-model="search.Price" /></td>
</tr>
<tr>
<td>By Quantity: </td>
<td><input type="text" ng-model="search.Quantity" /></td>
</tr>
</table>
<br />
<table border="1">
<thead>
<tr>
<th>Name</th>
<th>Price</th>
<th>Quantity</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in items | orderBy:mySortFunction | filter:search">
<td>{{item.Name}}</td>
<td>{{item.Price | currency}}</td>
<td>{{item.Quantity}}</td>
</tr>
</tbody>
</table>
<br />
</div>
</div>
Javascript
function ShoppingCartCtrl($scope) {
$scope.items = [
{Name: "Soap", Price: "25", Quantity: "10"},
{Name: "Shaving cream", Price: "50", Quantity: "15"},
{Name: "Shampoo", Price: "100", Quantity: "5"}
];
$scope.mySortFunction = function(item) {
if(isNaN(item[$scope.sortExpression]))
return item[$scope.sortExpression];
return parseInt(item[$scope.sortExpression]);
}
}
CSS
.bold { font-weight:bold; }
table td{
padding: 10px;
}
table th{
font-weight: bold;
text-align: center;
}
demo_click here

Update text field based on selection in drop-down list(Angular JS)

I am trying to create a drop-down list using angular-Js.
The element that is coming should be currently selected in drop-down list is coming from some databse.(Initialized as $scope.choice = "two", in sample app).
With the below code, last element in the list is the sleected element alwyas.
Also, in the associated text box, I want the description to change based on the selected element, but it always defaults to the description of the first item in list box.
JS File
var app = angular.module('app',[]);
app.controller('Test',function($scope)
{
$scope.choice = "two";
$scope.items = [{name: 'one', age: 30, description: 'Thirty' },{ name: 'two', age: 27, description: 'Twenty Seven' },{ name: 'three', age: 50, description: 'Fifty' }];
});
HTML
<html ng-app="app">
<body>
<div ng-controller="Test">
<table class="table table-striped">
<tbody>
<tr>
<td><select
ng-model="selectedItem"
ng-options="item.name for item in items track by item.name" ></select></td>
<td><input type="text" name="field" ng-model=" selectedItem.description"
class="form-control"ng-pattern="/{{ selectedItem.description}}/" required /></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
When I change the drop-down element in list, I get the following error:
Error: [$parse:syntax] http://errors.angularjs.org/1.3.2/$parse/syntax?p0=undefined&p1=not%20a%20primary%20expression&p2=null&p3=%2F%2F&p4=%2F%2F
at Error (native)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js:6:416
at eb.throwError (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js:190:268)
at eb.primary (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js:189:450)
at eb.unary (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js:196:183)
at eb.multiplicative (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js:195:486)
at eb.additive (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js:195:280)
at eb.relational (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js:195:144)
at eb.equality (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js:195:6)
at eb.logicalAND (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js:194:387) <input type="text" name="field" ng-model=" selectedItem.description" class="form-control ng-pristine ng-untouched ng-valid" ng-pattern="/{{ selectedItem.description}}/" required=""> angular.js:11383(anonymous function) angular.js:11383(anonymous function)
Any help with this would be appreciated.
Thanks
That bit is reason of your error
ng-pattern="/{{ selectedItem.description}}/"
if you want choose default option you can do that by:
$scope.items = [{name: 'one', age: 30, description: 'Thirty' },{ name: 'two', age: 27, description: 'Twenty Seven' },{ name: 'three', age: 50, description: 'Fifty' }];
//set default option
$scope.selectedItem = $scope.items[1]
var app = angular.module('app', []);
app.controller('homeCtrl', function($scope) {
$scope.items = [{
name: 'one',
age: 30,
description: 'Thirty'
}, {
name: 'two',
age: 27,
description: 'Twenty Seven'
}, {
name: 'three',
age: 50,
description: 'Fifty'
}];
$scope.selectedItem = $scope.items[1]
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="homeCtrl">
<table class="table table-striped">
<tbody>
<tr>
<td>
<select ng-model="selectedItem" ng-options="item.name for item in items track by item.name"></select>
</td>
<td>
<input type="text" name="field" ng-model=" selectedItem.description" class="form-control" ng-pattern="" required />
</td>
</tr>
</tbody>
</table>
</div>
</div>

Knockout JS: Filtering a list unable to bind

I'm having a hard time getting a filter working. I'm roughly following the example at http://www.knockmeout.net/2011/06/10-things-to-know-about-knockoutjs-on.html, but I just can't seem to make it work. Any help is greatly appreciated.
HTML:
<h1><b>Medical Product Survey</b></h1>
<div class='facilities available'>
<div class='bar'>
<h2>Hospitals / Facilities</h2>
<a class='button add'>+</a>
</div>
<table>
<thead>
<tr>
<th>
<input data-bind="value: filter, valueUpdate: 'afterkeydown'" />
</th>
<th>Modified</th>
<th>Status</th>
</tr>
</thead>
<tbody data-bind="template: { name: 'facilitiesAvailableRow', foreach: filteredFacilties }"></tbody>
</table>
<!-- Row template for available facilities -->
<script type="text/html" id="facilitiesAvailableRow">
<tr>
<td>${name}</td>
<td>${modified}</td>
<td>${status}</td>
</tr>
</script>
</div>
<div class='facilities available'>
<div class='bar'>
<h2>Archived</h2>
</div>
<table>
<thead>
<tr>
<th><input type='search' id='facility_search' /></th>
<th>Archive Date</th>
<th>Size</th>
<th></th>
</tr>
</thead>
<tbody data-bind="template: { name: 'facilitiesArchivedRow', foreach: facilitiesArchived }"></tbody>
</table>
<!-- Row template for available facilities -->
<script type="text/html" id="facilitiesArchivedRow">
<tr>
<td>${name}</td>
<td>${modified}</td>
<td>${size}mb</td>
<td><input type='button' value='restore' /></td>
</tr>
</script>
</div>
Javascript:
//Model for facilities interaction on the front page.
var viewModel = {
facilitiesAvailable: ko.observableArray([
{ name: "Test 1", modified: "1/20/1986", status: "Good to go" },
{ name: "Test 2", modified: "1/21/1987", status: "Good to go2" },
{ name: "Test 3", modified: "1/22/1988", status: "Good to go3" },
{ name: "Test 4", modified: "1/23/1989", status: "Good to go4" },
{ name: "Test 5", modified: "1/24/1990", status: "Good to go5" }
]),
facilitiesArchived: ko.observableArray([
{ name: "Archive 1", modified: "1/20/1982", size: 123 },
{ name: "Archive 2", modified: "1/21/1983", size: 198 },
{ name: "Archive 3", modified: "1/22/1984", size: 340 }
]),
filter: ko.observable(""),
};
//Filtering.
viewModel.filteredFacilities = ko.dependentObservable(function() {
var filter = this.filter().toLowerCase();
if(!filter) {
return this.facilitiesAvailable();
} else {
return ko.utils.arrayFilter(this.facilitiesAvailable(), function(item) {
if(item.name.toLowerCase().search(filter) != -1) {
return true;
}
});
}
}, viewModel);
ko.applyBindings(viewModel);
The error I'm getting is:
Uncaught Error: Unable to parse binding attribute.
Message: ReferenceError: filteredFacilties is not defined;
Attribute value: template: { name: 'facilitiesAvailableRow', foreach: filteredFacilties }
You misspelled filteredFacilties. It should be filteredFacilities in your template binding.
Change:
data-bind="template: { name: 'facilitiesAvailableRow', foreach: filteredFacilties }"
to:
data-bind="template: { name: 'facilitiesAvailableRow', foreach: filteredFacilities }"

Categories