AngularJS - Converting Incorrect Use of Service To Directive - angularjs

I have a table with a fixed width; if the data within the table exceeds the defined width, the user that the ability to scroll left and right as i have a CSS element of overflow: auto;.
What i am trying to do is introduce buttons on either side of the table, so that the user can click on them, and the table will scroll to the left or right.
I have achieved this using an Angular service, but on ng-click, the table only scrolls left or right once. I have a feeling this is because i have used a service, rather than a directive?
Here's my plunker: http://plnkr.co/edit/3rYVry3YtJESCxI190QL?p=preview
On clicking buttons in the above, you'll see a $ error, i do not get this on my project as i am using jQuery too.
HTML:
<body ng-controller="MyController">
<div >
<div class="scrollable my-table" ng-init="sectionIndex = $index; sectionID='my-table'" id="my-table">
<table>
<tr>
<th></th>
<th>Jun</th>
<th>May</th>
<th>Apr</th>
<th>Mar</th>
<th>Feb</th>
<th>Jan</th>
<th>Dec</th>
<th>Nov</th>
<th>Oct</th>
<th>Sep</th>
<th>Aug</th>
<th>Jul</th>
</tr>
<tbody>
<tr>
<th>Preditcion</th>
<td>11</td>
<td>12</td>
<td>13</td>
<td>14</td>
<td>15</td>
<td>16</td>
<td>17</td>
<td>18</td>
<td>19</td>
<td>20</td>
<td>21</td>
<td>22</td>
</tr>
<tr>
<th>Recored</th>
<td>10</td>
<td>09</td>
<td>12</td>
<td>13</td>
<td>04</td>
<td>21</td>
<td>14</td>
<td>15</td>
<td>20</td>
<td>25</td>
<td>17</td>
<td>15</td>
</tr>
</tbody>
</table>
</div>
<div class="scroll-btns-area">
<div class="scroll-btns">
<div class="scroll-left" ng-click="scrollLeft(sectionIndex, sectionID)">
<img src="http://www.designofsignage.com/application/symbol/hospital/image/600x600/arrow-left.jpg" width="25px">
</div>
<div class="scroll-right" ng-click="scrollRight(sectionIndex, sectionID)">
<img src="http://www.designofsignage.com/application/symbol/hospital/image/600x600/arrow-right.jpg" width="25px">
</div>
</div>
</div>
</div>
</body>
JS:
var app = angular.module('myApp', []);
app.controller('MyController', function($scope, scrollLeftRightService) {
$scope.scrollLeft = scrollLeftRightService.moveLeft;
$scope.scrollRight = scrollLeftRightService.moveRight;
});
app.factory('scrollLeftRightService', function() {
return {
moveLeft: function(sectionIndex, sectionID) {
console.log("sectionIndex = " + sectionIndex);
console.log("sectionID = " + sectionID);
var scrollViewport_width = $(window).width();
var pixelsToMove = 0;
if (typeof sectionIndex != 'undefined') {
$('#' + sectionID + sectionIndex).scrollLeft(pixelsToMove - 100);
pixelsToMove = pixelsToMove - 100;
if (pixelsToMove <= 0) {
pixelsToMove = 0;
} else {
pixelsToMove = pixelsToMove;
}
} else {
$('#' + sectionID).scrollLeft(pixelsToMove - 100);
pixelsToMove = pixelsToMove - 100;
if (pixelsToMove <= 0) {
pixelsToMove = 0;
} else {
pixelsToMove = pixelsToMove;
}
}
},
moveRight: function(sectionIndex, sectionID) {
console.log("sectionIndex = " + sectionIndex);
console.log("sectionID = " + sectionID);
var scrollViewport_width = $(window).width();
var pixelsToMove = 0;
if (typeof sectionIndex != 'undefined') {
$('#' + sectionID + sectionIndex).scrollLeft(pixelsToMove + 100);
pixelsToMove = pixelsToMove + 100;
if (pixelsToMove >= scrollViewport_width) {
pixelsToMove = scrollViewport_width;
} else {
pixelsToMove = pixelsToMove;
}
} else {
$('#' + sectionID).scrollLeft(pixelsToMove + 100);
pixelsToMove = pixelsToMove + 100;
if (pixelsToMove >= scrollViewport_width) {
pixelsToMove = scrollViewport_width;
} else {
pixelsToMove = pixelsToMove;
}
}
}
};
});
How would i go about removing as service and use directive?

The problem is here:
var pixelsToMove = 0;
...
$('#' + sectionID + sectionIndex).scrollLeft(pixelsToMove - 100);
every time you set pixelsToMove to 0 so then it only scrolls scrollLeft to -100 and you don't increment it by any number
Cheers

Related

The ng-repeat array is updating table data for the first time i'm selecting value, but its not updating the table data only once

I'm trying to update the table view depending on select option. The table view is updating only once, when i select the option second time the view is not updating, I'm not getting what's the problem. please help me solve this..
here is app.js
$scope.User = {};
$scope.arr = [];
$scope.loaddata = function(User) {
$scope.User.site = layouts;
AllServices.teamAllDataFunction1(User)
.then(function(response) {
$scope.User.data=response.data;
});
};
$scope.getdatalayoutwise = function(User) {
var total = 0;
var total1 = 0;
for (var i = 0; i < ($scope.User.data).length; i++) {
if($scope.User.data[i].Layout == $scope.User.selectedSite) {
total += parseInt($scope.User.data[i].dp_inst_pending);
$scope.arr.push($scope.User.data[i]);
}
}
for (var j = 0; j < ($scope.User.data1).length; j++) {
if($scope.User.data1[j].Layout == $scope.User.selectedSite) {
total1 += parseInt($scope.User.data1[j].DP_Inst_Pending);
}
}
$scope.User.teamTotal = total;
$scope.User.personalTotal = total1;
$scope.data = [$scope.User.teamTotal, $scope.User.personalTotal];
$scope.totamnt = parseInt($scope.User.personalTotal) + parseInt($scope.User.teamTotal);
$scope.User.totalamount = $filter('translate')('totalpending') + ": " + $filter('currency')($scope.totamnt, "");
$scope.User.data = $scope.arr;
};
here is html
<select name="site" ng-model="User.selectedSite" ng-change="getdatalayoutwise(User)">
<option value="">--{{'selectsite_message' | translate}}--</option>
<option ng-repeat= "option in User.site" value="{{option.Layout}}">{{option.Layout}}</option>
</select>
<table ng-table>
<tr>
<th>advisor_name</th>
<th>totalpending</th>
</tr>
<tr ng-repeat="data in User.data | filter : {Layout: User.selectedSite}: true" ng-if="data.dp_inst_pending">
<td class="ui-helper-center"><a ng-click="advisorDetails($index, data, User)">{{data.AdvisorName}}</a></td>
<td>{{data.dp_inst_pending | currency:"₹":0}}</td>
</tr>
</table>
you need to use $scope.$apply() :
$scope.getdatalayoutwise = function(User) {
$scope.$apply(function () {
var total = 0;
var total1 = 0;
for (var i = 0; i < ($scope.User.data).length; i++) {
if($scope.User.data[i].Layout == $scope.User.selectedSite) {
total += parseInt($scope.User.data[i].dp_inst_pending);
$scope.arr.push($scope.User.data[i]);
}
}
...
});
}
https://www.grafikart.fr/formations/angularjs/apply-watch-digest
Change your function to this
$scope.loaddata = function(User) {
$scope.User.data = [];
$scope.User.site = layouts;
AllServices.teamAllDataFunction1(User)
.then(function(response) {
$scope.User.data=response.data;
});
and add a ng-if
<table ng-table ng-if="User.data.length">
<tr>
<th>advisor_name</th>
<th>totalpending</th>
</tr>
<tr ng-repeat="data in User.data | filter : {Layout: User.selectedSite}: true" ng-if="data.dp_inst_pending">
<td class="ui-helper-center"><a ng-click="advisorDetails($index, data, User)">{{data.AdvisorName}}</a></td>
<td>{{data.dp_inst_pending | currency:"₹":0}}</td>
</tr>
</table>
Add this as the first line in getdatalayoutwise () function:
$scope.arr = [];
got it working by just doing following
$scope.safeApply = function(fn) {
var phase = this.$root.$$phase;
if(phase == '$apply' || phase == '$digest') {
if(fn && (typeof(fn) === 'function')) {
fn();
}
} else {
this.$apply(fn);
}
};
$scope.getdatalayoutwise = function(User) {
var total = 0;
var total1 = 0;
for (var i = 0; i < ($scope.User.data).length; i++) {
if($scope.User.data[i].Layout == $scope.User.selectedSite) {
total += parseInt($scope.User.data[i].dp_inst_pending);
$scope.arr.push($scope.User.data[i]);
}
}
...
$scope.safeApply (function () {
$scope.User.data = $scope.arr;
});
};

AngularJS niether ng-keypress or custom directive are working

Trying to implement a simple keypress event on a div but somehow nothing happens. I have read at some places that I need tabindex="0", however problem still prevails. Here is my html:
<body ng-app="myModule">
<div ng-controller="myCtrl" movement tabindex="1" ng-keypress="iterate($event)">
<div ng-repeat="entity in entities" entity-position="entity"></div>
<div class="table">
<div>
<select selected='name' ng-model="selected" id="select">
<option value="name" >First</option>
<option value="id">Second</option>
<option value="id">Third</option>
</select>
</div>
<table id="table">
<tr ng-repeat="item in cars | orderBy:selected" ng-click="go(item)">
<td>{{item.plate}}</td>
<td>{{item.name}}</td>
<td>{item.price}}</td>
</tr>
</table>
</div>
"movement" is a custom directive with it's own controller, I'm guessing the problem is connected to this, but I'm not sure.
This is inside the movement directive's controller (never logs anything):
$scope.iterate = function($event){
console.log('iterate')
}
Thank you for your help.
Edit: Added directive
app.directive('movement', function() {
return {
controller: function($scope, animFrame) {
var width = window.innerWidth;
var height = window.innerHeight;
var speed = .5;
var lastTime = new Date().getTime();
$scope.entities = [];
$scope.changeCount = function(count) {
while(count>0) {
$scope.entities.push({
x: width/2 * Math.random()+100,
y: height/2 * Math.random()+100,
velX: 0.2,//speed * Math.random()/2,
velY: 0.1,//speed * Math.random()/3
});
count--;
}
while(count<0) {
$scope.entities.pop();
count++;
}
}
$scope.tick = function($event){
//console.log('tick')
var now = new Date().getTime(),
delay = now - lastTime,
entities = $scope.entities;
for(var i=0; i<entities.length; i++) {
var b = entities[i];
b.x += delay * b.velX;
b.y += delay * b.velY;
if (b.x < 0) { b.x *= -1; b.velX *= -1;}
if (b.y < 0) { b.y *= -1; b.velY *= -1; }
if (b.x > width) { b.x = 2*width - b.x; b.velX *= -1;}
if (b.y > height) { b.y = 2*height - b.y; b.velY *= -1; }
}
lastTime = now;
animFrame($scope.tick);
}
$scope.changeCount(1);
$scope.tick();
}
};
});

Angular Pagination with Show All Records and Show Less Records

I am using AngularJS to show JSON data in table format. I have done with the fetching data. i have also implemented the pagination for the data movement.
Here I have three Link's to Adjust the Data like "Show All Records", "Show 10 More Records" and "Reset to 10 Records.
JavaScript:
var app = angular.module("MyApp",['ui.bootstrap']);
app.controller("MyController",function($scope,$http){
$http({method:"GET",url:'db.json'}).success(function(data,status,headers,config){
$scope.DBTotalData = data.length;
$scope.TotalPages='';
$scope.filteredapp = [],$scope.currentPage = 1,$scope.numPerPage = 5,$scope.maxSize = 1;
$scope.numPages = function () {
return Math.ceil(data.length / $scope.numPerPage);
};
$scope.$watch('currentPage + numPerPage', function() {
var begin = (($scope.currentPage - 1) * $scope.numPerPage)
, end = begin + $scope.numPerPage;
$scope.TotalPages=Math.ceil(parseInt(data.length,0)/parseInt($scope.numPerPage,0));
$scope.filteredapp = data.slice(begin, end);
$scope.DBData=$scope.filteredapp;
});
}).error(function(data,status,headers,config){
console.debug("error");
});
});
HTML:
<div data-pagination="" data-num-pages="numPages()" data-current-page="currentPage" data-max-size="maxSize" data-boundary-links="true"></div>
<div class="rgDataShowCtrl">
Show 10 More Records
Reset to 10 Records
Show All Results <div class="clear"></div></div>
<div class="clear"></div>
<tr ng-repeat="dData in DBData">
<td>{{dData.IaAcqNumber}}</td>
<td>{{dData.IaAssetNumber}}</td>
<td>{{dData.IaRepAssetNumber}}</td>
<td>{{dData.IaYearApp}}</td>
<td>{{dData.IaMake1}}</td>
<td>{{dData.IaModelRP}}</td>
<td>{{dData.IaOrganization}}</td>
<td>{{dData.IaDepartment}}</td>
<td>{{dData.IaTemplate}}</td>
</tr>
Javascript:
var app = angular.module("MyApp",['ui.bootstrap']);
app.controller("MyController",function($scope,$http){
$http({method:"GET",url:'db.json'}).success(function(data,status,headers,config){
$scope.DBTotalData = data.length;
$scope.TotalPages='';
$scope.filteredapp = [],$scope.currentPage = 1,$scope.numPerPage = 10,$scope.maxSize = 1;
$scope.ShowAll=function(value){
if(value==0){
$scope.numPerPage = $scope.numPerPage+10;
$(".showreset").show();
}else if(value==1){
$scope.numPerPage = 10;
$(".showreset").hide();
}else if(value==2){
$scope.numPerPage = data.length;
$(".showreset").show();
}
};
$scope.numPages = function () {
return Math.ceil(data.length / $scope.numPerPage);
};
$scope.$watch('currentPage + numPerPage', function() {
var begin = (($scope.currentPage - 1) * $scope.numPerPage)
, end = begin + $scope.numPerPage;
$scope.TotalPages=Math.ceil(parseInt(data.length,0)/parseInt($scope.numPerPage,0));
$scope.filteredapp = data.slice(begin, end);
$scope.DBData=$scope.filteredapp;
});
}).error(function(data,status,headers,config){
console.debug("error");
});
});
HTML:
<div data-pagination="" data-num-pages="numPages()" data-current-page="currentPage" data-max-size="maxSize" data-boundary-links="true"></div>
<div class="rgDataShowCtrl">
Show More per Page
Reset to 10 per Page
Show All Results
<div class="clear"></div>
</div>
<div class="clear"></div>
<tr ng-repeat="dData in DBData">
<td>{{dData.IaAcqNumber}}</td>
<td>{{dData.IaAssetNumber}}</td>
<td>{{dData.IaRepAssetNumber}}</td>
<td>{{dData.IaYearApp}}</td>
<td>{{dData.IaMake1}}</td>
<td>{{dData.IaModelRP}}</td>
<td>{{dData.IaOrganization}}</td>
<td>{{dData.IaDepartment}}</td>
<td>{{dData.IaTemplate}}</td>
</tr>

{{numPages}} not being calculated by pagination directive

I was under the impression with the pagination directive that the {{numPages}} value would be calculated by the directive. It isn't returning anything for me.
Is there anything I am missing to get this working properly? I don't want to have to calculate it, if the directive is supposed to be doing this for me. Otherwise paging is working great.
<pagination
total-items="totalItems"
ng-model="currentPage"
max-size="maxSize"
items-per-page="itemsPerPage"
class="pagination-sm"
boundary-links="true" rotate="false">
</pagination>
<table class="table table-striped">
<tr>
<td style="width:150px;">GPT ID</td>
<td style="width:250px;">Therapy Area</td>
<td style="width:450px;">GPT Description</td>
<td style="width:150px;">Actions</td>
</tr>
<tr ng-repeat="prGpt in prGpts | orderBy:['therapyArea.therapyArea','gptDesc'] | startFrom:(currentPage -1) * itemsPerPage | limitTo: itemsPerPage">
<td>{{prGpt.id}}</td>
<td>
<span ng-if="!prGpt.editMode">{{prGpt.therapyArea.therapyArea}}</span>
<span ng-if="prGpt.editMode && !createMode">
<select class="form-control" style="width:150px;" ng-model="selectedGpt.therapyArea" ng-options="item as item.therapyArea for item in therapyAreas"/>
</span>
</td>
<td>
<span ng-if="!prGpt.editMode">{{prGpt.gptDesc}}</span>
<span ng-if="prGpt.editMode && !createMode"><input class="form-control" type="text" style="width:400px;" ng-model="selectedGpt.gptDesc" /></span>
</td>
<td>
<span ng-if="!prGpt.editMode" class="glyphicon glyphicon-pencil" ng-click="copySelectedGpt(prGpt);beginEditGpt()"/>
<span ng-if="prGpt.editMode && !createMode" class="glyphicon glyphicon-floppy-disk" ng-click="saveEditGpt()"/>
<span ng-if="prGpt.editMode && !createMode" class="glyphicon glyphicon-thumbs-down" ng-click="cancelEditGpt()"/>
<span ng-if="!prGpt.editMode && !createMode" class="glyphicon glyphicon-remove-circle" ng-click="copySelectedGpt(prGpt);openDeleteDialog()"/>
<span><a ng-href="#!pr/gptProjects/{{prGpt.id}}">Edit Projects</a>
</span>
</tr>
</table>
<br/>
<pre>Page: {{currentPage}} / {{numPages}}</pre>
</div>
controller:
// GPT List Controller
.controller('prGPTCtrl',['$scope', '$modal', '$dialog', 'Restangular', 'prTAService', 'prGPTService', function($scope, $modal, $dialog, Restangular, prTAService, prGPTService) {
// window.alert('prGPTCtrl');
$scope.prGpts = {};
$scope.therapyAreas = {};
$scope.createMode = false;
$scope.selectedGpt = {};
$scope.newGpt = {};
// pagination
$scope.currentPage = 1;
$scope.itemsPerPage = 10;
$scope.maxSize = 20;
$scope.totalItems = $scope.prGpts.length;
Restangular.setBaseUrl('resources/pr');
//call the TA service to get the TA list for the drop down lists
//and then get the gpt list once successful
prTAService.getTAs().then(function(tas) {
$scope.therapyAreas = tas;
prGPTService.getGPTs().then(function(gpts) {
//window.alert('prGPTCtrl:getGPTs');
$scope.prGpts = gpts;
});
});
$scope.$watch('prGpts.length', function(){
$scope.totalItems = $scope.prGpts.length;
});
/*
* Take a copy of the selected GPT to copy in
*/
$scope.copySelectedGpt = function(prGpt) {
$scope.selectedGpt = Restangular.copy(prGpt);
};
$scope.beginEditGpt = function() {
var gpt = {};
var ta = {};
var gpt;
for(var i = 0; i < $scope.prGpts.length;i++) {
gpt = $scope.prGpts[i];
gpt.editMode = false;
}
var index = _.findIndex($scope.prGpts, function(b) {
return b.id === $scope.selectedGpt.id;
});
gpt = $scope.prGpts[index];
gpt.editMode = true;
var taIndex = _.findIndex($scope.therapyAreas, function(b) {
return b.id === $scope.selectedGpt.therapyArea.id;
});
ta = $scope.therapyAreas[taIndex];
$scope.selectedGpt.therapyArea = ta;
$scope.createMode = false;
};
$scope.cancelEditGpt = function() {
var gpt;
for(var i = 0; i < $scope.prGpts.length;i++) {
gpt = $scope.prGpts[i];
gpt.editMode = false;
}
var index = _.findIndex($scope.prGpts, function(b) {
return b.id === $scope.selectedGpt.id;
});
$scope.selectedGpt = null;
$scope.prGpts[index].editMode = false;
};
$scope.saveEditGpt = function() {
$scope.selectedGpt.save().then(function (gpt) {
// find the index in the array which corresponds to the current copy being edited
var index = _.findIndex($scope.prGpts, function(b) {
return b.id === $scope.selectedGpt.id;
});
$scope.prGpts[index] = $scope.selectedGpt;
$scope.prGpts[index].editMode = false;
$scope.selectedGpt = null;
},
function(err) {
window.alert('Error occured: ' + err);
}
);
};
// create a new GPT
$scope.createGpt = function() {
$scope.createMode = true;
var gpt;
for(var i = 0; i < $scope.prGpts.length;i++) {
gpt = $scope.prGpts[i];
gpt.editMode = false;
}
};
$scope.saveNewGpt = function() {
Restangular.all('/gpt/gpts').post($scope.newGpt).then(function(gpt) {
$scope.newGpt = {};
$scope.prGpts.push(gpt);
$scope.createMode = false;
// window.alert('created new GPT ' + gpt.gptDesc + ' with id ' + gpt.id);
});
};
$scope.openDeleteDialog = function() {
var title = "Please confirm deletion of GPT " + $scope.selectedGpt.gptDesc;
var msg = "<b>Delete GPT? Please confirm...</b>";
var btns = [{result:'CANCEL', label: 'Cancel'},
{result:'OK', label: 'OK', cssClass: 'btn-primary'}];
$dialog.messageBox(title, msg, btns, function(result) {
if (result === 'OK') {
$scope.deleteGpt();
}
});
};
$scope.deleteGpt = function() {
$scope.selectedGpt.remove().then(function() {
$scope.prGpts = _.without($scope.prGpts, _.findWhere($scope.prGpts, {id: $scope.selectedGpt.id}));
$scope.selectedGpt = null;
},
function() {
window.alert("There was an issue trying to delete GPT " + $scope.selectedGpt.gptDesc);
}
);
};
}]);
I have a startFrom filter.
.filter('startFrom', function () {
return function (input, start) {
if (input === undefined || input === null || input.length === 0
|| start === undefined || start === null || start.length === 0 || start === NaN) return [];
start = +start; //parse to int
try {
var result = input.slice(start);
return result;
} catch (e) {
// alert(input);
}
};
})
Regards
i
Looks like you're just missing num-pages="numPages" on your <pagination> tag. Essentially you have to provide a variable to pagination in which to return the number of pages. This is done via num-pages
<pagination
num-pages="numPages" <!-- Add this here -->
total-items="totalItems"
ng-model="currentPage"
max-size="maxSize"
items-per-page="itemsPerPage"
class="pagination-sm"
boundary-links="true" rotate="false">
</pagination>

How to update angular progress bar every time I click

Hi I am using angular progress bar and I want to update every time I click a button.
<div ng-controller="ProgressDemoCtrl">
<br/>
<h3>
Dynamic
<button class="btn btn-sm btn-primary" ng-click="random()" type="button">Randomize</button>
</h3>
<small>
<em>No animation</em>
</small>
<progressbar animate="false" type="success" value="dynamic">
<b>{{dynamic}}%</b>
</progressbar>
</div>
ANGULAR
var ProgressDemoCtrl = function ($scope) {
$scope.max = 00;
$scope.random = function() {
var value = Math.floor((Math.random() * 100) + 1);
var type;
if (value < 25) {
type = 'success';
} else if (value < 50) {
type = 'info';
} else if (value < 75) {
type = 'warning';
} else {
type = 'danger';
}
$scope.showWarning = (type === 'danger' || type === 'warning');
$scope.dynamic = value;
$scope.type = type;
};
$scope.random();
$scope.randomStacked = function() {
$scope.stacked = [];
var types = ['success', 'info', 'warning', 'danger'];
for (var i = 0, n = Math.floor((Math.random() * 4) + 1); i < n; i++) {
var index = Math.floor((Math.random() * 4));
$scope.stacked.push({
value: Math.floor((Math.random() * 30) + 1),
type: types[index]
});
}
};
$scope.randomStacked();
};
as you can see in here what it does when i click the button is filling it up randomly.So what i want to do is be able to click a button and update the progress bar.
If you are using angular bootstrap's progressbar this is very easy. I just made a plunkr for it.
Your HTML
<div ng-controller="ProgressDemoCtrl">
<h3>Progress bar value is {{dynamic}}</h3>
<progressbar max="max" value="dynamic">
<span style="color:black; white-space:nowrap;">
{{dynamic}} / {{max}}
</span>
</progressbar>
<input type="button" ng-click="progress()" value="Click Me To Progress" />
</div>
</body>
</html>
and JS
angular.module('plunker', ['ui.bootstrap']);
var ProgressDemoCtrl = function ($scope) {
$scope.dynamic = 10;
$scope.max = 100;
$scope.progress = function(){
$scope.dynamic = $scope.dynamic + 10;
};
};

Resources