React get codemirror value onClick - reactjs

I am trying to get the following code below to display the CodeMirror onChange value when the button is clicked and then display that value inside the "output" div.
I am fairly new to react so not sure if it's best to pass the value through state or if there's an easier method.
Here is my code so far:
import React, { Component } from "react";
import { UnControlled as CodeMirror } from "react-codemirror2";
import "codemirror/mode/javascript/javascript";
import "codemirror/lib/codemirror.css";
export default class Code extends Component {
render() {
return (
<div>
<CodeMirror
value='console.log("Hello World")'
options={{
mode: "javascript",
lineNumbers: true
}}
onChange={(editor, data, value) => {
console.log(value);
}}
/>
<button onClick={}>run code</button>
<div className="Output">
<p>// Value should go here</p>
</div>
</div>
);
}
}

You can make use of state to maintain your values, and show output from your state,
class Code extends Component {
constructor(props) {
super(props)
this.state = {
runCode: false,
outputText: 'console.log("Hello World")',
}
}
runCode = () => {
this.setState({runCode: true})
}
render() {
return (
<div>
<CodeMirror
value={this.state.outputText}
options={{
mode: 'javascript',
lineNumbers: true,
}}
onChange={(editor, data, value) => {
this.setState({
runCode: false,
outputText: value,
})
}}
/>
<button onClick={this.runCode}>run code</button>
<div className="Output">
<pre>{this.state.runCode && this.state.outputText}</pre>
</div>
</div>
)
}
}
Demo - Output appended on click of button.
Demo1 - Outout appended as you type in.

You need to add a state in such situations:
export default class Code extends Component {
state={
value: ''
}
render() {
return (
<div>
<CodeMirror
value='console.log("Hello World")'
options={{
mode: "javascript",
lineNumbers: true
}}
onChange={(editor, data, value) => {
this.setState({value});
}}
/>
<button onClick={}>run code</button>
<div className="Output">
<p>{this.state.value}</p>
</div>
</div>
);
}
}

Related

Calling an onclick event from a different Component

I am desperatly trying to make my code works between 2 components by using the onclick event of my modal component to my Avaibalities component but nothing happens.
How can i make the value of my state ShowModal works?
Avaibalities Component
import React from 'react';
import Calendar from 'react-calendar';
import Modal from '../pages/Modal';
class Avaibalities extends React.Component {
state = {
date: new Date(),
showDate: false,
showModal: false,
};
onChange = (date) => {
this.setState({ date });
};
validation = () => {
this.setState({
showDate: true,
});
};
togglePop = () => {
this.setState({
showModal: true
});
};
render() {
return (
<div>
<div className="home">
<div className="calendarContent">
<div>
<Calendar
onChange={this.onChange}
value={this.state.date}
locale="en-GB"
/>
<>
<button className={'button'}>Validate</button>
<div>
{this.state.showModal ? (
<Modal toggle={this.togglePop} />
) : null}
</>
{this.state.showDate ? (
<div>
<p>
From : {this.state.date[0].toLocaleDateString()} to :{' '}
{this.state.date[1].toLocaleDateString()}
</p>
</div>
) : null}
</div>
</div>
</div>
);
}
}
export default Avaibalities;
Modal Component
import React from 'react';
class Modal extends React.Component {
handleClick = () => {
this.props.toggle();
};
render() {
return (
<div className="modal">
<div className="modal_content">
<span className="close" onClick={this.handleClick}>×</span>
<p>I'm A Pop Up!!!</p>
</div>
</div>
);
}
}
export default Modal;
Looking for someone to help me,
Thank you very much
You do not render your modal in this code because I see that showModal initially false and to set it as true you call tooglePop function as a props in Modal. But render of Modal component depends on showModal state so it never renders because initially false
You can't expect something to happen here.
To display your modal, you need this.state.showModal = true. In your modal, you are setting showModal to true but it's not different than te previous state, so nothing happens.
Change your method as follow :
togglePop = () => {
this.setState(prevState => ({
...prevState,
showModal: !prevState.showModal
}));
};

How to update the Child component state on Updating the Parent Component state

I have two components 1) Accordion Component and 2) MyCustom Component
Now I am importing Accordion Component into MyCustom Component as Below
import { Accordion } from '../../../controls/accordion';
public clickEvent = () =>{
this.setState({
attachmentsAccordionCollapsed:!this.state.attachmentsAccordionCollapsed
});}
<Accordion title="Attachments" defaultCollapsed={this.state.attachmentsAccordionCollapsed} className={styles.itemCell} ></Accordion>
Now I am changing the state attachmentsAccordionCollapsed value on change event in the MyCustom Component but the property "defaultCollapsed" value of Accordion component does not change or update on changing the state of the MyCustom component.
Accordion Component
import * as React from 'react';
import styles from './Accordion.module.scss';
import { IAccordionProps, IAccordionState } from './index';
import { css } from "#uifabric/utilities/lib/css";
import { DefaultButton, IIconProps } from 'office-ui-fabric-react';
/**
* Icon styles. Feel free to change them
*/
const collapsedIcon: IIconProps = { iconName: 'ChevronRight', className: styles.accordionChevron };
const expandedIcon: IIconProps = { iconName: 'ChevronDown', className: styles.accordionChevron };
export class Accordion extends React.Component<IAccordionProps, IAccordionState> {
private _drawerDiv: HTMLDivElement = undefined;
constructor(props: IAccordionProps) {
super(props);
this.state = {
expanded: props.defaultCollapsed == null ? false : !props.defaultCollapsed
};
}
public componentDidUpdate(prevProps) {
this.state = {
expanded: this.props.defaultCollapsed == null ? false : !this.props.defaultCollapsed
};
}
public render(): React.ReactElement<IAccordionProps> {
return (
<div className={css(styles.accordion, this.props.className)}>
<DefaultButton
toggle
checked={this.state.expanded}
text={this.props.title}
iconProps={this.state.expanded ? expandedIcon : collapsedIcon}
onClick={() => {
this.setState({
expanded: !this.state.expanded
});
}}
aria-expanded={this.state.expanded}
aria-controls={this._drawerDiv && this._drawerDiv.id}
/>
{this.state.expanded &&
<div className={styles.drawer} ref={(el) => { this._drawerDiv = el; }}>
{this.props.children}
</div>
}
</div>
);
}
}
Instead of copying props.defaultCollapsed to negated props.expanded I would suggest not having local state in the accordion and just pass the toggle function to expand from parent like any other controlled component:
class Accordion extends React.Component {
render() {
return (
<div>
Is expanded: {String(this.props.expanded)}
<button onClick={this.props.toggleExpanded}>
toggle expanded
</button>
</div>
);
}
}
class Parent extends React.PureComponent {
state = {
expanded: true,
};
toggleExpanded = () => {
this.setState({ expanded: !this.state.expanded });
};
render() {
return (
<div>
<button onClick={this.toggleExpanded}>
toggle from parent
</button>
<Accordion
expanded={this.state.expanded}
toggleExpanded={this.toggleExpanded}
/>
</div>
);
}
}
ReactDOM.render(
<Parent />,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>

React checkbox local storage

I am building a To-Do List web app with React as my first project.
I want to implement local storage which works fine only that,I am unable to handle check and uncheck of the checkbox prefectly.
Here is a link to the deployed website so you can understand the problem I am having.
https://rapture-todo.netlify.app/
When you add a todo, and mark it complete.
on reload, the checkbox of the todo is unchecked but the todo is marked complete.
Here is my source code[github link- https://github.com/coolpythoncodes/React-ToDo-List].
For App.js
import React, { Component } from 'react';
import Header from './component/Header';
import Info from './component/Info';
import AddToDo from './component/AddToDo';
import TodoListItem from './component/TodoListItem';
import './sass/main.scss';
class App extends Component{
constructor(props){
super(props);
this.state= {
value: '',
list: [],
show: true,
};
this.handleChange= this.handleChange.bind(this);
this.handleSubmit= this.handleSubmit.bind(this);
this.handleInputChange = this.handleInputChange.bind(this);
this.deleteTask = this.deleteTask.bind(this);
}
componentDidMount() {
const list = window.localStorage.getItem('userTodo') ? JSON.parse(localStorage.getItem('userTodo')) : [];
this.setState({ list })
}
handleChange(e) {
this.setState({value:e.target.value})
}
// Handle submission of user todo item
handleSubmit(e) {
e.preventDefault();
const newTask = {
id: Date.now(),
userTodo: this.state.value,
isCompleted: false,
checked: false,
}
// Validate form so user doesn't add an empty to do
if (this.state.value.length > 0) {
this.setState({
list: [newTask, ...this.state.list],
value: '', // Clear input field
show: true, // Success message
}, ()=>{
window.localStorage.setItem('userTodo', JSON.stringify(this.state.list));
})
}
}
// Handles checkbox
handleInputChange(id) {
this.setState({list: this.state.list.map(item => {
if (item.id === id) {
item.isCompleted = !item.isCompleted;
item.checked = !this.state.checked;
}return item
})}, ()=>{
window.localStorage.setItem('userTodo', JSON.stringify(this.state.list));
})
}
// Delete a task
deleteTask(id){
this.setState({list: this.state.list.filter(item => item.id !== id )},()=>{
window.localStorage.setItem('userTodo', JSON.stringify(this.state.list))
})
console.log(this.state.list)
}
render(){
return(
<div>
<Header />
<Info />
<AddToDo onChange={this.handleChange} value={this.state.value} onSubmit={this.handleSubmit} />
<TodoListItem deleteTask={this.deleteTask} onChange={this.handleInputChange} list={this.state.list} defaultChecked={this.state.checked} />
</div>
)
}
}
export default App;
For TodoListItem.js
import React, { Component } from 'react';
import ToDoItem from './ToDoItem';
import '../sass/main.scss';
class ToDoListItem extends Component{
render(){
const {list, onChange, deleteTask, defaultChecked} = this.props;
return(
<div>
{list.map((todo)=>{
return (
<ToDoItem
key={todo.id}
userTodo={todo.userTodo}
isCompleted={todo.isCompleted}
onChange={onChange}
id={todo.id}
deleteTask={deleteTask}
defaultChecked={defaultChecked}
/>
)
})}
</div>
)
}
}
export default ToDoListItem;
For TodoItem.js
import React, { Component } from 'react';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
import { faTrashAlt } from '#fortawesome/free-solid-svg-icons'
import '../sass/main.scss';
class ToDoItem extends Component{
render(){
const {userTodo, isCompleted, onChange, id, deleteTask, defaultChecked} = this.props;
const checkStyle = isCompleted ? 'completed-todo' : 'not-completed-todo';
return(
<div className={`container ${checkStyle}`}>
<input type="checkbox" onChange={onChange.bind(this, id)} defaultChecked={defaultChecked}/>
<div >
<p className='title'>{userTodo}</p>
</div>
{/* Delete button */}
<button onClick={deleteTask.bind(this, id)}><FontAwesomeIcon className='remove-icon' icon={faTrashAlt} /></button>
</div>
)
}
}
export default ToDoItem;
Please note: I have gone through other questions similar to the problem I am having but I could not solve this problem.
If I did not state the question well, please let me know.
In the below code in App.js,
<TodoListItem deleteTask={this.deleteTask} onChange={this.handleInputChange} list={this.state.list} defaultChecked={this.state.checked} />
You are setting, defaultChecked={this.state.checked} Why do you do that? There is nothing called checked in the state.
In fact, there is no need to pass the defaultValue.
Make the following changes,
In App.js, remove defaultValue prop for TodoListItem
<TodoListItem deleteTask={this.deleteTask} onChange={this.handleInputChange} list={this.state.list}/>
In TodoListItem.js, remove defaultChecked={defaultChecked}
<ToDoItem
key={todo.id}
userTodo={todo.userTodo}
isCompleted={todo.isCompleted}
onChange={onChange}
id={todo.id}
deleteTask={deleteTask}
defaultChecked={defaultChecked} // Remove this.
/>
In ToDoItem.js,
<input type="checkbox"onChange={onChange.bind(this, id)}
defaultChecked={isCompleted} // Replace defaultValue with isCompleted
/>

no longer show popup if user has subscribed in React (LocalStorage)

The popup show up after 1 sec. But I need to show it only to user who doesn't subscribe yet, by using localStorage. I did try use local storage like this code below, but then all I've got is a blank white page when it's time to show/not show popup. Is the localStorage I coded was totally wrong? Please help
import React from 'react'
import styled from 'react-emotion'
import Rodal from 'rodal'
import '../styles/rodal.css'
import Delayed from '../components/Delayed'
const Signup = () => (
<Containers>
<SubsribtionForm
action="https://subscribe/post?/....."
method="post"
>
<SubscribeInput type="email" name="EMAIL" placeholder="Subscribe to Updates!" required />
<Button type="submit" onClick={this.submit}>Add Me</Button>
</SubsribtionForm>
</Containers>
)
export default class Popup extends React.Component {
constructor(props) {
super(props)
this.state = { visible: true }
if (localStorage.getItem('submit')) {
this.setState({ visible: false })
}
this.submits = this.submits.bind(this)
}
submits() {
const newsub = this.state.submit
localStorage.setItem('submit', newsub)
}
show() {
this.setState({ visible: true })
}
hide() {
this.setState({ visible: false })
}
render() {
return (
<div>
<Container>
<Delayed waitBeforeShow={1000}>
<Rodal
visible={this.state.visible}
onClose={this.hide.bind(this)}
width={500}
height="100%"
customStyles={customStyles}
>
<Box>
<Banner />
<ContainerContent>
<Header>Subscribe to our mailing list</Header>
<Words>
We will organize and send regular updates Stay informed!
</Words>
</ContainerContent>
<ContainerForm>
<Signup />
</ContainerForm>
</Box>
</Rodal>
</Delayed>
</Container>
</div>
)
}
}
constructor(props) {
super(props)
this.state = {
visible: !(localStorage.getItem('submit') !== '' && localStorage.getItem('submit') !== null),
}
this.submits = this.submits.bind(this)
}
Just check if submit is not empty, like above.
Another approach would be to do the following in componentDidMount life cycle
componentDidMount() {
if (localStorage.getItem('submit')) {
this.setState({ visible: false })
}
}
You are calling this.setState inside the class constructor, you can use a simple conditional in this.state to assign the value directly and please use the bind in the constructor :D. I use the length because if the string is '' the length is 0 then that value in the conditional is false
import React from 'react'
import styled from 'react-emotion'
import Rodal from 'rodal'
import '../styles/rodal.css'
import Delayed from '../components/Delayed'
const Signup = () => (
<Containers>
<SubsribtionForm
action="https://subscribe/post?/....."
method="post"
>
<SubscribeInput type="email" name="EMAIL" placeholder="Subscribe to Updates!" required />
<Button type="submit" onClick={this.submit}>Add Me</Button>
</SubsribtionForm>
</Containers>
)
export default class Popup extends React.Component {
constructor(props) {
super(props)
const submit = localStorage.getItem('submit')
this.state = { visible: !submit && !submit.length }
this.submits = this.submits.bind(this)
this.show = this.show.bind(this)
this.hide = this.hide.bind(this)
}
submits() {
const newsub = this.state.submit
localStorage.setItem('submit', newsub)
}
show() {
this.setState({ visible: true })
}
hide() {
this.setState({ visible: false })
}
render() {
return (
<div>
<Container>
<Delayed waitBeforeShow={1000}>
<Rodal
visible={this.state.visible}
onClose={this.hide}
width={500}
height="100%"
customStyles={customStyles}
>
<Box>
<Banner />
<ContainerContent>
<Header>Subscribe to our mailing list</Header>
<Words>
We will organize and send regular updates Stay informed!
</Words>
</ContainerContent>
<ContainerForm>
<Signup />
</ContainerForm>
</Box>
</Rodal>
</Delayed>
</Container>
</div>
)
}
}

How to toggle class of a div element by clicking on button in react js?

I want to toggleclass name of one element by clicking on another element. Both elements are in separate component files. I don't know how to get the state of an element and pass it to another element. Please help me solving the problem.
file1.js
<Button onClick={this.toggleFunction}>Button</Button>
file2.js
<div class="wrapper"></div>
I want to toggle class active on wrapper div when the button is clicked.
Thanks
class MyComponent extends Component {
constructor(props) {
super(props);
this.addActiveClass= this.addActiveClass.bind(this);
this.state = {
active: false,
};
}
toggleClass() {
const currentState = this.state.active;
this.setState({ active: !currentState });
};
render() {
return (
<div
className={this.state.active ? 'your_className': null}
onClick={this.toggleClass}
>
<p>{this.props.text}</p>
</div>
)
}
}
Parent Component
import React from "react";
import ButtonComponent from "./buttonComponent";
import "./demo.css";
//Parent Component
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {
active: false
};
}
updateValue = value => {
this.setState({
active: value
});
};
render() {
return (
<div>
<ButtonComponent updateParent={this.updateValue} />
<div
className={
this.state.active ? "dropdownbutton1" : "dropdownbutton1Active"
}
>
<label>First</label>
<br />
<select>
<option value="yes">yes</option>
<option value="no">no</option>
</select>
</div>
</div>
);
}
}
export default Demo;
Child Component
import React from "react";
import ToggleButton from "react-toggle-button";
import "./demo.css";
class ButtonComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
active: false,
defaultValue: 1
};
}
togglebutton = () => {
this.props.updateParent(this.state.active);
this.setState({ active: !this.state.active });
if (this.state.active) {
this.setState({ defaultValue: 1 });
} else {
this.setState({ defaultValue: -1 });
}
};
render() {
return (
<div>
<div className="ToggleButton">
<ToggleButton onClick={this.togglebutton} value={this.state.active} />
</div>
</div>
);
}
}
export default ButtonComponent;
Link :https://codesandbox.io/s/m4py2y97zp

Resources