How to change the classname of next sibling in React js? - html

I am trying to toggle the classname of the clicked element's next sibling element. Here the code:
<li>
<Link onClick={(event) => event.currentTarget.nextElementSibling.classList.toggle("show")}>Nav Item A</Link>
<ul className='submenu'>
<li>
<Link to="#0" onClick={closeMenu} >Submenu Item 1</Link>
</li>
<li>
<Link to="#0" onClick={closeMenu} >Submenu Item 2</Link>
</li>
</ul>
</li>
<li>
<Link onClick={(event) => event.currentTarget.nextElementSibling.classList.toggle("show")}>Nav Item B</Link>
<ul className='submenu'>
<li>
<Link to="#0" onClick={closeMenu} >Submenu Item 3</Link>
</li>
<li>
<Link to="#0" onClick={closeMenu} >Submenu Item 4</Link>
</li>
</ul>
</li>
But in console, after it toggles to "show", many errors come and it doesn't remove "show" on next click since it stucks. Errors are like this:
Uncaught ReferenceError: process is not defined
and
DevTools failed to load source map: Could not load content for chrome-extension://gighmmpiobklfepjocnamgkkbiglidom/browser-polyfill.js.map: System error: net::ERR_FILE_NOT_FOUND
history.js:47 Uncaught TypeError: Cannot read properties of undefined (reading 'pathname')
at createPath (history.js:47:1)
at navigate (Link.js:104:1)
at onClick (Link.js:51:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:188:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:237:1)
at invokeGuardedCallback (react-dom.development.js:292:1)
at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:306:1)

You're using React the wrong way.
You need use to use state.
//Submenu.js
export const Submenu = (children) => {
const[active, setActive] = useState("false")
const toggleActive = () => setActive(!active);
return(
<div>{children}</>
);
//Main.js
<li>
<Link onClick={toggleActive} />
{active && <Submenu>....children....</Submenu>
</li>

Related

How to order a list with nav?

I am attempting to create a way of ordering a list into specific sections using a nav bar. For example, all list items displays under 'All' and then the option to refine the list into 3 other sections.
Current example
https://ibb.co/pvBV4Lf
Does anyone have any suggestions on how to achieve this? Any examples?
I'm not even sure what you would name this kind of function
<div class="nav">
<h1>All</h1>
<h1><span>Residential</span></h1>
<h1><span>Commercial</span></h1>
<h1><span>Retail</span></h1>
</div>
<ul>
<li>Granville Place</li><br>
<li>Palisade</li><br>
<li>King & Phillip</li><br>
<li>Castle Residences</li><br>
<li>Opera Residences</li><br>
<li>Brighton Collection</li><br>
<li>Carpe Group</li><br>
<li>The Lennox</li><br>
<li>South Quarter</li><br>
<li>One Barangaroo</li><br>
<li>One Queensbridge</li><br>
<li>Australia 108</li><br>
<li>Oceans Freshwater</li><br>
<li>The Pavilions</li>
</ul>
Welcome to stackoverflow,
one way to filter your list element is to append a data-* attribute to your elements and bind a javascript function on your links in the div.nav to filter the list:
window.addEventListener('DOMContentLoaded', () => {
// filter list
const filterList = e => {
e.preventDefault();
// fetch filtertype
const type = e.target.closest('a').getAttribute('data-filter-type');
// hide or display list elements
document.querySelectorAll('ul li').forEach(li => {
li.style.display = type === li.getAttribute('data-filter-type') || type === 'all' ? 'list-item' : 'none';
});
};
// bind links
document.querySelectorAll('.nav a').forEach(a => {
a.addEventListener('click', filterList)
});
});
h1 { font-size: 18px; }
<div class="nav">
<h1>All</h1>
<h1><span>Residential</span></h1>
<h1><span>Commercial</span></h1>
<h1><span>Retail</span></h1>
</div>
<ul>
<li data-filter-type="residential">Granville Place</li>
<li data-filter-type="residential">Palisade</li>
<li data-filter-type="commercial">King & Phillip</li>
<li data-filter-type="commercial">Castle Residences</li>
<li data-filter-type="residential">Opera Residences</li>
<li data-filter-type="residential">Brighton Collection</li>
<li data-filter-type="commercial">Carpe Group</li>
<li data-filter-type="retail">The Lennox</li>
<li data-filter-type="retail">South Quarter</li>
<li data-filter-type="residential">One Barangaroo</li>
<li data-filter-type="residential">One Queensbridge</li>
<li data-filter-type="retail">Australia 108</li>
<li data-filter-type="commercial">Oceans Freshwater</li>
<li data-filter-type="commercial">The Pavilions
</ul>

Cant onClick event do <li> tag React

I have a sideBar that opens when I click on a button and i have <li> items there.
I want do add an onCLick event to those items but, onClick event fires when page is loaded and when ever I click on <nav className={drawClass}> elements.
Any information is helpful, thank you.
const Sidedraw = props => {
let drawClass = "sideDraw";
if (props.show) {
drawClass = "sideDraw open";
}
return (
<nav className={drawClass}>
<ul>
<li className="matches" onclick={console.log("work work")}>
Pro matches
</li>
<li className="matches">Public mathes</li>
<li className="matches">Players</li>
<li className="matches">Teams</li>
</ul>
</nav>
);
};
As others have mentioned, the onClick should be a function reference.
Also, you will likely get a warning with the current code:
Non-interactive elements should not be assigned mouse or keyboard event listeners
You should place an interactive element (anchor, button, etc.) within the list item.
<ul>
<li className="matches">
<button onClick={() => console.log('work work')}>Pro matches</button>
</li>
<li className="matches">Public mathes</li>
<li className="matches">Players</li>
<li className="matches">Teams</li>
</ul>
You’re setting the onClick to the result of the console.log call, not the function itself. You want:
onClick={() => console.log("work work")}
Check out the docs for Handling events.
Also, you might want to move your click handler into its own function so that you can easily add it to all nav items.
const Sidedraw = props => {
let drawClass = "sideDraw";
if (props.show) {
drawClass = "sideDraw open";
}
function clickHandler(evt) {
console.log(evt.target)
}
return (
<nav className={drawClass}>
<ul>
<li className="matches" onClick={clickHandler}>Pro matches</li>
<li className="matches" onClick={clickHandler}>Public mathes</li>
<li className="matches" onClick={clickHandler}>Players</li>
<li className="matches" onClick={clickHandler}>Teams</li>
</ul>
</nav>
);
};
Stackblitz
you must add clickeventhandler to each element you want to perform some actions.
<li className="matches" onClick={handleValueChange}>Pro matches</li>
and you must add that function ie
handleValueChange = (e) => {
// ...
}

Angular 6 routerLinkActive not working

I am building a site using Angular 6 and have been stuck for a few days now on a problem. I am trying to change text color (list items) on a navbar based on the active page. I have seen examples on how to do this using AngularJS and javascript. I have come across the routerActiveLink library documentation at https://angular.io/api/router/RouterLinkActive library for Angular 5+ which seems to be a simple solution, but it is not working for me. I have tried many different examples I have seen online and none have worked. Am I missing something? Here are some code snippets:
header.component.html
<div class="navbar-collapse collapse navbar-nav pull-right" id="navbar">
<ul class="navbar-nav" style="align-items: center;">
<li class="main-links" [routerLinkActive]="['active']">
<a class="al" [routerLink]="['home']" id="home-button" href="home">Home</a>
</li>
<li class="main-links">
<a class="al" routerLink="/about" routerLinkActive="active" id="about-button" href="about">About</a>
</li>
<li class="main-links">
<a class="al" id="blog-button" href="https://tspace.web.att.com/blogs/financelive/?lang=en_us" target="_blank">Blog</a>
</li>
<li class="main-links">
<a class="al" routerLink="/albums" routerLinkActive="active" id="albums-button" href="albums">Platinum Albums</a>
</li>
<li class="main-links">
<a class="al" routerLink="/programs" routerLinkActive="active" id="programs-button" href="programs">Development Programs</a>
</li>
<li class="main-links">
<a class="al" routerLink="/contact" routerLinkActive="active" id="contact-button" href="contact">Contact Us</a>
</li>
</ul>
This is my declaration for active in header.component.less:
.active {
color: #009fdb;
font-family: font-bold;
}
When I use [routerLinkActive] with the brackets, the page does not load at all, and when I user routerLink and routerLinkActive in the a tag, it does not register at all. Are there some imports I am missing. I have tried importing router, routerlinkactive, and routerlink from #angular/core.
I purposely left both different styles of using routerLinkActive in the code example. It was not like this when I actually ran it.
I have Angular 6, bootstrap 4.1.1, jquery 3, and popperjs installed.
After further review, I have discovered that routerLinkActive works correctly on elements inside the root app-module. I created a new module for my header and footer called UiModule and the functionality is not working inside the header. Any ideas on how to get routerLinkActive to work on this module?
Try importing RouterModule into your UiModule, it won't be able to make use of that imported in your app.module.ts file
import { RouterModule } from '#angular/router';
// some other imports here
#NgModule({
imports: [
RouterModule
],
exports: [
// export UI components
],
declarations: [
// declare UI components
]
})
When I had this issue, I imported everything right. It took me days before I figured the problem was from how I structured my HTML
<li class="nav-list">
<a routerLinkActive="active"
[routerLinkActiveOptions]="{exact: true}"
routerLink="/"
href="/">
<i class="material-icons nav-link-icon">person</i>
<span class="nav-link-text">Profile</span>
</a>
</li>
The problem there was that I was watching for the .active class to appear in the li element while it had always been appearing in the anchor element. Just be sure that is not what is happening in your case.

Avoid writing multiple variable values in Angular 2 when changing class of clicked items

I hope this is a good question and I am not just missing something total simple. I am very new to Angular 2 and I am always into saving code lines and time :)
I want to change the active css class of my tabs (I dont want to use router!) and I ended up with something like this:
activeTab: string;
switchActiveTab(newTab: string) {
this.activeTab = newTab;
}
<div class="buttonLine">
<ul class="nav nav-pills">
<li role="presentation" [ngClass]="{'active': activeTab === 'Example Tab 1'}" (click)="switchActiveTab('Example Tab 1');">
<a>Example Tab 1</a>
</li>
<li role="presentation" [ngClass]="{'active': activeTab === 'Example Tab 2'}" (click)="switchActiveTab('Example Tab 2');">
<a>Example Tab 2</a>
</li>
</ul>
</div>
So I had to declare the string value "Example Tab 1" three times in my HTML. This is pretty annoying, especially when I would have 5 or more tabs here.
Is it possible to avoid reapeating the expression "Example Tab 1" three times in my HTML? Or is it possible to do this kind of stuff in a more elegant way?
Method 1
To simplify the template code, you can declare the list of tabs in the component class:
public tabList: Array<string> = ["Example Tab 1", "Example Tab 2"];
and generate the li elements with the *ngFor directive:
<li *ngFor="let tab of tabList" [ngClass]="{'active': activeTab === tab}" (click)="switchActiveTab(tab);" role="presentation">
<a>{{tab}}</a>
</li>
Method 2
To keep the code more declarative, each item could refer to itself with a template reference variable instead of using the tab caption (as illustrated in this plunker):
<div class="buttonLine">
<ul class="nav nav-pills">
<li #tab1 [ngClass]="{'active': activeTab === tab1}" (click)="switchActiveTab(tab1);" role="presentation">
<a>Example Tab 1</a>
</li>
<li #tab2 [ngClass]="{'active': activeTab === tab2}" (click)="switchActiveTab(tab2);" role="presentation">
<a>Example Tab 2</a>
</li>
</ul>
</div>
The code would be modified accordingly:
activeTab: HTMLElement;
switchActiveTab(newTab: HTMLElement) {
this.activeTab = newTab;
}

Opening jsp pages in an iframe from a drop-down menu

I'm creating an application in jsp & servlet. So I have created a home.jsp page it is a main page of an application and it contains a menu bar . When user clicks on menu item the following page should appear in my iframe and if user clicks on another menu item the selected page should appear in the same iframe.
I need a help.... The following code is creating a menu bar and menu item
<li>Master
<ul>
<li>Customer</li>
<li>Suplier</li>
<li>Item</li>
</ul>
</li>
<li>Transaction
<ul>
<li>Purchase</li>
<li>Sales</li>
</ul>
</li>
<li>Contact</li>
After menu bar I have a iframe in which I want to show a menu item.
I don't know how do i do this. please help me out
You will need to bind a function onclick of your <a> tag. Then using jQuery find the href of the <a> which is clicked, finally assign that href as src of your iframe
HTML
<li>Master
<ul>
<li>Customer</li>
<li>Suplier</li>
<li>Item</li>
</ul>
</li>
<li>Transaction
<ul>
<li>Purchase</li>
<li>Sales</li>
</ul>
</li>
<li>Contact</li>
<br />
<iframe src="" height="300" width="500"></iframe>
jQuery
$(document).ready(function () {
$('a').click(function () {
var target = $(this).attr('href');
$('iframe').attr('src', target);
return false;
});
});
Here's a working DEMO. I just changed the href of first two items as example.