I'm working on a React project. I need to add new data to a table using a form. In here when I run 'npm start' command it will show 'Audi' in the list. But when I trying to add new vehicle brand it will not adding. There are no errors showing. Can anyone solve this problem.
This is my vehicleType.jsx file
import React, { Component } from "react";
import { Button } from "reactstrap";
import {FormGroup,Form,Input,Col} from "reactstrap";
class VehicleType extends Component {
constructor(props){
super(props);
this.state = {
items : ['Audi']
}
}
addItem(e){
e.preventDefault();
const {items} =this.state;
const newItem = this.newItem.value;
this.setState({
items : [...this.state.items,newItem]
})
}
render() {
const { items } = this.state;
return (
<>
<Form onSubmit={(e) => {this.addItem(e)}}>
<Row>
<Col md="3">
<FormGroup className="has-success">
<Input ref={(input) => this.newItem =input } className="is-valid" placeholder="Add" type="text"/>
</FormGroup>
</Col>
<Col md="4">
<Button color="primary" size="lg" type="submit" >
Add new vehicle brand
</Button>
</Col>
</Row>
</Form>
<Table className="align-items-center" responsive>
<tbody>
{
items.map(item => {
return(
<tr key = {item}>
<th scope="row" col-md-2>
<span className="mb-0 text-sm">
{item}
</span>
</th>
</tr>
)}
}
</tbody>
</Table>
</>
);
}
}
export default VehicleType;
I think it's some issue with the reactstrap on the ref they provide here is the working sandbox for your requirement
sandbox
if you still need to use reactstrap then you need to go with state variable like
<Input onChange={handleInputChange} value={this.state.addValue} className="is-valid" placeholder="Add" type="text"/>
in the handleChange add this
handleInputChange(e){
this.setState({addValue:e.target.value})
}
Try this
addItem(e){
e.preventDefault();
const {items} =this.state;
items.push(this.newItem.value)
this.setState({ items })
}
Related
So I am building an appointment app where if someone is sick i need to change the color of that person to red.
I am working with useState for this. My problem is that when i want to change that person my event handler doesnt target the person i want to. Can someone help me with that please?
this is my code
import React, {useState} from "react";
import {clients} from "./utils"
import "./userlist.css"
const AddClient = ({addContact}) => {
const [client, setClient] = useState(clients)
const onChangeClient = (e) =>{
setClient({...client, [e.target.name] : e.target.value})
}
const handleSubmit = (e) =>{
e.preventDefault();
addContact(client);
setClient({first_name: client.first_name,
last_name: client.last_name,
phone: client.phone,
email: client.email
});}
const isSick = client.isSick
const handleSick = () =>{
setClient(client => ({ ...client, [isSick]: !client[isSick]})
)
console.log('working')
setClient(prevState => {
console.log("prevState",prevState)
return prevState
})
}
return (
<div>
<form onSubmit={handleSubmit}>
<input
type="text"
value = {client.first_name}
placeholder="name"
name = "first_name"
onChange={onChangeClient}/>
<input
type="text"
value = {client.last_name}
name="last_name"
placeholder="surname"
onChange={onChangeClient}/>
<input
type="email"
value = {client.email}
name="email"
placeholder="email"
onChange={onChangeClient}/>
<input
type="number"
value = {client.number}
name="phone"
placeholder="phone"
onChange={onChangeClient}/>
<button >Add Client</button>
</form>
<tbody className="tablerow">
{clients.map((client) => (
<tr className="table-row" style={{backgroundColor: isSick && 'red'}} key={client.phone}>
<td className=" col col-1">{client.first_name}</td>
<td className=" col col-2">{client.last_name}</td>
<td className=" col col-3">{client.email}</td>
<td className=" col col-4">{client.phone}</td>
<td><button key={client.phone} onClick={() => handleSick()}>Sick</button></td>
</tr> )
)}
</tbody>
</div>
)}
export default AddClient
this is what i see on the console
Check this working implementation of what you are trying to do: https://stackblitz.com/edit/react-avueyp?file=src%2FApp.js
Consider that we are using a static array of objects as our data model ( clients ), usually you would use data retrieved by a database, so every update to any of that data will have to be written on the db and updated data has to be sent back to th client. React UI will only care to render that updated data.
**import React, { Component } from 'react'
import moment from 'moment'
import {Form, Formik, Field, ErrorMessage} from 'formik'
import TodoDataService from '../../api/todo/TodoDataService'
import AuthenticationService from './AuthenticationService'
class TodoComponent extends Component {
constructor(props){
super(props)
this.state = {
id:this.props.params.id,
description:'',
targetDate: moment(new Date()).format('YYYY-MM-DD')
}
this.onSubmit = this.onSubmit.bind(this);
this.validate = this.validate.bind(this);
}
componentDidMount(){
let username = AuthenticationService.getLoginUserName()
TodoDataService.retrieveTodo(username, this.state.id)
.then(response => this.setState({
description: response.data.description,
targetDate: moment(response.data.targetDate).format('YYYY-MM-DD')
}))
}
validate(values){
let error = {}
if(!values.description){
error.description = "Enter a Description"
}
else if(values.description.length<5){
error.description = "Enter atleast 5 Characters in Description"
}
if(!moment(values.targetDate).isValid()){
error.targetDate="Enter a valid date"
}
return error
}
onSubmit(values){
let username = AuthenticationService.getLoginUserName()
let todo={
id: this.state.id,
description:values.description,
targetDate:values.targetDate
}
console.log(values)
if(this.state.id === -1){
TodoDataService.createTodo(username, todo)
.then(()=> this.props.navigate('/todos'))
}else{
TodoDataService.updateTodo(username, this.state.id,
todo).then(() => this.props.navigate('/todos'))
}
}
render() {
let {description, targetDate} = this.state;
return (
<div>
<h1>Update Todo Form </h1>
<div className="container">
<Formik initialValues = {{description, targetDate}} onSubmit={this.onSubmit}
validateOnChange={false} validateOnBlur={false} validate={this.validate} enableReinitialize={true}>
{
(props) =>(
<Form>
<ErrorMessage name="description" component="div" className="alert alert-warning"/>
<ErrorMessage name="targetDate" component="div" className="alert alert-warning"/>
<fieldset className="form-group">
<label>Description</label>
<Field className="form-control" type="text" name="description"/>
</fieldset>
<fieldset className="form-group">
<label>Target Date</label>
<Field className="form-control" type="date" name="targetDate"/>
</fieldset>
<button className="btn btn-success" type="submit" >Save</button>
</Form>
)
}
</Formik>
</div>
</div>
)
}
}
export default TodoComponent;**
import React, { Component } from 'react';
import TodoDataService from '../../api/todo/TodoDataService';
import AuthenticationService from './AuthenticationService';
import moment from 'moment';
class ListTodoComponent extends Component{
constructor(props){
super(props);
this.state={
todos:[],
message:null
}
this.deleteTodoClicked = this.deleteTodoClicked.bind(this);
this.refreshTodos = this.refreshTodos.bind(this);
this.updateTodoClicked = this.updateTodoClicked.bind(this);
this.addTobeClicked = this.addTobeClicked.bind(this);
}
componentDidMount(){
this.refreshTodos();
}
addTobeClicked(){
this.props.navigate(`/todos/-1`)
}
deleteTodoClicked(id){
let username = AuthenticationService.getLoginUserName()
TodoDataService.deleteTodo(username, id)
.then( response =>{
this.setState({message:`Delete of todo id ${id} Successfull`})
this.refreshTodos()
})
}
refreshTodos(){
let username = AuthenticationService.getLoginUserName()
TodoDataService.retrieveAllTodos(username)
.then(
response => {
this.setState({todos:response.data})
}
)
}
updateTodoClicked(id){
console.log("updated");
this.props.navigate(`/todos/${id}`)
}
render(){
return (
<div>
<div className="container">
<h1>List of Todos</h1>
{this.state.message &&<div className="alert alert-success">{this.state.message}</div>}
<table className="table">
<thead>
<tr>
<th>ID</th>
<th>Description</th>
<th>Is Completed?</th>
<th>Target Date</th>
<th>Delete</th>
<th>Update</th>
</tr>
</thead>
<tbody>
{
this.state.todos.map(
todo =>
<tr key={todo.id}>
<td>{todo.id}</td>
<td>{todo.description}</td>
<td>{String(todo.done)}</td>
<td>{moment(todo.targetDate).format('YYYY-MM-DD')}</td>
<td><button className="btn btn-warning" onClick={() => this.deleteTodoClicked(todo.id)}>Delete</button></td>
<td><button className="btn btn-success" onClick={() => this.updateTodoClicked(todo.id)}>Update</button></td>
</tr>
)
}
</tbody>
</table>
<div className="row">
<button className="btn btn-success" onClick={this.addTobeClicked}>Add Todo</button>
</div>
</div>
</div>
)
}
}
export default ListTodoComponent
When I try to add date but date remain same date but in console it shows the new added date why new added date don't show in screen.
When I try to add date but date remain same date but in console it shows the new added date why new added date don't show in screen.
When I try to add date but date remain same date but in console it shows the new added date why new added date don't show in screen.
I am using a wizard in my project. In step 2 I have one form with a data table. The purpose of a data table is when I click on the button a form value pushes into a data table. I have done this when I submit the form, a form value append or push into a data table but I am facing an issue is that I can't maintain or set the state of that a data table array.
My code is shown below
import React, {useState, Fragment} from 'react';
import PropTypes from 'prop-types';
import { Field, FieldArray, reduxForm } from 'redux-form'
import FormInput from './../FormInput'
import ConsigneeTables from './ConsigneeTables'
import {
Button,
Card,
CardBody,
Col,
FormGroup,
Input,
Label,
Row,
Table,
Progress
} from 'reactstrap'
const ConsigneeLocations = (props) => {
const {handleSubmit, previousPage} = props
const consigneeData = []
const initialFormState = {
id: null,
consignee_branch_number: '',
consignee_add1: '',
}
const [CurrentConsignee, setCurrentConsignee] = useState(initialFormState)
const [consignees, setConsignees] = useState(consigneeData)
const [consignee, setConsignee] = useState(initialFormState)
const handleInputChange = (event) => {
const {name, value} = event.target
setConsignee({
...consignee,
[name]: value
})
}
const addConsignee = () => {
consignee.id = consignees.length + 1
console.log(consignee);
consignees.push(consignee)
setConsignees([...consignees])
}
return (<form onSubmit={handleSubmit}>
<h2>View users</h2>
<ConsigneeTables consignees={consignees}/>
<Col xs="12" sm="12">
<Card className="card-border">
<CardBody>
<Col xs="12" sm="12">
<Card className="card-border">
<CardBody>
<FormGroup row>
<Col xs="12" lg="6">
<Field name="consignee_branch_number" type="text" component={FormInput} value={consignee.consignee_branch_number} onChange={handleInputChange} label="Branch Sr No" inputPlaceHolder="Enter Branch Sr No"/>
</Col>
<Col xs="12" lg="6">
<Field name="consignee_add1" type="textarea" component={FormInput} value={consignee.consignee_add1} onChange={handleInputChange} label="Address 1" inputPlaceHolder="Enter Address 1"/>
</Col>
</FormGroup>
</CardBody>
<div style={{
paddingBottom: 30
}}>
<Button color="primary" className="btn-pill pull-right" type="button" onClick={addConsignee} style={{
marginRight: '20px'
}}>
Add
</Button>
</div>
</Card>
</Col>
<div style={{
paddingBottom: 30
}}>
<Button color="primary" className="btn-pill pull-left" onClick={previousPage} style={{
marginLeft: '20px'
}}>
<i className="fa fa-chevron-left"/>
Previous
</Button>
<Button color="primary" className="btn-pill pull-right" type="submit" style={{
marginRight: '20px'
}}>
Next
<i className="fa fa-chevron-right"/>
</Button>
</div>
</CardBody>
</Card>
</Col>
</form>);
};
ConsigneeLocations.propTypes = {
handleSubmit: PropTypes.func,
pristine: PropTypes.bool,
previousPage: PropTypes.func,
submitting: PropTypes.bool
};
export default reduxForm({form: 'consigneesLocation', destroyOnUnmount: false, forceUnregisterOnUnmount: true})(ConsigneeLocations);
My data table component
import React from 'react'
const ConsigneeTables = props => (
<table>
<thead>
<tr>
<th>Branch Number</th>
<th>Address</th>
</tr>
</thead>
<tbody>
{props.consignees.length > 0 ? (
props.consignees.map(consignee => (
<tr key={consignee.id}>
<td>{consignee.consignee_branch_number}</td>
<td>{consignee.consignee_add1}</td>
</tr>
))
) : (
<tr>
<td colSpan={3}>No Data</td>
</tr>
)}
</tbody>
</table>
)
export default ConsigneeTables
Please suggest to me how to handle consignees state. I already use setState onClick but I don't know how to handle consignees state every step.
I got a table, filled by data coming from my API, I'm learning React and come to the solution in several tries.
Now I got the data printed in my table, but, these data is repeated three times (as the rows number multiplied by row number).
Here is my code:
import React from "react";
// reactstrap components
import {Card, CardHeader, CardBody, Row, Col, Breadcrumb, BreadcrumbItem, CardTitle, Button, Table} from "reactstrap";
// core components
import PanelHeader from "components/PanelHeader/PanelHeader.jsx";
class Registries extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoaded: false,
error: null,
articles: [],
};
}
componentDidMount() {
fetch('http://127.0.0.1:8004/api/articles/all/')
.then(results => {
return results.json();
})
.then(data => {
let articles = data.map((row) => {
return(
<tr key={row.id}>
<td>{row.id}</td>
<td>{row.name}</td>
<td>{row.category}</td>
<td style={{width:"106px"}}>
<Button size={"sm"} color={"warning"}>
<i className={"fa fa-edit"} />
</Button>
<Button size={"sm"} color={"danger"}>
<i className={"fa fa-trash"} />
</Button>
</td>
</tr>
)
});
this.setState({
isLoaded: true,
articles: articles
});
console.log(articles);
})
}
render() {
return (
<>
<PanelHeader size="sm" />
<div className="content">
<Row>
<Col xs={12}>
<Card>
<CardHeader>
<Breadcrumb>
<BreadcrumbItem>Home</BreadcrumbItem>
<BreadcrumbItem active>Articoli</BreadcrumbItem>
</Breadcrumb>
<Row>
<Col xs="10">
<CardTitle tag="h4">Articoli</CardTitle>
</Col>
<Col xs="2">
<Button icon="ui-1_simple-add" size="lg" color="success" outline className={"btn-block"}>
<i className={"fa fa-plus"} /> Nuovo
</Button>
</Col>
</Row>
</CardHeader>
<CardBody>
<Table data={this.state.articles} responsive className={"table-hover"}>
<thead className="text-primary">
<tr>
<th>ID</th>
<th>Nome</th>
<th>Categoria</th>
<th style={{width:"106px"}}>Opzioni</th>
</tr>
</thead>
<tbody>
{this.state.articles.map((prop, key) => {
if(this.state.error) {
return(<div>Error: {this.state.error.message}</div>);
}
else if(this.state.isLoaded === false) {
return(
<div>
<i className={"fa fa-spin fa-spinner"}/>
<br/>
Caricamento...
</div>
);
}
else if(this.state.articles) {
return (
<>
{this.state.articles.map((prop, key) => {
return <>{prop}</>;
})}
</>
);
}
})}
</tbody>
</Table>
</CardBody>
</Card>
</Col>
</Row>
</div>
</>
);
}
}
export default Registries;
Here is how the table looks like:
The goal is to get only 3 rows, as the API return
You are calling this.state.articles.map in another this.state.articles.map in your render function.
Try to refactor this part of code:
{this.state.articles.map((prop, key) => {
if(this.state.error) {
return(<div>Error: {this.state.error.message}</div>);
}
else if(this.state.isLoaded === false) {
return(
<div>
<i className={"fa fa-spin fa-spinner"}/>
<br/>
Caricamento...
</div>
);
}
else if(this.state.articles) {
return (
<>
{this.state.articles.map((prop, key) => {
return <>{prop}</>;
})}
</>
);
}
})}
One of possible refactorings could be like this:
{
this.state.error ?
(<div>Error: {this.state.error.message}</div>) :
(
this.state.isLoaded === false ?
(
<div>
<i className={"fa fa-spin fa-spinner"}/>
<br/>
Caricamento...
</div>
) :
(
this.state.articles && this.state.articles.map((prop, key) => {
return (<>{prop}</>);
})
)
)
}
I have used React validation library
https://www.npmjs.com/package/react-validation
If I visit my page from any other page, it does not give any error. but when I refresh the page, it gives an error
TypeError: Cannot convert undefined or null to object
Please suggest an idea if anybody has faced this issue before.
Code:
import React from 'react';
import {
Card,
CardBody,
CardTitle,
Row,
Col,
FormGroup,
Label,
Alert
} from 'reactstrap';
import Input from 'react-validation/build/input';
import Button from 'react-validation/build/button';
import Form from 'react-validation/build/form';
import axios from 'axios';
import api from '../../config/api';
import messages from '../../config/messages';
import Select from 'react-validation/build/select';
import CKEditor from '#ckeditor/ckeditor5-react';
import ClassicEditor from '#ckeditor/ckeditor5-build-classic';
const required = (value, props,components) => {
if(components.formReset!=undefined)
{
if (!components.formReset[0].value && (!value || (props.isCheckable && !props.checked))) {
return <span className="text-danger is-visible">{messages.required}</span>;
}
else if(components.formReset[0].value)
{
return <span className="text-danger is-visible"></span>;
}
}
}
;
class View extends React.Component {
constructor(props) {
super(props);
this.onInputChange = this.onInputChange.bind(this);
this.sendReply = this.sendReply.bind(this);
this.toggle = this.toggle.bind(this);
this.onStatusChange=this.onStatusChange.bind(this);
this.handleEditorChange=this.handleEditorChange.bind(this);
this.state = {
response:null,
loading: false,
message:'',
status:'',
attachment1:[],
status_list:[],
formReset:true
};
}
componentDidMount() {
this.setState({formReset:true});
}
onStatusChange(event) {
this.setState({"formReset":false});
this.setState({
status: event.target.value
});
}
handleEditorChange(data) {
this.setState({"formReset":false});
this.setState({ message:data });
}
sendReply()
{
/*** code after form submission***/
}
toggle() {
}
onInputChange(event) {
event.preventDefault();
this.setState({"formReset":false});
this.setState({
[event.target.name]: event.target.value
});
}
render() {
var _this = this;
return (
<aside className="customizer">
{/*--------------------------------------------------------------------------------*/}
{/* Toggle Customizer From Here */}
{/*--------------------------------------------------------------------------------*/}
<div className="customizer-body pt-3">
<div>
{/* --------------------------------------------------------------------------------*/}
{/* Start Inner Div*/}
{/* --------------------------------------------------------------------------------*/}
<Row>
<Col md="12">
<Card>
<CardTitle className=" border-bottom p-3 mb-0">
</CardTitle>
<CardBody>
<Form ref={c => {
this.replyform = c;
}}>
<Input type="hidden" name="formReset" id="formReset" value={this.state.formReset} />
<FormGroup>
<Row>
<Label sm="2">Reply *</Label>
<Col sm="10">
<CKEditor
editor={ ClassicEditor }
data={this.state.message}
config={ {
toolbar: [ 'heading', '|', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote' ]
} }
onChange={ ( event, editor ) => {
const data = editor.getData();
this.handleEditorChange(data);
} }
/>
</Col>
</Row>
</FormGroup>
<FormGroup>
<Row>
<Label sm="2">Status</Label>
<Col sm="10">
<Select id="status" className="custom-select form-control" name="status" onChange={this.onStatusChange} value={this.props.status_id: null}>
<option value="">Select</option>
{this.state.status_list.map((status, index) => {
return (
<option key={index} value={status.value}>{status.label}</option>
);
})}
</Select>
</Col>
</Row>
</FormGroup>
<FormGroup>
<Row>
<Label sm="2">Attachments</Label>
<Col sm="10">
<Input
type="file"
id="attachment1" name="attachment1[]"
onChange={this.onInputChange}
multiple="multiple"
/>
</Col>
</Row>
</FormGroup>
<div className="border-top pt-3 mt-3 d-flex no-block">
<Button type="button" onClick={this.sendReply} className="btn btn-dark mr-2 ml-auto">
Send Reply
</Button>
</div>
</Form>
</CardBody>
</Card>
</Col>
</Row>
{/* --------------------------------------------------------------------------------*/}
{/* End Inner Div*/}
{/* --------------------------------------------------------------------------------*/}
</div>
</div>
</aside>
);
}
}
export default View;
Error image:
Really crazy error:
import { Formik, Form, Field } from 'formik';
above required initial values on any cost if you dont want to give initial value initialize it with empty.for example
const initialValues = {
firstname: "",
lastname: ""
}
and then in <Formik tag
initialValues={initialValues}
I was facing the same error using formik
After debugging I came to know I had a typo in the initialValues object name. Make sure you are having the same object for initalValues that you have defined. In my case I had timeCapturesInitialValues object but used timeCapturesInitailValues in the Formik prop.
after upgrading react & it's packages i was facing above issue & it's resolved by Hassan Ali Shahzad answer,
code that may help some one
<Formik
enableReinitialize={true}
initialValues={{
heatmaps: '',
}}
if your return statement is null at any given point this error occurs.
Example:
const obj = null;
return(
obj
);
Please check your code .