I am new to react. I am displaying 10 question with 3 answers per question. Im having trouble capturing which answers they choose per question and storing the value as a array. Here is my code. Im not sure but I think i will need a handle change and a handle submit and bind them to the answers.
import React, { Component } from 'react';
import {
BrowserRouter as Router,
Route,
Link,
Redirect,
withRouter
} from 'react-router-dom';
import axios from 'axios';
import AnswerOption from "./answersContent";
import RaisedButton from 'material-ui/RaisedButton';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
const styles = {
display: 'flex',
justifyContent: "center"
};
const style = {
margin: 15,
};
const Content = {
padding: 10,
margin: 10,
backgroundColor: "",
color: "",
display: "inline-block",
fontFamily: "monospace",
fontSize: "18",
};
const answ ={
listStyle: 'none'
};
class Questions extends Component {
constructor(props) {
super(props);
this.state = {
redirect: "",
user: "",
questions: [],
answers: []
}
}
componentDidMount() {
console.log(this.props.user);
axios.post('/questions')
.then((response) => {
console.log(response);
if (response.status === 200) {
console.log("successfull");
// self.setState({ user: response.data.user.id});
this.setState({user: this.props.user});
this.setState({redirect: false});
this.setState ({ questions :
response.data.surveyQuestions})
}
})
.catch(function (error) {
console.log(error);
});
}
handleClick(event){
const payload={
"answers": this.state.answers
};
console.log(payload)
}
render(){
const { redirect } = this.state;
if (redirect) {
return <Redirect to='/login'/>;
}
return (
<div className="dashboard" style={styles}>
< MuiThemeProvider>
<div style={Content}>
<h1>Welcome to The Well-Stocked Stork!</h1>
<br />
{this.state.questions.map((quest) => (
<p> {quest.id}. {quest.question}
<ul style={answ}>
<li> <input type="radio" name=
{quest.surveyAnswers[0].body} value={quest.surveyAnswers[0].value}
onChange = {(event,value) => this.setState({answers:
quest.surveyAnswers[0].value})} />{quest.surveyAnswers[0].body}</li>
<li> <input type="radio" name=
{quest.surveyAnswers[1].body} value={quest.surveyAnswers[1].value}
onChange = {(event,value) => this.setState({answers:
quest.surveyAnswers[1].value})} />{quest.surveyAnswers[1].body}</li>
<li> <input type="radio" name=
{quest.surveyAnswers[2].body} value={quest.surveyAnswers[2].value}
onChange = {(event,value) => this.setState({answers:
quest.surveyAnswers[2].value})} />{quest.surveyAnswers[2].body}</li>
</ul>
</p>
))}
<RaisedButton label="Submit" primary={true} style=
{style} onClick={(event) => this.handleClick(event)}/>
</div>
</MuiThemeProvider>
</div>
)
}
}
export default Questions;
You are right to handle change but you are missing one thing. You should bind you handleClick method in the constructor. Something like this.handleClick = this.handleClick.bind(this) otherwise you will get an error something ..state is not defined...
Related
I need such an editor on react https://cloverhearts.github.io/quilljs-markdown/ , as you can see in it you can put markdown characters directly into the text.
import React from "react";
import ReactQuill, {Quill} from 'react-quill';
import 'react-quill/dist/quill.snow.css';
const QuillMakrdown = require('quilljs-markdown');
interface UIQuillEditorDemoProps { }
interface UIQuillEditorDemoState { text: string; }
export class UIQuillEditorDemo extends React.Component<UIQuillEditorDemoProps, UIQuillEditorDemoState> {
constructor(props: UIQuillEditorDemoProps) {
super(props);
this.state = { text: "" }
}
handleChange = (text: any) => {
this.setState({ text });
}
modules = {...}
formats = [...]
convertToMarkdown() {
// const turndownService = new TurndownService();
// this.setState({ text: turndownService.turndown(this.state.text) });
const editor = new Quill('#editor', {
theme: 'snow'
})
new QuillMakrdown(editor);
}
render() {
return (
<div className='d-flex flex-column'>
<ReactQuill style={{ height: '300px', marginBottom: '50px' }}
theme="snow" modules={this.modules} formats={this.formats}
placeholder={"Write something..."}
onChange={this.handleChange}
/>
<div>
<Button onClick={() => this.convertToMarkdown()}>Convert To Markdown</Button>
<div id="editor"></div>
<RenderToMarkDown text={this.state.text} />
</div>
</div>
);
}
}
I found https://www.npmjs.com/package/react-quill this quilljs for react, but I don't know how to combine it with markdown https://www.npmjs.com/package/quilljs-markdown can anyone help?
I want to clear input after my form submission get successful. I don't want to use reset button in this case.
I have passed submitted data to api that is in another file.
Please help.
file forgotPassword.js
import React, { Component } from "react";
import { Link, withRouter } from "react-router-dom";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { forgotPassword } from "../../actions/authActions";
import classnames from "classnames";
class ForgotPassword extends Component {
constructor() {
super();
this.state = {
email:"",
errors: {}
};
}
componentWillReceiveProps(nextProps) {
if (nextProps.errors) {
this.setState({
errors: nextProps.errors
});
}
}
onChange = e => {
this.setState({ [e.target.id]: e.target.value });
};
onSubmit = e => {
e.preventDefault();
var emailId = {
email: this.state.email
};
this.props.forgotPassword(emailId, this.props.history);
};
render(){
const { errors } = this.state;
return (
<div className="container">
<div className="row">
<div className="col s8 offset-s2">
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<h4><b>Forgot Password</b></h4>
</div>
<form noValidate onSubmit={this.onSubmit}>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.email}
error={errors.email}
id="email"
type="email"
className={classnames("", {
invalid: errors.email
})}
/>
<label htmlFor="email">Email</label>
<span className="red-text">{errors.email}</span>
</div>
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<button
style={{
width: "150px",
borderRadius: "3px",
letterSpacing: "1.5px",
marginTop: "1rem"
}}
type="submit"
className="btn btn-large waves-effect waves-light hoverable blue accent-3"
>
Submit
</button>
</div>
</form>
</div>
</div>
</div>
);
}
onHandleSubmit(e) {
e.preventDefault();
const email = this.state.email;
this.props.onSearchTermChange(email);
console.log(email);
this.setState({
email: ''
});
}
}
ForgotPassword.propTypes = {
forgotPassword: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
errors: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth,
errors: state.errors
});
export default connect(
mapStateToProps,
{ forgotPassword }
)(ForgotPassword);
File authaction.js where calling api
import axios from "axios";
import setAuthToken from "../utils/setAuthToken";
import jwt_decode from "jwt-decode";
import { GET_ERRORS, SET_CURRENT_USER, USER_LOADING} from "./types";
export const forgotPassword = (userData, history) => dispatch => {
axios
.post("/api/users/forgotpassword", userData)
.then(res =>
console.log("forgot password",res)
)
.catch(err =>
dispatch({
type: GET_ERRORS,
payload: err.response.data
})
);
};
After successfull result on api I'm unable to clear input in forgot password form component.
Please let me know if any other way to do this task.I'm a newbie in react.
Many thanks for help.
Changing the value of a TextInput component
You can change the context of the input after an onPress event coming from a button.
export default class App extends React.Component {
state = {
text : "Username"
}
render() {
return (
<View style={styles.container}>
// TextInput gets its value from the state.text above.
<TextInput value={this.state.text } style={{borderColor:"black", border:1}}/>
// Button calls the function in onPress when it is pressed, which cleans up the state.text
<Button title="CLEAN" onPress={() => this.setState({text: ""})} />
</View>
);
}
}
im new in react and well im trying to pass a value from a card click to a child component, i tried a lot of different options but is not working.... can please someone give me a hand with this.
Parent :
import React, { Component } from 'react';
import {
Card, CardImg, CardBody,
CardTitle
} from 'reactstrap'; import { Container, Dimmer, Loader } from 'semantic-ui-react'
import logo from './santa.png'
import Divisiones from './division';
class divisionesSisa extends Component {
constructor() {
super()
this.state = {
division: "1"
}
this.methodFetch = this.methodFetch.bind(this)
this.handleClick = this.handleClick.bind(this);
}
componentDidMount() {
this.methodFetch()
}
fetch(endpoint) {
return window.fetch(endpoint)
.then(response => response.json())
.catch(error => console.log(error))
}
methodFetch() {
this.fetch('/####')
.then(results => {
return results;
}).then(data => {
this.setState(data)
})
}
handleClick = (e) =>{
this.setState({ division: e.target.id });
}
render() {
let { data } = this.state
return data
?
<div className="row">
{Object.keys(data).map((key) => {
return <div className="col-md-2">
<Card>
<CardImg style={{ justifyContent: 'center', alignItems: 'center', marginLeft: 0, marginRight: 1 }} src={logo} alt="Card image cap" />
<CardBody style={{ marginBottom: 10, marginLeft: 0, marginRight: 0 }}>
<a id={data[key]} href="sisa/division" onClick={() => this.handleClick}><CardTitle align="center" >{data[key]}</CardTitle></a>
</CardBody>
</Card>
</div>
})}
<Divisiones division={this.handleClick.bind(this)}/>
</div>
: <Container text>
<Dimmer active inverted>
<Loader content='Loading' />
</Dimmer>
</Container>
}
}
export default divisionesSisa;
Child component
import React, { Component } from 'react';
class division extends Component {
constructor(props){
super(props)
}
componentDidMount(){
console.log(this.props.division)
}
show(){
}
render() {
return(
<div>
<h2>{this.props.division}</h2>
</div>
);
}
}
export default division;
what im doing wrong?
i take any suggestions to fix this problem or change the way im using react
I believe you should use the state to set division prop in 'Divisiones'
const { division } = this.state
<Divisiones division={ division }
[Edit]
As you are receiving 'undefined', I have noticed that you don't pass event to your handleClick function.
You are expecting an event parameter here:
handleClick = (e) => {
this.setState({ division: e.target.id });
}
So you should pass the parameter like this:
onClick={(event) => this.handleClick(event)}
plus you could also add a onClick function on the CardImg
I'm using ReactJS (and nodejs, mongodb..) and I have projects with the delete option and I want to show a delete alert confirm window and I'm using SweetAlert for the first time. It shows the SweetAlert but doesn't let me choose the option, delete the project immediately. I'll show a gif so you can see what is happening.
Thank you!
My ProjectPage Component:
import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
import moment from 'moment';
import SweetAlert from 'react-bootstrap-sweetalert'
import Tasks from '../../TaskList/Tasks/Tasks';
import './ProjectPage.css';
class ProjectPage extends Component {
constructor(props) {
super(props);
this.state = {
project: {},
alert: null
};
}
componentDidMount() {
const { match: { params } } = this.props;
fetch(`/dashboard/project/${params.id}`)
.then(response => {
return response.json()
}).then(project => {
this.setState({
project: project
})
})
}
deleteProject(e){
const getAlert = () => (
<SweetAlert
warning
showCancel
confirmBtnText="Yes!"
confirmBtnBsStyle="danger"
cancelBtnBsStyle="default"
title="Are you sure you want to delete this project?"
onConfirm={() => this.deleteFile()}
onCancel={() => this.onCancelDelete()}
>
You will not be able to recover this project!
</SweetAlert>
);
this.setState({
alert: getAlert()
});
e.preventDefault();
}
onCancelDelete(){
this.setState({
alert: null
});
}
render() {
const { match: { params } } = this.props;
const BackgroundImage = {
backgroundImage: `url(${this.state.project.imageURL})`,
backgroundRepeat: 'no-repeat',
backgroundSize: 'cover',
backgroundPosition: 'center',
height: '350px',
opacity: '0.7'
}
return (
<div>
<header style={BackgroundImage}>
[...]
<form method='POST' action={`/dashboard/project/${params.id}/delete?_method=DELETE`}>
<button id='button__project-delete' style={{ boxShadow: 'none' }} className='button__options--project btn btn-outline-secondary'
type='submit' onClick={() => this.deleteProject()}>Delete</button> {this.state.alert}
</form>
</header>
[...]
</div>
);
}
}
export default ProjectPage;
GIF what's happening:
It looks your page refreshed on button click, because it is inside a form object. On button click, click event can not be accessible. So e.preventDefault() does not work.
You have to pass event object to deleteProject() method.
Change this line
<button id='button__project-delete' style={{ boxShadow: 'none' }} className='button__options--project btn btn-outline-secondary'
type='submit' onClick={() => this.deleteProject()}>Delete</button> {this.state.alert}
to
<button id='button__project-delete' style={{ boxShadow: 'none' }} className='button__options--project btn btn-outline-secondary'
type='submit' onClick={(e) => this.deleteProject(e)}>Delete</button> {this.state.alert}
this.setState({
alert: getAlert()
});
Please check after changing this to
this.setState({
alert: getAlert
});
I'm using the official Semantic UI React components to create a web application. I have a form on a search page, which contains an input field.
import React from 'react'
import {Form} from "semantic-ui-react";
import RadiusOfSearchInput from "./RadiusOfSearchInput";
const NearbyShopsSearchForm = (props) => {
const { onSubmit, size, action, onChange, value, style } = props
return (
<Form onSubmit={onSubmit}>
<RadiusOfSearchInput size={size}
action={action}
onChange={onChange}
value={value}
style={style} />
</Form>
)
}
export default NearbyShopsSearchForm
The component that uses the form is as shown below:
import React, { Component } from 'react'
import {Menu, Container, Segment} from 'semantic-ui-react'
import ShopCardList from "../components/ShopCardList";
import axios from 'axios';
import NearbyShopsSearchForm from "../components/NearbyShopsSearchForm";
class NearbyShopsPage extends Component {
constructor(props) {
super(props)
this.state = {
radius: '',
shops: []
}
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleChange = (e, { value } ) => {
this.setState({ radius: value })
}
handleSubmit = (e, data) => {
const { radius } = this.state
const url = `/api/shops/#33.846978,-6.775816,${radius}`
axios.get(url)
.then((response) => {
this.setState({ shops: response.data })
})
.catch((error) => {
console.log(error)
})
e.preventDefault()
}
render() {
const { radius } = this.state
return (
<Segment basic>
<Menu fixed='top' size='huge' borderless>
<Menu.Item>
<NearbyShopsSearchForm onSubmit={this.handleSubmit}
size='large'
action={{ color: 'teal', content: 'Search', size: 'small' }}
onChange={this.handleChange}
value={radius}
style={{ width: '17.5em' }} />
</Menu.Item>
</Menu>
<Container style={{ marginTop: '5.5em' }}>
<ShopCardList shops={this.state.shops}/>
</Container>
</Segment>
)
}
}
export default NearbyShopsPage
I want to validate the form so it won't submit values other than decimals, which are valid values to represent a distance. I didn't find validation support in the SUIR official documentation. I'm aware of the redux-form possibility, but i fail to implement it correctly. what's the recommended and simplest way to implement the data validation feature?