How to apply css class to single items in ngFor - html

I have two *ngFors in which the first one displays the text names of venues and uses (mouseenter) and (mouseleave) to call functions that change the color of pins on a map below the names. The second *ngFor is for displaying map pins for each venue. The maps pin color is controlled by the [iconUrl]="iconColor" in the ngfor.
The problem is that when I hover over the text of the venue name, every map pin changes color, instead of just the single pin that I want to change.
What would be the best way to go about this?
HTML:
<body>
<div>
<div align="center">
<div *ngFor="let venue of mapVenues">
<div class="venue-name" (mouseenter)="markerHovered()" (mouseleave)="markerNotHovered()">
{{ venue }}
</div>
</div>
</div>
<agm-map [latitude]="lat" [longitude]="lng" [zoom]="11" (mapready)="markerAnimation()">
<agm-marker *ngFor='let show of usersShows'
[latitude]="show.venue.lat"
[longitude]="show.venue.lng"
[animation]="animation"
[iconUrl]="iconColor"
></agm-marker>
</agm-map>
</div>
</body>
Typescript:
markerHovered() {
this.hovered = true;
this.iconColor = 'https://chart.apis.google.com/chart?chst=d_map_pin_letter_withshadow&chld=%E2%80%A2|4286f4';
}
markerNotHovered() {
this.hovered = false;
this.iconColor = 'https://chart.apis.google.com/chart?chst=d_map_pin_letter_withshadow&chld=%E2%80%A2|FF0000';
}

You can try [ngClass]:
<div [ngClass]="hovered?'hovered-venue':'venue-name'" (mouseenter)="markerHovered()" (mouseleave)="markerNotHovered()">
{{ venue }}
</div>
And define your style for class 'hovered-venue' as you like, ex:
.hovered-venue {
color: red;
}

You need to add hovered property to usersShows object, and then use condition to hovered object to apply url.
<agm-marker *ngFor='let show of usersShows'
[latitude]="show.venue.lat"
[longitude]="show.venue.lng"
[animation]="animation"
[iconUrl]="show.hovered ? iconColor : ''"
></agm-marker>

Related

Angular - css style changes in the list of objects in *ngFor

I have two components, parent:
<ng-container *ngIf="itemList != null">
<div *ngFor="let item of itemList">
<component-item [componentItem]="item"></component-item>
</div>
</ng-container>
and child (component-item):
<div class="row myClass" [ngClass]="{'selected': isSelected }" (click)="method()">
...
</div>
As a result I have list of items. I have two css styles: default and "selected". I would like to change styles of items after clicking on them like: when I click on the first item it should change to "selected" and then after clicking second item it should change to "selected" and the first one return to the default. My variable "isSelected" is a boolean type and I change its value on "true" in "method()". How can I change its value on "false" when I select another item from the list?
Try like this, it may work
In component.ts File
cssEnabled:any="";
private method(itemName:string)
{
this.cssEnabled=itemName;
}
In compontent.html :
<div class="row myClass" [ngClass]="{'selected': componentItem==cssEnabled}" (click)="method(componentItem)">
...
</div>

How to display custom DOM element in particular position of agm-map

I'm going to display custom dom into agm-map in my angular6 project.
When I use agm-marker I can only display specific icon and label.
What I want to display looks like:
.user-location i {
opacity: 0.7;
}
.user-location img {
border-radious: 100%;
}
...
<a class="user-location">
<i class="pin-icon"></i>
<figure>
<img src="../../assets/layouts/layout/img/new-icon.png" alt="" />
</figure>
...
</a>
I have changed the marker the following way:
<agm-map [latitude]="lat" [longitude]="lng" [styles]="mapStyle === 'dark' ? styleDark : styleLight">
<div *ngFor="let marker of markers;">
<agm-marker [iconUrl]="'/assets/markers/'+marker.type+'.png'" [latitude]="marker.lat" [longitude]="marker.long" (markerClick)='openMarkerInfo(markerInfo, marker)'>
</agm-marker>
</div>
</agm-map>
If you ever want to customize the map too you can do the following:
[styles]="mapStyle === 'dark' ? styleDark : styleLight"
in your ts file you will have all the properties. To learn more about how to customize a map with icons and colors in the map take a look to this repo:
https://github.com/devpato/SOSmap

How to get innerHTML of this dynamic div in my Angular 2 application?

<div *ngFor="let field of page.fields">
<div #ce class="infills richtextbox textarea {{field.groupid}}" contentEditable="true"
*ngIf="(field.fieldtype=='textarea' && field.isexpandable=='true')"
id="{{field.id}}" name="{{field.id}}"
[ngStyle]="{'position':'absolute','top':field.y+'px','left':field.x+'px',
'font-size':'12px','font-family':'Courier New','height':field.height+'px',
'width':field.width+'px','background':'#EEE'}"
[(ngModel)]="field.value" title="{{field.description}}"
(dblclick)="openFullRTE(field.id)" (focusout)="getHTMLContent()">
</div>
</div>
In ts part,
getHTMLContent() {
console.log(this.ce.nativeElement.innerHTML);
}
When I write anything in first div, respective innerHTML is consoled properly. Then if I write something in second div, console gets overridden by data of first div. Please suggest a way to get HTML content of individual fields and to console them separately.
<div *ngFor="let field of page.fields; let i=index">
<div #ce class="infills ri...
(focusout)="getHTMLContent(i)"
class MyComponent {
#ViewChildren('ce') ces:QueryList<ElementRef>;
constructor(private elRef:ElementRef) {}
getHtmlContent(i) {
console.log(this.ces.toArray()[i].nativeElement.innerHTML);
}
}
The easiest way:
<div *ngFor="let field of page.fields">
<div #ce ... (focusout)="getHTMLContent(ce)">
</div>
</div>
getHTMLContent(element) {
console.log(element.innerHTML);
}

How to select a <p> tag in HTML/Angular

I am currently trying to implement a selectable listview but am running into a few issues. I am trying to use ui-listview, an angular add-on of sorts, but want to (1) highlight the < p > tag that the user clicks on, and (2) get this string into an angular variable. Is there a way to do this, or a different implementation of a listview that allows this?
<div class="panel-body" padding:0>
<div class="ui-list-view-striped" ui-list-view="contact in contacts | orderBy:'Project' | filter:search">
<p class="name">{{ contact.ListView }}</p>
</div>
</div>
Can you modify the objects in your contacts list? If so, you can add a selected boolean attribute to them that can be fired by an ng-click event over every <p> element. Then you can use that selected attribute in an ng-class to set a style marking the element as selected. Ej:
html:
<div class="panel-body" padding:0>
<div class="ui-list-view-striped" ui-list-view="contact in contacts | orderBy:'Project' | filter:search">
<p class="name" ng-class="{'css-selected': contact.selected}">{{ contact.ListView }}</p>
</div>
</div>
javascript:
in your controller:
yourController.markSelected = function(contact) {
contacts.map(function(c) { c.selected = false; });
contact.selected = true;
}
css:
.css-selected {
/* your style for the selected element */
}

Use ng-model to add class to all previous childrens Angular JS

Here is my html code:
<div ng-repeat="(key, a) in items" data-id="{{ Id }}" class="item" id="{{Key}}" ng-click="item($event, key)">
<div class="bubble></div>
<p>
<span> {{ description }}</span>
</p>
</div>
This is the list of items. When we click on the item in the list - all previous elements are set as active (add class).
Here is how it's done:
$scope.item = function(event, key) {
var current;
if ( $(event.target).hasClass('bubble')){
current = $(event.target).closest('#'+ Key);
changeItem(current);
}
function changeItem(current){
$(current).addClass('active');
$(current).prevAll().addClass('active');
$(current).nextAll().removeClass('active');
}
};
Is it possible to use ng-model or something else to set the active value by default form json file? Mean, in json - we have item 3 - marked as active, so how could I add this value to the $scope.item as current? or probably use ng-model?
I have not tried it, but something like this should work.Assuming that the class has to be applied to ng-repeat div. Change your ng-repeat div to:
<div ng-repeat="(key, a) in items" data-id="{{ Id }}" class="item" id="{{Key}}" ng-click="markSelected($index)" ng-class="{'active':selectedIndex<$index}">
</div>
The ng-click call a method markSelected($index) on the controller that sets the currently selected item index. The ng-class uses the current index ($index) and the selectedIndex to determine what class to apply.
The final task is to implement the function which looks like:
$scope.markSelected=function(index) {
$scope.selectedIndex=index;
}
You should stop using jquery and start to think in a more angular way.
There is a directive ng-class that is used to add or remove classes
You can find more information here : https://docs.angularjs.org/api/ng/directive/ngClass
<div ng-repeat="(key, a) in items" data-id="{{ Id }}" class="item" id="{{Key}}" ng-click="item(key)">
<div ng-class="{active : a.active, inactive : a.inactive}"></div>
<p>
<span> {{ description }}</span>
</p>
</div>
$scope.item = function(key){
$scope.items[key].active = true;
$scope.items[key].inactive = false;
}