Vue: Change Class In V-For-Loop On ONE Link - javascript

How can I make ONE link in the FOR-Loop active?
<ul>
<li v-for="channel in $store.state.forum.channels" v-bind:key="channel.key">
<a v-bind:class="{ active: toggle }" v-on:click="selectChannel({ key: channel.key })">{{ channel.title }}</a>
</li>
</ul>
Or:
How can I access an iteration in the for loop from outside the loop?

Related

Angular highlighting based on routerLinkActive

i want to toggle highlighting for the routerLinkActive based on the routes,
i have a dashboard component and both the dashboard menu item and labels menu item refer to the same component, i want to add class to the li items based on the route
for dashboard the route will be
http://localhost:4300/dashboard
and for the labels , the route will be
http://localhost:4300/dashboard/5d1bb53877ed8702d8a01940
Code for the menu item
<ul class="sidebar-nav">
<li [ngClass]="{ active: rlal && rlal.isActive == false }">
<a [routerLink]="['/dashboard']" (click)="loadSnippet(null)">
<mat-icon>dashboard</mat-icon>
<span>Dashboard</span>
</a>
</li>
<h3 *ngIf="labelList && labelList.length!=0">Labels</h3>
<ul class="sidebar-nav">
<li *ngFor="let label of labelList" [ngClass]="rlal && rlal.isActive ? 'active' : ''"
routerLinkActive="rlal.isActive">
<a [routerLink]="['/dashboard', label._id]" routerLinkActive #rlal="routerLinkActive"
(click)="loadSnippet(label)">
<mat-icon>label</mat-icon>
<span>{{ label.label_name }} </span>
</a>
</li>
</ul>
Routes:
{
path: "dashboard",
component: DashboardComponent,
canActivate: [LoggedInGuard]
},
{
path: "dashboard/:labelId",
component: DashboardComponent,
canActivate: [LoggedInGuard]
}
The highlighting works fine for the individual label items, but for the dashboard , the li is not getting highlighted
If you want the dashboard link to be active only if there's no route parameter, you need to add routerLinkActive and [routerLinkActiveOptions]="{exact: true}" to you dashboard li node.
Also, you don't need to set the active class via ngClass, because routerLinkActive will do that for you.
<li routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">
<a routerLink="/dashboard" (click)="loadSnippet(null)">
<mat-icon>dashboard</mat-icon>
<span>Dashboard</span>
</a>
</li>
...
<li routerLinkActive="active" *ngFor="let label of labelList">
<a [routerLink]="['/dashboard', label._id]" (click)="loadSnippet(label)">
<mat-icon>label</mat-icon>
<span>{{ label.label_name }}</span>
</a>
</li>

Loop through DOM elements with JQuery to assign a click handler

I need to loop through the DOM with JQuery, and add a click handler to multiple parent elements that contain a child that will also be given a slideToggle(). I have the logic working fine when I add the click handlers manually, but now I need to be able to dynamically do this to multiple parent elements.
Here is my HTML:
<div class="map-poi-nav">
<ul class="map-poi-nav-dropdown">
//Parent #1
<li class="sub-menu-link" id="sub-menu-link-1">
<a href="#">
<img src="https://svgshare.com/i/ADc.svg"> Activities
</a>
</li>
<li class="sub-menu">
<ul class="sub-menu-list" id="sub-menu-list-1">
<li><a><span>•</span>Golden State Park</a></li>
<li><a><span>•</span>Sunrise Oaks City Park</a></li>
</ul>
</li>
</ul>
<ul class="map-poi-nav-dropdown">
//Parent #2
<li class="sub-menu-link" id="sub-menu-link-2">
<a href="#">
<img src="https://svgshare.com/i/ADc.svg"> Dining
</a>
</li>
<li class="sub-menu">
<ul class="sub-menu-list" id="sub-menu-list-2">
<li><a><span>•</span>The Loft Grill</a></li>
<li><a><span>•</span>Fish Grill & Bar</a></li>
</ul>
</li>
</ul>
</div>
Basically, you click on .sub-menu-link to slideToggle() .sub-menu-list.
Here is the JS that I have working so far. It targets the id's manually currently, which feels gross:
$('#sub-menu-link-1').click(function() {
$('#sub-menu-list-1').slideToggle(100);
$(this).toggleClass('active-menu-link');
});
$('#sub-menu-link-2').click(function() {
$('#sub-menu-list-2').slideToggle(100);
$(this).toggleClass('active-menu-link');
});
My apologies if this is something very apparent to do in JQuery. I am not at all familiar with it, and it just so happens to be a requirement of this project.
you could simply use below code.
select all list items with class name and add listener. click will be attached to all elements
$('.sub-menu-link').click(function() {
$(this).slideToggle(100);
$(this).toggleClass('active-menu-link');
});
You already have classes, so just use them instead of the ids: use this to refer to the clicked element, .next() to get the next sibling (the li.sub-menu), and .find('.sub-menu-list') to get to the ul you want to toggle:
$('.sub-menu-link').click(function() {
const $subMenuList = $(this).next().find('.sub-menu-list');
console.log($subMenuList.text().trim());
$subMenuList.slideToggle(100);
$(this).toggleClass('active-menu-link');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="map-poi-nav">
<ul class="map-poi-nav-dropdown">
//Parent #1
<li class="sub-menu-link" id="sub-menu-link-1">
<a href="#">
<img src="https://svgshare.com/i/ADc.svg"> Activities
</a>
</li>
<li class="sub-menu">
<ul class="sub-menu-list" id="sub-menu-list-1">
<li><a><span>•</span>Golden State Park</a></li>
<li><a><span>•</span>Sunrise Oaks City Park</a></li>
</ul>
</li>
</ul>
<ul class="map-poi-nav-dropdown">
//Parent #2
<li class="sub-menu-link" id="sub-menu-link-2">
<a href="#">
<img src="https://svgshare.com/i/ADc.svg"> Dining
</a>
</li>
<li class="sub-menu">
<ul class="sub-menu-list" id="sub-menu-list-2">
<li><a><span>•</span>The Loft Grill</a></li>
<li><a><span>•</span>Fish Grill & Bar</a></li>
</ul>
</li>
</ul>
</div>
You can use jQuery's .next() like so:
$(".sub-menu-link").click(function() {
$(this).next(".sub-menu-link").slideToggle(100);
$(this).toggleClass("active-menu-link");
})
Or you can chain them and use ES6 arrow syntax to make it more concise:
$(".sub-menu-link").click(() => $(this).toggleClass("active-menu-link").next(".sub-menu-link").slideToggle(100));
You should try this if your list and link ids have similiar pattern as in the code you have shown
$('#sub-menu-link').click(function() {
var id = $(this).attr("id").replace("sub-menu-link", "")
$('#sub-menu-list-'+ id).slideToggle(100);
$(this).toggleClass('active-menu-link');
});

How do I add 'active' class dynamically on vue js 2?

My view is like this :
<ul class="nav nav-tabs nav-cat">
#foreach($countries as $country)
<li role="presentation" class="{{ $loop->first ? 'active' : '' }}">{{ ucfirst($country->name) }}</li>
#endforeach
</ul>
I want add class="active" in li tag. So, when the tab clicked, the li tag will active
How can I do it?
You can use v-for to loop through a variable in vue.js and use index to check for the first element. Use v-bind:class to apply a class dynamically. The correct solution for doing this should be:
<ul class="nav nav-tabs nav-cat">
<li v-for="(country, index) as {$countries}" role="presentation" :class="{index == 0 : 'active'}">{{ ucfirst(country.name) }}
</li>
</ul>
Using JQuery:
$("#ID").addClass("active");
Using Javascript:
document.getElementById("ID").className += " active";

how to identify specific list element field and set its displaying objects's property to true

So using *ngFor i displayed the list of name property of object, this object also has a property named isAvailable I want to set isAvalable property to toggle between true and false when I click on it, and based on isAvalible a text next to li will display is available or not
<p>Authors</p>
<ul>
<li *ngFor='let author of authors' (click)='onClick()'>
{{author.name}}
</li>
</ul>
As I understand you want this
<p>Authors</p>
<ul>
<li *ngFor='let author of authors'>
<span [hidden]='author.isAvalible'>{{author.name}}</span>
<span (click)='author.isAvalible = !author.isAvalible '>author.isAvalible</span>
</li>
</ul>
<p>Authors</p>
<ul>
<li *ngFor='let author of authors'>
<span [hidden]='author.isAvalible'>{{author.name}}</span>
<span (click)='onClick()'>author.isAvalible</span>
</li>
</ul>
onClick(value){
value=!value;
}

Give dynamic id Angular2 Binds

My JavaScript:
this.items = [
{name: 'Amsterdam1', id: '1'},
{name: 'Amsterdam2', id: '2'},
{name: 'Amsterdam3', id: '3'}
];
My HTML:
<ul>
<li *ngFor="#item of items" id={{item.id}}>
{{ item.name}}
</li>
</ul>
I want to assign a dynamic id to each element, but can't get it to work. The name is showing up but the id is not.
the way you said works, Angular 2.0.0.beta.8.
in this case you can use for example:
[id]="item.id"
[attr.id]="item.id"
id={{item.id}}
<ul>
<li *ngFor="#item of items" #elem [id]="item.id">
{{ item.name}} ID: {{elem.id}}
</li>
</ul>
<ul>
<li *ngFor="#item of items" #elem [attr.id]="item.id">
{{ item.name}} ID: {{elem.id}}
</li>
</ul>
<ul>
<li *ngFor="#item of items" #elem id={{item.id}}>
{{ item.name}} ID: {{elem.id}}
</li>
</ul>
Plunker
You can look here for more information in Template syntax.
https://angular.io/guide/cheatsheet
All the methods provided by #AngelAngel are correct but just to explain why to use [attr.id] posted as answer.
Angular by default uses property binding. To tell Angular explicitly to use attribute binding, we use instead:
<ul>
<li *ngFor="#item of items" #elem [attr.id]="item.id">
{{ item.name}} ID: {{elem.id}}
</li>
</ul>
With attr.id you have to explicitly opt in to attribute binding because attribute binding is expensive. Attributes are reflected in the DOM and changes require for example to check if CSS selectors are registered that match with this attribute set. Property binding is JS only and cheap, therefore the default.
<ul>
<li *ngFor="#item of items" attr.id={{item.name}}>
{{ item.name}}
</li>
</ul>
This should work (worked for me on angular2).
I found the answer. I can use [attr.id] tag on the 'li' tag.

Categories