My application have two components, one renders a list and the other render the form:
I would like to use the same component to create new categories and also to edit the categories that already exists.
The create categories is working fine already, but to edit, needs to pass the id of the category in the list to the form inside the modal, as i am new into react, i would like some help. Thanks in advance.
The list file is called,
Categories.jsx
import React, { Component } from 'react'
import { Alert, Modal, Button } from "react-bootstrap";
import Datatable from '../../../globalcomponents/datatable/Datatable';
import CategoryForm from './CategoryForm';
const Api = require('../../api/CategoriesApi.js')
class Categories extends Component {
constructor(props) {
super(props)
this.state = {
categories: [],
isLoaded: false,
error: null,
isOpen: false
}
}
openModal = () => this.setState({ isOpen: true });
closeModal = () => this.setState({ isOpen: false });
componentDidMount() {
Api.getCategories()
.then(response => {
const [error, data] = response
if (error) {
this.setState({
isLoaded: true,
categories: [],
error: data
})
} else {
this.setState({
isLoaded: true,
categories: data
})
}
})
}
render() {
const { error, isLoaded, categories } = this.state
if (error) {
return (
<Alert color="danger">
Error: {error}
</Alert>
)
} else if (!isLoaded) {
return (
<Alert color="primary">
Loading...
</Alert>
)
} else {
return (
<>
<Button className="float-right" variant="primary" onClick={this.openModal}>
Adicionar
</Button>
<h4 className="mt-4 mb-4">Categorias de investimentos</h4>
<Datatable>
<table className="table table-striped my-4 w-100">
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>Url (Slug)</th>
<th></th>
</tr>
</thead>
<tbody>
{categories.map(category => (
<tr key={category.id}>
<td>{category.id}</td>
<td>{category.title}</td>
<td>{category.slug}</td>
<td>
<Button className="float-right mr-2" variant="primary" onClick={this.openModal}>
Modal Edit
</Button>
</td>
</tr>
))}
</tbody>
</table>
</Datatable>
<Modal show={this.state.isOpen} onHide={this.closeModal}>
<Modal.Header closeButton>
<Modal.Title>Adicionar / Editar</Modal.Title>
</Modal.Header>
<Modal.Body>
<CategoryForm />
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={this.closeModal}>
Close
</Button>
</Modal.Footer>
</Modal>
</>
)
}
}
}
export default Categories
The form file is used to create or edit categories. And it is called: CategoryForm.jsx
import React, { Component } from 'react'
import { Redirect } from 'react-router'
import { Row, Col, Alert, Button, Form, FormGroup, Label, Input } from 'reactstrap'
const Api = require('../../api/CategoriesApi.js')
class CategoryForm extends Component {
constructor(props) {
super(props)
this.state = {
category: {
id: this.getCategoryId(props),
title: '',
slug: '',
},
redirect: null,
errors: []
}
this.setTitle = this.setTitle.bind(this)
this.setSlug = this.setSlug.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
getCategoryId(props) {
try {
return props.match.params.id
} catch (error) {
return null
}
}
setTitle(event) {
let newVal = event.target.value || ''
this.setFieldState('title', newVal)
}
setSlug(event) {
let newVal = event.target.value || ''
this.setFieldState('slug', newVal)
}
setFieldState(field, newVal) {
this.setState((prevState) => {
let newState = prevState
newState.category[field] = newVal
return newState
})
}
handleSubmit(event) {
event.preventDefault()
let category = {
title: this.state.category.title,
slug: this.state.category.slug,
}
Api.saveCategory(category, this.state.category.id)
.then(response => {
const [error, errors] = response
if (error) {
this.setState({
errors: errors
})
} else {
this.setState({
// reload categories
redirect: '/admin'
})
}
})
}
componentDidMount() {
if (this.state.category.id) {
Api.getCategory(this.state.category.id)
.then(response => {
const [error, data] = response
if (error) {
this.setState({
errors: data
})
} else {
this.setState({
category: data,
errors: []
})
}
})
}
}
render() {
const { redirect, category, errors } = this.state
if (redirect) {
return (
<Redirect to={redirect} />
)
} else {
return (
<>
<Row>
<Col>
{errors.length > 0 &&
<div>
{errors.map((error, index) =>
<Alert color="danger" key={index}>
{error}
</Alert>
)}
</div>
}
<Form onSubmit={this.handleSubmit}>
<FormGroup>
<Label for="title">Title</Label>
<Input type="text" name="title" id="title" value={category.title} placeholder="Enter title" onChange={this.setTitle} />
</FormGroup>
<FormGroup>
<Label for="slug">Slug</Label>
<Input type="text" name="slug" id="slug" value={category.slug} placeholder="Enter slug" onChange={this.setSlug} />
</FormGroup>
<Button color="success">Submit</Button>
</Form>
</Col>
</Row>
</>
)
}
}
}
export default CategoryForm