I want to render data from API which I render it through for loop but when I'm displaying it to UI, it displays only 1 value.
Specification: - when user upload a text image, API displays text which is present in the image and name, which is the JSON data is an array so I render DetectedText value-form API using for loop but not able to display all value of DetectedText in UI so please tell me where I'm doing wrong please see the below code
import React, { Component } from 'react';
import axios from 'axios'
class Image extends Component {
constructor(props) {
super(props);
this.state = { file: '', imagePreviewUrl: '', selectedOption: '', change: [], response: [], path: [], jsonData: [], dText: [] };
}
handleSubmit(e) {
e.preventDefault();
var byteCode = this.state.imagePreviewUrl.substring((e.target.value).indexOf(',') + 23);
let url = "http://192.168.4.138/MediaAnalysisImage_Amazon/api/DetectText/DetectText";
const data = { "fileByte": byteCode }
const response = axios.post(url, data)
.then(response => {
this.setState({
change: response,
byteArr: response.data.fileByte,
jsonData: response.data.jsondata.replace(/[&\/\\#+()$"~%.'*?<>{}]/g, ''),
path: response.data.jsondata.DetectedText,
});
console.log('json detected data', this.state.jsonData)
const parseData = JSON.parse(response.data.jsondata)
let x = ""
for (let x of parseData) {
const DetectedText = x.DetectedText
this.setState({
dText: DetectedText
})
console.log('setting dtext', this.state.dText)
}
})
}
handleImageChange(e) {
e.preventDefault();
let reader = new FileReader();
let file = e.target.files[0];
reader.onloadend = () => {
this.setState({
file: file,
imagePreviewUrl: reader.result
});
}
reader.readAsDataURL(file)
}
render() {
const img = "data:image/png;base64" + ',' + this.state.byteArr
let { imagePreviewUrl } = this.state;
let $imagePreview = null;
if (imagePreviewUrl) {
$imagePreview = (<img src={imagePreviewUrl} className="img-responsive imgp" />);
} else {
$imagePreview = (<span className="previewText">Please select an Image for Preview</span>);
}
return (
<div className="wrapper">
<h2 className="text-center heading" >Text Recognization</h2>
<div className="container ">
<section className="celeb">
<form className="Fform bg-light mb-4">
<div class="form-group ">
<input className="fileInput"
type="file"
onChange={(e) => this.handleImageChange(e)} class="btn btn-secondary" />
</div>
<button className="btn btn-success"
type="submit"
onClick={(e) => this.handleSubmit(e)}>Upload Image</button>
</form>
<hr></hr>
<div className="row grid">
<div className="col-md-6">
<h3>Input Image</h3>
{$imagePreview}
</div>
<div className="col-md-6">
<h3>Output Image</h3>
<img src={img} className="img-responsive imgp" />
</div>
</div>
<div>
<hr></hr>
<h4>Description </h4>
<table className="table table-hover">
<tr>
<th ><label>Name :- </label></th>
<td>{this.state.dText}</td>
</tr>
</table>
</div>
</section>
</div>
</div>
)
}
}
export default Image;
You may change like this:
this.setState({
dText: parseData.map(x => x.DetectedText),
})
and in your render method:
<td>{ this.state.dText.map((text, index) => <div key={index}>{text}</div>) }</td>
Related
I have a form, and I have an input in the form, I upload several images in this input, like so:
<input type="file" name="gallery" onChange={imageHandler} required multiple />
And when I output the images in the console, it correctly displays an array of files, but when I append the images, formData.append("gallery", images); it is not saved as an array. It's saved as a File!
const [selectedFile, setSelectedFile] = useState();
const [images, setImages] = useState([]);
const token = localStorage.getItem("TOKEN");
const imageHandler = (e) => {
setImages([...images, e.target.files[0]]);
};
useEffect(() => {
images.length && console.log(images);
}, [images]);
console.log(images);
const sendDisease = async (e) => {
e.preventDefault();
console.log(images);
const form = document.getElementById("signUpForm");
const formData = new FormData(form);
formData.append("gallery", images);
console.log(formData);
try {
const api = "https://localhost/api/v1/website/disease/add";
const { data } = await axios.post(api, formData, {
headers: {
headers: { "Content-Type": "multipart/form-data" },
Authorization: `Bearer ${token}`,
},
});
toast.success(data.message, { autoClose: 15000 });
} catch (e) {
console.log(e);
toast.error(e.response.data.error, { autoClose: 15000 });
console.log(e.response.data.error);
}
};
const handleFileSelect = (event) => {
setSelectedFile(event.target.files[0]);
};
return (
<>
<div className="container">
<div className="row">
<form id="signUpForm" className="md-12">
<h2 className="text-center mb-4 font-weight-bold">Add Disease</h2>
<div className="form-row mt-4">
<div className="col-md-6 mb-3">
<label for="">Add Disease</label>
<input
type="text"
className="form-control"
name="unique_name"
required
onChange={(e) => setUniqueName(e.target.value)}
/>
</div>
<div className="col-md-6 mb-3">
<label for="">Title</label>
<input
type="text"
className="form-control"
name="title"
placeholder="Title"
onChange={(e) => setTitle(e.target.value)}
required
/>
</div>
</div>
<div className="form-row">
<div className="col-md-12 mb-3">
<label for="">Gallery</label>
<input type="file" name="gallery" onChange={imageHandler} required multiple />
</div>
</div>
<input type="file" name="image" onChange={handleFileSelect} />
</div>
<button
type="button"
className="btn btn-primary mt-4"
onClick={sendDisease}
>
Submit
</button>
</form>
</div>
</div>
</>
);
Calling new FormData(form) is enough. You don't need to call formData.append("gallery", images) as the constructor will pick on its own all the images for you. So you may not even need this images state.
The code below would log all your files if you wanna be sure about it. I also created a working Codesandbox for testing.
export default function App() {
const handleSubmit = (e) => {
e.preventDefault();
const form = document.getElementById("signUpForm");
const formData = new FormData(form);
console.log(formData.getAll("gallery"));
};
return (
<form id="signUpForm" onSubmit={handleSubmit}>
<input type="file" name="gallery" required multiple />
<button>Sumbit</button>
</form>
);
}
If it's not working, try changing formData.append("gallery", images) to the code below (it's apparently what's needed for PHP servers for example):
images.forEach((image) => {
formData.append('gallery[]', image);
});
Here in my case Am using ASP.NET Core and its working fine
images.forEach((image) => {
formData.append('images', image);
});
My Controller
[HttpPost]
public async Task<IActionResult> UpdateProfile([FromForm] UpdateProfileModel updateProfileModel)
{
try
{
await Task.CompletedTask;
return Ok("Done.");
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
My Modal
public class UpdateProfileModel
{
public List<IFormFile> Images { get; set; } = new List<IFormFile>();
}
I've added a search bar to my React-Firebase Dashboard.As a result, the search bar is displayed with the table of clients stored in Cloud Firestore, when I enter a text in the search bar It returns an empty table even if that word exists in the table.
PS: Both of the Results are shown below in screenshots
The table initially rendered
table after writing anything in the search bar
Customer.js
import React, { Fragment, useState } from "react";
import { Avatar } from '#material-ui/core';
import PageTitle from "../../../../layouts/PageTitle";
import { Dropdown, Table } from "react-bootstrap";
import { fire } from "../../../../../fire";
import { firestore } from "../../../../../fire";
import { collection, query, where } from "../../../../../fire";
import App from "../../../../../App";
export default class Recipe extends React.Component {
state = {
searchTerm : "",
Users: []
}
constructor(props){
super(props);
}
searchByTerm = (value) => {
this.setState({searchTerm : value});
}
componentDidMount() {
firestore.collection("Users").get().then((querySnapshot) => {
let User = []
querySnapshot.forEach((doc) => {
console.log(`${doc.id} => ${doc.data().lastn}`);
User.push({
id : doc.id,
data: doc.data()})
});
this.setState({Users : User})
});
}
delete = (id) => {
console.log(id)
firestore.collection("Users").doc(id).delete().then(() => {
console.log("Document successfully deleted!");
this.props.history.push("#")
}).catch((error) => {console.error("Error removing document: ",
error);
});
}
render() {
return (
<Fragment>
<div className="col-12">
<div className="card">
<div className="card-header">
<div className="input-group search-area d-lg-inline-flex d-none mr-
5">
<input
type="text"
className="form-control"
placeholder="Search here"
onChange ={(e) => {
this.searchByTerm(e.target.value);
}}
/>
<div className="input-group-append">
<span className="input-group-text"
>
<svg
width={20}
height={20}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M23.7871 22.7761L17.9548 16.9437C19.5193 15.145 20.4665 12.7982 20.4665 10.2333C20.4665 4.58714 15.8741 0 10.2333 0C4.58714 0 0 4.59246 0 10.2333C0 15.8741 4.59246 20.4665 10.2333 20.4665C12.7982 20.4665 15.145 19.5193 16.9437 17.9548L22.7761 23.7871C22.9144 23.9255 23.1007 24 23.2816 24C23.4625 24 23.6488 23.9308 23.7871 23.7871C24.0639 23.5104 24.0639 23.0528 23.7871 22.7761ZM1.43149 10.2333C1.43149 5.38004 5.38004 1.43681 10.2279 1.43681C15.0812 1.43681 19.0244 5.38537 19.0244 10.2333C19.0244 15.0812 15.0812 19.035 10.2279 19.035C5.38004 19.035 1.43149 15.0865 1.43149 10.2333Z"
fill="#A4A4A4"
/>
</svg>
</span>
</div> </div>
<h4 className="card-title">Customer List </h4>
</div>
<div className="card-body">
<Table responsive className="w-100">
<div id="example_wrapper" className="dataTables_wrapper">
<table id="example" className="display w-100 dataTable">
<thead>
<tr role="row">
<th>Avatar</th>
<th>Email</th>
<th>Firstname</th>
<th>Lastname</th>
<th>PhoneNumber</th>
{/* <th className="pl-5 width200">
Billing Address
</th> */}
<th>Action</th>
</tr>
</thead>
<tbody>
{this.state.Users.filter( (val) =>{
const { email = "", firstname = "" } = val;
// console.log(this.state.searchTerm);
if (this.state.searchTerm === "") {
return val;
} else if (
email.toLowerCase().includes(this.state.searchTerm.toLowerCase()) ||
firstname.toLowerCase().includes(this.state.searchTerm.toLowerCase())
) {
return val;
}
}).map(data => {
return (
<tr>
<td> <Avatar className ="rounded-circle img-fluid" src={data.data.avatar}/> </td>
<td>{data.data.email}</td>
<td>{data.data.firstname}</td>
<td>{data.data.datalastname}</td>
<td>{data.data.phonenumber}</td>
<td>
<div
className="btn btn-danger shadow btn-xs sharp" onClick ={this.delete.bind(this, data.id)}
>
<i className="fa fa-trash"></i> </div></td>
</tr>
);
})}
</tbody>
</table>
</div>
</Table>
</div>
</div>
</div>
</Fragment>
);
};
};
Array.prototype.filter callback should be returning a boolean, not the element being iterated over.
This is how I suggest rewriting your filter function: if there is no search term (i.e. falsey) then return true to indicate all elements iterated over should be return, otherwise, return the result of the comparison.
const { Users, searchTerm } = this.state;
const term = this.state.searchTerm.toLowerCase();
...
Users.filter((val) => {
const { data: { email = "", firstname = "" } = {} } = val;
if (term) {
return (
email.toLowerCase().includes(term) ||
firstname.toLowerCase().includes(term)
);
}
return true;
})
A slightly more succinct version could be written as follows:
const { Users, searchTerm } = this.state;
const term = this.state.searchTerm.toLowerCase();
...
Users.filter(({ data: { email = "", firstname = "" } = {} }) =>
term ? email.concat(firstname).toLowerCase().includes(term) : true
)
Update
After you've stated that you implemented my suggestions and it's still not working I took a closer look at what you are rendering and noticed that in the .map callback you reference each field (email, firstname, etc...) from a data property on each element. Since it seems you are able to render your data when no filter is being applied I'll assume this structure to be correct. As such then, the .filter callback needs to also reference the nested field properties from a data property. I've updated the above code snippets.
I'm working in a personal project and I was trying to implement a string interpolation, but for some reason it isn't working and it is throwing an error.
I'm using visual studio code and the errors it's throwing are the following:
Property assignement expected
';' expected (2 times)
Declaration or statement expected
this is the line where I put the specific interpolation:
newsection = {`${newsectionnmb}`:"placeholder"}
this is my complete code:
import React, { Component } from "react";
import { NavLink, match } from "react-router-dom";
import { withRouter } from "react-router-dom";
import axios from "axios";
class AddContent extends Component{
constructor(props) {
super(props)
this.state = {
name: "",
content: "",
courseName:"",
actualContent: [],
section:"NEW",
video: ""
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
componentDidMount() {
axios.get(`http://localhost:5000/course/id/${Number(this.props.match.params.id)}`)
.then( (response)=> {
this.setState({
courseName: response.data.name,
actualContent: response.data.content
});
if(this.props._id != response.data.adminId) {
this.props.history.push("/");
}
})
.catch(function (error) {
console.log(error);
alert("we couldn't fetch the course data, try again later by reloading the page")
})
}
handleChange(event) {
const target = event.target;
const value = target.value;
const name = target.name;
this.setState({
[name]: value
});
}
handleSubmit= (event)=> {
if (this.state.name !== "" ) {
if (this.state.section === "NEW") {
newsectionnmb = this.state.actualContent.length +1;
newsection = {`${newsectionnmb}`:"placeholder"}
}
event.preventDefault();
axios({
method: 'put',
url: `http://localhost:5000/course/add-content/${Number(this.props.match.params.id)}`,
data: {
content: this.state.content
}
})
}
}
render() {
let sectionlist = this.state.actualContent.length > 0
&& this.state.actualContent.map((item, i) => {
return (
<option key={i} value={item.name}>{item.name}</option>
)
}, this);
return (
<div className="courses">
{this.props.registered === true?
<div>
<form onSubmit={this.handleSubmit} className="Register">
<h1>Add guide</h1>
<h2>{this.state.courseName}</h2>
<p>quotation marks aren't allowed</p>
<div>
<input
name="name"
type="text"
onChange={this.handleChange}
placeholder="name"/>
</div>
<div>
<input
name="video"
type="text"
onChange={this.handleChange}
placeholder="URL for video"/>
</div>
<div>
<textarea
name="content"
type="text"
onChange={this.handleChange}
placeholder="content"/>
</div>
<label>select section:</label>
<select name="section" onChange={this.handleChange} className="select">
<option value="NEW">New Section</option>
{sectionlist}
</select>
<button type="submit" className="coursesub">Submit</button>
<NavLink exact to="/courses">Go back to course</NavLink>
</form>
</div>
:
<div>
<h1>Welcome to SSG courses app, to start using please login.</h1>
<NavLink exact to="/login">Login</NavLink>
</div>
}
</div>
)
}
}
export default withRouter(AddContent);
If you want to make newsection an object, it should be done like this
newsection = {newsectionnmb:"placeholder"}
If you are trying to make it a string, this should work for you
newsection = `${newsectionnmb}:"placeholder"`
I am still new in React and Redux. So, I know the existence of redux-form, but Im not intend to use in this project. So, what I am doing is creating a form without using redux-form. This form will grab the data from the reducers and pass it to backend API.
This is my main CreateListing.jsx page.
// #flow
import React from 'react';
import { connect } from 'react-redux';
import { Helmet } from 'react-helmet';
import { SEOService } from '[services]';
import CreateListingFormPage1 from './CreateListing/CreateListingFormPage1';
import CreateListingFormPage2 from './CreateListing/CreateListingFormPage2';
import CreateListingFormPage3 from './CreateListing/CreateListingFormPage3';
import WhereAmI from './CreateListing/WhereAmI';
import SuccessCreateListing from './CreateListing/SuccessCreateListing';
type Props = {
...props...
};
class CreateListing extends React.Component<Props> {
getPageBySequence(pagenum) {
// depending on whether User is logged in or not, show/hide the Login/Signup form which is Page3
let sequence = [ CreateListingFormPage1, CreateListingFormPage2, CreateListingFormPage3 ];
if (this.props.isLoggedIn) {
sequence = [ CreateListingFormPage1, CreateListingFormPage2, CreateListingFormPage2 ];
}
return sequence[pagenum-1];
}
getSubmitCreateListing = (e) => {
e.preventDefault();
const propertyType = this.props.listingType;
const propertyName = this.props.suggestedBuildings.selected;
const propertyBuildingType = this.props.propertyBuildingType;
const bedrooms = this.props.bed;
const bathrooms = this.props.bath;
const price = this.props.price;
const builtUp = this.props.builtUp;
const title = this.props.title;
const tenure = this.props.tenure;
const description = this.props.description;
/* IN CASE USER NOT YET LOGGGED IN */
if(this.props.isLoggedIn === false) {
const email = this.props.email;
const password = this.props.password;
this.props.cacheCreateListing({ email, password, propertyType, propertyName, propertyBuildingType, bedrooms, bathrooms, price, builtUp, title, tenure, description });
}
this.props.cacheCreateListing({ propertyType, propertyName, propertyBuildingType, bedrooms, bathrooms, price, builtUp, title, tenure, description });
if(CreateListingFormPage1.landedTypes.includes(propertyBuildingType)) {
this.props.geocodingRequired(true);
}
else {
this.props.geocodingRequired(false);
}
this.props.onSubmitCreateListing();
}
onAuthenticateAndCreateListingButton() {
if(this.props.isLoggedIn) {
return(
<div role="presentation">
<div className={`column ${this.props.formCurrentPage === 1 ? '':'displayNone'}`}>
<button type="button" className="Button button-next is-red" onClick={this.props.onNextClick}>
NEXT
</button>
</div>
<div className={`column ${this.props.formCurrentPage === 2 || this.props.formCurrentPage === 3 ? '':'displayNone'}`}>
<button type="submit" className="Button button-create is-red" onClick={this.props.onLoadingCreateListing}>
CREATE LISTING
</button>
</div>
</div>
)
}
return <div className={`column ${this.props.formCurrentPage < 3 ? '':'displayNone'}`}>
<button type="button" className="Button button-next is-red" onClick={this.props.onNextClick}>
NEXT
</button>
</div>
}
render() {
if(this.props.isListingCreated){
return <SuccessCreateListing />;
}
else if(this.props.isListingLoading){
return <div className="create-listing-spinner" />
}
const CurrentPage = this.getPageBySequence(this.props.formCurrentPage);
return (
<div className={`CreateListing${this.props.isMobile ? '' : ' is-desktop'}`}>
<Helmet>
<title>{ SEOService.getMetaTitle('Create Property Listing') }</title>
{ SEOService.getCanonicalTag('/blogs') }
</Helmet>
<section className="CreateListing--Main">
<div className="CreateListing--Container">
<div className="CreateListing--WhereAmI">
<WhereAmI page={this.props.formCurrentPage} />
</div>
<div className="CreateListing--Body">
<form className="CreateListing--Form" onSubmit={ this.getSubmitCreateListing }>
<CurrentPage />
<div className='columns'>
<div className='column'/>
{/* CHANGE THIS this.props.formCurrentPage < 3 later */}
<div className={`column ${this.props.formCurrentPage > 1 && this.props.formCurrentPage < 4 ? '':'displayNone'}`}>
<button type="button" className="Button button-back" onClick={this.props.onPrevClick}>
BACK
</button>
</div>
{ this.onAuthenticateAndCreateListingButton() }
<div className='column'/>
</div>
</form>
</div>
</div>
</section>
</div>
);
}
};
const MapStateToProps = (state: State) => ({...});
const MapDispatchToProps = (dispatch: Dispatch) => ({
onLoadingCreateListing: () => dispatch({type: 'CREATE_LISTING_LOADING'}),
onSubmitCreateListing: () => dispatch({type: 'CREATE_LISTING_SUBMIT_FORM'}),})
export default connect(MapStateToProps,MapDispatchToProps)(CreateListing);
So, my <input type="text" /> are all from CreateListingFormPage1, CreateListingFormPage2 and CreateListingFormPage3 and put together in <CurrentPage />. My <form onSubmit={...}></form> is in this CreateListing.jsx page. Im not whether it is allowed to do it like this.
So, when I click submit, I got warning of Form submission canceled because the form is not connected.
My example of <input type="" /> in CreateListingFormPage1 are:
// #flow
import React from 'react';
import { connect } from 'react-redux';
import {Dropdown} from '[elements]';
type Props = {...props...};
class CreateListingFormPage2 extends React.Component<Props> {
static get selectTenure() { return ["Select Tenure"].concat(this.tenureTypes) };
static get selectTitle() { return ["Select Title"].concat(this.titleTypes) };
static get selectBedroom() { return["Select Bedrooms no"].concat(this.bedroomNo) };
static get selectBathroom() { return["Select Bathrooms no"].concat(this.bathroomNo) };
static get tenureTypes(){
return[
"FREEHOLD",
"LEASEHOLD",
"OTHERS"
]};
static get titleTypes(){
return[
"RESIDENTIAL",
"COMMERCIAL",
"INDUSTRIAL"
]};
static get bedroomNo(){
return[
"1",
"2",
"3",
"4",
"5"
]};
static get bathroomNo(){
return[
"1",
"2",
"3",
"4",
"5"
]};
get selectTenure() { return this.constructor.selectTenure; }
get selectTitle() { return this.constructor.selectTitle; }
get selectBedroom() { return this.constructor.selectBedroom; }
get selectBathroom() { return this.constructor.selectBathroom; }
get tenureTypes() { return this.constructor.tenureTypes; }
get titleTypes() { return this.constructor.titleTypes; }
get bedroomNo() { return this.constructor.bedroomNo; }
get bathroomNo() { return this.constructor.bathroomNo; }
hasInputError = (name) => {
if (this.props.errors[name]) {
return ' is-error';
}
return '';
}
render() {
return (
<div className={`Listing--Create${ this.props.isMobile ? '' : ' is-desktop' }`} id='form-second-page'>
{/* <form className="Listing--form"> */}
<div className="Listing--bedrooms-bathrooms">
<div className="type-title">No. of Bedrooms</div>
<Dropdown namespace="bedroom" selected={ this.selectBedroom[0] } options={ this.selectBedroom } onOptionSelect={ this.onBedroomDropdownSelect }/>
<div className="type-title">Asking Price</div>
<input className={`text-input price-input${ this.hasInputError('price')}`} type="text" onChange={ (e) => this.props.onPrice(e.currentTarget.value) } value={this.props.price} placeholder="RM"/>
</div>
<div className="Listing--price-built-up">
<div className="type-title">No. of Bathrooms</div>
<Dropdown namespace="bathroom" selected={ this.selectBathroom[0] } options={ this.selectBathroom } onOptionSelect={ this.onBathroomDropdownSelect }/>
<div className="type-title">Built-up Size</div>
<input className={`text-input built-up-input${ this.hasInputError('built_up_size')}`} type="text" onChange={ (e) => this.props.onBuiltUpSize(e.currentTarget.value) } value={this.props.builtUp} placeholder="sqft."/>
</div>
<div className="Listing--tenure">
<div className="type-tenure">Select Tenure</div>
<Dropdown namespace="tenure" selected={ this.selectTenure[0] } options={ this.selectTenure } onOptionSelect={ this.onTenureDropdownSelect }/>
</div>
<div className="Listing--title">
<div className="type-title">Select Title</div>
<Dropdown namespace="title" selected={ this.selectTitle[0] } options={ this.selectTitle } onOptionSelect={ this.onTitleDropdownSelect }/>
</div>
<div className="Listing--photos">
<div className="type-title">Upload Photos</div>
<button className={`text-input photos-input${ this.hasInputError('photos')}`}>Click to upload</button>
</div>
<div className="Listing--description">
<div className="type-title">Describe your property</div>
<textarea className={`text-input description-input${ this.hasInputError('description')}`} onChange={ (e) => this.props.onDescription(e.currentTarget.value) } value={this.props.description} placeholder="Describe your property"/>
</div>
</div>
);
}
};
const MapStateToProps = (state: State) => ({
...
});
const MapDispatchToProps = (dispatch: Dispatch) => ({
...
})
export default connect(MapStateToProps, MapDispatchToProps)(CreateListingFormPage2);
Basically, there is nothing wrong with my redux store. All the value of the input is captured successfully. The problem is when submitting the form, either the onSubmit or my form structure method is incorrect.
This is CreateListing.js reducer should it be helpful:
const INITIAL_STATE= {
isListingLoading: false,
isListingCreated: false,
}
const CreateListing = (state = INITIAL_STATE, action) => {
switch(action.type){
case 'CREATE_LISTING_LOADING':
return Object.assign({}, state, {isListingLoading: true});
case 'CREATE_LISTING_SUBMIT_FORM':
return Object.assign({}, state, {isListingCreated: true});
default:
return state;
} }
export default CreateListing;
Any help is much appreciated.
if you have any other buttons in your form you should add type="button".
so make changes like this.
<button type="button" className="Button button-create is-red" onClick={this.props.onLoadingCreateListing}>
CREATE LISTING
</button>
I have a problem. I'm lost in the deep forest of reactJs. I'm new here.
I have 8 components which I need to get via clicking on short-name button .
What are the steps.
I select what I need from the first filter and I get short_names and all the components without data.
I don't want to get all the components, i need just 1 component that I'll get by clicking on a short name.
Screenshot here
Here is code of rendering page:
import React, { Component } from 'react';
import { Link } from 'react-router';
import { getAll, getAllRates } from '../actions';
import { MODULE_NAME } from './index';
import { PanelHeader, PanelFooter, LocalFilter } from 'Components';
import locales from 'Shared/locales';
import search from 'Shared/search';
import sortBy from 'Shared/sortBy';
import { AvsProviders, FakProviders, LaaProviders, Laac1Providers,
Laac2Providers, Laac3Providers, MpgProviders, Mpg2Providers } from '../ComponentsProviders';
export default class ListsAccounting extends Component {
state = {
data: [],
le_id: null,
year: new Date().getFullYear(),
totalPages: 0,
searchString: '',
limit: '50',
page: 1,
};
search = search(this);
sortBy = sortBy(this);
loadData = (params) => {
const { searchString } = this.state;
const q = searchString === '' ? null : searchString;
getAll({ leId: this.state.le_id, name: MODULE_NAME, params: { q, year: this.state.year, ...params } })
.then(success => this.setState({
data: success.data,
totalPages: success.totalPages,
page: success.page,
limit: String(success.limit || ''),
}));
};
constructor() {
super();
this.onClick = this.handleClick.bind(this);
}
handleClick(event) {
const { id } = event.target;
console.log(id);
}
getData = (leId, id, type, year) => {
getAllRates({ leId, id, type, year, name: MODULE_NAME })
.then(() => this.loadData());
};
changeState = state => this.setState(state, () => this.loadData());
render() {
const { limit, totalPages, data } = this.state;
console.log(this);
return (
<div className="container">
<div className="row">
<div className="col-xs-12 col-sm-12 col-md-6">
<div className="panel panel-adminme table-dynamic">
<PanelHeader
name="insurances"
currentState={{
state: this.state,
loadData: this.loadData,
}}
/>
<div className="table-filters">
<div className="row no-x-margin">
<div className="col-sm-4 col-xs-6">
<LocalFilter
name="all-providers-leg-entities"
placeholder="le_id"
option="le_id"
value={this.state.le_id}
changeState={this.changeState}
/>
</div>
<div className="col-md-3 col-sm-4 col-xs-6">
<LocalFilter
name="insurance-years"
placeholder="year"
option="year"
value={this.state.year}
changeState={this.changeState}
/>
</div>
</div>
</div>
<div className="table-responsive">
<table className="table table-bordered table-striped table-hover">
<thead>
<tr className="text-center">
<th>
NAME
</th>
<th>
SHORT_NAME
</th>
<th>
ACTION
</th>
</tr>
</thead>
<tbody>
{
!data.length &&
<tr>
<td colSpan="3" className="text-center">
{locales('no_rows')}
</td>
</tr>
}
{
data.map((row, index) => (
<tr key={`${MODULE_NAME}-${index}`}>
<td>
<h5>{row.type}</h5>
</td>
<td>
{
row.text.map((name, indexText) => (
<span key={name} className="margin-right-10">
<Link
key={row.type}
role="button"
onClick={ () => this.getData(
this.state.le_id,
row.text_id[indexText],
row.type,
row.year,
)}
>
{name}
</Link>
</span >
))
}
</td>
<td className="btn btn-info">
ADD
</td>
</tr>
))
}
</tbody>
</table>
</div>
<PanelFooter
limit={limit}
totalPages={totalPages}
loadData={this.loadData}
/>
</div>
</div>
<div className="col-xs-12 col-sm-12 col-md-6">
{ data.type === data.type && data.text_id === data.text_id &&
data.map((row) => {
console.log(row.type);
switch (row.type) {
case 'AVS':
return (
<AvsProviders/>
);
case 'FAK' :
return (
<FakProviders/>
);
case 'LAA':
return (
<LaaProviders/>
);
case 'LAAC1':
return (
<Laac1Providers/>
);
case 'LAAC2':
return (
<Laac2Providers/>
);
case 'LAAC3':
return (
<Laac3Providers/>
);
case 'MPG':
return (
<MpgProviders/>
);
case 'MPG2':
return (
<Mpg2Providers/>
);
default:
return null;
}
})
}
</div>
</div>
</div>
);
}
}
Here is page of 1 of the rendering components:
import React, { Component } from 'react';
import { getAllRates } from '../../actions';
import { PanelHeader } from 'Components';
const MODULE_NAME = 'FAK';
export default class FakProviders extends Component {
state = {
data: [],
le_id: null,
year: new Date().getFullYear(),
totalPages: 0,
searchString: '',
limit: '50',
page: 1,
};
componentDidMount() {
this.loadData();
}
loadData = (params) => {
const { searchString } = this.state;
const q = searchString === '' ? null : searchString;
getAllRates({ leId: this.props.params.le_id,
id: this.props.params.text_id,
name: MODULE_NAME,
params: { q, ...params } })
.then(success => this.setState({
data: success.data,
totalPages: success.totalPages,
page: success.page,
limit: String(success.limit || ''),
}));
};
changeState = state => this.setState(state, () => this.loadData());
render() {
const { data } = this.state;
return (
<div className="panel panel-adminme table-dynamic">
<PanelHeader
name="insurances"
currentState={{
search: this.search,
state: this.state,
loadData: this.loadData,
}}
/>
<div className="table-responsive">
<table className="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>
<h4>{data.fak_short_name}</h4>
</th>
<th>
<h4>{data.year}</h4>
</th>
</tr>
</thead>
<tbody>
<tr>
<th>
<h4>fak_rate_ee</h4>
</th>
<th>
<h4>
{data.fak_rate_ee}
</h4>
</th>
</tr>
<tr>
<th>
<h4>fak_rate_er</h4>
</th>
<th>
<h4>
{data.fak_rate_er}
</h4>
</th>
</tr>
</tbody>
</table>
</div>
<div className="panel-footer" />
</div>
);
}
}