Hello I got a weird problem... I lost almost 2 hrs and I have no idea why it doesn't work.
It should sum all values for every dept where username = name choosed by select and where date = date choosed by datepicker.
It works great on jsFiddle but when I am trying use it with responsed data it doesn't work and don't have any errors in console.
What am I doing wrong? This is code in my app not the same which is in jsFiddle
HTML:
<div layout="row">
<md-datepicker ng-model="myDateUser" md-placeholder="Enter date"></md-datepicker>
{{myDateUser}}
<md-input-container flex="50">
<label for="repeatSelect"> Select user: </label>
<md-select ng-model="data.model" ng-change="sum(data.model)">
<md-option ng-value="logins.name" ng-repeat="logins in chooseLogins">{{logins.name}}</md-option>
</md-select>
</md-input-container>
<br/>
<hr/>
<tt>{{data.model}}</tt>
</div>
<md-table-container>
<table md-table>
<thead md-head>
<tr md-row>
<th md-column>Dept</th>
<th md-column>Total time</th>
<th md-column></th>
</tr>
</thead>
<tbody md-body>
<tr ng-if="!data.model" md-row md-select="test" md-on-select="" md-auto-select ng-repeat="test in tests">
<td md-cell>{{ test.dept }}</td>
<td md-cell>{{ test.total }}</td>
<td md-cell></td>
</tr>
<tr ng-if="data.model" md-row md-select="test" md-on-select="" md-auto-select ng-repeat="(key,val) in data.model">
<td md-cell>{{ key }}</td>
<td md-cell>{{ val }}</td>
<td md-cell></td>
</tr>
</tbody>
</table>
</md-table-container>
JS:
function getTotalTime() {
$http.get('db_files/totalTimeDB.php').then(function(response) {
$scope.data = response.data;
$scope.sum = function(name) {
let model = $scope.data.filter(function(item) {
return (item.username == name && TheDate(item))
});
let tests = {};
model.forEach(function(item) {
if (!tests.hasOwnProperty(item.dept)) {
tests[item.dept] = 0;
}
tests[item.dept] += parseFloat(item.task_time);
});
$scope.data.model = tests;
}
function TheDate(item){
if($scope.myDateUser){
var myDateUser = new Date($scope.myDateUser);
var itemDate = new Date(item.task_end);
console.log("task_end " + item.task_end);
console.log("myDate " + $scope.myDateUser);
if(myDateUser.getFullYear() != itemDate.getFullYear() || myDateUser.getMonth() != itemDate.getMonth()){
return false;
}
}
return true
}
Example console.log from $scope.data = response.data;
Object
dept:"Test2"
status:"Closed"
task:"test test test"
task_end:"2016-09-02"
task_start:"2016-09-02"
task_time:"80"
username:"Nelson"
__proto__:Object
It works like show total sum only where username = choosed name and TheDate function is ignored. Also console.log shows nothing ( in example jsFiddle console.log shows selected date and name )
It looks like the function isn't called.
Related
Currently, if I filter, the BookingID and Product I see that filtered result in UI. How do I have to add a filter for a name? because this name is coming from another array and getting it based on id
need to add filter based on BookingID, Product and name fields
Here's my code:
<div ng-app="datatable" ng-controller="datacontroller">
<md-card>
<div layout="row" style="height:50px; vertical-align: middle;">
<md-input-container md-no-float class="md-block" flex="85" >
<input ng-model="searchBooking" type="text" placeholder="Search">
</md-input-container>
</div>
</md-card>
<md-table-container>
<table md-table>
<thead md-head md-order="filter">
<tr md-row>
<th md-column><span>BookingID</span></th>
<th md-column><span>Product</span></th>
<th md-column><span>Name</span></th>
</tr>
</thead>
<tbody md-body>
<tr md-row ng-repeat="row in filterBooking() | orderBy:filter">
<td md-cell>{{row.BookingID}}</td>
<td md-cell>{{row.Product}}</td>
<td>
<md-select ng-model="row.UserID" ng-change="test(row)">
<md-option ng-repeat="user in users" ng-value="user.id">{{user.name}}</md-option>
</md-select>
</td>
</tr>
</tbody>
</table>
</md-table-container>
</div>
controller
angular.module("datatable", ['ngRoute', 'ngMaterial', 'md.data.table']).controller("datacontroller", ['$scope', function($scope) {
$scope.bookings = [
{
"BookingID":1,
"Product":"test",
"Shop":"A",
"ContactNumber":124,
"UserID":1
},
{
"BookingID":2,
"Product":"bgh",
"Shop":"d",
"ContactNumber":345,
"UserID":2
}
];
$scope.users = [
{
"id":1,
"name":"abc"
},
{
"id":2,
"name":"xyz"
}
]
$scope.searchBooking = '';
$scope.filterBooking = function () {
return $scope.bookings.filter(function (item) {
return (
item.BookingID.toString().indexOf($scope.searchBooking) > -1||
( item.Product.toLowerCase().indexOf($scope.searchBooking.toLowerCase()) > -1)
);
});
};
}]);
demo
Please advice
user name comes from a different array so I'm not sure how should filter name
so if you first add a 'name' property to every object in your bookings array, having its value cross matched from your 'users' array, this will make your life easier as you can then filter like:
<tr md-row ng-repeat="row in filterBooking() | orderBy:'+name'">
'name' being the new property in each of your objects, and + indicating an ascending order.
Adding the 'name' property to the items of your bookings array can be done with a simple for loop.
for (var i=0; i<$scope.bookings.length; i++) {
$scope.bookings[i].name = $scope.users.filter(function(_){ _.id === $scope.bookings[i].UserID })[0].name;
}
I am writing an Angular application and I have an old code i want to convert this angular js code to angular
table.html
<table ng-repeat="group in vm.groups" style="float: left">
<thead>
<tr>
<th><b>Sl. No</b></th>
<th><b>Generated Code</b></th>
</tr>
</thead>
<tr ng-repeat="g in group.values">
<td ng-style="$odd ? {'background': 'lightgrey' } : {'background': 'white' }">{{$parent.$index * 10 + $index + 1}}</td>
<td ng-style="$odd ? {'background': 'lightgrey' } : {'background': 'white' }">{{g.value}}</td>
</tr>
</table>
table.ts
app.controller('Ctrl', function() {
var vm = this;
var items = [{value: 'bbb'},{value: 'bbb'},{value: 'bbb'},{value: 'bbb'},{value: 'bbb'}];
vm.groups = [];
var i,j,temparray,chunk = 10;
for (i=0,j=items.length; i<j; i+=chunk) {
temparray = items.slice(i,i+chunk);
vm.groups.push({values: temparray});
}
});
i Want to convert this code to Angular2+. I am new to angular please help me.
Angular 2 onwards you should use *ngFor directive to loop over array.
so , your component.html should look like below :
<table *ngFor="let group of groups; let i=index">
<thead>
<tr>
<th><b>Sl. No</b></th>
<th><b>Generated Code</b></th>
</tr>
</thead>
<tr *ngFor="let g of group.values; let x=index" [ngClass]="(x%2===0)?'even':'odd'">
<td>{{i * 10 + x + 1}}</td>
<td>{{g.value}}</td>
</tr>
</table>
Below is the Angular 8 conversion of your code : demo
I faced with a small problem related with ng-class. I have a list of checkboxes. For this list, I setup ng-class next way, if checkbox selected, set custom css class for selected item. Also I have a checkbox "Select All ", if I click on this box, css class applied for all items, but when I deselect all, css class doesn't change for items which been selected manually before.
I created plunker to show my problem.
What am I missing and where is my mistake? Thanks in advance.
html
<table class="table table-hover">
<tr ng-class="{'selected': allCategoriesSelected, 'default': !allCategoriesSelected}">
<td class="col-md-2">
<input type="checkbox" ng-click="selectAllCategories()" >
</td>
<td class="col-md-10" ng-if="!allCategoriesSelected">Select all</td>
<td class="col-md-10" ng-if="allCategoriesSelected">Deselect all</td>
</tr>
<tr ng-repeat="category in categories | orderBy : 'id'" ng-class="{'selected': allCategoriesSelected, 'default': !allCategoriesSelected}" >
<td class="col-md-2">
<input type="checkbox" ng-model="allCategoriesSelected" ng-click="updateCategory(category.id)">
</td>
<td class="col-md-10">{{ category.name }}</td>
</tr>
</table>
js
$scope.selectedCategories = [];
$scope.allCategoriesSelected = false;
$scope.selectAllCategories = function() {
$scope.allCategoriesSelected = !$scope.allCategoriesSelected;
};
$scope.updateCategory = function(categoryId) {
if ($scope.selectedCategories.indexOf(categoryId) > -1) {
$scope.selectedCategories.splice($scope.selectedCategories.indexOf(categoryId), 1);
} else {
$scope.selectedCategories.push(categoryId);
}
};
Take a look at this plunker, it should work.
This is the controller :
$scope.selectAllCategories = function () {
if(!$scope.allCategoriesSelected) $scope.setAll(false);
else $scope.setAll(true);
};
$scope.updateCategory = function () {
if($scope.checkedAll()) $scope.allCategoriesSelected = true;
else $scope.allCategoriesSelected = false;
};
$scope.checkedAll = function(){
var ret = true;
$scope.categories.forEach(function(item){
if(!item.selected) ret = ret && false;
});
console.log(ret);
return ret;
}
$scope.setAll = function(state){
$scope.categories.forEach(function(item){
item.selected = state;
});
}
I think you are making it too complicated. This can be easily solved with much less code. Here is a working plunker: https://plnkr.co/edit/xJz8pdRa4CBWUbdeYbyk?p=preview
Instead of trying to make a separate array to keep track of selected items, just set selected property on categories array.
<table class="table table-hover">
<tr ng-class="{'selected': allCategoriesSelected, 'default': !allCategoriesSelected}">
<td class="col-md-2">
<input type="checkbox" ng-model="allCategoriesSelected" ng-click="selectAllCategories()" >
</td>
<td class="col-md-10" ng-if="!allCategoriesSelected">Select all</td>
<td class="col-md-10" ng-if="allCategoriesSelected">Deselect all</td>
</tr>
<tr ng-repeat="category in categories | orderBy : 'id'" ng-class="{'selected': category.selected}" >
<td class="col-md-2">
<input type="checkbox" ng-model="category.selected">
</td>
<td class="col-md-10">{{ category.name }}</td>
</tr>
</table>
Changing the markup above, allows this to be accomplished with only one method.
$scope.allCategoriesSelected = false;
$scope.selectAllCategories = function () {
var selected = $scope.allCategoriesSelected ? true : false;
angular.forEach($scope.categories, function(category) {
category.selected = selected;
});
};
I'm trying to create a prototype that populates a list of unpaid invoices using ng-repeat. Within this, I am creating an input for each invoice. I want to be able to have a user input $ amounts into these inputs and then display a total of all inputs. Going off of this example: http://jsfiddle.net/d5ug98ke/9/ I cannot get it to work as it does in the fiddle. Here is my code:
<table class="table table-striped header-fixed" id="invoiceTable">
<thead>
<tr>
<th class="first-cell">Select</th>
<th class="inv-res2">Invoice #</th>
<th class="inv-res3">Bill Date</th>
<th class="inv-res4">Amount</th>
<th class="inv-res5">Amount to Pay</th>
<th class="inv-res6"></th>
</tr>
</thead>
<tbody>
<tr ng-if="invoices.length" ng-repeat="item in invoices | filter: {status:'Unpaid'}">
<td class="first-cell"><input type="checkbox" /></td>
<td class="inv-res2">{{item.invoiceNum}}</td>
<td class="inv-res3">{{item.creationDate}}</td>
<td class="inv-res4" ng-init="invoices.total.amount = invoices.total.amount + item.amount">{{item.amount | currency}}</td>
<td class="inv-res5">$
<input ng-validate="number" type="number" class="input-mini" ng-model="item.payment" ng-change="getTotal()" min="0" step="0.01" /></td>
</tr>
</tbody>
</table>
<table class="table">
<tbody>
<tr class="totals-row" >
<td colspan="3" class="totals-cell"><h4>Account Balance: <span class="status-error">{{invoices.total.amount | currency }}</span></h4></td>
<td class="inv-res4"><h5>Total to pay:</h5></td>
<td class="inv-res5">${{total}}</td>
<td class="inv-res6"></td>
</tr>
</tbody>
</table>
And the Angular:
myBirkman.controller('invoiceList', ['$scope', '$http', function($scope, $http) {
$http.get('assets/js/lib/angular/invoices.json').success(function(data) {
$scope.invoices = data;
});
$scope.sum = function(list) {
var total=0;
angular.forEach(list , function(item){
total+= parseInt(item.amount);
});
return total;
};
$scope.total = 0;
$scope.getTotal = function() {
$scope.invoices.forEach(function(item){
$scope.tot += parseInt(item.payment);
});
};
}]);
Any help would be appreciated. I dont necessarily need to use the method in the fiddle if someone has a better idea.
It seems there are two issues. First a simple typo:
$scope.tot += parseInt(item.payment, 10);
should be
$scope.total += parseInt(item.payment, 10);
And you should also reset $scope.total to 0 at the beginning of getTotal().
Edit: The way you did it, you always have to remember to update the total when something changes. Instead, you could let getTotal just return the total and write {{ getTotal() }} in the template. You don't have to trigger getTotal() in via ng-change then. If you don't have a lot of inputs you shouldn't worry about performance here.
I used ng-repeat to repeat json array. I calculated Night(s) by using dayDiff() function. Now I want to get total night all invoices. I am using angularjs.
How can I get total nights for all invoices?
<table class="table" ng-show="filteredItems > 0">
<tr>
<td>No</td>
<td>Invoice No</td>
<td>Name</td>
<td>Eamil</td>
<td>Room Name</td>
<td>Check In Date</td>
<td>Check Out Date</td>
<td>No. Room</td>
<td>Night(s)</td>
<td>Booking Date</td>
<td>Amount</td>
</tr>
<tr ng-repeat="data in filtered = (list | filter:search ) | startFrom:(currentPage-1)*entryLimit | limitTo:entryLimit">
<td>{{$index+1}}</td>
<td>{{data.invoicenumber}}</td>
<td>{{data.firtname}}{{data.lastname}}</td>
<td>{{data.email}}</td>
<td>{{data.roomname}}</td>
<td ng-model='fromDate'>{{data.cidt}}</td>
<td ng-model='toDate'>{{data.codt}}</td>
<td>{{data.qty}}</td>
<td ng-model='night'>{{dayDiff(data.cidt,data.codt)}}</td>
<td>{{data.bdt}}</td>
<td>{{data.btotal}}</td>
</tr>
</table>
You need to add an extra row to begin with. This extra row will look like this:
<tr>
<td colspan="11">Total nights: {{calcTotal(filtered)}}</td>
</tr>
Then in your controller you need to add a function to calculate the nights like
$scope.calcTotal = function(filtered){
var sum = 0;
for(var i = 0 ; i<filtered.length ; i++){
sum = sum + filtered[i].nights;
}
return sum;
};
You could first, use a factory for your JSON model, to store the computed nights:
// We inject the dayDiff function via the dayDiffService service
angular.factory('invoice', ['dayDiffService', function(dayDiffService) {
var Invoice = function(data) {
// merge json properties to self
angular.merge(this, data);
// we compute the night(s)
this.nights = dayDiffService.dayDiff(data.cidt, data.codt);
}
return Invoice;
}]);
Then, in your controller, you add a function to sum up the nights from a filtered list:
angular.controller('invoicesCtrl', ['$scope', 'invoice', function($scope, Invoice) {
$scope.list = [];
// let's say that JSON holds your json model from http's response
$scope.list = JSON.map(function() {
return new Invoice(i)
});
$scope.sumNights = function(filtered) {
filtered.reduce(function(sum, invoice) {
sum += invoice.nights;
sum
}, 0);
}
}]);
Then, in your html you add a new row to display the computed result:
<div ng-controller="invoicesCtrl as vm">
<table>
...
<tbody>
<tr ng-repeat="data in filtered = (vm.list | filter:search ) | startFrom:(currentPage-1)*entryLimit | limitTo:entryLimit">
<td>{{$index+1}}</td>
...
<tr>
</tbody>
<tfoot>
<tr>
<td colspan="8"></td
<td>{{vm.sumNights(filtered)}}</td
<td colspan="2"></td
</tr>
</tfoot>
</table>
</div>