Changing icon images with the switch statement - javascript

Depending on a notification type, I need to change icon image of this notification.
There are three types of notifications.
notifications_type:
answer_created
user_subscribed
answer_selected
Icon image is placed inside i tag in a span tag. I don't want to use any conditions, instead I want to do this with switch statement. How am I supposed to do this?
Here is my code:
<div class="media g-mb-20">
<span v-bind="changeIcon" class="u-icon-v3 g-rounded-50x g-mt-2 g-mr-15 g-height-40 g-width-40 g-bg-gray-light-v5">
<i class="icon-bubble g-font-size-18 g-color-gray-light-v1"></i>
</span>
<a href="#"
class="media-body g-brd-around g-brd-gray-light-v4 g-py-10 g-px-15 g-bg-gray-light-v5--hover u-link-v5 g-rounded-3">
<p class="mb-0 g-font-size-16 g-color-gray-dark-v3">
<span class="g-font-stag-medium">{{ item.message }}</span>
</p>
</a>
</div>
I suppose that I need to bind a function with the help of a v-bind directive to a span with an icon. Then I would add the switch statement to this function.

You don't need to bind anything, it's just a matter of using the right classes. define your icon as such:
<i class="g-font-size-18 g-color-gray-light-v1" :class="switchIcon"></i>
then you define a new computed property:
computed: {
switchIcon () {
switch (this.notification_type) {
case 'some_type':
return 'icon-bubble'
default:
return ''
}
}
}
this way, when notification_type is equal to some_type, your icon will render as:
<i class="icon-bubble g-font-size-18 g-color-gray-light-v1"></i>

Related

How to set a class name dependant on another attribute of the same element in Svelte?

I want to set a conditional class based on an attribute of the same element so that I can stay dry. At first I got this:
<div class="hidden md:flex items-center space-x-3">
Farm
LeaderBoard
WafBox
Buy
Info
</div>
Now I would like this:
<div class="hidden md:flex items-center space-x-3">
Farm
LeaderBoard
WafBox
Buy
Info
</div>
Then I would simply have to check the attribute of href in my function isActive. But here this does not seem to have the right informations inside. Is there a way to do it ? It would clean my code a lot
Edit: isActive() would look like this:
<script>
function isActive(element) {
return 'Active' if (currentPageName == element.attr('href'))
}
</script>
One problem with your approach is that both in
LeaderBoard
and the proposed answer using the class:directive
<a href="#Index" class:active-link={isActive('Index')}>Index</a>
is that the function will only run once, at the first render and then never re-execute, not even when currentPageName changes.
The most obvious, straight solution would be to simply ditch the function call and use the class:directive like this:
<a href="#Index" class:active-link={currentPageName == 'Index'}>Index</a>
this will make sure the classes change as currentPageName changes.
When declaring the function with the arrow syntax and making it reactive by adding $: it looks like alternatively to using the class:directive (which checks if value is truthy/falsy) the classname could be directly set inside the class="" attribute as well
A REPL
<script>
let currentPageName = 'Index'
$: isActive = (linkText) => {
if (linkText === currentPageName) return 'active-link'
// else if (...) return 'other-class-name' // possible class name switch
else return ''
}
</script>
<div class="">
Index
</div>
<div class="">
Leaderboard
</div>
<br>
<button on:click={() => currentPageName = 'Leaderboard'}>change currentPageName</button>
<style>
.active-link {
color: purple;
}
</style>

How I can set focus on the element when I am setting it to content editable in Angular 6?

I am using the contentEditable attribute of Angular 6 for editing the content of the element (in the ngFor)
How I can set focus on a tag element when it's contentEditable attribute is true?
<div class="tag" *ngFor="let tag of tags">
<span [contentEditable]="underUpdateTagId==tag.id" [textContent]="tag.title
(input)="tag.title=$event.target.textContent">
</span>
<span *ngIf="underUpdateTagId!=tag.id" class="edit text-info" (click)="beforeEdit(tag)">
<i class="fas fa-pencil-alt"></i>
</span>
<span *ngIf="underUpdateTagId==tag.id" class="update text-success" (click)="editTag(tag)">
<i class="fas fa-check save"></i>
</span>
<span class="delete text-danger" (click)="delete(tag)">
<i class="fas fa-trash-alt"></i>
</span>
</div>
The user interface:
We can use ViewChildren to get a hold of all the spans, by placing a template reference, pick up the span that is selected and set the focus to the element.
So I suggest adding template reference and in your beforeEdit() pass the index of the tag (we get it from ngFor), so we can refer to it when we want to place the focus on the field:
<!-- add template reference in below span tag --->
<span [contentEditable]="underUpdateTagId==tag.id" ... #spans>
<!-- pass index as from ngFor iteration to beforeEdit() -->
<span *ngIf="underUpdateTagId!=tag.id" class="edit text-info" (click)="beforeEdit(tag, i)">
<!-- more code --->
In the component we refer to spans, the template reference. And when clicked upon specify that the span with the index passed should be focused:
#ViewChildren("spans") spans: QueryList<ElementRef>;
underUpdateTagId = null;
beforeEdit(tag, index) {
this.underUpdateTagId = tag.id;
// wait a tick
setTimeout(() => {
this.spans.toArray()[index].nativeElement.focus();
});
}
STACKBLITZ
PS, this sets the focus in the beginning, you might want it at the end, maybe this question can help you with it if that is the case: Use JavaScript to place cursor at end of text in text input element

How do I toggle a class in Angular

I have a button that I want to be able to toggle a class on a div to hide and show the div how would I do that in Angular?
HTML
<div id="chatsidebar">
<app-chatsidebar></app-chatsidebar>
</div>
<div>
<button type="button" id="sidebarCollapse" class="btn btn-info" (click)="togglesideBar()">
<i class="glyphicon glyphicon-align-right"></i>
Toggle Sidebar
</button>
</div>
I want to add the class "active" onto the #chatsidebar div
app.component.ts
togglesideBar() {
}
Thanks
I'm answering this part of your question:
I want to add the class "active" onto the #chatsidebar div
To do it, you can use NgClass. NgClass allows you to add or remove any class to or from an element based on the given condition. Your code will looks something like this:
HTML
<div id="chatsidebar" [ngClass]="{'active': isSideBarActive}"> <!-- this ngClass will add or remove `active` class based on the `isSideBarActive` value -->
<app-chatsidebar></app-chatsidebar>
</div>
<div>
<button type="button" id="sidebarCollapse" class="btn btn-info" (click)="togglesideBar()">
<i class="glyphicon glyphicon-align-right"></i>
Toggle Sidebar
</button>
</div>
Component
isSideBarActive: boolean = true; // initial value can be set to either `false` or `true`, depends on our need
togglesideBar() {
this.isSideBarActive = !this.isSideBarActive;
}
HTML
<div id="chatsidebar" *ngIf="status">
<app-chatsidebar></app-chatsidebar>
</div>
<div>
<button type="button" id="sidebarCollapse" class="btn btn-info" (click)="togglesideBar()">
<i class="glyphicon glyphicon-align-right"></i>
Toggle Sidebar
</button>
</div>
app.component.ts:
status:boolean=true;
togglesideBar() {
if(this.status == true) this.status=false;
else this.status = true;
}
Demo:
https://plnkr.co/edit/fNoXWhUhMaUoeMihbGYd?p=preview
you can try below.
<div id="chatsidebar" class="{{activeClass}}"> ... </div>
and on your component define a property and set the class value on toggle function
// On Component
activeClass : string = "";
...
togglesideBar() {
this.activeClass = 'active'
}
it shall work, but may not the ideal solution.
Assuming you have a class named hide:
<div [class.hide]="hide">
<app-chatsidebar></app-chatsidebar>
</div>
<div>
<button type="button" class="btn btn-info" (click)="togglesideBar()">
<i class="glyphicon glyphicon-align-right"></i>
Toggle Sidebar
</button>
</div>
togglesideBar() { this.hide = !this.hide; }
This will hide the element in question, while leaving it in the DOM. The other solutions using *ngIf will add and remove the element to and from the DOM. There are subtle reasons in specific cases to prefer one over the other, well described in the on-line documentation you have already read. In this case, it doesn't really matter.
The [class.className]=boolean format is just one of several ways to control classes in Angular. For instance, you could also have said:
[ngClass]="{'hide': hide}"
This is slightly more flexible because you can add/remove multiple classes at once.
Since you are using glyphicons, you are probably using Bootstrap, so you most likely already have the hide class defined.
As an aside, you rarely need IDs, and using them is pretty much of an anti-pattern in Angular.
Take a variable in your component something like
isShowChatSidebar:boolean=true;
then modify your method and html
togglesideBar() {
this.isShowChatSidebar=!this.isShowChatSidebar
}
<div id="chatsidebar" [ngClass]="{'active': isShowChatSidebar}">>
<app-chatsidebar></app-chatsidebar>
</div>

Hide tooltip if empty in md-tooltip

I have following tooltip:
<i ng-click="createDetails(item)" class="fa fa-info-circle">
<md-tooltip md-direction="top">
{{item.details}}
</md-tooltip>
</i>
$scope.createDetails = function (item) {
item["details"] = "example";
}
If i click, details appears (tooltip is not centered, another problem but OK for now)
The main problem is: I want to hide the tooltip if there is no information, so when item.details == undefined
I tried ng-show, md-visible, ng-class etc. Is there a solution for these problem(s)?
You can use ng-if to evaluate content of item.details variable to decide whether <md-tooltip> element is created or not.
<i ng-click="createDetails(item)" class="fa fa-info-circle">
<md-tooltip md-direction="top" ng-if="item.details">
{{item.details}}
</md-tooltip>
</i>

Show/hide multiple children classes for an individual parent click (Jquery)

I'm fairly new to Javascript/Jquery and I'm trying to hide multiple children/adjacent classes when a specific parent class is clicked.
Here's my HTML
<div class="container">
<div class="row">
<div class ="col-md-2 pov_icon">
<div class="pov_icon_small">
<i class="fa fa-clock-o"></i>
</div>
<div class="pov_title_small">
MEASURE
</div>
</div>
<div class ="col-md-2 pov_icon">
<div class="pov_icon_large">
<i class="fa fa-map-marker"></i>
</div>
<div class="pov_title_large">
MEASURE
</div>
</div>
<div class ="col-md-2 pov_icon">
<div class="pov_icon_small">
<i class="fa fa-commenting"></i>
</div>
<div class="pov_title_small">
MEASURE
</div>
</div>
</div>
</div>
What I'm aiming to do is: When a user clicks one of the two smaller icons shown (pov_icon_small), for that individual icon: the classes pov_icon_small and pov_title_small will change to pov_icon_large and pov_title_large respectively. In the same time, I want the other 'large' icon and 'title' to revert back to the 'small' state
I've started calling some Javascript but I don't think I'm headed the right way:
$('.pov_icon_small').on('click', function (e) {
$(this).toggleClass("pov_icon_large");
});
Would anyone be willing to point me to the right direction?
To use individual click
$('.pov_icon_small , .pov_icon_large').on('click', function (e) {
$('.pov_icon_large').not($(this)).removeClass('pov_icon_large').addClass('pov_icon_small');
$(this).toggleClass("pov_icon_small").toggleClass("pov_icon_large");
});
and for title the same way
$('.pov_title_small , .pov_title_large').on('click', function (e) {
$('.pov_title_large').not($(this)).removeClass('pov_title_large').addClass('pov_title_small');
$(this).toggleClass("pov_title_small").toggleClass("pov_title_large");
});
Working Demo
To run both action on icon click use this
$('.pov_icon_small , .pov_icon_large').on('click', function () {
$('.pov_icon_large').not($(this)).removeClass('pov_icon_large').addClass('pov_icon_small');
$('.pov_title_large').not($(this).next('div[class^="pov_title_"]')).removeClass('pov_title_large').addClass('pov_title_small');
$(this).toggleClass("pov_icon_small").toggleClass("pov_icon_large");
$(this).next('div[class^="pov_title_"]').toggleClass("pov_title_small").toggleClass("pov_title_large");
});
Working Demo
Note: be sure to include Jquery
You can add a common class icon for the icon div and title for the title div and following code will work,
$(".pov_icon_small").on('click',function(){
$(this).parent().siblings().children('div').each(function(value){
if($(this).hasClass('icon'))
$(this).addClass('pov_icon_small').removeClass('pov_icon_large');
else if($(this).hasClass('title'))
$(this).addClass('pov_title_small').removeClass('pov_title_large');
});
$(this).addClass('pov_icon_large').removeClass('pov_icon_small');
$(this).siblings('.title').addClass('pov_title_large').removeClass('pov_title_small');
});
Here as you can see, I am first getting parent of the icon clicked i.e. Your pav_icon div now I am changing for all the siblings now each div in the sibling. If it is Iicon changing icon classes as required if title changing title classes.

Categories