Get origin of a Ng-click on buttons? - angularjs

I'm trying to reset background-colors (bgNeutral) of all my buttons, except the only one who are solicited (who have to switch in "bgSelected"):
<button ng-class="button1" ng-click="addActifOnMe($1)" class="bgSelected"></button>
<button ng-class="button2" ng-click="addActifOnMe($2)" class="bgNeutral"></button>
<button ng-class="button3" ng-click="addActifOnMe($3)" class="bgNeutral"></button>
This is my .js:
app.controller("angularController", function ($scope) {
$scope.button1 = "bgSelected";
$scope.addActifOnMe = function (1) {
$scope.button2 = "bgNeutral";
$scope.button3 = "bgNeutral";
$scope.button1 = "bgSelected";
};
$scope.addActifOnMe = function (2) {
$scope.button1 = "bgNeutral";
$scope.button3 = "bgNeutral";
$scope.button2 = "bgSelected";
};
$scope.addActifOnMe = function (3) {
$scope.button1 = "bgNeutral";
$scope.button2 = "bgNeutral";
$scope.button3 = "bgSelected";
};
});
CSS can be something like that:
.bgSelected{
background-color: red;
}
.bgNeutral{
background-color: blue;
}
But actually this, doesn't work... I'm trying to use ngClick with $event in my function. Someone have a better way for doing that ?
Thank you ! Best regards.

You can do this by using a variable selectedButton in your controller to track which button is selected.
<button class="neutral" ng-class="{selected: todoList.selectedButton === 1}" ng-click="todoList.select(1)">button 1</button>
<button class="neutral" ng-class="{selected: todoList.selectedButton === 2}" ng-click="todoList.select(2)">button 2</button>
<button class="neutral" ng-class="{selected: todoList.selectedButton === 3}" ng-click="todoList.select(3)">button 3</button>
controller:
angular.module('todoApp', [])
.controller('TodoListController', function() {
var todoList = this;
todoList.selectedButton = 1;
todoList.select = function(buttonNumber) {
todoList.selectedButton = buttonNumber;
}
});
Here's a plunker to demonstrate this working

Related

AngularJs change button text as well as color

Hi I am trying to change color as well as text of a button i.e. switch between two texts & colors. Suspend/unsuspend text and red/green color.
What I want to do is for the moment (because later, server will give info about whether user is suspended or not) randomly give them any one of these two texts&colors, and I click on button it should turn to other text & color.
I tried but I am wrong somewhere and I cant find it. Please help. And if there is any better way then please suggest to me, I am new to angular.
HTML:
<button type="button" class="btn btn-danger" ng-if="checkStatus(person.isSuspended)" ng-click="person.isSuspend=suspendUser(!person.isSuspend)">{{suspendText}}</button>
<button type="button" class="btn btn-primary" ng-if="checkStatus(!person.isSuspended)" ng-click="person.isSuspend=suspendUser(person.isSuspend)">{{suspendText}}</button>
Javascript:
$scope.checkStatus = function (bool) {
if (bool) {
$scope.suspendText = "UNSUSPEND"
return true;
} else {
$scope.suspendText = "SUSPEND"
return false;
}
}
$scope.suspendUser = function (bool) {
if (bool) {
if ($window.confirm("Are You Sure Want to Unsuspend ?")) {
$scope.suspendText = "SUSPEND"
return !bool;
}
else {
return bool;
}
} else {
if ($window.confirm("Are You Sure Want to Suspend ?")) {
$scope.suspendText = "UNSUSPEND"
return !bool;
} else {
return bool;
}
}
}
Check this Plunkr: http://plnkr.co/edit/DEbTtpwu749sVT6iSojd?p=preview
Asumming you are through a User List with name & status (boolean true: Active - false: inactive):
user = {name:'John', status: true}
Here you can check how change the status, text & button color. In a short angular Way.
<li ng-repeat="user in users">
({{ user.active ? 'Active' : 'Inactive'}})
{{ user.name }}
<div ng-class="user.active? 'btn btn-danger' : 'btn btn-primary' " ng-click="user.active=!user.active">
{{ user.active ? 'Suspend' : 'Unsuspend'}}
</div>
</li>
<body ng-controller="MainCtrl as vm">
<button class="btn"
ng-class="{ 'btn-primary': vm.isSuspended , 'btn-danger': !vm.isSuspended }"
ng-bind="vm.text"
ng-click="vm.toggleSuspend()">
</button>
</body>
angular.module('app', [])
.controller('MainCtrl', function() {
var vm = this;
vm.toggleSuspend = function() {
vm.isSuspended = !vm.isSuspended;
vm.text = vm.isSuspended ? 'unsuspend' : 'suspend';
};
vm.isSuspended = true;
vm.toggleSuspend();
});
You will just need one button instead of two. A better way of showing the colors would be using ng-class, where you can write expressions to toggle the class.
<button type="button" class="btn" ng-class="person.isSuspended? 'btn-danger':'btn-success'" ng-click="person.isSuspended = !person.isSuspended">{{suspendText}}</button>
Note the way ng-class is written. I am using ternary operator to check if person.isSuspeneded is true, if it is, apply the class btn-danger, else apply btn-success. Now you have got a way cleaner code.
Attached is the plnkr - http://plnkr.co/edit/Uk2rHFacMFLbXyxGzK1b?p=preview
Try to replace your ng-if with ng-show in button.
<div ng-controller="MyCtrl">
<button type="button" class="btn btn-danger"
ng-show="person.isSuspend"
ng-click="person.isSuspend=suspendUser(!person.isSuspend)">{{suspendText}}</button>
<button type="button" class="btn btn-primary"
ng-show="!person.isSuspend"
ng-click="person.isSuspend=suspendUser(person.isSuspend)">{{suspendText}}</button>
</div>
var myApp = angular.module('myApp',[]);
function MyCtrl($scope, $window) {
// first you need to initialize your scope if you didn't
$scope.person = {
isSuspend: false
};
$scope.suspendText = "SUSPEND";
$scope.suspendUser = function (bool) {
if (bool) {
if ($window.confirm("Are You Sure Want to Unsuspend ?")) {
$scope.suspendText = "SUSPEND"
$scope.person.isSuspended = false;
}
else {
$scope.person.isSuspended = true;
}
} else {
if ($window.confirm("Are You Sure Want to Suspend ?")) {
$scope.suspendText = "UNSUSPEND"
$scope.person.isSuspended = true;
} else {
$scope.person.isSuspended = false;
}
}
}
}
angular change button text

InfiniteScroll - AngularJS not working

Edit:
Just for checking purposes, I also did a console.log inside the nextPage function, to check if it's being triggered:
$scope.nextPage = function() {
var captureLength = $scope.captures.length;
console.log('TRIGGER');
if($scope.busy) {
return;
}
...
}
};
And it seems I'm getting a infinite loop, but I can't see why.
=================================
I'm trying to implement infinitescroll into a view but for some reason it's only loading the initial 4 images and not triggering the rest.
Here is my code:
CTRL:
/* ----------------------- Variables ----------------------- */
$scope.auth = auth;
$scope.captures = [];
$scope.following = [];
$scope.allData = [];
$scope.busy = true;
var page = 0;
var step = 4;
$scope.nextPage = function() {
var captureLength = $scope.captures.length;
if($scope.busy) {
return;
}
$scope.busy = true;
$scope.captures = $scope.captures.concat($scope.allData.splice(page * step, step));
page++;
$scope.busy = false;
if($scope.captures.length === 0) {
$scope.noMoreData = true;
}
};
/* ----------------------- Process Data ----------------------- */
$q.all({follows: findFollow(), users: getUsers(), captures: getAllCaptures()}).then(function(collections) {
var follows = collections.follows;
var users = collections.users;
var captures = collections.captures;
follows.filter(function(follow) {
return follow.follower_id === auth.profile.user_id;
}).forEach(function(follow) {
users.filter(function(user) {
return user.user_id === follow.followed_id;
}).forEach(function(user) {
$scope.following.push(user);
});
});
follows.filter(function(follow) {
return follow.follower_id === auth.profile.user_id;
}).forEach(function(follow) {
captures.filter(function(capture){
return follow.followed_id === capture.userId;
}).forEach(function(capture){
console.log(capture);
$scope.allData.push(capture);
});
});
$scope.nextPage();
$scope.busy = false;
});
/* ----------------------- Retrieve Services - Data ----------------------- */
function findFollow() {
return userApi.findFollow().then(function(res) {
return res.data;
});
}
function getUsers() {
return userApi.getUsers().then(function(res) {
return res.data.users;
});
}
function getAllCaptures() {
return captureApi.getAllCaptures().then(function(res) {
return res.data;
});
}
Partial:
<div class="col-md-8">
<div class="well main-well">
<h3 class="page-header-h3">Following Dashboard:</h3>
<hr />
<h4 align="center" ng-show="!captures.length">
<strong>The people that you are following, have not posted anything yet.. Yikes!</strong>
<br /><br />
Quickly, go follow more people!</h4>
<div class="row" infinite-scroll="nextPage()" infinite-scroll-disabled="busy || noMoreData" infinite-scroll-distance="0.1">
<ul class="dynamic-grid" angular-grid="captures" ag-id="gallery">
<li data-ng-repeat="capture in captures | orderBy :'created_at':true" class="grid">
<a ui-sref="detail({id: capture._id})">
<img ng-src="{{capture.picture}}" class="grid-img" />
<span class="follow-capture-info">
<span class="follow-capture-name"><span class="glyphicon glyphicon-user"></span>
{{capture.author}}
<span class="following-capture-time">ยท
<span class="glyphicon glyphicon-time"></span>
<span am-time-ago="capture.created_at"></span>
</span>
</span>
</span>
</a>
</li>
</ul>
</div>
<div ng-show="busy">Loading more...</div>
</div>
Anyone know where I went wrong?
Thanks.

{{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;
};
};

How to do the Logic behind the next button in angularjs wizard

I have a customers.create.html partial bound to the WizardController.
Then I have 3 customers.create1,2,3.html partial files bound to WizardController1,2,3
Each WizardController1,2 or 3 has an isValid() function. This function determines wether the user can proceed to the next step.
The next button at the bottom of the pasted html should be disabed if ALL ? isValid() functions are false...
Thats my question but the same time that seems not correct to me.
I guess I am not doing the Wizard correctly...
Can someone please guide me how I should proceed with the architecture that the bottom next button is disabled when the current step isValid function returns false, please.
How can I make a connection from the WizardController to any of the WizardController1,2 or 3 ?
Is Firing an event like broadcast a good direction?
<div class="btn-group">
<button class="btn" ng-class="{'btn-primary':isCurrentStep(0)}" ng-click="setCurrentStep(0)">One</button>
<button class="btn" ng-class="{'btn-primary':isCurrentStep(1)}" ng-click="setCurrentStep(1)">Two</button>
<button class="btn" ng-class="{'btn-primary':isCurrentStep(2)}" ng-click="setCurrentStep(2)">Three</button>
</div>
<div ng-switch="getCurrentStep()" ng-animate="'slide'" class="slide-frame">
<div ng-switch-when="one">
<div ng-controller="WizardController1" ng-include src="'../views/customers.create1.html'"></div>
</div>
<div ng-switch-when="two">
<div ng-controller="WizardController2" ng-include src="'../views/customers.create2.html'"></div>
</div>
<div ng-switch-when="three">
<div ng-controller="WizardController3" ng-include src="'../views/customers.create3.html'"></div>
</div>
</div>
<a class="btn" ng-click="handlePrevious()" ng-show="!isFirstStep()">Back</a>
<a class="btn btn-primary" ng-disabled="" ng-click="handleNext(dismiss)">{{getNextLabel()}}</a>
'use strict';
angular.module('myApp').controller('WizardController', function($scope) {
$scope.steps = ['one', 'two', 'three'];
$scope.step = 0;
$scope.wizard = { tacos: 2 };
$scope.isFirstStep = function() {
return $scope.step === 0;
};
$scope.isLastStep = function() {
return $scope.step === ($scope.steps.length - 1);
};
$scope.isCurrentStep = function(step) {
return $scope.step === step;
};
$scope.setCurrentStep = function(step) {
$scope.step = step;
};
$scope.getCurrentStep = function() {
return $scope.steps[$scope.step];
};
$scope.getNextLabel = function() {
return ($scope.isLastStep()) ? 'Submit' : 'Next';
};
$scope.handlePrevious = function() {
$scope.step -= ($scope.isFirstStep()) ? 0 : 1;
};
$scope.handleNext = function(dismiss) {
if($scope.isLastStep()) {
dismiss();
} else {
$scope.step += 1;
}
};
});
durandalJS wizard sample code which could be used to rewrite a wizard for angularJS:
define(['durandal/activator', 'viewmodels/step1', 'viewmodels/step2', 'knockout', 'plugins/dialog', 'durandal/app', 'services/dataservice'],
function (activator, Step1, Step2, ko, dialog, app, service) {
var ctor = function (viewMode, schoolyearId) {
debugger;
if (viewMode === 'edit') {
service.editSchoolyear(schoolyearId);
}
else if (viewMode === 'create') {
service.createSchoolyear();
}
var self = this;
var steps = [new Step1(), new Step2()];
var step = ko.observable(0); // Start with first step
self.activeStep = activator.create();
var stepsLength = steps.length;
this.hasPrevious = ko.computed(function () {
return step() > 0;
});
self.caption = ko.observable();
this.activeStep(steps[step()]);
this.hasNext = ko.computed(function () {
if ((step() === stepsLength - 1) && self.activeStep().isValid()) {
// save
self.caption('save');
return true;
} else if ((step() < stepsLength - 1) && self.activeStep().isValid()) {
self.caption('next');
return true;
}
});
this.isLastStep = function() {
return step() === stepsLength - 1;
}
this.next = function() {
if (this.isLastStep()) {
$.when(service.createTimeTable())
.done(function () {
app.trigger('savedTimeTable', { isSuccess: true });
})
.fail(function () {
app.trigger('savedTimeTable', { isSuccess: false });
});
}
else if (step() < stepsLength) {
step(step() + 1);
self.activeStep(steps[step()]);
}
}
this.previous = function() {
if (step() > 0) {
step(step() - 1);
self.activeStep(steps[step()]);
}
}
}
return ctor;
});

Resources