Issue
I am learning to use angular, CSS(tailwind), HTML, and typescript to build a website.
I click the menu button in the navbar 3 times but why was this.name underdefined the first time the button was clicked?
How this.name gets the HTML name the first time the menu button is clicked ? image
top-bar.component.ts
import { Component,OnInit } from "@angular/core";
@Component({
selector:'app-top-bar',
templateUrl:'./top-bar.component.html'
})
export class TopBarComponent implements OnInit {
constructor() {
}
ngOnInit() {
}
menu(e:any) {
console.log(e)
console.log(e.name)
let list:any = document.querySelector('#mobile-menu');
let menu_on:any = document.querySelector('#menu-on');
let menu_off:any = document.querySelector('#menu-off');
if (e.name == "menu") {
e.name = "close";
list.classList.remove('hidden');
menu_on.classList.add('hidden');
menu_off.classList.remove('hidden');
} else {
e.name = "menu";
list.classList.add('hidden');
menu_off.classList.add('hidden');
menu_on.classList.remove('hidden');
}
}
dropdown(e:any) {
let list:any = document.querySelector('#user-dropdown');
if (e.name == 'dropdown') {
e.name = "close";
list.classList.remove('hidden');
} else {
e.name = "dropdown";
list.classList.add('hidden');
}
}
}
top-bar.component.html
<nav class="bg-gray-800">
<div class="max-w-7xl mx-auto px-6 flex items-center justify-between h-16">
<div class="flex items-center">
<div class="flex-shrink-0 px-3">
<img class="h-8 w-8" src="https://tailwindui.com/img/logos/workflow-mark-indigo-500.svg" alt="Workflow">
</div>
<div class="hidden md:block">
<a href="" class="text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium">Dashboard</a>
<a href="" class="text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium">Team</a>
<a href="" class="text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium">Projects</a>
<a href="" class="text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium">Calendar</a>
<a href="" class="text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium">Reports</a>
</div>
</div>
<div class="hidden md:block">
<div class="flex">
<div class="mx-4 flex items-center">
<button class="bg-gray-800 p1 rounded-full text-gray-400 hover:text-white focus:ring-2 focus:ring-white">
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
</svg>
</button>
</div>
<div class="flex items-center relative">
<button type="button" class="bg-gray-800 rounded-full active:ring-2 active:ring-white" (click)="dropdown(this)" name="dropdown">
<img class="h-8 w-8 rounded-full" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="">
</button>
<div id="user-dropdown" class="bg-white absolute right-0 mt-40 w-48 rounded-md shadow-lg py-1 z-10 hidden">
<a href="" class="block px-4 py-2 text-sm text-gray-700">Your Profile</a>
<a href="" class="block px-4 py-2 text-sm text-gray-700">Settings</a>
<a href="" class="block px-4 py-2 text-sm text-gray-700">Sign out</a>
</div>
</div>
</div>
</div>
<!-- button -->
<div class="md:hidden">
<!-- ################# this line ################# -->
<button type="button" class="bg-gray-800 items-center justify-center p-2 rounded-md text-gray-400 hover:text-white hover:bg-gray-700" name="menu" (click)="menu(this)">
<!-- ################################## -->
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" id='menu-on' fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M4 6h16M4 12h16M4 18h16" />
</svg>
<svg class="hidden h-6 w-6" xmlns="http://www.w3.org/2000/svg" id='menu-off' fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
</div>
<!-- mobile menu -->
<div class="md:hidden hidden" id="mobile-menu">
<div class="px-6 py-2">
<a href="#" class="text-gray-300 hover:bg-gray-700 hover:text-white block px-3 py-2 rounded-md text-base font-medium">Dashboard</a>
<a href="#" class="text-gray-300 hover:bg-gray-700 hover:text-white block px-3 py-2 rounded-md text-base font-medium">Team</a>
<a href="#" class="text-gray-300 hover:bg-gray-700 hover:text-white block px-3 py-2 rounded-md text-base font-medium">Projects</a>
<a href="#" class="text-gray-300 hover:bg-gray-700 hover:text-white block px-3 py-2 rounded-md text-base font-medium">Calendar</a>
<a href="#" class="text-gray-300 hover:bg-gray-700 hover:text-white block px-3 py-2 rounded-md text-base font-medium">Reports</a>
</div>
<div class="flex items-center px-9 border-t border-gray-700 pt-4">
<div class="flex-shrink-0">
<img class="h-10 w-10 rounded-full" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="">
</div>
<div class="mx-3">
<div class="text-base font-medium leading-none text-white">Tom Cook</div>
<div class="text-sm font-medium leading-none text-gray-400">tom@example.com</div>
</div>
<div class="ml-auto">
<button class="bg-gray-800 p1 rounded-full text-gray-400 hover:text-white">
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
</svg>
</button>
</div>
</div>
<div class="px-6 py-4">
<a href="#" class="text-gray-300 hover:bg-gray-700 hover:text-white block px-3 py-2 rounded-md text-base font-medium">Your Profile</a>
<a href="#" class="text-gray-300 hover:bg-gray-700 hover:text-white block px-3 py-2 rounded-md text-base font-medium">Setting</a>
<a href="#" class="text-gray-300 hover:bg-gray-700 hover:text-white block px-3 py-2 rounded-md text-base font-medium">Sign out</a>
</div>
</div>
</nav>
Solution
Instead of dropdown(this) in template, you need to call dropdown($event). this refers to the instance of the component here. And to retrieve the name property you need to do e.target.name in component method.
What is happening in your case is, in the first case when you log e it logs the component instance itself and you assign something like e.name="dropdown" so what you basically are doing is adding a property name to the instance of that component dynamically which is not ideal.
And the other thing, using document.querySelector is not ideal as either. You can use template reference variable using # keyword in template and get the reference to that using ViewChild in the component.
Answered By - Basu Dev Adhikari
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.