ng-class does not change class unless I refresh the page - javascript

I'm using ng-class in my view to change the class of and element and it works fine on page load. Here is my code:
<ul>
<li ng-class="'{{account.currency}}' == '{{currency}}' ? 'active': 'inactive'" ng-repeat="account in accounts" bind="accounts">
<a href="#/deposits/{{account.currency}}" ng-click="changeClass('{{account.currency}}', '{{currency}}')">
{{currency}}
</a>
</li>
<ul>
As you can see, it takes the second currency from the URL and compares it with another to decide which class it should assign to my li element.
The trouble now is that when someone clicks on the link and the URL changes, the class assigned does not change. Any idea how I can get the class assigned by ng-class to change when the

You don't need to call a function for this, this can be easily achieved inline
try like this:
<li ng-class="{'active' : account.currency == currency, 'inactive':
account.currency != currency}">
OR
<li ng-class="{true: 'active', false: 'inactive'}[account.currency == currency]">
If you're using angular v.1.1.4+
<li ng-class="account.currency == currency ? 'active': 'inactive'}">

Try this,
var app = angular.module('app', []);
app.controller('myctrl', function() {
var vm = this;
vm.accounts = [{
currency: 'Doller'
}, {
currency: 'Pound'
}, {
currency: 'Euro'
}];
vm.changeClass = function(account) {
vm.active = account.currency;
}
});
.active {
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body>
<div ng-app="app" ng-controller="myctrl as ct">
<ul>
<li ng-class="{'active': ct.active === account.currency}" ng-repeat="account in ct.accounts">
<a href="#" ng-click="ct.changeClass(account)">
{{account.currency}}
</a>
</li>
</ul>
</div>
</body>

Make the ng-class= {'active': account.currency === currency}
in the css file you should have the .active{} class. And let the inactive class be the default behaviour.
P.S The answers of Dhaval should work also

Related

Vue class binding attribute and multiple tailwind classes

I'm trying to bind an attribute and multiple tailwind classes to an html element. This is for a tab menu, so the idea is that for the "active" tab I take the title dynamically and inject also some tailwind classes to change the look and feel of the "active" tabs.
<li
:class="{
selected: title === selectedTitle,
selected ? ['border-b-2', 'border-blue-700' ]
}"
#click.stop.prevent="selectedTitle = title"
v-for="title in tabTitles"
:key="title"
role="presentation"
>
At the moment the previous code is not working for me.
From my point of view following line can't work:
selected ? ['border-b-2', 'border-blue-700' ]
This is a short if else without an else case - I think you ment writing something like this:
<li :class="{
'selected border-b-2 border-blue-700': title === selectedTitle,
}">
Try like following:
new Vue({
el: "#demo",
data() {
return {
tabTitles: ['aaa', 'bbb', 'ccc'],
selectedTitle: ''
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" integrity="sha512-wnea99uKIC3TJF7v4eKk4Y+lMz2Mklv18+r4na2Gn1abDRPPOeef95xTzdwGD9e6zXJBteMIhZ1+68QC5byJZw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<div id="demo">
<li :class=" selectedTitle === title ? 'border-b-2 border-blue-700' : '' "
#click.stop.prevent="selectedTitle = title"
v-for="title in tabTitles"
:key="title"
role="presentation"
>{{title}}</li>
</div>

Vue.js To add class active when click and remove the previous one

I want to achieve this active link on my div element here you can see the example that i want to do with my code
http://jsfiddle.net/fiddleyetu/9ff79/
$(function() {
$( 'ul.nav li' ).on( 'click', function() {
$( this ).parent().find( 'li.active' ).removeClass( 'active' );
$( this ).addClass( 'active' );
});
});
in here using vue.js i can't do the active link on my div elements
here is my code for the elements on which i have to do the links active
<div class="conversion">
<div class="file has-text-centered icon-active-color" v-on:click="activeiconc">
<img src="../imgs/png.png"/>
<h4>.PNG</h4>
</div>
<div class="file has-text-centered" v-on:click="activeicon" v-bind:class="{ 'icon-active-color':activeiconc,}">
<img src="../imgs/pdf.png"/>
<h4>.PDF</h4>
</div>
<div class="file has-text-centered" v-on:click="activeicon" v-bind:class="{ 'icon-active-color':activeiconc }">
<img src="../imgs/jpg.png"/>
<h4>.JPG</h4>
</div>
<div class="file has-text-centered" v-on:click="activeicon" v-bind:class="{ 'icon-active-color':activeiconc }">
<img src="../imgs/psd.png"/>
<h4>.PSD</h4>
</div>
</div>
js
export default {
components: {
MainLayout
},
data: function(){
return {
logo: false,
color:false,
list:true,
grid:false,
deletebtn:false,
isImageModalActive: false,
activerow: false,
activeiconc:false,
}
},
methods:{
showgrid:function(){
this.grid = true;
this.list = false;
},
showlist:function(){
this.list ^=true;
this.grid = false
},
showLogo:function(){
this.logo ^= true;
this.color = false;
this.deletebtn ^= true;
this.activerow ^= true
},
showColor:function(){
this.color ^= true;
this.logo = false;
},
activeicon:function(){
this.activeiconc ^= true;
}
}
}
I'm new to Vue but an easy way to turn your JQuery example into Vue.js is this:
Jsfiddle demo
Basically, you need to store the active element in your Vue data, and set the class based on in. You could use a v-for to render the list.
The HTML part:
<div id="app">
<ul>
<li #click="activate(1)" :class="{ active : active_el == 1 }">Link 1</li>
<li #click="activate(2)" :class="{ active : active_el == 2 }">Link 2</li>
<li #click="activate(3)" :class="{ active : active_el == 3 }">Link 3</li>
</ul>
</div>
The Vue.js:
var app = new Vue({
el:"#app",
data:{
active_el:0
},
methods:{
activate:function(el){
this.active_el = el;
}
}
});
If you want to active directly via code, VueJS allows you to bind the active of the anchor tag directly to the index of the li element so that when the vuejs variable bound to the index changes, the active also changes. Check these two links for more details
This is the crux of the solution
:class="{current:i == current}
available on the fiddle below and another post that explains in story format how anchor active can be dynamically controlled in vuejs
https://jsfiddle.net/Herteby/kpkcfcdw/
https://stackoverblow.wordpress.com/2021/04/03/how-modern-javascript-makes-click-simulation/
You can use more easily way like below instead of adding and removing active class:
<div class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div>
This paradigm provides dynamically set multiple different class for different scenarios.
This is from Vue 2 official documentation. There are many ways.

apply css based on condition angularjs

I'm alternating between two windows in angularjs using ng-click and ng-show :
<div ng-init="showTab2 = false">
<a ng-click="showTab2 = true; showTab1 = false ">#Tab1 </a>
</div>
<div ng-init="showTab2 = true">
<a ng-click="showTab1 = true; showTab2 = false">#Tab2</a>
</div>
then with ng-show they appear
Could you please tell me how I can change the color of the tab selected ?
Thank you
I'm not sure how your ng-show fits here but use ng-class to toggle css:
<a ng-class = "{'some-class': showTab1}"
ng-click="showTab1 = true; showTab2 = false">#Tab1</a>
Please check working example here: Example
JS
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.showTab = 1; //If you want to select default tab
});
HTML
<div>
<a ng-click="showTab = 1" ng-class="{'active': showTab == 1}">#Tab1 </a>
</div>
<div>
<a ng-click="showTab = 2" ng-class="{'active': showTab == 2}">#Tab2</a>
</div>
<div ng-switch="showTab">
<span ng-switch-when="1">Tab1</span>
<span ng-switch-when="2">Tab2</span>
</div>
CSS
.active {
color: red;
}

Toggle elements in sequence - show one, then hide it and show the next

Let's say we have 10 lights (we use li tag) . I want to show them one by one like this :
<h3>Light</h3>
<div ng-app ng-controller="MyCtrl">
<ul>
<li class="dot">
</li>
<li class="dot">
</li>
<li class="dot">
</li>
<li class="dot">
</li>
<li class="dot">
</li>
<li class="dot">
</li>
<li class="dot">
</li>
</ul>
</div>
First light = on
rest of theme = off .
after that
second light = on
First and other lights = off
How can i achieve this ?
Fiddle : http://jsfiddle.net/RkykR/1237/
This first example toggles through the elements manually on each click of the button.
Live demo (click here).
<div ng-app="myApp" ng-controller="MyCtrl">
<button ng-click="switch()">Switch</button>
<ul>
<li class="item" ng-class="{on: $index === selectedIdx}" class="item" ng-repeat="item in items track by $index"></li>
</ul>
</div>
.item {
background:red;
width:5px;
height:5px;
list-style:none;
margin-bottom:5px;
visibility: hidden;
}
.on {
visibility: visible;
}
angular.module('myApp', [])
.controller('MyCtrl', function($scope) {
// make array with 10 items
$scope.items = new Array(10);
$scope.selectedIdx = 0;
$scope.switch = function() {
++$scope.selectedIdx;
if ($scope.selectedIdx === $scope.items.length) {
$scope.selectedIdx = 0;
}
};
})
;
Here is another version where the lights move automatically and can be stopped and started again with the button Live demo (click here):
<div ng-app="myApp" ng-controller="MyCtrl">
<button ng-click="switch()">{{timer ? 'Stop' : 'Start'}}</button>
<ul>
<li class="item" ng-class="{on: $index === selectedIdx}" class="item" ng-repeat="item in items track by $index"></li>
</ul>
</div>
angular.module('myApp', [])
.controller('MyCtrl', function($scope, $interval) {
// make array with 10 items
$scope.items = new Array(10);
$scope.selectedIdx = null;
$scope.timer = null;
$scope.switch = function() {
$scope.timer ? stop() : start();
};
function stop() {
$interval.cancel($scope.timer);
$scope.timer = null;
}
function start() {
$scope.timer = $interval(function() {
$scope.selectedIdx = $scope.selectedIdx === null ? 0 : $scope.selectedIdx+1;
if ($scope.selectedIdx === $scope.items.length) {
$scope.selectedIdx = 0;
}
}, 500);
}
start();
})
;
You can use $timeout for lighting dots with a delay. So as you will see I use a recursive function to do...
CONTROLLER
function MyCtrl($scope, $timeout) {
$scope.lights = [0,1,2,3,4,5,6];
$scope.currentLight = 0;
function light(index){
if($scope.lights.length < index) {
light(0);
} else {
$scope.currentLight = index;
$timeout(function(){
light(++index);
}, 1000);
}
}
light(0);
}
HTML
<h3>Light</h3>
<div ng-app ng-controller="MyCtrl">
<ul ng-repeat="light in lights">
<li class="dot" ng-class="{'red': $index == currentLight}">
</li>
</ul>
</div>
Actually, this must be a small development exercise, that you are assigned to do in your class. So, I would normally not answer these kind of questions. However, since I am in a merry mood, I just updated your JSFiddle.
But do try your best to figure this out on your own. There are 1000 ways you can implement this. But below is a simple answer.
function MyCtrl($scope) {
$scope.activeLight = 3;
$scope.data = [1,2,3,4,5,6,7];
$scope.update = function(index) {
$scope.activeLight = index;
};
Click here for the updated fiddle << Please, try yourself before you just click this :) Just a friendly advice. Also, try a bit and add timer to run this automatically.

How to ng-style one element it's $index created by ng-repeat?

I have 2 directives: wa-hotspots & wa-tooltips.
On ng-mouseover of wa-hotspots it takes that $index of wa-hotspot and sets the visibility and position of wa-tooltip via ng-class:on and ng-style="tooltipCoords" by matching indexes.
Note: Since wa-hotspots & wa-tooltips share the same collection page.hotspots and therefore they share teh same index via ng-repeat
Problem:
When you hover over wa-hotspots it sets the ng-style position to ALL of the elements in wa-tooltips. I only want it ot set the proper matching index. Since the visiblity is controlled by ng-class, This doesn't really matter but it seems like it's extra overhead that could be avoid.
Therefore:
Question:
How can I make sure that my ng-style isn't styling all the wa-tooltips on hover of wa-hotspots? But rather, style only the tooltip that matches the proper shared index?
<ul id="wa-page-{{page.pageindex}}" class="wa-page-inner" ng-mouseleave="pageLeave()">
<li wa-hotspots
<map name="wa-page-hotspot-{{page.pageindex}}">
<area ng-repeat="hotspot in page.hotspots"
class="page-hotspot"
shape="{{hotspot.areashape}}"
coords="{{hotspot.coordinatetag_scaled}}"
ng-mouseover="showTooltip($index, hotspot.coordinatetag_scaled)"
ng-mouseout="hideTooltip()">
</map>
</li>
<li class="tooltip-wrapper">
<ul class="tooltip">
<li wa-tooltips
ng-repeat="hotspot in page.hotspots"
ng-class="{on: hovered.index == $index}"
ng-mouseover="hovered.active == true"
ng-mouseout="hovered.active == false"
ng-style="tooltipCoords" hotspot="hotspot">
</li>
</ul>
</li>
</ul>
tooltip:
You need to make it per item like in your case - hotspot.tooltipCoords then set that variable by index.
you can do the check inside the expression function.
Heres a fiddle
<div ng-controller="MyCtrl">
<div ng-repeat="item in items" ng-style="isChecked($index)">
name: {{item.name}}, {{item.title}}
<input type="checkbox" ng-model="item.checked" />
</div>
</div>
...
$scope.isChecked = function($index){
var color = $scope.items[$index].checked ? 'red' : 'blue';
return {color:color};
}
Instead of
ng-mouseover="hovered.active == true"
ng-mouseout="hovered.active == false"
use
ng-mouseover="hotspot.class== 'active'"
ng-mouseout="hotspot.class== ''"
and after that you can use hotspot.class in ng-class ie:
ng-class="hotspot.class"
Please see demo below:
var app = angular.module('app', []);
app.controller('homeCtrl', function($scope) {
$scope.items = [{
id: 1
}, {
id: 2
}, {
id: 3
}, {
id: 4
}]
});
.red {
background-color: yellow;
}
p {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="homeCtrl">
<p ng-repeat="i in items" ng-mouseover="i.class='red'" ng-class="i.class" ng-mouseout="i.class = ''">{{i.id}}</p>
</div>
</div>
Use the below one
<div class="col-md-4 col-xs-12 col-lg-4" ng-repeat="obj in items">
<button type="button" class="btn btn-sm pull-right" ng-class="obj.class" ng-click="obj.class='test'" >
Write a new class "test". Instead of click you can use the same in ngmouseover

Categories

Resources