Fetch data between two dates in React from Django API - reactjs

I am trying to filter data between two dates and display it in a table. Currently, my table shows all the data from the database but I want the user to be able to select from that date to this date, and data between the specified dates to be displayed in the table.
My code:
import React from "react";
import APIHandler from "../utils/APIHandler";
import _ from "lodash";
import moment from "moment";
import DatePicker from "react-datepicker";
import { initiateGetTransactions } from "../components/Transactions";
import ReactHTMLTableToExcel from "react-html-table-to-excel";
class FarmerStatementComponent extends React.Component {
constructor(props) {
super(props);
console.log(props.match.params.id);
}
state = {
errorRes: false,
errorMessage: "",
btnMessage: 0,
sendData: false,
orders: [],
startDate: new Date(),
endDate: new Date(),
dataLoaded: false,
formSubmitted: false,
name: "",
id: "",
};
componentDidMount() {
this.fetchFarmerData().then(response => {
console.log(response.data);
this.setState({
orders: response.data
});
});
}
handleStartDateChange = (date) => {
this.setState({
startDate: date
});
}
handleEndDateChange = (date) => {
this.setState({
endDate: date
});
}
handleSubmit = (event) => {
debugger;
event.preventDefault();
const data = { startDate:this.state.startDate, endDate:this.state.endDate};
}
async fetchFarmerData() {
var apihandler = new APIHandler();
var farmerdata = await apihandler.fetchFarmerDetails(this.props.match.params.id);
console.log(farmerdata);
this.setState({ orders: farmerdata.data.data.orders });
this.setState({ name: farmerdata.data.data.name });
this.setState({ phone: farmerdata.data.data.phone });
this.setState({ dataLoaded: true });
}
print() {
window.print();
}
render() {
return (
<section className="content">
<div className="container-fluid">
<div className="block-header">
<h2>FARMER STATEMENT</h2>
</div>
<div className="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div className="card">
<div className="header">
<h2>
{this.state.name}'S STATEMENT
</h2>
<div className="header-dropdown m-r--5">
<h2>
{this.state.id}
</h2>
</div>
</div>
<div className="body">
<div className="table-responsive">
<div id="DataTables_Table_1_wrapper" className="dataTables_wrapper form-inline dt-bootstrap">
<div className="dt-buttons">
<a className="dt-button buttons-csv buttons-html5" tabIndex="0" aria-controls="DataTables_Table_1" href="#">
<span>
<ReactHTMLTableToExcel
className="btn btn-success"
tabIndex="0"
aria-controls="DataTables_Table_1"
table="DataTables_Table_1"
filename="FarmerStatement"
sheet="Sheet"
buttonText="Excel"
/>
</span>
</a>
<a className="dt-button buttons-print" tabIndex="0" aria-controls="DataTables_Table_1" href="#" onClick={this.print}>
<span onClick={() => this.print()}>Print</span>
</a>
<br/>
<form onSubmit={this.handleSubmit}>
<button type="submit" className="btn btn-info" >
Generate Report
</button>
</form>
</div>
<div id="DataTables_Table_1_filter" className="dataTables_filter">
<form onSubmit={this.handleSubmit}>
<label>
<i className="material-icons">date_range</i>Start Date:
<DatePicker
selected={this.state.startDate}
className="form-control datepicker"
name="Start Date: 30/07/2022"
aria-controls="DataTables_Table_1"
value={this.state.startDate}
onChange={this.handleStartDateChange}
/>
</label>
<br/>
<label>
<i className="material-icons">date_range</i>End Date:
<DatePicker
selected={this.state.endDate}
className="form-control datepicker"
name="End Date: 30/07/2022"
aria-controls="DataTables_Table_1"
value={this.state.endDate}
onChange={this.handleEndDateChange}
/>
</label>
</form>
</div>
{this.state.dataLoaded === false ? (
<div className="text-center">
<div className="preloader pl-size-xl">
<div className="spinner-layer">
<div className="circle-clipper left">
<div className="circle"></div>
</div>
<div className="circle-clipper right">
<div className="circle"></div>
</div>
</div>
</div>
</div>
) : ""}
<table className="table table-bordered table-striped table-hover dataTable js-exportable" id="DataTables_Table_1" role="grid" aria-describedby="DataTables_Table_1_info">
<thead>
<tr role="row">
<th className="sorting_asc" tabIndex="0" aria-controls="DataTables_Table_1" rowSpan="1" colSpan="1" aria-sort="ascending" aria-label="Name: activate to sort column descending" style={{width: "40px"}}>
#ORDER NO
</th>
<th className="sorting" tabIndex="0" aria-controls="DataTables_Table_1" rowSpan="1" colSpan="1" aria-label="Position: activate to sort column ascending" style={{width: "150px"}}>
CUSTOMER NAME
</th>
<th className="sorting" tabIndex="0" aria-controls="DataTables_Table_1" rowSpan="1" colSpan="1" aria-label="Office: activate to sort column ascending" style={{width: "101px"}}>
KILOS
</th>
<th className="sorting" tabIndex="0" aria-controls="DataTables_Table_1" rowSpan="1" colSpan="1" aria-label="Age: activate to sort column ascending" style={{width: "100px"}}>
PRICE PER KG
</th>
<th className="sorting" tabIndex="0" aria-controls="DataTables_Table_1" rowSpan="1" colSpan="1" aria-label="Start date: activate to sort column ascending" style={{width: "115px"}}>
ORDERED ON
</th>
</tr>
</thead>
<tbody>
{this.state.orders.map((farmer) => (
<tr role="row" className="odd" key={farmer.id}>
<td className="sorting_1">{farmer.id}</td>
<td className="sorting_1">{farmer.customer.name}</td>
<td className="sorting_1">{farmer.kgs}</td>
<td className="sorting_1">{farmer.price}</td>
<td className="sorting_1">{new Date(farmer.added_on).toLocaleString()}</td>
</tr>
))}
</tbody>
</table>
<div className="dataTables_info" id="DataTables_Table_1_info" role="status" aria-live="polite">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
);
}
}
export default FarmerStatementComponent;

You can add filter in query or you can do filter to incoming data from database before passing to table

Related

I create a todo list system and I use a map to make a loop for all the items I have. But items are stuck for me in the same row in the table

I create a todo list system and I use a map to make a loop for all the items I have.
But items are stuck for me in the same row in the table.
This is a system I used to build in js vanila and now for practice I run it in react.
I would be happy for a solution.
In js vanila I would use insertAdjacentHTML
But I'm looking for the solution in react
demo for the app: https://v1-todolist.netlify.app
My Problem All items in one row.
I need not all items to be on the same line I need it to be dropped line like here
Example of how the item should look properly.
This system I built it in js vanila
if i add Div it not work
It does not sit well in the table and I also get a validateDOMNesting (...) error: cannot appear as a child of .
my code App.js
import { useState } from "react";
import "./App.css";
import Form from "./Form";
import Alert from "./Alert";
function App() {
const [nameTask, setNameTask] = useState("");
const [priority, setPriority] = useState("Low");
const [list, setList] = useState([]);
const [alert, setAlert] = useState({ show: false, type: "", msg: "" });
const handlerSubmit = function (e) {
e.preventDefault();
if (!nameTask) return showAlert(true, "danger", "you cannot input empty");
const newList = {
id: new Date().getTime().toString(),
title: nameTask,
priority: priority,
};
setList([...list, newList]);
};
const showAlert = function (show = false, type, msg) {
setAlert({ show, type, msg });
};
return (
<article className="vh-100 gradient-custom-2">
{alert.show && <Alert {...alert} showAlert={showAlert} />}
<Form
list={list}
setNameTask={setNameTask}
setPriority={setPriority}
handlerSubmit={handlerSubmit}
/>
</article>
);
}
export default App;
Form.js
import React from "react";
const Form = function ({ handlerSubmit, setNameTask, setPriority, list }) {
return (
<div className="container py-5 h-100">
<div className="row d-flex justify-content-center align-items-center h-100">
<div className="col-md-12 col-xl-10">
<div className="card mask-custom">
<div className="card-body p-4 text-white">
<div className="text-center pt-3 pb-2">
<img
src="https://mdbootstrap.com/img/Photos/new-templates/bootstrap-todo-list/check1.png"
alt="Check"
width="60"
/>
<h2 className="my-4">Task List</h2>
</div>
<form className="form-task" onSubmit={(e) => handlerSubmit(e)}>
<div className="col-auto">
<input
name="name-task"
type="text"
className="form-control task-input"
id="autoSizingInput"
placeholder="Add Task"
onChange={(e) => setNameTask(e.target.value)}
/>
</div>
<select
className="form-select"
aria-label="Default select example"
onChange={(e) => setPriority(e.target.value)}
>
<option value="Low">Low</option>
<option value="Normal">Normal</option>
<option value="High">High</option>
</select>
<button type="submit" className="btn btn-primary">
submit
</button>
</form>
<table className="table text-white mb-0">
<thead>
<tr>
<th scope="col">Task</th>
<th scope="col">Priority</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
<tr className="fw-normal">
{list.map((item, index) => {
return (
<React.Fragment key={index}>
<th>
<span className="ms-2" data-name={`${item.title}`}>
{item.title}
</span>
</th>
<td className="align-middle priority-class">
<span className="badge ${value.color}">
{item.priority}
</span>
</td>
<td className="align-middle">
<h6 className="mb-0" data-id="${value.id}">
<a className="remove-link" href="#">
<span className="badge bg-gradient remove">
❌
</span>
</a>
<a className="complete-link" href="#">
<span className="badge bg-gradient complete">
✔
</span>
</a>
</h6>
</td>
</React.Fragment>
);
})}
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
);
};
export default Form;
Check this CodeSandbox
I was able to solve your issu just by adding a flex propriety to the panel that contain your list and by changing React.fragment by a div.
However it would perhaps be better to swap the node with the class fw-normal to a div and change the React.fragment to the node tr.

Message prints in every Dynamic Accordion in ReactJs

I have a dynamic Accordion in ReactJs. I am getting the message from my backend. but it's printing in every Accordion. I'm sharing the code
import React, { useState, useEffect } from "react";
import ApplicantDash from "./ApplicantDash";
import {
Accordion,
AccordionSummary,
AccordionDetails,
Typography,
} from "#material-ui/core";
import * as FcIcons from "react-icons/fc";
import ApplicantService from "../services/ApplicantService";
export default function AvailJobs() {
const [aplcntEmail, setAplcntEmail] = useState("aman#gmail.com"); //change to aplcntemail
const [isShow, setIsShow] = useState(false);
const [msg, setMsg] = useState([""]);
const [job, setJob] = useState([
{
jobTitle: "",
dateOfPosting: Date,
lastDateToApply: new Date().toLocaleDateString([], {
year: "numeric",
month: "long",
day: "numeric",
}),
preferableSkills: [],
requiredExp: 0,
recruiterEmail: "",
companyName: "",
companyAddress: "",
},
]);
useEffect(() => {
const data = ApplicantService.getAllJobs()
.then((response) => {
console.log(response.data);
setJob(response.data);
})
.catch((error) => {
alert(error.response.data);
});
}, []);
const onApplyButton = (item,key) => {
const data2 = ApplicantService.applyForJob(aplcntEmail, item)
.then((response) => {
console.log(response.data);
setIsShow(true);
setMsg(response.data)
})
.catch((error) => {
setIsShow(true);
setMsg(error.response.data);
});
};
return (
<div>
<ApplicantDash />
<div className="container bg-light">
<div className="card-bodies">
<section className="mb-4">
<h2 className="h1-responsive font-weight-bold text-center my-4">
All Available jobs
</h2>
</section>
{job.map((item, key) => (
<>
<Accordion key={key}>
<AccordionSummary
expandIcon={<FcIcons.FcExpand />}
aria-controls="panel1a-content"
id="panel1a-header"
className="Accordian"
>
<Typography>
<div className="d-flex p-1 justify-content-evenly">
<div className="p-1">
<b> Job: </b> {item.jobTitle}
</div>
<div className="p-2"></div>
<div className="p-1">
<b> Company: </b> {item.companyName}
</div>
<div className="p-2"></div>
<div className="p-1">
<b> Last Date: </b> {item.lastDateToApply}
</div>
</div>
</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography>
<div className="container">
<table class="table table-borderless">
<tbody>
<tr>
<td>JOB TITLE</td>
<td>:</td>
<td>
<b>{item.jobTitle}</b>
</td>
</tr>
<tr>
<td>Company</td>
<td>:</td>
<td>
<b>{item.companyName}</b>
</td>
</tr>
<tr>
<td>Address</td>
<td>:</td>
<td>
<b>{item.companyAddress}</b>
</td>
</tr>
<tr>
<td>Last Date to Apply</td>
<td>:</td>
<td>
<b>{item.lastDateToApply}</b>
</td>
</tr>
<tr>
<td>Experience</td>
<td>:</td>
<td>
<b>{item.requiredExp}</b>
</td>
</tr>
<tr>
<td> Skills </td>
<td>:</td>
<td>
<table className="table table-condensed w-auto table-borderless table-hover">
{item.preferableSkills.map((S, index1) => {
return (
<tbody key={index1}>
<td scope="col">
{index1 + 1}.<b>{S}</b>
</td>
</tbody>
);
})}
</table>
</td>
</tr>
<tr>
<td></td>
<td></td>
<td>
<button
type="button"
class="btn btn-primary"
onClick={() => onApplyButton(item,key)}
>
Apply for the job{" "}
</button>
</td>
</tr>
</tbody>
{isShow && <>
{msg}
</>}
</table>
</div>
</Typography>
</AccordionDetails>
</Accordion>
</>
))}
</div>
</div>
</div>
);
}
Now when I click on Apply for this job button. The message I get from backend prints only to Active accordion
Here some pictures which might help.
enter image description here
As you can see the response from backend is prints in the both of the accordion
Issue
The issue here is that you've a single boolean isShow state and a single msg state, and all the accordion detail sections use the same single isShow state to conditionally render the msg state.
Solution
A simple solution would be to store the id, or title, or index, of the accordion to show the message of.
Example:
export default function AvailJobs() {
...
const [isShow, setIsShow] = useState({}); // <-- initially empty object
...
const onApplyButton = (item, key) => {
ApplicantService.applyForJob(aplcntEmail, item)
.then((response) => {
console.log(response.data);
setMsg(response.data);
})
.catch((error) => {
setMsg(error.response.data);
})
.finally(() => {
setIsShow(show => ({
...show,
[key]: true // <-- set true the specific key
}));
});
};
return (
<div>
...
{job.map((item, key) => (
<Accordion key={key}>
...
<AccordionDetails>
<Typography>
<div className="container">
<table class="table table-borderless">
<tbody>
...
<tr>
...
<td>
<button
type="button"
class="btn btn-primary"
onClick={() => onApplyButton(item, key)}
>
Apply for the job
</button>
</td>
</tr>
</tbody>
{isShow[key] && <>{msg}</>} // <-- check if isShow[key] is truthy
</table>
</div>
</Typography>
</AccordionDetails>
</Accordion>
))}
...
</div>
);
}

Add row to existing table dynamically in ReactJS

I am learning ReactJS.
I have pre-existing table rendered which contains thead and only 1 row by default. Now on button click, I want to append a row everytime the button click, but the max rows appended should not be greater than 4.
Here is my code:
import React, { Component } from "react";
import Sidebar from "../Home/Sidebar";
import axios from "axios";
import $ from "jquery";
import { isDivisibleBy100 } from "../utils/utility";
import { Chart } from "react-charts";
class Strategy extends Component {
state = {
Price: [],
chart_data: [],
loadData: true,
unit: parseFloat(0),
loadUnit: true,
};
componentDidMount() {
this.getPriceList();
}
getPriceList() {
axios.get("http://localhost:8000/listprice/").then(res => {
if (res.data.result === 1) {
this.setState({ Price: res.data.data });
}
});
}
appendRow(event) {
var rel = event.target.getAttribute("rel");
rel = parseInt(rel) + 1;
console.log(rel);
var addRow = (
<tr>
<td>
<input type="text" id={`select-type` + rel} />
</td>
<td>
<input type="text" id={`select-position` + rel} />
</td>
</tr>
);
$(".table tbody").append(appRow);
}
render() {
return (
<div className="container container_padding">
<div className="row">
<Sidebar />
<div className="col-md-9 col-sm-9 col-xs-12 white-box">
<div className="col-sm-12">
<h3 className="col-sm-4" style={{ padding: "0px" }}>
Strategy Plan:
</h3>
<div className="col-sm-7" />
<div className="col-sm-1" style={{ marginTop: "15px" }}>
<button
rel="1"
type="button"
id="addbtn"
className="btn btn-circle"
onClick={this.appendRow}
>
<i className="fa fa-plus" />
</button>
</div>
</div>
<div className="col-sm-12 a">
<div className="table-responsive">
<table className="table table-bordered">
<thead>
<tr>
<td>#</td>
<td>Type</td>
<td>Position</td>
<td>Price</td>
<td>Number</td>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>
<select
className="form-control"
name="select-type"
id="select-type"
>
<option value="select">Select</option>
<option value="one">1</option>
<option value="two">2</option>
</select>
</td>
<td>
<select
className="form-control"
name="select-position"
id="select-position"
>
<option value="select">Select</option>
<option value="a">A</option>
<option value="b">B</option>
</select>
</td>
<td>
<select
className="form-control"
name="price-list"
id="price-list"
onChange={event =>
this.handlePriceChange(event)
}
>
<option value="select">Select</option>
{this.state.Price.map(p => (
<option
value={p.pprice}
key={p.price}
>
{p.price}
</option>
))}
</select>
</td>
<td style={{ width: "180px" }}>
<input
id="input-number"
type="text"
className="form-control"
defaultValue="1"
/>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div className="col-sm-12">
<button
className="btn"
onClick={() => this.handleClick()}
>
Calculate
</button>
</div>
{this.state.loadData ? (
""
) : (
<div
style={{
width: "600px",
height: "300px",
marginTop: "35px",
marginLeft: "25px",
marginBottom: "10px"
}}
>
<Chart
data={this.state.chart_data}
series={{ type: "line" }}
axes={[
{ primary: true, type: "linear", position: "bottom" },
{ type: "linear", position: "left" }
]}
primaryCursor
secondaryCursor
tooltip
/>
</div>
)}
</div>
</div>
</div>
);
}
}
export default Strategy;
The appendRow function is not appending the row.
What am I missing? Is there any better way to achieve this?
Please suggest.
Thanks in advance
You are using jquery and directly handling real DOM. With React we use Virtual DOM and don't manipulate the real DOM. Unlike Jquery, in react you don't have to worry about handling UI. Your concern should be handling the data properly, leave the UI updates to React. You haven't provided the Table Component information here. So, I would give you a code sample which does exactly what you want to achieve. For the button you can place it where it's needed within this component.
import React from "react";
class Table extends React.Component {
state = {
data: []
};
appendChild = () => {
let { data } = this.state;
data.push(data.length); // data.length is one more than actual length since array starts from 0.
// Every time you call append row it adds new element to this array.
// You can also add objects here and use that to create row if you want.
this.setState({data});
};
render() {
return (
<table>
<thead>
<th>Type</th>
<th>Position</th>
</thead>
<tbody>
{this.state.data.map(id => (
<Row id = {id} />
))}
</tbody>
</table>
);
}
}
const Row = ({ id }) => (
<tr>
<td>
<input type="text" id={`select-type-${id}`} />
</td>
<td>
<input type="text" id={`select-position-${id}`} />
</td>
</tr>
);
Constructor method:
constructor(props) {
super(props)
this.state = {rows: []};
}
Inside your appendRow method, instead of adding the tr directly to your tbody, add the tr to the rows state:
appendRow(event) {
var rel = event.target.getAttribute("rel");
rel = parseInt(rel) + 1;
var joined = this.state.rows.concat(
<tr>
<td>
<input type="text" id={`select-type` + rel} />
</td>
<td>
<input type="text" id={`select-position` + rel} />
</td>
</tr>
);
this.setState({ rows: joined })
}
Inside your render method, just put the array in. It will be re-rendered whenever setState is called:
render() {
...
return (
...
<button
rel="1"
type="button"
id="addbtn"
className="btn btn-circle"
onClick={this.appendRow}>
<i className="fa fa-plus" />
</button>
...
<tbody>
{this.state.rows}
</tbody>
...
)
...
}

Meteor(REACT) -- Unable to update input text value

Unable to change/update value of input which is coming from database. Tried to understand https://facebook.github.io/react/docs/forms.html but not getting it.
Basically code is about showing roles collection data in table format and update facility is in modal input field.
This is my UMRolesList.jsx
export default class UMRolesList extends TrackerReact(Component) {
rolesListData(){
return Meteor.roles.find({}).fetch();
}
constructor(){
super();
this.state = {
subscription : {
"rolesData" : Meteor.subscribe('rolefunction'),
}
}
}
render(){
return(
<section className="Content">
<div className="row reportWrapper">
<div className="col-md-10 col-lg-12 col-sm-12 col-xs-12 noLRPad">
<div className="col-lg-12 col-md-12 col-sm-12 col-xs-12 noLRPad">
<h1 className="reportTitleName">LIST OF ROLES</h1>
<hr/>
<UMaddRoles/>
<table className="table-responsive table table-striped table-hover myTable dataTable no-footer">
<thead className="table-head umtblhdr">
<tr className="hrTableHeader">
<th className="umHeader"> Role </th>
<th className="umHeader"> Action </th>
</tr>
</thead>
<tbody>
{ this.rolesListData().map( (rolesData)=>{
return <UMadd_role key={rolesData._id} roleDataVales={rolesData}/>
})
}
</tbody>
</table>
</div>
</div>
</div>
</section>
);
}
}
This is my UMadd_role.jsx
export default class UMadd_role extends TrackerReact(Component) {
handleChange(event){
console.log("changing the text area to: " + event.target.value)
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
constructor(props) {
super(props);
this.state = {
roleName: props.roleDataVales.name,
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
render(){
return(
<tr>
<td> {this.props.roleDataVales.name}</td>
<td>
<button className="editrole fa fa-pencil-square-o" data-toggle="modal" data-target={`#edit-${this.props.roleDataVales._id}`} ></button>
<div id={`edit-${this.props.roleDataVales._id}`} className="modal fade" role="dialog">
<div className="modal-dialog">
<div className="modal-content reportWrapper">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal">×</button>
<h4 className="modal-title">Edit Role</h4>
</div>
<div className="modal-body col-lg-12 col-md-12 col-sm-12 col-xs-12">
<form className="editroles">
<div className="form-group col-lg-5 col-md-4 col-xs-12 col-sm-12 paddingLeftz">
<label>Role Name*</label>
<input type="text" ref="roleName" className="form-control rolesField" name={`${this.props.roleDataVales._id}-Namerole`} value=value={`${this.state.roleName}`} onChange={this.handleChange.bind(this)} required/>
</div>
<div className="form-group col-lg-1 col-md-4 col-xs-12 col-sm-12 ">
<label> </label>
<button type="button" onClick={this.editRole.bind(this)} id={this.props.roleDataVales._id} className="btn btn-primary submit" data-dismiss="modal">Edit Role</button>
</div>
</form>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-primary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</td>
</tr>
);
}
}
Thanks in advance!
The reason for that maybe because you have assigned this.props.roleDataVales.name and there is no onChange for the the input field.
Try storing the the value this.props.roleDataVales.name in the state in the constructor and have an onChange on input field to update the value.
Handle change event to change your value and setting it as a current state
handleChange(event){
this.setState({value: event.target.value});
}
In constructor, store your value which may be coming from database which is props.roleDataVales.name and save it in state which is (defined in constructor) {this.state.roleName}.
constructor(props) {
super(props);
this.state = {
roleName: props.roleDataVales.name,
};
this.handleChange = this.handleChange.bind(this);
}
And finally use defaultValue instead of value attribute and bind onChange event to input. Provide {this.state.roleName} to defaultValue which is coming from constructor.
<input type="text" ref="roleName" defaultValue={`${this.state.roleName}`} onChange={this.handleChange.bind(this)}/>

Creating multiple page application using react

I have created SPA using react and hence my address bar does not change when I move to another view.Kindly help in changing the address bar. News feed Code is
import React from 'react';
import axios from 'axios';
import Stories from './Stories';
export default class NewsFeed extends React.Component {
constructor(props) {
super(props);
this.state = { feed: [], showPopUp: false, showStoryPopUp: false, readArr: [], importantArr: [], counterArr: [], deleteArr: [] };
this.handleClose = this.handleClose.bind(this);
this.handleCreateFeed = this.handleCreateFeed.bind(this);
this.handlePost = this.handlePost.bind(this);
this.handleCreateStories = this.handleCreateStories.bind(this);
}
componentWillMount() {
let self = this;
axios.get('src/rest/feed.json')
.then(function (response) {
let counterArr = self.state.counterArr;
let readArr = self.state.readArr;
let deleteArr = self.state.deleteArr;
for (let item of response.data) {
counterArr.push(0);
readArr.push(false);
deleteArr.push(false);
}
self.setState({ feed: response.data });
})
.catch(function (error) {
console.log(error);
});
}
changeImportant(index) {
let arr = this.state.importantArr;
arr[parseInt(index)] = !arr[parseInt(index)];
this.setState({ importantArr: arr });
}
changeReadFlag(index) {
let arr = this.state.readArr;
arr[parseInt(index)] = !arr[parseInt(index)];
this.setState({ readArr: arr });
}
decrement(index) {
let arr = this.state.counterArr;
arr[parseInt(index)] = arr[parseInt(index)] - 1;
this.setState({ counterArr: arr });
}
handleDelete(index) {
let arr = this.state.deleteArr;
arr[parseInt(index)] = !arr[parseInt(index)];
this.setState({ deleteArr: arr });
}
increment(index) {
let arr = this.state.counterArr;
arr[parseInt(index)] = arr[parseInt(index)] + 1;
this.setState({ counterArr: arr });
}
handlePost(header, description,broker) {
// console.log(document.querySelector("#title-input").value,document.querySelector("#description-input").value)
let tempObj = { imgsrc: "images1.jpg" };
// tempObj.header = document.querySelector("#title-input").value;
// tempObj.description = document.querySelector("#description-input").value;
tempObj.header = header;
tempObj.description = description;
tempObj.broker = broker;
let tempArr = this.state.feed;
tempArr.push(tempObj);
let counterArr = this.state.counterArr.push(0);
this.setState({ showStoryPopUp: false });
}
handleClose() {
this.setState({ showPopUp: false, showStoryPopUp: false })
}
handleCreateFeed() {
this.setState({ showPopUp: true });
}
handleCreateStories() {
this.setState({ showStoryPopUp: true });
}
render() {
return (
<div className="email-class lis-cls">
{this.state.showStoryPopUp ? <Stories handlePost={this.handlePost} handleClose={this.handleClose} /> : null}
{this.props.userType === 'admin' ? <button id="story-btn" type="button" className="btn btn-primary fixed-cls fa fa-pencil" style={{ display: this.state.showPopUp || this.state.showStoryPopUp ? 'none' : 'inline-block' }} onClick={this.handleCreateStories} > Create Stories</button> : null}
{this.state.feed.map((feed, index) => {
return (<div key={index} id={index} className={this.state.showPopUp || this.state.showStoryPopUp ? 'row row-feed hide-cls' : this.state.deleteArr[index] ? 'row row-feed hide-cls' : 'row row-feed'} >
<h4 className="list-header">{feed.header}</h4>
<img src={"src/img/" + feed.imgsrc} alt="Smiley face" height="100" width="100" />
<span className="feed-text">{feed.description}</span>
<div className="row">
<div className="col-md-1">
<span className={this.state.readArr[index] ? "fa fa-check-circle pull-right" : ""}></span>
</div>
<div className="col-md-1">
<div className="pull-right">
<div className="fa fa-arrow-up display-block-cls" onClick={this.increment.bind(this, index)}></div>
<div className={this.state.counterArr[index] == 0 ? "vote-cls" : this.state.counterArr[index] > 0 ? "vote-cls upvote" : "vote-cls downvote"}>
{this.state.counterArr[index]}
</div>
<div className="fa fa-arrow-down display-block-cls" onClick={this.decrement.bind(this, index)}> </div>
</div>
</div>
<div className="col-md-8">
<button id="read" className="btn btn-success fa fa-pencil" onClick={this.changeReadFlag.bind(this, index)}> Read </button>
<button id="delete" className="btn btn-danger fa fa-trash-o" onClick={this.handleDelete.bind(this, index)}> Delete </button>
<button className="btn btn-primary fa fa-exclamation" onClick={this.changeImportant.bind(this, index)}> Important </button>
</div>
</div>
<hr className={this.state.importantArr[index] ? 'imp-cls' : 'hr-cls'} />
</div>)
})}
</div>
);
}
}
stoies code is
import React from 'react';
export default class Stories extends React.Component {
constructor(props) {
super(props);
this.handleClose = this.handleClose.bind(this);
this.handlePost = this.handlePost.bind(this);
}
handleClose() {
this.props.handleClose();
}
handlePost(){
let header = document.querySelector("#title-input").value;
let description = document.querySelector("#description-story-input").value;
let broker = document.querySelector("#broker-input").value;
this.props.handlePost(header,description,broker);
}
render() {
return (<div className={'popup-cls add-story-top'}>
<div className={'add-story email-class'}>
<img onClick={this.handleClose} className="cross-cls" src="src/img/cross.png" alt="Smiley face" height="35" width="35" />
<h4 className="list-header">Create Stories</h4>
<table>
<tbody>
<tr>
<td>
Title
</td>
<td>
<input type="text" id="title-input" />
</td>
</tr>
<tr>
<td>
Description </td>
<td> <textarea rows="4" cols="50" id="description-story-input"></textarea>
</td>
</tr>
<tr>
<td>
Broker </td>
<td> <input type="text" id="broker-input" />
</td>
</tr>
<tr>
<td>
Ticker </td>
<td> <input type="text" id="ticker-input" />
</td>
</tr>
<tr>
<td>
Category </td>
<td> <input type="text" id="category-input" />
</td>
</tr>
<tr>
<td>
Direction </td>
<td> <input type="number" min="-2" max="2" defaultValue="0" id="direction-input" />
</td>
</tr>
<tr>
<td>
Rating </td>
<td> <input type="number" min="-5" max="5" defaultValue="0" id="rating-input" />
</td>
</tr>
<tr>
<td>
Score </td>
<td> <input type="number" min="-4" max="4" defaultValue="0" id="score-input" />
</td>
</tr>
<tr>
<td>
Trade Price </td>
<td> <input type="text" id="trade-price-input" />
</td>
</tr>
<tr>
<td>
Pre Trade Price </td>
<td> <input type="text" id="pre-trade-input" />
</td>
</tr>
<tr>
<td>
Attachment </td>
<td> <input type="file" id="attachment-input" />
</td>
</tr>
<tr>
<td>
Links </td>
<td> <input type="text" id="links-input" />
</td>
</tr>
<tr>
<td>
Percentage Change </td>
<td> <input type="text" id="percentage-change-input" />
</td>
</tr>
<tr>
<td>
Tags </td>
<td> <input type="text" id="tag-input" />
</td>
</tr>
<tr>
<td></td>
<td><button onClick={this.handlePost} id="post-btn" type="button" className="btn btn-primary fa fa-envelope" > Post</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>);
}
}
login code is
import React from 'react';
import axios from 'axios';
export default class Login extends React.Component {
constructor(props) {
super(props);
this.state = { login: false, userName: '', password: '' ,isValid : true};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChangeUserName = this.handleChangeUserName.bind(this);
this.handleChangePassword = this.handleChangePassword.bind(this);
}
handleSubmit() {
let self = this;
axios.get('src/rest/login.json')
.then(function (response) {
response.data.map((user)=>{
if(user.userName === self.state.userName && user.password === self.state.password ){
self.props.setLogin( true,user.role);
self.setState({isValid :true })
}else{
self.setState({isValid :false })
}
});
})
.catch(function (error) {
console.log(error);
});
}
handleChangeUserName(event){
this.setState({userName : event.target.value});
}
handleChangePassword(event){
this.setState({password : event.target.value});
}
render() {
return (
<div className="email-class email-class-div login-cls">
<div className="row row-login header-class">
<h3 className="float-class" >Login</h3>
<img src="src/img/star.png" className="float-class img-class" alt="Smiley face" height="35" width="35" />
</div>
<div className="error-div" style={{display : !this.state.isValid?'block':'none'}}>Invalid username or password</div>
<div className="row row-login androidTextbox">
<input className="col-md-6" type="text" placeholder="User ID/Email" onChange={this.handleChangeUserName}/>
</div>
<div className="row row-login androidTextbox">
<input className="col-md-6" type="password" placeholder="Password" onChange={this.handleChangePassword} />
</div>
<div className="row row-login submit-row" onClick={this.handleSubmit}>
<div id="button" >SUBMIT</div>
</div>
</div>
);
}
}
All three have same address.
I'm not sure how you are navigating without routes unless you are showing/hiding components. You could look into implementing the hash router

Resources