Html hide button is hiding all buttons instead of one - javascript

I am trying to hide a button when clicked.
component.ts:
import { Component, Input, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '#angular/core';
import { DataService } from '../../shared/service/data.service';
import { TreeNode } from '../../shared/dto/TreeNode';
import html from './rightside.component.html';
import css from './rightside.component.css';
#Component({
selector: 'rightside-component',
template: html,
providers: [DataService],
styles: [css],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class RightSideComponent implements OnInit {
selections: string[];
#Input() treeNode: TreeNode<string>[];
hide: boolean = false;
constructor(private cd: ChangeDetectorRef) {}
ngOnInit() {
}
getSelections() : TreeNode<string>[] {
if (typeof(this.treeNode) == "undefined" || (this.treeNode) === null) {
return [];
}
return this.treeNode;
}
deselect(item: TreeNode<string>): void {
this.hide = true;
if((item.children) !== null) {
item.children.forEach(element => {
this.deselect(element);
});
}
item.selected = false;
}
}
component.html:
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<div>
<ul class="selection-list">
<li *ngFor="let item of getSelections()">
<button class="btn" (click)="deselect(item)" *ngIf="!hide">
<i class="fa fa-close"> {{ item.displayName }} </i>
</button>
</li>
</ul>
</div>
When I click on any button, all of the items are disappearing. I want just the clicked item to disappear. When I select the checkbox again, the item should re-appear. I want to implement something similar to this plunkr I found but for my data structure :
http://next.plnkr.co/edit/1Fr83XHkY0bWd9IzOwuT?p=preview&utm_source=legacy&utm_medium=worker&utm_campaign=next&preview
How can I fix this? Let me know if any other code is required.

Instead of using the common hide variable, use selected attribute in each item since you are making it false when you deselect.
<button class="btn" (click)="deselect(item)" *ngIf="item.selected">
<i class="fa fa-close"> {{ item.displayName }} </i>
</button>

Try This
hide= [];
<div>
<ul class="selection-list">
<li *ngFor="let item of getSelections();let i=index">
<button class="btn" (click)="deselect(item:
TreeNode<string>);hide[i]=!hide[i]" *ngIf="hide[i]">
<i class="fa fa-close"> {{ item.displayName }} </i>
</button>
</li>
</ul>
</div>

All your items disappears because they all share the same "hide" attribute so when you click on One of them it will change for all the items. What you should have is an attribute for each item (this attribute should be initialized at true)
component.html
<div>
<ul class="selection-list">
<li *ngFor="let item of getSelections()">
<button class="btn" (click)="deselect(item)" *ngIf="item.selected">
<i class="fa fa-close"> {{ item.displayName }} </i>
</button>
</li>
</ul>
</div>
component.ts
deselect(item: TreeNode<string>): void {
item.selected = false;
if((item.children) !== null) {
item.children.forEach(element => {
this.deselect(element);
});
}
}

Related

How to prevent angular child component’s click event from getting triggered too early?

I was trying to create a search bar component that opens after clicking on a search icon in its parent component, and closes after clicking outside of the search bar. However, after clicking the opening icon it immediately triggered a (document:click) event in the search bar component, which was closing it too early as a result.
I found a workaround for this problem by creating a ‘searchMode’ variable in the search bar component and setting a timeout (in ngOnInit) that set it to true after 100ms. However, I’m wondering, if there’s any better solution to this problem rather than setting the timeout?
(Expected results: user clicks the search icon in navigation component —> search bar component shows up in place of the search icon —> user clicks outside of the search bar component —> the search bar disappears and the search icon shows up again)
navigation.component.ts
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-navigation',
templateUrl: './navigation.component.html',
styleUrls: ['./navigation.component.scss'],
})
export class NavigationComponent implements OnInit {
searchActive = false;
constructor() {}
ngOnInit(): void {}
openSearchBar(): void {
this.searchActive = true;
}
closeSearchBar() {
this.searchActive = false;
}
}
navigation.component.html
<div class="weather-app__navigation">
<ul class="weather-app__navigation-list">
<li class="weather-app__navigation-list__item">
<i class="fas fa-bars bars-icon"></i>
</li>
<li class="weather-app__navigation-list__item">
<ng-container
*ngIf="searchActive; then searchBarContent; else searchIcon"
></ng-container>
</li>
<ng-template #searchBarContent
><app-search-bar (closeSearch)="closeSearchBar()"></app-search-bar
></ng-template>
<ng-template #searchIcon
><i class="fas fa-search search-icon" (click)="openSearchBar()"></i
></ng-template>
<li class="weather-app__navigation-list__item">
<i class="fas fa-info-circle about-icon"></i>
</li>
</ul>
</div>
search-bar.component.ts
import {
Component,
OnInit,
ElementRef,
ViewChild,
Output,
EventEmitter,
} from '#angular/core';
#Component({
selector: 'app-search-bar',
templateUrl: './search-bar.component.html',
styleUrls: ['./search-bar.component.scss'],
host: {
'(document:click)': 'onClick($event)',
},
})
export class SearchBarComponent implements OnInit {
searchMode = false;
city = '';
#ViewChild('searchBar') searchBar!: ElementRef;
#Output() closeSearch = new EventEmitter();
constructor() {}
ngOnInit(): void {
setTimeout(() => {
this.searchMode = true;
}, 100);
}
onSubmit() {
console.log('submitted');
}
onClick(event: Event) {
if (!this.searchMode) {
return;
}
if (!this.searchBar.nativeElement.contains(event.target)) {
this.closeSearch.emit();
}
}
}
search-bar.component.html
<div class="weather-app__search-bar" #searchBar>
<form class="weather-app__search-bar__form" (ngSubmit)="onSubmit()">
<input type="text" name="city" [(ngModel)]="city" placeholder="City Name" />
<input type="submit" value="Submit" class="btn" />
</form>
</div>
Use event.stopPropogation() on the click event captured on the search button, this will prevent the event from bubbling.
https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation

Modal does not open: TypeError: Cannot read property 'open' of undefined

I am trying to display a pop up that I tried to implement as modal, but I get the error:
TypeError: Cannot read property 'open' of undefined
I created the pop up as component:
import { Component, OnInit, ViewChild, ElementRef, Input } from '#angular/core';
import User from '../types/user'
#Component({
selector: 'app-modal',
templateUrl: './chat-user-profile.component.html',
styleUrls: ['./chat-user-profile.component.css']
})
export class ChatUserProfileComponent {
me: User;
ngOnInit() {}
#ViewChild('ChatUserProfile') modal: ElementRef;
open() {
this.modal.nativeElement.style.display = 'block';
}
close() {
this.modal.nativeElement.style.display = 'none';
}
}
<div #myChatUserProfile class="container">
<div class="content">
<p>Some content here...</p>
<div class="text-center mb-2">
<h4><span class="badge badge-pill">{{me?.username}}</span></h4>
</div>
<!-- <button (click)="save()">Save</button> -->
<button (click)="close()">Close</button>
</div>
</div>
Now I try to open it on clicking a button
#Component({
selector: 'app-nav',
templateUrl: './nav.component.html',
styleUrls: []
})
export class NavComponent {
isLoggedIn = false;
constructor(private amplifyService: AmplifyService, public router: Router) {
this.amplifyService.authStateChange$.subscribe(authState => {
const isLoggedIn = authState.state === 'signedIn' || authState.state === 'confirmSignIn';
if (this.isLoggedIn && !isLoggedIn) {
router.navigate(['']);
} else if (!this.isLoggedIn && isLoggedIn) {
router.navigate(['/chat']);
}
this.isLoggedIn = isLoggedIn;
});
}
public signOut() {
this.amplifyService.auth().signOut();
}
//Stuff for Profile Button
#ViewChild('app-modal') modal: ChatUserProfileComponent
openModal() {
this.modal.open();
}
}
<nav class="navbar navbar-toggleable-md navbar-inverse navbar-dark bg-dark fixed-top">
<a class="navbar-brand text-white" routerLink='/'>
<img src="../../assets/img/chat.png" width="30" height="30" class="d-inline-block align-top" alt="http://freepngimg.com/png/11489-chat-free-download-png">
<strong>ChatQL</strong>
</a>
<!--STUFF TO INTEGRATE THE POP UP-->
<app-modal #modal></app-modal>
<button (click)="openModal()">Open Modal</button>
<!------------->
<ul class="nav navbar-nav">
<li *ngIf="isLoggedIn" class="nav-item">
<button class="btn btn-primary" (click)="signOut()">Sign Out <i class="ion-log-in" data-pack="default" data-tags="sign in"></i></button>
</li>
</ul>
</nav>
I also tried adding the modal to the constructor but that gave me a No Provider error.
I am based on the chatQL project and using this as template for the pop up. I think something is wrong when initializing but I can not figure out where exactly.
In your HTML code, you have used template reference #modal
<app-modal #modal></app-modal>
So in typescript file you have to replace '#ViewChild('app-modal')' with '#ViewChild('modal')' like below
#ViewChild('modal') modal: ChatUserProfileComponent
Currently, you are using the wrong template reference so you are getting this undefined error because there is no template with reference 'app-modal'.

Error while designing oxford dictionary application

I am designing a personal dictionary application using oxford dictionary api. I am trying to display a full page view of the word after clicking the search button or clicking the word in the list of suggested words. But I am getting error "Cannot read property "pathname" of undefined "after clicking the word in the list or the search button. Also the full page view is not coming
I have written two functions called btnClick() and onListClick() in search box component to achieve this. This has been handled in the respective HTML file. Also, I have one component called fullview which gives the full view of the word.
search-box.component.ts
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { FormControl } from '#angular/forms';
import { WordService } from '../word.service';
import { ToastrService } from 'ngx-toastr';
import { filter , switchMap } from 'rxjs/operators';
#Component({
selector: 'app-search-box',
templateUrl: './search-box.component.html',
styleUrls: ['./search-box.component.css']
})
export class SearchBoxComponent implements OnInit {
public searchField : FormControl = new FormControl();
public wordList:any;
public displayList = false;
public link;
constructor(private router:Router, private http:WordService, private toastr:ToastrService) { }
ngOnInit() {
this.searchField.valueChanges
.pipe(
filter(value => !value || value.length > 2 || value !== ''),
filter(value => value !== ''),
switchMap( query => query.length > 2 ? this.http.getWord(query) : this.wordList = ' ')
)
// handling observable
.subscribe(
data => {
this.wordList = '';
this.displayList = true;
this.wordList = data;
},
// handling http error codes
error => {
console.log(error);
if(error.status === 404 || error.status === 414){
this.toastr.error('Try again with valid word');
}
else if(error.status === 403){
this.toastr.error(`Invalid credentials`,`Please enter correct details`);
}
else if(error.status === 414){
this.toastr.error(`Your word is too long`,`Please reduce the length of the word`);
}
else if(error.status === 500){
this.toastr.warning(`Something is broken`,`Please contact developer`);
}
else if(error.status === 502){
this.toastr.info(`Oxford Dictionaries API is down or being upgraded`,`Bad Gateway`);
}
else if(error.status === 503){
this.toastr.info(`Please try again later`, `Service Unavailable`);
}
else if(error.status === 504){
this.toastr.info(`Please try again later`, `Gateway timeout`);
}
}
);
}
// declared focus function for search box value
public onFocus(value)
{
if(value.length > 0)
{
this.displayList = true;
}
else
{
this.displayList = false;
}
}
// declared onListClick function for clicking word in list
public onListClick(e)
{
this.link = this.router.url.split('/');
if (this.link.indexOf('definition') > -1) {
this.displayList = false;
}
e.stopPropagation();
this.router.navigate([e.target.children['0'].pathname]); // error in this line
}
//declared button click function
public btnClick(value)
{
const letters = /^[A-Za-z ]*$/;
const regexp = value.match(letters);
if(regexp === null || value === '')
{
alert('Please enter a word');
}
else
{
this.router.navigate(['/definition',value]);
}
}
}
search-box.component.html
<div class="form-inline m-auto flex-center input-group">
<input #searchBox [formControl]="searchField" type="search" class="form-control" placeholder="Enter More than 3 Characters"
(focus)="onFocus(searchBox.value)" required>
<div class="input-group-append">
<button (click)="btnClick(searchBox.value)" class="btn-rounded btn-md btn-mdb-color m-0" type="button"
>Search
<i class="fa fa-search" aria-hidden="true"></i>
</button>
</div>
<div *ngIf="displayList">
<ul class="autocomplete-wrap mt-3" *ngIf="wordList">
<li *ngFor="let word of wordList.results " (click)="onListClick($event)">
<a [routerLink]="['/definition', word.id]">
{{word.word}}
</a>
</li>
</ul>
</div>
</div>
full-view.component.ts
import { Component, OnInit } from '#angular/core';
import { ToastrService } from 'ngx-toastr';
import { Router, ActivatedRoute } from '#angular/router';
import { WordService } from '../word.service';
import { unionBy, uniq, sortBy } from 'lodash-es';
#Component({
selector: 'app-full-view',
templateUrl: './full-view.component.html',
styleUrls: ['./full-view.component.css']
})
export class FullViewComponent implements OnInit {
public fulldata;
public antonyms = [];
public synonyms = [];
public resultObject;
public lexicalentries = [];
public varientforms = [];
public wordOrigin;
public currentWord;
public residueData = [];
public notes = [];
public show = false;
constructor(private router:Router,private route:ActivatedRoute,private http:WordService,private toastr:ToastrService) {}
ngOnInit() {
// Getting the parameter from URL
this.route.params.subscribe(routeParams => {
this.currentWord = routeParams.id;
this.http.getDefinition(routeParams.id).subscribe(
data => {
this.fulldata = data;
this.updateData(this.fulldata);
},
error => {
this.handleError(error);
}
);
});
}
public updateData(data) {
this.resultObject = data.results['0'];
this.lexicalentries = this.resultObject['lexicalEntries'];
// removing residue data from full data
this.residueData = this.lexicalentries.filter(
lexicalEntry => lexicalEntry.lexicalCategory !== 'Residual'
);
// making arrays empty for new data
this.antonyms = [];
this.synonyms = [];
this.wordOrigin = '';
this.notes = [];
this.extractData(this.residueData);
}
play(audio)
{
audio.play(); // play audio on clicking speak icon
}
public extractData(data) {
for(let singleData of data){
console.log(singleData); // printing the word
// extracting word origin data
if(singleData.entries['0'].etymologies){
this.wordOrigin = singleData.entries['0'].etymologies;
}
// extracting varient forms data
if(singleData.entries['0'].hasOwnProperty('varientforms')){
this.varientforms.push(singleData.entries['0'].varientforms['0'].text);
}
// extracting notes
if(singleData.entries['0'].hasOwnProperty('notes')){
const temp = [];
for(const note of singleData.entries['0'].notes){
temp.push(note);
}
const not = unionBy(temp, 'text');
this.notes = not;
}
}
this.getSyn();
this.toastr.success(`Definition of ${this.resultObject['word']} is Loaded`);
}
// function to get the synonyms
public getSyn() {
this.http.SynAnt(this.currentWord).subscribe(
data => {
let values = data;
this.separateData(values);
},
error => {
this.handleError(error);
}
);
}
// separate synonym and antonym into separate arrays
public separateData(values) {
const synonyms = [];
const antonyms = [];
for(const data of values.results['0'].lexicalentries){
for(const syn of data.entries['0'].senses){
if(syn.synonyms){
synonyms.push(syn.synonyms);
}
if(syn.antonyms){
antonyms.push(syn.antonyms);
}
}
}
this.separateSyn(synonyms);
this.separateAnt(antonyms);
}
// separating antonyms
public separateAnt(data) {
const temp = [];
data.map(i => {
i.map(j => {
temp.push(j.text);
});
});
this.antonyms = sortBy(uniq(temp));
}
// separating synonyms
public separateSyn(data) {
const temp = [];
data.map(i => {
i.map(j => {
temp.push(j.text);
});
});
this.synonyms = sortBy(uniq(temp));
}
// function to handle error responses
public handleError(error)
{
if(error.status === 404 || error.status === 414){
this.toastr.error('Try again with valid word');
}
else if(error.status === 403){
this.toastr.error(`Invalid credentials`,`Please enter correct details`);
}
else if(error.status === 414){
this.toastr.error(`Your word is too long`,`Please reduce the length of the word`);
}
else if(error.status === 500){
this.toastr.warning(`Something is broken`,`Please contact developer`);
}
else if(error.status === 502){
this.toastr.info(`Oxford Dictionaries API is down or being upgraded`,`Bad Gateway`);
}
else if(error.status === 503){
this.toastr.info(`Please try again later`, `Service Unavailable`);
}
else if(error.status === 504){
this.toastr.info(`Please try again later`, `Gateway timeout`);
}
}
}
full-view.component.html
<div class="mt-6 container-fluid">
<div class="mt-2 mb-3">
<app-search-box></app-search-box>
</div>
<div class="jumbotron z-depth-3" *ngIf="fullData">
<p> Definition of
<span class="text-secondary font-weight-bold">{{ resultObject.word }}</span> in English ({{ resultObject.language }}) </p>
<h1 class="h1 red-text text-capitalize"> {{ resultObject.word }} </h1>
<p *ngIf="wordOrigin" class="lead font-weight-normal">
<strong>Origin : </strong>
<span class="text-muted">{{wordOrigin}}</span>
</p>
<hr class="my-1">
<div *ngFor="let lexicalEntry of residueData">
<h4 class="blue-text h4-responsive">
<u>{{lexicalEntry.lexicalCategory}}</u> :
</h4>
<h6 class="font-weight-normal" *ngIf="lexicalEntry.pronunciations.length > 0">Pronunciations :
<span *ngFor="let pronunciations of lexicalEntry.pronunciations">
<span> {{ pronunciations.phoneticSpelling }}
<audio #audio [src]="pronunciations.audioFile"></audio>
<a (click)=play(audio)>
<i class="fa fa-volume-up" aria-hidden="true"></i>
</a>
</span>
</span>
</h6>
<p> Definitions :</p>
<span *ngFor="let sense of lexicalEntry.entries['0'].senses">
<p>
<i class="fa fa-arrow-right indigo-text" aria-hidden="true"></i> {{ sense.definitions }} </p>
</span>
<button class="btn btn-outline-secondary btn-rounded btn-sm waves-light" type="button" (click)="test.toggle()" (click)="show = !show"
mdbWavesEffect>Show More
<i class="fa ml-1" [ngClass]="show ? 'fa-minus' : 'fa-plus'" aria-hidden="true"></i>
</button>
<div class=" bg-vio p-2" [mdbCollapse]="isCollapsed" #test="bs-collapse">
<div *ngIf="lexicalEntry.entries['0'].senses">
<span>Examples :</span>
<ul *ngFor="let senses of lexicalEntry.entries['0'].senses">
<li #eg *ngFor="let example of senses.examples"> {{ example.text }} </li>
</ul>
</div>
</div>
<hr class="dropdown-divider m-2">
</div>
<div class="card pink darken-1 z-depth-2" *ngIf="varientforms.length > 0">
<div class="card-body">
<span class="white-text mb-0">
<span>Variant Forms : {{ varientforms }}</span>
</span>
</div>
</div>
<div class="card pink darken-1 z-depth-2 mt-2" *ngIf="notes.length > 0">
<div class="card-body">
<span class="white-text mb-0">
<span>Notes : </span>
<ul class="list-group">
<li class="list-group-item black-text" *ngFor="let note of notes">
<span class=" font-weight-bold blue-text">{{note.type | uppercase}} :</span>
<span> {{note.text}}</span>
</li>
</ul>
</span>
</div>
</div>
<hr class="dropdown-divider m-2" *ngIf="synonyms.length > 0">
<div class="row">
<div class="col-12" *ngIf="synonyms.length > 0">
<button class="btn btn-outline-primary btn-rounded btn-sm waves-light text-center" type="button" (click)="syn1.toggle()"
(click)="show = !show" mdbWavesEffect>
synonyms
<i class="fa ml-1" [ngClass]="show ? 'fa-minus' : 'fa-plus'" aria-hidden="true"></i>
</button>
<div class="card indigo z-depth-2" [mdbCollapse]="isCollapsed" #syn1="bs-collapse">
<div class="card-body">
<ul class="list-inline white-text mb-0">
<li class="list-inline-item" *ngFor="let syn of synonyms;let last=last"> {{syn}}{{last ? ' ' : ', '}} </li>
</ul>
</div>
</div>
</div>
<hr class="dropdown-divider m-2" *ngIf="antonyms.length > 0">
<div class="col-12" *ngIf="antonyms.length > 0">
<button class="btn btn-outline-primary btn-rounded btn-sm waves-light text-center" type="button" (click)="ant.toggle()" (click)="show = !show"
mdbWavesEffect>
antonyms
<i class="fa ml-1" [ngClass]="show ? 'fa-minus' : 'fa-plus'" aria-hidden="true"></i>
</button>
<div class="card indigo z-depth-2" [mdbCollapse]="isCollapsed" #ant="bs-collapse">
<div class="card-body">
<ul class="list-inline white-text mb-0">
<li class="list-inline-item" *ngFor="let syn of antonyms;let last=last"> {{syn}}{{last ? ' ' : ', '}} </li>
</ul>
</div>
</div>
</div>
</div>
</div>

How to disable anchor with CSS using Angular?

I'm creating 3 buttons, which should be clickable in order. So after clicking the first, the second should become active. Inspecting the elements my logic works, but the CSS is not changing. I'm new to Angular, what am I doing wrong here:
CSS:
.disabled {
cursor: not-allowed;
color: red;
}
HTML:
<div style="text-align:center">
<div>
<h6>TAG</h6>
<a class="btn btn-info" (click)="setPackageClickable($event)">TAG FELISMERESE</a>
</div>
<div>
<h6>CSOMAG</h6>
<a class="btn btn-info" ngClass="{ disabled: {{this.packageClickable}} }" (click)="setpaletteClickable($event)">CSOMAG FELISMERESE</a>
</div>
<div>
<h6>paletteA</h6>
<a class="btn btn-info" ngClass="{ disabled: {{this.paletteClickable}} }">PALETTA FELISMERESE</a>
</div>
</div>
MODULE:
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-pairing-dashboard',
templateUrl: './pairing-dashboard.component.html',
styleUrls: ['./pairing-dashboard.component.scss']
})
export class PairingDashboardComponent implements OnInit {
packageClickable: boolean;
paletteClickable: boolean;
setPackageClickable(event) {
this.packageClickable = false;
}
setpaletteClickable(event) {
this.paletteClickable = false;
}
constructor() {
this.packageClickable = true;
this.paletteClickable = true;
}
ngOnInit() {
}
}
Doc
Should be:
<div style="text-align:center">
<div>
<h6>TAG</h6>
<a class="btn btn-info" (click)="setPackageClickable($event)">TAG FELISMERESE</a>
</div>
<div>
<h6>CSOMAG</h6>
<a class="btn btn-info" [ngClass]="{'disabled': packageClickable}" (click)="setpaletteClickable($event)">CSOMAG FELISMERESE</a>
</div>
<div>
<h6>paletteA</h6>
<a class="btn btn-info" [ngClass]="{'disabled': paletteClickable}">PALETTA FELISMERESE</a>
</div>
</div>
or you can make it simpler like this
[class.disabled]="packageClickable"
Do not use this. in html:
Use
[ngClass]="{'disabled': packageClickable}"
OR
[class.disabled]="packageClickable"
you need to use [ngClass] instead of ngClass here, and you dont need this
[ngClass]="{ 'disabled': packageClickable }" and
[ngClass]="{ 'disabled': paletteClickable }"

Angular2 tree checkbox with EventEmitter

I have problems with tree view which has checkboxes on children. So, the problem is that I get nested stuff from event emitter. Please see screenshot and code.
This is my custom component where I have recursion and I just want to pass selected child or parent.
Component
import { Component, Input, EventEmitter, Output } from '#angular/core';
#Component ({
selector: 'category-tree-view',
template: `
<ul class="tree">
<li *ngFor="let category of treeData">
<label class="control control--checkbox" *ngIf="hasCheckbox">
<input type="checkbox" [checked]="category.checked" (change)="selectedCategory(category, $event)" />
<div class="control__indicator"></div>
</label>
<span *ngIf="category.subcategories?.length" (click)="toggleChildren(category)" class="toggle">+</span>
{{category.name}}
<div class="tree-actions" *ngIf="hasActions">
<button class="btn btn-link edit" (click)="editCategory(category)">
<i class="icon-admin-edit"></i>
</button>
<button class="btn btn-link delete" (click)="deleteCategory(category)">
<i class="icon-admin-close"></i>
</button>
</div>
<category-tree-view [treeData]="category.subcategories" *ngIf="category.visible" (edit)="editCategory($event)" (delete)="deleteCategory($event)" [hasCheckbox]="hasCheckbox" (selected)="selectedCategory($event)" [hasActions]="hasActions"></category-tree-view>
</li>
</ul>
`
})
export class ProductCategoryTreeView {
#Input() treeData: any[];
#Input() hasCheckbox: boolean = false;
#Input() hasActions: boolean = false;
#Output() edit = new EventEmitter();
#Output() delete = new EventEmitter();
#Output() selected = new EventEmitter();
constructor() {}
toggleChildren(node: any) {
node.visible = !node.visible;
}
editCategory(category){
this.edit.emit(category);
}
deleteCategory(category) {
this.delete.emit(category);
}
selectedCategory(category, event) {
this.selected.emit({category, event});
}
}
This is what I have in my other html page, which is the different component, in this case, product-form.component.html
<category-tree-view [treeData]="categories" (edit)="editCategory($event)" (delete)="deleteCategory($event)" (selected)="selectCategory($event)" [hasCheckbox]="true"></category-tree-view>
And also I just have method in component product-form.component.ts
selectCategory(cat, event) {
console.log(cat, event);
}
Here's the screenshot what I got when I console log that data.
Can you please try with below code and check if it works or not?
selectedCategory(category, event) {
this.selected.emit(event);
}

Categories