Open and close expandable button in list view - html

I have a list of Messages that you should be able to click and expand more for info. At the moment, my implementation expands/collapses all messages by clicking on any message.
I tried using the code below:
this.state = {
activeIndex:0,
isExpandable:false
}
And applying the condition as:
{!this.state.isExpandable && this.state.activeItem === i} to the map() where i was retrieving properties of each object.
image of buttons in collapsable state
image of buttons in expanded state
import React, { Component } from 'react'
import { Card, Feed } from 'semantic-ui-react'
import { Input } from 'react-input-component';
import { Collapse, Button} from 'reactstrap';
import styled from 'styled-components';
function searchingForName(search){
return function(x){
return x.firstName.toLowerCase().includes(search.toLowerCase()) || x.lastName.toLowerCase().includes(search.toLowerCase()) || !search ;
}
}
class Home extends Component {
constructor(props){
super(props);
this.state = {
results:[],
search:'',
collapse:false,
newSearch:'',
tags:[],
isExpandable:false,
activeIndex:0
}
this.onchange = this.onchange.bind(this);
this.toggle = this.toggle.bind(this);
this.inputKeyDown = this.inputKeyDown.bind(this);
// this.handleKeyPress = this.handleKeyPress.bind(this);
}
onchange = e => {
console.log(this.state.search)
this.setState({search:e.target.value});
}
// handleKeyPress = e => {
// if(e.key === 'Enter'){
// this.setState({newSearch: e.target.value});
// }
// }
inputKeyDown = (e) => {
const val = e.target.value;
if(e.key === 'Enter' && val){
if (this.state.tags.find(tag => tag.toLowerCase() === val.toLowerCase())) {
return;
}
this.setState({tags: [...this.state.tags,val]});
this.tagInput.value=null;
}
}
toggle(){
this.setState({collapse: !this.state.collapse});
}
componentDidMount(){
fetch('https://www.hatchways.io/api/assessment/students')
.then(res => res.json())
.then(data => {
console.log(data.students);
this.setState({results:data.students})
}).catch(err => {
console.log(err);
});
}
render() {
return (
<div>
<Card style={{'marginTop':'40px','width':'520px','marginRight':'auto','marginLeft':'auto'}}>
<Card.Content>
<Input
style={{'width':'519px'}}
placeholder="Search by name..."
onChange={this.onchange}
/>
<Input
style={{'width':'519px'}}
placeholder="Search by tags..."
onChange={this.onchange}
/>
{this.state.results.length ?
this.state.results.filter(searchingForName(this.state.search)).map((value,i) => (
<Feed>
<Feed.Event style={{'margin':'10px'}}>
<Image>
<Feed.Label image={value.pic} />
</Image>
<div style={{'float':'right'}}>
{!this.state.collapse ?
<Button onClick={this.toggle}>+</Button>
: <Button onClick={this.toggle}>-</Button>}
</div>
<Feed.Content style={{'textAlign':'center','marginBottom':'10px'}}>
<Feed.Summary><strong>{value.firstName.toUpperCase()} {value.lastName.toUpperCase()}</strong></Feed.Summary>
<Feed.Summary>Email: {value.email}</Feed.Summary>
<Feed.Summary>Company: {value.company}</Feed.Summary>
<Feed.Summary>Skill: {value.skill}</Feed.Summary>
<Feed.Summary>Average : {value.grades.map((x,i,arr)=> {
return x/arr.length;})
.reduce((a,b) => {
return a + b;
}) + "%"}
</Feed.Summary><br />
<Collapse isOpen={this.state.collapse}>
<Feed.Summary>
{Array.isArray(value.grades) && value.grades.map(val => {
return <div>Test {value.grades.indexOf(val)} : {parseFloat(val) + "%"}</div>
})}
</Feed.Summary><br />
{this.state.tags.map((tag,index) => (
<div>
<span className="addTag"key={index}>{tag}</span>
</div>
))}<br />
<input
type="text"
onKeyDown={this.inputKeyDown}
ref={c => { this.tagInput = c; }}
placeholder="add a tag..."
/>
{/* <div>{this.state.newSearch}</div><br />
<Input
style={{'width':'200px'}}
placeholder="add a tag..."
value={this.state.newSearch}
onKeyPress={this.handleKeyPress}
/> */}
</Collapse>
<hr/>
</Feed.Content>
</Feed.Event>
</Feed>
)) : ''}
</Card.Content>
</Card>
</div>
)
}
}
const Image = styled.div`
border: 1px solid #001;
border-radius: 60px;
overflow:hidden;
padding:18px;
height:90px;
width: 90px;
margin-top:30px;
margin-right:auto;
margin-left:auto;
margin-bottom:20px;
`
export default Home;
What is causing them all to expand/collapse at once and how can i change that to only expand/collapse the button is clicked?

Your main problem is that you don't have isOpened card for every student. You can only open all or none with one single collapse state. I have updated your code with solution here:
https://codesandbox.io/s/peaceful-kapitsa-tr9yn
I have changes toggle function, which takes index as parameter and updates single students card status - isOpened true or false.
toggle(index) {
const results = this.state.results.map((item, idx) => {
if (index === idx) {
return {
...item,
isOpened: !item.isOpened
};
}
return item;
});
this.setState({ results });
}
When you load all students data from API endpoint, you have to map through all items and add default isOpened state (by default I've added false - closed).
componentDidMount() {
fetch("https://www.hatchways.io/api/assessment/students")
.then(res => res.json())
.then(data => {
console.log(data.students);
const results = data.students.map(student => {
return {
...student,
isOpened: false
};
});
this.setState({ results });
})
.catch(err => {
console.log(err);
});
}
In render() method I have updated every item to check not this.state.collapse, but student.isOpened on Collapse component and toggle button.
Toggle button
<div style={{ float: "right" }}>
{!value.isOpened ? (
<Button onClick={() => this.toggle(i)}>+</Button>
) : (
<Button onClick={() => this.toggle(i)}>-</Button>
)}
</div>
Collapse component
<Collapse isOpen={value.isOpened}>
...
</Collapse>

Related

how to Dynamic add field post with reactjs and axios post

I am working on Dynamic add field data submit with reactjs and axios. Its working fine but only on one filed when i want to add more field then the field added but when i put my data and want to post data then only one field working. i am using react and axios post for submit my form.
My code
import React from 'react';
import axios from 'axios';
import { Grid, Button } from "#material-ui/core/";
import Alert from '#material-ui/lab/Alert';
import CloseIcon from "#material-ui/icons/Close";
import TextField from "#material-ui/core/TextField";
import AddIcon from '#material-ui/icons/Add';
class FaqPage extends React.Component<{},any>{
constructor(props) {
super(props)
this.state = {
faqList:[{index: Math.random(), question:'', answer: ''}],
// question: '',
// answer: '',
questions: ['hello']
}
this.state = { values: [{question: '',response: ''}] };
this.handleSubmit = this.handleSubmit.bind(this);
}
componentDidUpdate(){
setTimeout(() => this.setState({errorMessage:''}), 40000);
setTimeout(() => this.setState({sucessMessage:''}), 40000);
}
uploadDocument = (e) => {
console.log(e);
}
handlequestionChange = event => {this.setState({ question: event.target.value })}
handleanswerNameChange = event => {this.setState({ answer: event.target.value })}
handleSubmit = event => {
event.preventDefault();
event.target.reset()
// const openDate = {userid: this.state.openDate};
// const closeDate = {fullname: this.state.closeDate};
// const listingDate = {usergroup: this.state.listingDate};
axios.post('https://api.com/api/faqs',
{
ipoId: '328',
faqList:[
{ question: this.state.question,
answer: this.state.answer,
}
]
}
)
.then(res => {
console.log(res);
console.log(res.data);
console.log('thank you')
this.setState({sucessMessage: res.data});
})
.catch(err => {
this.setState({errorMessage: err.message});
})
}
createUI(){
return this.state.values.map((el, i) =>
<div key={i} className="commonInput">
<div className="formW">
<TextField type="text" label="question" name="question" onChange={this.handlequestionChange}/>
</div>
<div className="formW">
<TextField type="text" label="answer" name="answer" onChange={this.handleanswerNameChange}/>
</div>
{
i ?
<button type="button" className="button remove" onClick={() => this.removeClick(i)}><CloseIcon /></button>
: null
}
</div>
)
}
handleChange (i,event) {
let values = [...this.state.values];
values[i][event.target.id] = event.target.value;
this.setState({ values });
}
addClick(){
this.setState(prevState => ({ values: [...prevState.values, {question: '',response: '',}]}))
}
removeClick(i){
let values = [...this.state.values];
values.splice(i,1);
this.setState({ values });
}
componentDidMount() {
axios.get(`https://api.com/api/get/all`)
.then(res => {
const posts = res.data;
this.setState({ posts });
})
}
render() {
return (
<Grid className="CoomonT">
<div className="clapse ">
<form onSubmit={this.handleSubmit}>
<br/>
{this.createUI()}
<input type='button' value='add more' onClick={this.addClick.bind(this)}/>
{/* <div className="form-btn formW">
<Button
size="small"
variant="contained"
className=""
color="primary"
onClick={this.addClick.bind(this)}
>
<AddIcon/>
</Button>
</div> */}
{/* <div>file<TradeImportComponent/></div> */}
{/* <button type="submit" color="primary">Add</button> */}
<div className="form-btn formW">
<Button
size="small"
variant="contained"
className=""
color="primary"
type="submit"
disableElevation
>
Submit
</Button>
</div>
</form>
</div>
</Grid>
)
}
}
export default FaqPage;
Screenshot
Why are you using this.state two times? Each class component in React has only 1 state. So first of all, you should correct your state definition. Moreover, Your values state is an Array. So when you want to edit your question/answer or post data via axios, you should use the whole values array.
There are also some questions that you should answer to yourself to have a cleaner code. I implemented some general changes and commented those questions in the below code. Answer them and change code based on their answer, so that your code works.
import axios from 'axios';
import React from 'react';
import { Grid, Button } from "#material-ui/core/";
import Alert from '#material-ui/lab/Alert';
import CloseIcon from "#material-ui/icons/Close";
import TextField from "#material-ui/core/TextField";
import AddIcon from '#material-ui/icons/Add';
class FaqPage extends React.Component<{},any>{
constructor(props) {
super(props)
// What is defference between faqList and values? Could'nt you use just one of them? and build the other one from another one (whenever needed)?
this.state = {
faqList:[{index: Math.random(), question:'', answer: ''}],
values: [{question: '',response: ''}]
}
this.handleSubmit = this.handleSubmit.bind(this);
}
componentDidUpdate(){
setTimeout(() => this.setState({errorMessage:''}), 40000);
setTimeout(() => this.setState({sucessMessage:''}), 40000);
}
uploadDocument = (e) => {
console.log(e);
}
handleQuestionChange = (event, index) => {
const faq = this.state.values
faq[index].question = event.target.value
this.setState(faq)
}
handleAnswerNameChange = (event, index) => {
const faq = this.state.values
faq[index].answer = event.target.value
this.setState(faq)
}
handleSubmit = event => {
event.preventDefault();
event.target.reset()
// What is ipoId? Is it different from the `index` field in `this.state.faqList`?
axios.post('https://api.com/api/faqs',
{
ipoId: '328',
faqList:this.state.value
}
)
.then(res => {
console.log(res);
console.log(res.data);
console.log('thank you')
this.setState({sucessMessage: res.data});
})
.catch(err => {
this.setState({errorMessage: err.message});
})
}
createUI(){
return this.state.values.map((el, i) =>
<div key={i} className="commonInput">
<div className="formW">
<TextField type="text" label="question" name="question" onChange=(e, i) => {this.handleQuestionChange(i)}/>
</div>
<div className="formW">
<TextField type="text" label="answer" name="answer" onChange=(i) => {this.handleAnswerNameChange(e, i)}/>
</div>
{
i ?
<button type="button" className="button remove" onClick={() => this.removeClick(i)}><CloseIcon /></button>
: null
}
</div>
)
}
addClick(){
this.setState(prevState => ({ values: [...prevState.values, {question: '',response: '',}]}))
}
removeClick(i){
let values = [...this.state.values];
values.splice(i,1);
this.setState({ values });
}
componentDidMount() {
axios.get(`https://api.com/api/get/all`)
.then(res => {
const posts = res.data;
this.setState({ posts });
})
}
render() {
return (
<Grid className="CoomonT">
<div className="clapse ">
<form onSubmit={this.handleSubmit}>
<br/>
{this.createUI()}
<input type='button' value='add more' onClick={this.addClick.bind(this)}/>
{/* <div className="form-btn formW">
<Button
size="small"
variant="contained"
className=""
color="primary"
onClick={this.addClick.bind(this)}
>
<AddIcon/>
</Button>
</div> */}
{/* <div>file<TradeImportComponent/></div> */}
{/* <button type="submit" color="primary">Add</button> */}
<div className="form-btn formW">
<Button
size="small"
variant="contained"
className=""
color="primary"
type="submit"
disableElevation
>
Submit
</Button>
</div>
</form>
</div>
</Grid>
)
}
}
export default FaqPage;

Ant design Tree defaultExpandAll doesnt work with button click for react

Iam using Ant Design for React Js UI. Am using Tree component to show up in the list. I also have 2 button to expand and collapse the Tree list. I use the defaultExpandAll prop to manage this.
On the expand and collapse button click i set a bool to true and false respectively.
Button it doesn't expand on the button click.
If I set True initially to that flag state it works.
Is there any work Around.
I have 2 components. (Expand and collapse button are in parent component)
**Parent Component**
setExpandOrCollapse(value) {
this.setState({ expandOrCollapse: value });
}
<HeaderRow>
<Button onClick={() => this.setExpandOrCollapse(true)}>Expand All</Button>
<Button onClick={() => this.setExpandOrCollapse(false)}>Collapse All</Button>
</HeaderRow>
<Card>
{ItemTree && (ItemTree.length > 0) ? (
<ItemTree
dataSource={ItemTree}
expandOrCollapse={expandOrCollapse}
/>
) : null }
</Card>
**Child Component**
<Tree
draggable={isDraggable}
defaultExpandAll={expandOrCollapse}
>
{loopitemNodes(dataSource)}
</Tree>
dataSource is obtained from Redux api call.
Is there any work around.
The states in Ant design which are prefixed with default only work when they are rendered for the first time (and hence the default).
For working out programmatic expand and collapse, you need to control the expansion of tree using expandedKeys and onExpand props.
import { flattenDeep } from "lodash";
class Demo extends React.Component {
state = {
expandedKeys: []
};
constructor(props) {
super(props);
this.keys = this.getAllKeys(treeData);
}
getAllKeys = data => {
// This function makes an array of keys, this is specific for this example, you would have to adopt for your case. If your list is dynamic, also make sure that you call this function everytime data changes.
const nestedKeys = data.map(node => {
let childKeys = [];
if (node.children) {
childKeys = this.getAllKeys(node.children);
}
return [childKeys, node.key];
});
return flattenDeep(nestedKeys);
};
onExpand = expandedKeys => {
console.log("onExpand", expandedKeys);
// if not set autoExpandParent to false, if children expanded, parent can not collapse.
// or, you can remove all expanded children keys.
this.setState({
expandedKeys
});
};
renderTreeNodes = data =>
data.map(item => {
if (item.children) {
return (
<TreeNode title={item.title} key={item.key} dataRef={item}>
{this.renderTreeNodes(item.children)}
</TreeNode>
);
}
return <TreeNode key={item.key} {...item} />;
});
expandAll = () => {
this.setState({
expandedKeys: this.keys
});
};
collapseAll = () => {
this.setState({
expandedKeys: []
});
};
render() {
return (
<Fragment>
<button onClick={this.expandAll}>Expand All</button>
<button onClick={this.collapseAll}>Collapse All</button>
<Tree onExpand={this.onExpand} expandedKeys={this.state.expandedKeys}>
{this.renderTreeNodes(treeData)}
</Tree>
</Fragment>
);
}
}
Codesandbox
class Demo extends React.Component {
state = {
expandedKeys: ["0-0-0", "0-0-1"],
autoExpandParent: true,
selectedKeys: []
};
onExpand = expandedKeys => {
console.log("onExpand", expandedKeys);
// if not set autoExpandParent to false, if children expanded, parent can not collapse.
// or, you can remove all expanded children keys.
this.setState({
expandedKeys,
autoExpandParent: false
});
};
onSelect = (selectedKeys, info) => {
console.log("onSelect", info);
this.setState({ selectedKeys });
};
renderTreeNodes = data =>
data.map(item => {
if (item.children) {
return (
<TreeNode title={item.title} key={item.key} dataRef={item}>
{this.renderTreeNodes(item.children)}
</TreeNode>
);
}
return <TreeNode key={item.key} {...item} />;
});
onExpandAll = () => {
const expandedKeys = [];
const expandMethod = arr => {
arr.forEach(data => {
expandedKeys.push(data.key);
if (data.children) {
expandMethod(data.children);
}
});
};
expandMethod(treeData);
this.setState({ expandedKeys });
};
onCollapseAll = () => {
this.setState({ expandedKeys: [] });
};
render() {
return (
<Fragment>
<Button onClick={this.onExpandAll} type="primary">
ExpandAll
</Button>
<Button onClick={this.onCollapseAll} type="primary">
CollapseAll
</Button>
<Tree
onExpand={this.onExpand}
expandedKeys={this.state.expandedKeys}
autoExpandParent={this.state.autoExpandParent}
selectedKeys={this.state.selectedKeys}
>
{this.renderTreeNodes(treeData)}
</Tree>
</Fragment>
);
}
}
please refer to the Codesandbox link

Render input fields dynamically inside a list

I have set of components where it would consist of input fields along with text rows.
As given in the image the users should be able to add categories and description. After adding them they will be rendered as a list of components. like this
Inside a category there will be tags as given in the above image and to add them i have to add a input component. This input component should be available only when the user clicks on the Add tag button below each category row. When a user clicks on it,it should enable the input(should render a input component inside the selected category row) and should be able to type the tag name on it and save it. I need to make this input field enable only when i click on the add tag button. and it should enable only in the selected category row. This is the code that i have tried.
import React, { Component, Fragment } from "react";
import { Button, Header, Input } from "semantic-ui-react";
import "semantic-ui-css/semantic.min.css";
import ReactDOM from "react-dom";
class App extends Component {
state = {
category: "",
description: "",
categories: []
};
onChange = (e, { name, value }) => {
this.setState({ [name]: value });
};
addCategory = () => {
let { category, description } = this.state;
this.setState(prevState => ({
categories: [
...prevState.categories,
{
id: Math.random(),
title: category,
description: description,
tags: []
}
]
}));
};
addTag = id => {
let { tag, categories } = this.state;
let category = categories.find(cat => cat.id === id);
let index = categories.findIndex(cat => cat.id === id);
category.tags = [...category.tags, { name: tag }];
this.setState({
categories: [
...categories.slice(0, index),
category,
...categories.slice(++index)
]
});
};
onKeyDown = e => {
if (e.key === "Enter" && !e.shiftKey) {
console.log(e.target.value);
}
};
tags = tags => {
if (tags && tags.length > 0) {
return tags.map((tag, i) => {
return <Header key={i}>{tag.name}</Header>;
});
}
};
enableTagIn = id => {};
categories = () => {
let { categories } = this.state;
return categories.map(cat => {
return (
<Fragment key={cat.id}>
<Header>
<p>
{cat.title}
<br />
{cat.description}
</p>
</Header>
<Input
name="tag"
onKeyDown={e => {
this.onKeyDown(e);
}}
onChange={this.onChange}
/>
<Button
onClick={e => {
this.addTag(cat.id);
}}
>
Add
</Button>
{this.tags(cat.tags)}
</Fragment>
);
});
};
render() {
return (
<Fragment>
{this.categories()}
<div>
<Input name="category" onChange={this.onChange} />
<Input name="description" onChange={this.onChange} />
<Button onClick={this.addCategory}>Save</Button>
</div>
</Fragment>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
This is the codesandbox url.
Any idea on how to achieve this?.
I changed your code by using function components and react hooks and i created category component which has it own state like this:
import React, { Fragment } from "react";
import { Button, Header, Input } from "semantic-ui-react";
import "semantic-ui-css/semantic.min.css";
import ReactDOM from "react-dom";
const App = () => {
const [Category, setCategory] = React.useState({
title: "",
description: ""
});
const [Categories, setCategories] = React.useState([]);
return (
<div>
{console.log(Categories)}
<Input
value={Category.title}
onChange={e => setCategory({ ...Category, title: e.target.value })}
/>
<Input
value={Category.description}
onChange={e =>
setCategory({ ...Category, description: e.target.value })
}
/>
<Button onClick={() => setCategories([...Categories, Category])}>
Save
</Button>
<div>
{Categories.length > 0
? Categories.map(cat => <CategoryItem cat={cat} />)
: null}
</div>
</div>
);
};
const CategoryItem = ({ cat }) => {
const [value, setvalue] = React.useState("");
const [tag, addtag] = React.useState([]);
const [clicked, setclicked] = React.useState(false);
const add = () => {
setclicked(false);
addtag([...tag, value]);
};
return (
<Fragment>
<Header>
<p>
{cat.title}
<br />
{cat.description}
</p>
</Header>
<Input
name="tag"
value={value}
style={{ display: clicked ? "initial" : "none" }}
onChange={e => setvalue(e.target.value)}
/>
<Button onClick={() => (clicked ? add() : setclicked(true))}>Add</Button>
<div>{tag.length > 0 ? tag.map(tagname => <p>{tagname}</p>) : null}</div>
</Fragment>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
and here a sandbox

How to login validation using my api in React Js

React JS
I'm new to react js
In my api there is username and password. If the user login, have to validate from my json value
handleSubmit(e) {
fetch('https://randomuser.me/api?results=1')
.then((response) => {
return response.json()
.then((json) => {
if (response.ok) {
return Promise.resolve(json)
}
return Promise.reject(json)
})
})
alert(json) not working to check the result.
How can i fetch the username and password in the response?
And how to take this next page if the user was logged in successfully ?
My full Code
App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import CSSTransitionGroup from 'react-transition-group/CSSTransitionGroup';
const ReactCSSTG = CSSTransitionGroup;
class App extends Component {
constructor(props) {
super(props);
this.state = {
isVisible: true
}
// Bindings
this.handleSubmit = this.handleSubmit.bind(this);
this.handleRemount = this.handleRemount.bind(this);
}
handleSubmit(e) {
alert("dsa");
fetch('https://randomuser.me/api?results=1')
.then((response) => {
return response.json()
.then((json) => {
if (response.ok) {
return Promise.resolve(json)
}
return Promise.reject(json)
})
})
}
handleRemount(e) {
this.setState({
isVisible: true
}, function () {
console.log(this.state.isVisible)
});
e.preventDefault();
}
render() {
// const for React CSS transition declaration
let component = this.state.isVisible ? <Modal onSubmit={this.handleSubmit} key='modal' /> : <ModalBack onClick={this.handleRemount} key='bringitback' />;
return <ReactCSSTG transitionName="animation" transitionAppear={true} transitionAppearTimeout={500} transitionEnterTimeout={500} transitionLeaveTimeout={300}>
{component}
</ReactCSSTG>
}
}
// Modal
class Modal extends React.Component {
render() {
return <div className='Modal'>
<Logo />
<form onSubmit={this.props.onSubmit}>
<Input type='text' name='username' placeholder='username' />
<Input type='password' name='password' placeholder='password' />
<button> Sign In</button>
</form>
<a href='#'>Lost your password ?</a>
</div>
}
}
// Generic input field
class Input extends React.Component {
render() {
return <div className='Input'>
<input type={this.props.type} name={this.props.name} placeholder={this.props.placeholder} required />
<label htmlFor={this.props.name}></label>
</div>
}
}
// Fake logo
class Logo extends React.Component {
render() {
return <div className="logo">
<i><img src={logo} className="App-logo" alt="logo" /></i>
<span> Test </span>
</div>
}
}
// Button to brind the modal back
class ModalBack extends React.Component {
render() {
return (
<button className="bringitback" onClick={this.props.onClick} key={this.props.className}>Back to login page!</button>
);
}
}
export default App;
Thanks in Advance!
If you just want to catch data for now this will do the trick
fetch('https://randomuser.me/api?results=1')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(JSON.stringify(myJson));
});
fetch('https://randomuser.me/api?results=1')
.then((response) => {
// check for status code from service if success
// set response in state such as login success
this.route.navigate(['/']);
})
.catch(error =>{
console.log(error);
});
})
Taking user to next page. Use react router for achieving this.
Step 1: Wrap your <App /> inside <BrowserRouter />
Now validate response if username/password are correct using service call.
Then this.route.navigate(['/']);
This will navigate user to home page of app after successful login.
Heres What I did, keep in mind I set up my backend with express/node.
I used Axios to fetch from my api.
onSubmit = (e) => {
e.preventDefault();
axios.get('API_PATH')
.then(res => {
const user = res.data[0].username;
const password = res.data[0].password;
const username = this.state.username;
const passwordEntered = this.state.password;
if(username === '' && passwordEntered === ''){
document.getElementById('status').innerHTML = '<p>Please Enter A Valid Username and Password</p>';
}else if(user === username && passwordEntered === password){
document.getElementById('status').innerHTML = '';
console.log(user, password)
}else{
document.getElementById('status').innerHTML = '<p>Please Enter A Valid Username and Password</p>';
}
})
.catch(error => {
console.log(error);
});
}
Here is the form I used.
<Form
>
<Form.Row>
<Form.Group as={Col}>
<Form.Label>Username</Form.Label>
<Form.Control
type="text"
name="username"
id="username"
value={this.state.value}
onChange={this.handleChange}
>
</Form.Control>
</Form.Group>
<Form.Group as={Col}>
<Form.Label>Password</Form.Label>
<Form.Control
type="text"
id="password"
name="password"
value={this.state.value}
onChange={this.handleChange}
/>
</Form.Group>
</Form.Row>
<Button className="btn btn-sm btn-light" onClick={this.onSubmit}>
<i style={redColor} className="fas fa-sign-in-alt"></i> Login
</Button>
</Form>

My dialog box component is not Showing in Reactjs

I have a component name dialog Box and i want to show it on click over all other components . I have a main component as
class ImageEditor extends Component {
constructor() {
super();
this.state = { images: [], redirect: 'no', imageId: '', isDialogOpen: 'no' };
}
componentDidMount() {
let promise = apiGateway.getImages();
promise.then((images) => {
this.setState({ images: images });
});
}
openDialog = () =>{
this.setState({ isDialogOpen : 'yes' });
}
closeDialog = () =>{
this.setState({ isDialogOpen: 'no' });
}
deleteImage = (id) => {
apiGateway.removeImage(id);
}
setRedirect = (id) => {
this.setState({ redirect: 'yes', imageId: id });
}
renderImage(image,index){
return(
<div key={index}>
<p>Title: {image.title}</p>
<p>Description: {image.description}</p>
<button onClick={(e)=> this.deleteImage(image._id)}>DELETE</button>
<button onClick={(e)=> this.setRedirect(image._id)}>UPDATE</button>
<button onClick={this.openDialog}>SHARE</button>
<img className='image' src={image.link} width='100' height='100' alt='nature'/>
<br/><br/>
</div>
);
}
render() {
const { redirect , isDialogOpen } = this.state;
if(redirect === 'yes'){
return <Redirect to={`/update/${this.state.imageId}`}/>
}
if(isDialogOpen === 'yes'){
<DialogBox /> ????????
}
return(
<div>
<div>{
this.state.images.map((image,index)=>{
return this.renderImage(image,index);
})
}
</div>
</div>
);
}
}
export default ImageEditor;
When a person clicks on SHARE , I want Dialog Box to Open.I donot know the way i am doing i.e loading component with dialogBox is right or wrong. So every Advice or any suggestion will definitely help me. Here is my dialogue component(Right now i am getting a error as :Expected an assignment or function call and instead saw an expression no-unused-expressions)
class DialogBox extends Component {
render() {
return(
<div>
<Dialog title="Dialog Title" modal={true} onClose={this.handleClose} buttons={ [{ text: "Close", onClick: () => this.handleClose() }] }>
<h1>Dialog Content</h1>
<p>More Content. Anything goes here</p>
</Dialog>
</div>
);
}
}
You can do this:
return (
<div>
<insert your other components>
{this.state.isDialogOpen === 'yes' && <DialogBox />}
<div>
)
I'd advise using boolean instead of string for isDialogOpen.