I want add active class to click element but it is toogle. How can i fixed it?
const PodcastTab = () => {
const [tabOpened, setTabOpened] = useState(false);
return <div>
<div>
<span className={classNames('my-podcast',{'active':tabOpened})} onClick={()=>{setTabOpened(!tabOpened)}}>My Podcast</span>
<span className={classNames('podcasts-stats',{'active':!tabOpened})} onClick={()=>{setTabOpened(!tabOpened)}}>Podcast's Stats</span>
<div className="my-podcast-tab">
<Podcast />
</div>
<div className="podcasts-stats-tab">
<Podcast imgURL="https://i.picsum.photos/id/144/75/75.jpg?hmac=9kweqWXv0sL19dFj1CaMKxbH3kQMIuFFbHy2hWhKJ4w" status="x" title="y"/>
</div>
</div>
</div>;
}
You can use the following className:
className={classNames('podcasts-stats',{tabOpened ? 'active' : ''})}
Related
I am creating a Next js site mcqs and answer.
Initially only questions are rendered with the title and options.
There is a button to show the answer of given question but when button is clicked it is changing the state of all elements in the map function instead of element that is clicked.
export default function Chapter({ chapter }) {
const [right, setRight] = useState(false)
function handleOnClick() {
setRight(!right)
}
<main className='main_q'>
<h1>{chapter.items[0].name}</h1>
{chapter.items[0].questions.items.map((question, index) => {
return (
<div key={question.id} className='question_container'>
<div className='question_q_t'>
<div className='question_q'>Q</div>
<div className='question_t'>
<Markdown>{question.title}</Markdown>
</div>
</div>
<div className='option_container'>
<div className='option_a_o'>
<div className='option_a'>A</div>
<div className='option_o'>
<Markdown>{question.optionA}</Markdown>
</div>
</div>
<div className='option_a_o'>
<div className='option_a'>B</div>
<div className='option_o'>
<Markdown>{question.optionB}</Markdown>
</div>
</div>
<div className='option_a_o'>
<div className='option_a'>C</div>
<div className='option_o'>
<Markdown>{question.optionC}</Markdown>
</div>
</div>
<div className='option_a_o'>
<div className='option_a'>D</div>
<div className='option_o'>
<Markdown>{question.optionD}</Markdown>
</div>
</div>
</div>
<a
className='solution_link'
target='_blank'
href={`/${question.chapter.subject.category.slug}/${question.chapter.subject.slug}/${question.chapter.slug}/${question.id}`}
>
See Solution
</a>
<button onClick={handleOnClick}>Answer</button>
{right && <div>{question.rightAnswer}</div>}
</div>
)
})}
</main>
}
Put each question div into its own component, and make a right state in that component:
const Question = ({ question }) => {
const [right, setRight] = useState(false)
return (
<div key={question.id} className='question_container'>
// etc
Or make an array of right states in the parent:
export default function Chapter({ chapter }) {
const qs = chapter.items[0].questions.items;
const [rights, setRights] = useState(qs.map(q => false));
const makeHandleClick = (i) => {
setRights(
rights.map((r, j) => j === i ? r : !r)
);
};
// ...
<button onClick={makeHandleClick(i)}>Answer</button>
{rights[i] && <div>{question.rightAnswer}</div>}
this is my code i'm trying to add a class on click to a clicked div but i have more than 1 div have the same classname so when i click to any
div the toggle class added to all divs not the one which i clicked what i want to know how can i specify the div which i want to add toggle class to it
Code:
const [isActive, setActive] = useState(false);
const toggleClass = () => {
setActive(!isActive)
console.log('sad')
}
return (
<div className="command_wrapper">
<div className="command_list">
{
Commands.map((item, index) => {
return (
<div className="command" >
<div className="command_face" onClick={toggleClass}>
<h1>{item.Command}</h1>
<p>{item.Description}</p>
</div>
<div className={isActive ? "command_body" : "disapper"}>
<div className="command_usage">
<h1>Usage</h1>
<p>{item.Usage}</p>
</div>
<div className="command_required">
<h1>Required Permissions</h1>
<p>{item.premissions}</p>
</div>
</div>
</div>
)
})
}
</div>
</div>
```
You can pass the item inside toggle function and verify if item passed is activated or just save the item clicked.
const [itemActive, setItemActive] = useState();
const toggleClass = (item) => {
setItemActive(item)
}
return (
<div className="command_wrapper">
<div className="command_list">
{
Commands.map((item, index) => {
return (
<div className="command" >
<div className="command_face" onClick={() => toggleClass(item)}>
<h1>{item.Command}</h1>
<p>{item.Description}</p>
</div>
<div className={item === itemActive ? "command_body" : "disapper"}>
<div className="command_usage">
<h1>Usage</h1>
<p>{item.Usage}</p>
</div>
<div className="command_required">
<h1>Required Permissions</h1>
<p>{item.premissions}</p>
</div>
</div>
</div>
)
})
}
</div>
</div>
```
If item has any unique property, you can save just then, like an ID or name. I think it will be better.
/*const [isActive, setActive] = useState(false);
const toggleClass = () => {
setActive(!isActive)
console.log('sad')
}*/
function handleClick(el){
//toggle the class which indicates selection ex. 'active'
el.classList.toggle('active');
//other stuff todo
}
return (
<div className="command_wrapper">
<div className="command_list">
{
Commands.map((item, index) => {
return (
<div className="command" >
//destruct event objet{event.target}
<div onClick={({target})=>handleClick(target)}>
<h1>{item.Command}</h1>
<p>{item.Description}</p>
</div>
....
...
</div>
)
})
}
</div>
</div>
Here's what I've have so far - Full working view https://codesandbox.io/s/hungry-elbakyan-v3h96
Accordion component:
const Accordion = ({ data }) => {
return (
<div className={"wrapper"}>
<ul className={"accordionList"}>
{data.map((item) => {
return (
<li className={"accordionListItem"} key={item.title}>
<AccordionItem {...item} />
</li>
);
})}
</ul>
</div>
);
};
const AccordionItem = ({ content, title }) => {
const [state, setState] = useState({
isOpened: false
});
return (
<div
className={cn("accordionItem", state.isOpened && "opened")}
onClick={() => setState({ isOpened: !state.isOpened })}
>
<div className={"lineItem"}>
<h3 className={"title"}>{title}</h3>
<span className={"icon"} />
</div>
<div className={"inner"}>
<div className={"content"}>
<p className={"paragraph"}>{content}</p>
</div>
</div>
</div>
);
};
When I click on the accordion item nothing happens. I can see the content appears in inspect and the state changes as expected but it doesn't slide down. Did I miss something in my css or component?
Here is what I was able to achieve. You may not like it completely(animations). But things seems sorted
https://codesandbox.io/s/relaxed-babbage-2zt4f?file=/src/styles.css
props name was not right for accordion body
and styles need to be changes once the accordion is in open state.
You need to add or remove the className inner when state.isOpen so you can see your content
So I've got two input boxes that I want to be able to toggle (hide) between by clicking on them. They populate a table below them. I know it's not difficult but can't seem to make it happen easily.
It's all happening in the one component. Something like this:
<p id="toggle">
<span> Employer </span>
<span> Location </span>
</p>
<div id="left">..input box 1</div>
<div id="right">..input box 2</div>
What's the function I'd need to implement it? Thanks!
Your issue is indeed not very difficult.
Here is a solution with a function component:
const MyComponent = (props) => {
const [selected, setSelected] = useState(0)
return (
<div>
<p id="toggle">
<span onClick={() => setSelected(0)}> Employer </span>
<span onClick={() => setSelected(1)}> Location </span>
</p>
{(selected === 0) && <div id="left"> ..input box 1</div>}
{(selected === 1) && <div id="right"> ..input box 2</div>}
</div>
)
}
Here is a solution with a class component:
class MyComponent extends React.Component {
constructor(props) {
super(props)
this.state = {
selected: 0
}
}
render() {
return (
<div>
<p id="toggle">
<span onClick={() => this.setState({ selected: 0 })}> Employer </span>
<span onClick={() => this.setState({ selected: 1 })}> Location </span>
</p>
{(selected === 0) && <div id="left"> ..input box 1</div>}
{(selected === 1) && <div id="right"> ..input box 2</div>}
</div>
)
}
}
If I'm understanding you're wanting to toggle the display of the div elemements on clicking the span elements (why not use anchors they're better suited). Below is a simple way to implement this,
(() =>
{
const togglers = document.querySelectorAll('#toggle span');
const togglees = document.querySelector('#toggle').parentNode.querySelectorAll('div');
togglers.forEach((toggler, index) =>
{
toggler.addEventListener('click', () =>
{
togglees.forEach(togglee => togglee.style.display = 'none');
togglees[index].style.display = 'block';
}, true);
});
})();
/* HIDE THOSE TOGGLEES BY DEFAULT CHANGE THIS!!!!!!!! */
div > div
{
display: none;
}
<div>
<p id="toggle">
<span> Employer </span>
<span> Location </span>
</p>
<div id="left"> ..input box 1</div>
<div id="right"> ..input box 2</div>
</div>
import Link from 'next/link';
function myClick(e){
console.log(e);
}
const Index = () => (
<section className="min-vh-100">
<div className="input_bar border rounded-maximum p-1 mx-1 bg-white d-flex">
<input className="myButton submit_bar text-black" placeholder="Insert your input…"/>
<Link href="#"><a onClick={myClick} className="input_icon"></a></Link>
</div>
</section>
);
I'm using nextjs and I'm trying to change a div's class through a click function in another div, I couldn't find examples of how to do that so I can understand how it works. Thank you.
Here is an example using refs:
import Link from 'next/link'
const Index = () => {
let myDiv = React.createRef()
function myClick() {
myDiv.current.classList.add('add-this-class')
}
return (
<section className="min-vh-100">
<div
ref={myDiv}
className="input_bar border rounded-maximum p-1 mx-1 bg-white d-flex"
>
<input
className="myButton submit_bar text-black"
placeholder="Insert your input…"
/>
<Link href="#">
<a onClick={myClick} className="input_icon" />
</Link>
</div>
</section>
)
}
To understand what I'm doing here. I'm creating a reference with this line:
let myDiv = React.createRef()
Then I assign it to the element I want to access, in the example I assign it to the div:
<div ref={myDiv} className="..." >
And on the onClick function I access the div and add a class:
myDiv.current.classList.add('add-this-class')
Let me know if this works for you. (If it did, thank Abderrahman)
I used hooks.
const Index = () => {
const [className, setClassName] = useState("")
const myClick = () => {
setClassName("some-class")
}
return (
<div>
<button onClick={myClick}>Click me</button>
<div className={className}>Classname gets changes</div>
</div>
)
}