im trying to toggle active class when you click on a card , for some reason its only working for the first div i have and not working for the second div element. basicly it should remove the box class and add active class when you click on the div element , however when i click on the second div it affects the style of the first div element instead. ANy help is greatly appreciated!
class RegisterForm extends React.Component {
constructor(props) {
super(props);
this.handleClick= this.handleClick.bind(this);
this.handleClick2= this.handleClick.bind(this);
this.state = {
active: false,
active2: false
};
}
handleClick(){
this.setState({ active: !this.state.active });
console.log(this.state.active);
}
handleClick2(){
this.setState({ active2: !this.state.active2 });
console.log(this.state.active2);
}
render() {
const { form } = this.props
return (
<div>
{' '}
<h1 id={styles.n}> Get started Today </h1>
<h5 id="f">No credit card required </h5>
<br />
<br />
<div className="container">
<div className={this.state.active ? styles.active : styles.box} onClick={this.handleClick} onKeyDown={this.handleClick} role="presentation">
<span className={styles.cont}>
<i className="fa fa-rocket" />.
</span>
<h3>Organization</h3>
<p className={styles.expand}>
<span className="plus">full access to all settings</span>
<span className="minus">-</span>
</p>
</div>
<div className={this.state.active2 ? styles.active : styles.box} onClick={this.handleClick2}>
<span className={styles.cont}>
<i className="fa fa-edit" />.
</span>
}
You are binding the this.handleClick function to this.handleClick2 in the constructor.
Related
This project is using React.
The goal is that when the maximize icon is clicked on the the Editor component, the Preview component will be hidden. When the maximize icon is clicked on the Preview component, the Editor component will be hidden.
The problem is, when I click the maximize icon on the Editor component, the only thing that displays is the text "not found." But the Preview maximize icon works when clicked.
I logged state to the console so I know that the state is updating when the editor button is clicked, but I can't figure out what is wrong with the way I am rendering the Editor element.
Codepen link: https://codepen.io/Jamece/pen/Exbmxmv
Thank you for any help you can provide.
import * as marked from "https://cdn.skypack.dev/marked#4.0.12";
class Application extends React.Component {
constructor(props) {
super(props);
this.state = {
editorOnly: false,
previewOnly: false,
inputValue: "",
outputValue: ""
};
this.handleChange = this.handleChange.bind(this);
this.editorChange = this.editorChange.bind(this);
this.previewChange = this.previewChange.bind(this);
}
handleChange(event) {
this.setState({
inputValue: event.target.value
});
}
//changes view to editorOnly when editor maximize button is clicked then back to full view when clicked again
editorChange() {
this.setState((state) => {
if (state.editorOnly === false) {
return { editorOnly: true };
} else {
return { editorOnly: false };
}
});
}
//changes view to previewOnly when preview maximize button is clicked then back to full view when clicked again
previewChange() {
this.setState((state) => {
if (state.previewOnly === false) {
return { previewOnly: true };
} else {
return { previewOnly: false };
}
});
}
render() {
console.log(this.state);
if (this.state.editorOnly === false && this.state.previewOnly === false) {
return (
<div className="container-fluid px-0">
<div className="d-flex flex-column main">
<Editor editorChange={this.editorChange}
handleChange={this.handleChange}/>
<Preview previewChange={this.previewChange} />
</div>
</div>
);
} else if (
this.state.editorOnly === true &&
this.state.previewOnly === false
) {
return (
<div className="container-fluid px-0">
<div className="d-flex flex-column main">
<Editor editorChange={this.editorChange}
handleChange={this.handleChange}/>
</div>
</div>
);
} else if (
this.state.editorOnly === false &&
this.state.previewOnly === true
) {
return (
<div className="container-fluid px-0">
<div className="d-flex flex-column main">
<Preview previewChange={this.previewChange} />
</div>
</div>
);
}
else {
return(
<div></div>
)
}
}
}
class Editor extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="d-flex justify-content-center">
<form>
<div className="boxes">
<div className="d-flex align-items-center label-bar">
<div className="leftcon">
<i className="fa-solid fa-book"></i>
</div>
<div className="headings">Editor</div>
<div className="rightcon">
<button className="btn" onClick={this.props.editorChange}>
<i className="fa-solid fa-maximize"></i>
</button>
</div>
</div>
<textarea
value={this.props.inputValue}
onChange={this.props.handleChange}
></textarea>
</div>
</form>
</div>
);
}
}
class Preview extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<div className="d-flex justify-content-center">
<form>
<div className="boxes">
<div className="d-flex align-items-center label-bar">
<div className="leftcon">
<i className="fa-solid fa-book"></i>
</div>
<div className="headings">Preview</div>
<div className="rightcon">
<button className="btn" onClick={this.props.previewChange}>
<i className="fa-solid fa-maximize"></i>
</button>
</div>
</div>
<div className="preview">
<br /> <br /> <br /> <br /> <br /> <br /> <br /> <br />
</div>
</div>
</form>
</div>
</div>
);
}
}
ReactDOM.render(<Application />, document.getElementById("app"));
A button element inside a form element by default has type="submit".
Hence, when you click the maximize button it tries to submit the form, making an http request.
This is not what you want here so you should set type="button" on your buttons. This way they will not trigger a form submission on click.
The same thing happens on your Preview component, but note that in the console you get the following message:
Form submission canceled because the form is not connected
I believe this is because the way you order the elements in the different states causes React to recreate the preview window in the DOM. If you switch Editor and Preview around in the state where both are visible then Editor works fine and Preview is broken.
So, im trying to display my component named documentReader inside div with class desktop-app-grid by clicking and icon below, but icon is also a component, i tried doing this by using state, but i don't know how I can do this. I'm dropping my code below with hope someone can help me.
I got this:
<div className="desktop">
<div
className="desktop-app-grid"
>
</div>
<div className="taskbar">
<div className="taskbar-content">
<div className="apps">
<TaskbarAppIcon
appName="documentReader"
icon={icon}
title="My CV"
/>
</div>
<div className="status">
<Clock className="clock" />
</div>
</div>
</div>
</div>
);
}
And on click i want to get displayed in desktop-app-grid like this:
<div
className="desktop-app-grid"
>
<documentReader />
</div>
icon.js (code isn't complete)
class TaskbarAppIcon extends React.Component {
constructor() {
super();
this.state = {
clicked: false
};
this.handleClick = this.handleClick.bind(this);
}
handleClick = () => {
const icon = document.querySelector("img");
icon.classList.toggle("icon-active");
setTimeout(() => {
icon.classList.toggle("icon-active");
}, 200);
this.setState({
clicked: true
});
}
render(){
const classes = this.props.appName + "Icon icon";
return (
<div className={classes} onClick={this.handleClick}>
<img src={this.props.icon} alt={this.props.appName} title={this.props.title} className="icon-image"></img>
<div className="isActive"></div>
</div>
);
}
}
export default TaskbarAppIcon;
is there any function that works like innerHTML, but isn't a dangerouslyInnerHTML?
what you need to do is move your handleClick and clicked state to the parent component where you rendering TaskbarAppIcon. Being more specific where you have this code:
<div className="desktop">
<div className="desktop-app-grid">
</div>
<div className="taskbar">
<div className="taskbar-content">
<div className="apps">
<TaskbarAppIcon
appName="documentReader"
icon={icon}
title="My CV"
/>
</div>
<div className="status">
<Clock className="clock" />
</div>
</div>
</div>
</div>
So for example, the above code is in you App component, so you need to let it like this:
class App extends React.Component {
constructor() {
super();
this.state = {
clicked: false,
};
this.handleClick = this.handleClick.bind(this);
}
handleClick = () => {
const icon = document.querySelector("img");
icon.classList.toggle("icon-active");
setTimeout(() => {
icon.classList.toggle("icon-active");
}, 200);
this.setState({
clicked: !this.state.clicked,
});
};
render() {
return (
<div className="desktop">
<div className="desktop-app-grid">
// here's the trick, if your clicked state is TRUE it will show <documentReader />
{this.state.clicked && <documentReader />}
</div>
<div className="taskbar">
<div className="taskbar-content">
<div className="apps">
<TaskbarAppIcon
// Here you are specifying that TaskbarAppIcon has a prop handleClick and its a function
handleClick={this.handleClick}
appName="documentReader"
icon={icon}
title="My CV"
/>
</div>
</div>
</div>
</div>
);
}
}
And in your TaskbarAppIcon component you just need to change
<div className={classes} onClick={this.handleClick}>
to
<div className={classes} onClick={this.props.handleClick}>
I'm using react and have a list with images, when hovered them it shows a text and when clicked it opens a modal, but each "li" has different content that goes in the modal. The problems is that every item of the list open only one modal, the last one, how can I do to open the correct modal?
Modal code
constructor(props) {
super(props);
this.state = {
visible : false
}
}
openModal() {
this.setState({
visible : true,
});
}
closeModal() {
this.setState({
visible : false,
});
}
list with the modal
<li className="bor">
<img src={bor}/>
<span className="first">teste</span>
<span className="second">veja o case completo</span>
<input type="button" onClick={() => this.openModal()} />
<section>
<Modal className="modal" visible={this.state.visible} width="90%" height="90%" effect="fadeInUp" onClickAway={() => this.closeModal()}>
<div className="close">
<a href="javascript:void(0);" onClick={() => this.closeModal()}>X</a>
</div>
<div>
<h1>teste1</h1>
</div>
</Modal>
</section>
</li>
<li className="baz">
<img src={baz}/>
<span className="first">teste2</span>
<span className="second">veja o case completo</span>
<input type="button" onClick={() => this.openModal()} />
<section>
<Modal className="modal" visible={this.state.visible} width="90%" height="90%" effect="fadeInUp" onClickAway={() => this.closeModal()}>
<div className="close">
<a href="javascript:void(0);" onClick={() => this.closeModal()}>X</a>
</div>
<div>
<h1>teste2</h1>
</div>
</Modal>
</section>
</li>
As #FatemehQasemkhani said it is best practice to use single modal & pass corresponding data like below. I approaced same way & it is working fine. I am taking some dummy data inside items. Whenever user is clicking on any list(li) item I am storing that currrent clicked item inside activeItemData and passing that value in modal.
import React, { Component } from "react";
import Modal from "react-awesome-modal";
class ProList extends Component {
constructor(props) {
super(props);
this.state = {
visible: false,
activeItemData: "",
items: [
{
desc: "this is item 1 "
},
{
desc: "this is item 2"
}
]
};
}
closeModal() {
this.setState({
visible: false
});
}
handleCurrentItem = item => {
// you can set two properties in setState or you can set visible property in callback also...
this.setState(
{
activeItemData: item.desc,
visible:true
},
// () => this.setState({ visible: true })
)
};
render() {
return (
<div>
<ul>
{ this.state.items.map(item => (
<li key={item.desc} onClick={() => this.handleCurrentItem(item)}>
{item.desc}
</li>
))}
</ul>
<Modal
className="modal"
visible={this.state.visible}
width="90%"
height="90%"
effect="fadeInUp"
onClickAway={() => this.closeModal()}
>
<div className="close">
<a href="javascript:void(0);" onClick={() => this.closeModal()}>
X
</a>
</div>
<div>
<h1>{this.state.activeItemData}</h1>
</div>
</Modal>
</div>
)
}
}
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>
I've a list of photos being displayed as a React Component.
The individual list items are initially displayed with a + sign. The behavior I'm trying to acheive is on clicking a particular list item, the sign changes to -, and once a different list item is clicked, the first one reverts to + and the current one goes to -.
This is my render code,
render() {
let classes = "glyphicon add-icon " + (this.state.glyphClass ? "glyphicon-plus" : "glyphicon-minus");
return (
<div className="row">
<ul className="list-inline">
{this.props.images.map(function (image) {
return (<li key={image.id}>
<a href="#" onClick={this.getMediaId} data-id={image.id} data-class={image.src} data-owner={image.owner}>
<div className="img-wrapper">
<div className="img" style={{backgroundImage: `url(${image.src})`}}></div>
<div className="img-selector">
<span className={classes} id="plus-icon" aria-hidden="true"></span>
</div>
</div>
</a>
</li>);
}, this)}
</ul>
</div>
);
}
This is the constructor,
constructor(props){
super(props);
this.getMediaId = this.getMediaId.bind(this);
this.state = { glyphClass : true };
}
And this is the method that does the toggle,
getMediaId(event){
event.preventDefault();
this.setState({
glyphClass: !this.state.glyphClass
});
console.log(this.state.glyphClass);
....
}
The behavior that I'm getting now is that onClick on any list item all the list items are toggling to - and then on a subsequent click all are toggling to +. I'd really appreciate some help in fixing this.
You can have a selectedItem in the state instead.
constructor(props){
super(props);
this.getMediaId = this.getMediaId.bind(this);
this.state = { selectedItem : null };
}
Then in the get media set the id of selectedItem when clicked.
getMediaId(id){
this.setState({
selectedItem: id
});
}
Then you can check the id when rendering the list.
if the selectedItem has the same id of the list, render the - else render +.
render() {
return (
<div className="row">
<ul className="list-inline">
{this.props.images.map(function (image) {
const classes = this.state.selectedItem === image.id ? 'glyphicon add-icon glyphicon-minus' : 'glyphicon add-icon glyphicon-plus';
return (<li key={image.id}>
<a href="#" onClick={(event) => {event.preventDefault(); this.getMediaId(image.id); }} data-id={image.id} data-class={image.src} data-owner={image.owner}>
<div className="img-wrapper">
<div className="img" style={{backgroundImage: `url(${image.src})`}}></div>
<div className="img-selector">
<span className={classes} id="plus-icon" aria-hidden="true"></span>
</div>
</div>
</a>
</li>);
}, this)}
</ul>
</div>
);
}