Angularjs toggle image onclick - angularjs

I'm trying to toggle a button image when a user clicks it. I prefer to use angularjs instead of jquery if possible. Right now I have a working version which toggles the image when clicked, the only problem is it changes ALL the images on click. How do I reduce the scope or pass in the src attribute for the img element?
<div ng-repeat="merchant in merchants">
<div class="followrow">
<a ng-click="toggleImage()"><img id="followbutton" ng-src="{{followBtnImgUrl}}" /></a>
</div>
</div>
app.controller('FollowCtrl', function CouponCtrl($scope) {
$scope.followBtnImgUrl = '/img1'
$scope.toggleImage = function () {
if ($scope.followBtnImgUrl === '/img1.jpg') {
$scope.followBtnImgUrl = baseUrl + '/img2.jpg';
} else {
$scope.followBtnImgUrl = 'img1.jpg';
}
}
});
Can I pass in the img src attribute the function like toggleImage(this.img.src) or similar?

<div ng-repeat="merchant in merchants">
<div class="followrow">
<a ng-click="toggleImage(merchant)"><img id="followbutton" ng-src="{{merchant.imgUrl}}" />
</a>
</div>
</div>
.
app.controller('FollowCtrl', function CouponCtrl($scope) {
$scope.followBtnImgUrl = '/sth.jpg'
$scope.merchants = [{imgUrl: "img1.jpg", name:"sdf"},
{imgUrl: "img2.jpg", name: "dfsd"}];
$scope.toggleImage = function(merchant) {
if(merchant.imgUrl === $scope.followBtnImgUrl) {
merchant.imgUrl = merchant.$backupUrl;
} else {
merchant.$backupUrl = merchant.imgUrl;
merchant.imgUrl = $scope.followBtnImgUrl;
}
};
});

What you want is a new scope for each followrow. As your code stands, there's only one scope that all of the followrows are referencing.
A simple answer is to create a new controller that you attach to each followrow:
<div class="followrow" ng-controller="ImageToggleCtrl">...</div>
And then move the image toggling logic to that new controller:
app.controller('ImageToggleCtrl', function($scope) {
$scope.followBtnImgUrl = '/img1';
$scope.toggleImage = function() { /* the toggling logic */ };
});
Now, a new scope will be instantiated for each row, and the images will toggle independently.

I just added two clickable images:
<div ng-app="FormApp" ng-controller="myController" max-width="1150px;" width="1150px;" >
<input ng-show="ShowDown" type="image" style="width:250px; height:40px;" src="~/Content/Images/contactShow.png" ng-click="ShowHide()"/>
<input ng-show="ShowUp" type="image" style="width:250px; height:40px;" src="~/Content/Images/contactHide.png" ng-click="ShowHide()" />
</div>
They toggle eachothers visibility. At page load one is visible, one is not, and both clickable images call the same function:
<script type="text/javascript">
var app = angular.module('FormApp', [])
app.controller('myController', function ($scope) {
$scope.ShowDown = true;
$scope.ShowUp = false;
$scope.ShowHide = function () {
$scope.ShowDown = $scope.ShowDown ? false : true;
$scope.ShowUp = $scope.ShowUp ? false : true;
}
});
</script>

Related

Disable link after click angular js

Could anybody help me with a solution.
I need to make the link disabled (PAY Now) after clicking on that to avoid multi clicking.
<div class="Class1" data-ng-show="ShowButton == 'TRUE'">
PAY NOW</div>
There is no disabled attribute for hyperlinks. If you don't want to do something with that you'll need to add some style into the <a> tag altogether and handle the flag into the controller.
Try this :
angular.module('myApp', [])
.controller('myCtrl', ['$scope', function($scope) {
$scope.isDisabled = false;
if($scope.isDisabled === false) {
$scope.PayNow = function() {
$scope.isDisabled = true;
}
}
}]);
.disabled {
cursor: not-allowed;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
PAY NOW
</div>
You can in the PayNow() function create an extra variable which disables the button like so:
JS:
$scope.PayNow = function() {
$scope.DisabledButton = true;
// other code
}
HTML
PAY NOW
In your html
.disabled {
cursor: not-allowed;
}
<a ng-click="PayNow()" ng-class="{'disabled': DisabledButton}">Add</a>
OR
<button ng-click="PayNow()" ng-disabled="DisabledButton">Add</button>
In JS
$scope.DisabledButton = false;
$scope.PayNow = function() {
$scope.DisabledButton = true;
// other code
...
//when you want to re-enable
$scope.DisabledButton = false;
}
i hope if this can help you!!!. So in my example I am using condition to check the length of the array and constraining the button to make more textboxes. Plus you can use count instead.
$scope.technologies = [];
$scope.addtech = function () {
$scope.minus = true;
if ($scope.technologies.length < 3)
$scope.technologies.push({});
}

how to get calculated values(totalPriceAmt) from js to html in by using angular js

Js
var myApp = angular.module("DataEntryApp", []);
myApp.controller("DataEntryController",function($scope) {
alert("totalPrice?" + $scope.totalPriceAmt);
}
$scope.Add = function() {
alert("Total amount commint:" +$scope.totalPriceAmt);
};
Html side
<div ng-app="DataEntryApp" ng-controller="DataEntryController">
<button ng-click="Add()">Submit</button>
<span>Total: {{ totalPriceAmt }} </span>
</div>
I am not able to get the values totalPriceAmt in HTML side after clicking on submit button or I want to directly display totalPrice in HTML.
there is syntax error
function is defined outside controller
var myApp = angular.module("DataEntryApp", []);
myApp.controller("DataEntryController",function($scope) {
$scope.totalPriceAmt =10;
$scope.Add = function() {
$scope.totalPriceAmt =$scope.totalPriceAmt+10;
};
});
http://codepen.io/vkvicky-vasudev/pen/xOOBGq
If you want to display $scope value in html, you need to assign some value to that. As i can see from your code , no assignment of value is happening.
var myApp = angular.module("DataEntryApp", []);
myApp.controller("DataEntryController",function($scope) {
$scope.totalPriceAmt = 10;
}
$scope.Add = function() {
$scope.totalPriceAmt = 10;
};
<div ng-app="DataEntryApp" ng-controller="DataEntryController">
<button ng-click="Add()">Submit</button>
<span>Total: {{ totalPriceAmt }} </span>
</div>
Now if you run the app, after clicking the button , it will work.
Hey you must bind the variable using the ng-bind and then give access to the controller and use the $scope and perform the operation.
There was a syntax error in your example for registering the controller with the angular application. Fixing that, in the attached code snippet, you can see that I initialize the value totalPriceAmount to 0 in the controller, and then increment it by 10 each time the Add method is called when clicking the button. You'll also see that the data-binding to the scope variable occurs correctly as well.
var myApp = angular.module("DataEntryApp", []);
myApp.controller("DataEntryController", function($scope) {
$scope.totalPriceAmt = 0;
$scope.Add = function() {
$scope.totalPriceAmt += 10;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<div ng-app="DataEntryApp" ng-controller="DataEntryController">
<button ng-click="Add()">Submit</button>
<span>Total: {{ totalPriceAmt }} </span>
</div>

How to get the value from ACE-Angular editor

I am having problems on getting Ace code editor results from whatever I type on the code editor.
As you can see I set up my controller with all the functionalities
and options. The only thing that is not working is rendering the results from editor. Thank you in advance....
app.controller('AceCtrl', function ($scope) {
$scope.modes = ['CoffeeScript'];
$scope.mode = $scope.modes[0];
$scope.aceOption = {
mode: $scope.mode.toLowerCase(),
onLoad: function (editor) {
// defaults
editor.setTheme("ace/theme/monokai");
// options
editor.setOptions({
showGutter: true,
showPrintMargin: false,
});
$scope.modeChanged = function () {
editor.getSession().setMode("ace/mode/" + $scope.mode.toLowerCase());
};
}
};
//Runs every time the value of the editor is changed
$scope.aceChanged = function(_editor){
console.log('Ace editor changed');
// Get Current Value
var currentValue = _editor.getSession().getValue();
// Set value
_editor.getSession().setValue('This text is now in the editor');
};
});
<div class="wrapper" ng-controller="AceCtrl">
<section >
<select ng-model="mode" ng-options="m for m in modes" ng-change="modeChanged()" autofocus="0"></select>
<div ui-ace="aceOption" ng-model="aceModel" class="ace_editor"></div>
</section>
<div ng-change="aceChanged" style="border:1px solid red; position:relative; width:50%; height:300px; float:right;"></div>
</div>
If you want to do this in the onChange handler of ui-ace you could get the document from the editor's session and grab it's value:
editor.getSession().getDocument().getValue();
Reference: http://ajaxorg.github.io/ace/#nav=api&api=document
Example code:
<div ui-ace="{
onLoad: aceLoaded,
onChange: aceChanged
}"></div>
<textarea id="ace_document">
{{aceDocumentValue}}
</textarea>
$scope.aceLoaded = function(_editor) {
$scope.aceSession = _editor.getSession();
};
$scope.aceChanged = function () {
$scope.aceDocumentValue = $scope.aceSession.getDocument().getValue();
};
Working example on Plunker: http://plnkr.co/edit/9swlVY9JnIfOnbOAfXui?p=preview
But the easiest way is to assign the value to scope and use ng-model on the directive's element:
Controller:
angular.module('app').controller('rootController', [
'$scope',
function ($scope) {
$scope.aceValue = 'Foobar';
}
]);
Template:
<div ui-ace ng-model="aceValue"></div>
<textarea id="ace_document" ng-model="aceValue"></textarea>
Working example on Plunker: http://plnkr.co/edit/fbtzYDEqIQEwB6Ascm3s?p=preview

Start/Stop/Resume all in one button with Angular Timer

Using the pre-built "Angular Timer" directives available here (scroll down to progress bar example), I'm trying to build a progress bar with a Start, Stop and Resume button all-in-one.
Examples on their websites are made of two buttons and I would like to merge them.
One solution could be to use innerHTML to get the current state ("Start" or "Stop") and a if condition in the controller.js but i'd like the button to be a icon-only-button switching from play to pause icon.
An example from simple timer implementation is available here
Here is my html
<button class="button button-icon icon" ng-class="{'icon ion-play': !play, 'icon ion-pause': play}" ng-click="stopResumeTimer(this)"></button>
<timer interval="1000" autostart="false"><div class="progress"> <div class="bar" style="width: {{seconds}}%;"></div> </div></timer>
And the controller.js code with the if condition
$scope.stopResumeTimer = function(btn) {
if (not yet started) {
$scope.startTimer();
}
else if (already started) {
$scope.stopTimer();
}
else {
$scope.resumeTimer();
}
}
I am discouraged by the repeated failure on this, any help would be great! Thanks
In the controller where you are setting the ng-click function, you can set flags to determine whether the click function should start, stop, or resume. Those flags can also set the text for the button to be either "Start", "Stop", or "Resume".
JS:
(function(angular) {
function controller($scope) {
var isStart = false;
var isStop = false;
$scope.timerBtnText = "Start";
$scope.timer = function() {
if (isStart) {
$scope.startTimer();
isStart = false;
isStop = true;
$scope.timerBtnText = "Stop";
return;
}
if (isStop) {
$scope.stopTimer();
isStop = false;
$scope.timerBtnText = "Resume";
} else {
$scope.resumeTimer();
isStop = true;
$scope.timerBtnText = "Stop";
}
};
}
angular.module("app", []).controller("controller", ["$scope", controller]);
})(angular);
HTML:
<button ng-click="timer()" ng-bind="timerText"></butotn>
Here is a working proof of concept: http://plnkr.co/edit/NlQFPysVH1M2EyjogQQv
This is how I would solve it (Plunker)
Controller:
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.operation = 'start';
$scope.startOrStop = function(){
document.getElementById('first')[$scope.operation]();
$scope.operation = ($scope.operation === 'start' || $scope.operation === 'resume') ? 'stop' : 'resume';
}
});
Declare it like this:
<button ng-click="startOrStop()" ng-class="{start:operation==='start', stop:operation==='stop', resume:operation==='resume'}"></button>
<timer id="first" interval="1000" autostart="false"><div class="progress"><div class="progress-bar" role="progressbar" style="width: {{seconds}}%;"></div></div></timer>
Css:
.start::before{
content:"Start";
}
.stop::before{
content:"Stop";
}
.resume::before{
content:"Resume";
}

Isolating re-used controller scopes with AngularJS

I'm currently working on a project where I use a primary navigation to open tabs which lazy-load templates.
EDIT: to clarify, the number of tabs can vary on a user basis, so I cannot do this hard coded.
My way to try and accomplish this is by using a Tabs-controller with headers and the tab-items themselves:
<section class="tabs" ng-controller="Tabs">
<div class="tabs__header">
<div class="tabs__header__item is-hidden" ng-repeat="tab in tabs" data-item="{{tab.item}}" ng-if="!tab.header">
<a class="tabs__header__item__text" ng-href="#/{{tab.item}}" ng-click="tabClicked($event)" data-item="{{tab.item}}">{{tab.name}}</a>
x
</div>
</div>
<div class="tabs__container">
<div class="tabs__container__tab is-hidden" ng-repeat="tab in tabs" id="tab-{{ tab.item }}" ng-if="!tab.header" ng-controller="Tab" ng-include src="template.url"></div>
</div>
</section>
And the controllers would look like this:
Tabs.js:
function Tabs(scope, root) {
root.$on('/general/page/initdata', function(e, data) {
//set default elements
scope.tabs = data['nav-primary'];
//open dashboard
});
root.$on('/nav/primary/open', function(e, itemName) {
root.$emit('/tabs/activate', itemName);
_setActiveTab(itemName);
});
scope.tabClicked = function(e) {
e.preventDefault();
var name = e.target.getAttribute('data-item');
_setActiveTab(name);
};
function _setActiveTab(itemName) {
var collection = document.querySelectorAll('.tabs__header__item.js-is-active, .tabs__container__tab.js-is-active');
angular.element(collection).removeClass('js-is-active');
collection = document.querySelectorAll('#tab-'+itemName+', .tabs__header__item[data-item="'+itemName+'"]');
angular.element(collection).addClass('js-is-active').removeClass('is-hidden');
}
};
Tabs.$inject = ['$scope', '$rootScope'];
Tab.js
function Tab(scope, root) {
var loaded = false;
root.$on('/tabs/activate', function(e, itemName){
if(scope.tab.item === itemName && !loaded) {
loaded = true;
scope.template = {url: '/frontend/templates/'+itemName+'.html'};
}
});
};
Tab.$inject = ['$scope', '$rootScope'];
Now, the problem is that template.url is modified for each tab whereas I only want to modify it for one tab. It turns out scope is shared between the various Tab-instances. How can I circumvent this?
It turns out the problem wasn't with AngularJS. I had simply made an error with my js-is-active class, causing the wrong tab to be displayed.

Resources