I am working with simple form validation in react. The problem here is error message is not displaying in while it is showing in console.log! I am quite new to react and stucked here for quite some time. How can I solve this?
I've seen many youtube videos but nothing is working properly.
const [logindata, setLogindata] = useState({
customeremail: '',
customerpass: ''
})
const [err, seterr] = useState({
Email: '',
Passwordnew: ''
});
const handlechange = event => {
const val = event.target.value
const name = event.target.name
setLogindata({ ...logindata, [name]: val })
console.log(val)
}
function login() {
const NewErr = {...err};
if (logindata.customeremail == "") {
NewErr.Email = "Email should not be empty";
alert(NewErr.Email)
console.log(NewErr)
}
}
return (
<>
<div className="container">
<div className="row">
<div className="col-12 col-sm-12 col-md-6 col-lg-6 main-col offset-md-3">
<div className="mb-4">
<form method="post" action="home" id="CustomerLoginForm" acceptCharset="UTF-8" className="contact-form">
<div className="row">
<div className="col-12 col-sm-12 col-md-12 col-lg-12">
<div className="form-group">
<label htmlFor="CustomerEmail">Email</label>
<input type="email" name="customeremail" placeholder="" id="CustomerEmail" className="" autoCorrect="off" autoCapitalize="off" autoFocus="" onChange={handlechange} value={logindata.customeremail} required = {true} />
</div>
<div className="alert alert-danger" role="alert">
{seterr.Email}
</div>
</div>
<div className="col-12 col-sm-12 col-md-12 col-lg-12">
<div className="form-group">
<label htmlFor="CustomerPassword">Password</label>
<input type="password" name="customerpass" placeholder="" id="CustomerPassword" className="" onChange={handlechange} value={logindata.customerpass} />
</div>
</div>
</div>
<div className="row">
<div className="text-center col-12 col-sm-12 col-md-12 col-lg-12">
<input type="button" style={{ backgroundColor: '#000', color: '#fff' }} className="btn mb-3" value="Sign In" onClick={login} />
<p className="mb-4">
Forgot your password? |
Create account
</p>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</>
There are 2 problem in your code
1. Not setting state
You are not setting state for err using seterr as:
if (logindata.customeremail == '') {
NewErr.Email = 'Email should not be empty';
alert(NewErr.Email);
console.log(NewErr);
seterr(NewErr); // MISSING
}
CODESANDBOX LINK
2. Showing error message with wrong way
When you use useState then it will give you an array of value and function through which you can update the value and on change of the value it will re-render it. You have to use err obj not the function seterr.
You should use {err.Email}} instead of {seterr.Email}}
<div className='alert alert-danger' role='alert'>
{/* {seterr.Email} */}
{err.Email}
</div>;
Related
I'm working on dynamic react form. I want to update dynamic form data. I have populate and get the data from backend successfully but when I enter in input field for change some data then I'm not able to change it. I am adding here my form image. Please check and tell me how can I can fix it.
import React from "react"
const VarientDetailEdit = (props) => {
return (
props.varientDetails.map((val, idx) => {
let sort=`sort-${idx}`, sku=`sku-${idx}`, waightunitno=`waightunitno-${idx}`, unit=`unit-${idx}`, mrp=`mrp-${idx}`, discount=`discount-${idx}`, price=`price-${idx}`, stock=`stock-${idx}`, minstock=`minstock-${idx}`, outofstock=`outofstock-${idx}`
return (
<div>
<div style={{float:"right"}}>
{
idx ?
<button style={{paddingLeft:"10px"}} className="btn btn-danger" onClick={(() => props.delete(val))} ><i className="fa fa-minus" aria-hidden="true"></i></button> : null
}
</div>
<div><br></br><br></br>
<div key={val.index} className='row'>
<div class="form-group col-sm-4">
<label>Sort:</label>
<input type="text" value={val.sort} name="sort" data-id={idx} id={sort} className="form-control " />
</div>
<div class="form-group col-sm-4">
<label>SKU</label>
<input type="text" value={val.sku} name="sku" data-id={idx} id={sku} className="form-control " />
</div>
<div class="form-group col-sm-4">
<label>Weight/Quantity</label>
<input type="text" value={val.waightunitno} name="waightunitno" id={waightunitno} data-id={idx} className="form-control " />
</div>
</div>
<div className='row'>
<div class="form-group col-sm-4">
<label>Unit</label>
<input type="text" value={val.unit} name="unit" id={unit} data-id={idx} className="form-control " />
</div>
<div class="form-group col-sm-4">
<label>MRP <em style={{color:"tomato"}}>*</em></label>
<input type="text" value={val.mrp} name="mrp" id={mrp} data-id={idx} className="form-control " />
</div>
<div class="form-group col-sm-4">
<label>Discount(%) <em style={{color:"tomato"}}>*</em></label>
<input type="text" value={val.discount} name="discount" id={discount} data-id={idx} className="form-control " />
</div>
</div>
<div className='row'>
<div class="form-group col-sm-4">
<label>Price <em style={{color:"tomato"}}>*</em></label>
<input type="text" value={val.price} name="price" id={price} data-id={idx} className="form-control " />
</div>
<div class="form-group col-sm-4">
<label>Stock <em style={{color:"tomato"}}>*</em></label>
<input type="text" value={val.stock} name="stock" id={stock} data-id={idx} className="form-control " />
</div>
<div class="form-group col-sm-4">
<label>Min Stock Alert <em style={{color:"tomato"}}>*</em></label>
<input type="text" value={val.minstock} name="minstock" id={minstock} data-id={idx} className="form-control " />
</div>
<div className='col-sm-4'>
<div className="form-group">
<label className="form-label">Variant Out of Stock Status <em style={{color:"tomato"}}>*</em></label>
<select name="outofstock" value={val.outofstock} id={outofstock} data-id={idx} className="form-control" >
<option value="pending">Pending</option>
<option value="In Progress">In progress</option>
<option value="Completed">Completed</option>
<option value="Hold">Hold</option>
</select>
</div>
</div>
<hr className="my-4"></hr>
</div>
</div>
</div>
)
})
)
}
export default VarientDetailEdit
Parent component
handleChange = (e) => {
if (["sort", "sku", "waightunitno", "unit", "mrp", "discount", "price", "stock", "minstock", "outofstock"].includes(e.target.name)) {
let varientDetails = [...this.state.varientDetails]
varientDetails[e.target.dataset.id][e.target.name] = e.target.value;
} else if (["isTex"].includes(e.target.name)) {
this.setState({ [e.target.name]: e.target.value })
console.log(e)
// }else if (["files[]"].includes(e.target.name)) {
// this.setState({ files:e.target.files });
}
else {
this.setState({ [e.target.name]: e.target.value })
}
}
addNewRow = () => {
this.setState((prevState) => ({
varientDetails: [...prevState.varientDetails, { index: Math.random(), sort:5,
sku: "",
waightunitno: "",
unit:"",
mrp:0,
discount:0,
price:0,
stock:0,
minstock:0,
outofstock:""}],
}));
}
deteteRow = (index) => {
this.setState({
varientDetails: this.state.varientDetails.filter((s, sindex) => index !== sindex),
});
}
handleSubmit = (e) => {
e.preventDefault();
console.log(this.state)
if(this.state.date==='' || this.state.description==='')
{
NotificationManager.error(" Error -Please Fill up all Required Field!!!");
return false;
}
for(var i=0;i<this.state.varientDetails.length;i++)
{
if(this.state.varientDetails[i].sort==='' || this.state.varientDetails[i].varient==='')
{
NotificationManager.error("Error- Product Varient Fields are required!!!");
return false;
}
}
const formData = new FormData();
for (const file of this.state.files) {
formData.append('file', file)
}
const config = {
Headers: {
'content-type': 'multipart/form-data',
"Content-Type": "multipart/form-data; boundary=AaB03x" +
"--AaB03x" +
"Content-Disposition: file" +
"Content-Type: png" +
"Content-Transfer-Encoding: binary" +
"...data... " +
"--AaB03x--",
"Accept": "application/json",
"type": "formData"
},
productId:this.state.id,
name:this.state.name,
description:this.state.description,
lableType:this.state.lableType,
photo:this.state.thumbNailphoto,
isTex:this.state.isTex,
GSTrate:this.state.GSTrate,
GSTtyp:this.state.GSTtyp,
HSNcode:this.state.HSNcode,
videoUpload:this.state.videoUpload,
// categoryId:this.state.categoryId,
// subCategoryId:this.state.subCategoryId,
tags:this.state.tags,
file:formData,
reccomendedProduct:this.state.reccomendedProduct,
varientDetails:this.state.varientDetails
};
console.log(this.state)
swal({
title: "Are you sure?",
text: "You want to Add New Product",
icon: "warning",
buttons: true,
dangerMode: true,
})
.then(async (success) => {
if (success) {
let list = await GetProductDetails.getUpdateProduct(config);
if (list) {
this.setState({ isLoaded: false })
this.props.history.push("/admin/mainproduct/list")
} else {
NotificationManager.error("Please! Check input field", "Input Field");
}
}
});
}
clickOnDelete(record) {
this.setState({
varientDetails: this.state.varientDetails.filter(r => r !== record)
});
}
render() {
let { varientDetails,subCategoryId,files,updateFile,loading,productphotos,categoryId,reccomendedProduct } = this.state//let { notes, date, description, varientDetails } = this.state
console.log(updateFile)
return (
<div className="container-fluid">
<div className="row">
<div className="col-lg-5 col-md-9 col-lg-6">
<h2 className="mt-30 page-title">Products</h2>
</div>
<div className="col-lg-5 col-md-3 col-lg-6 back-btn">
<button className='btntop btn text-light' onClick={(e) => this.handleBack()}><i className="fas fa-arrow-left" />cancle</button>
<button type="submit" onClick={this.handleSubmit} className='btntop btn text-light mx-2'>Add</button>
</div>
</div>
<ol className="breadcrumb mb-30">
<li className="breadcrumb-item">Dashboard</li>
<li className="breadcrumb-item">Products</li>
<li className="breadcrumb-item active">Edit Product</li>
</ol>
<hr></hr>
<div className='container'>
<form onChange={this.handleChange} >
<div className='row'>
<div className='col-sm-8'>
<div className='row'>
<div className='col-sm-8'>
<div className="form-group">
<label htmlFor="name" class="form-label">Title <em style={{ color: "tomato" }}>*</em></label>
<input type="text" id="name" value={this.state.name} name="name" class=" w3-input w3-border form-control" aria-describedby="passwordHelpBlock" />
</div>
</div>
<div className="col-lg-12 col-md-12">
<div className="form-group">
<label className="form-label">Description*</label>
<RichTextEditor
style={{ height: " 275.438px" }}
className="w3-input w3-border"
content={this.state.description}
handleContentChange={this.handleContentChange}
placeholder="insert text here..." />
</div>
</div>
<div className='col-sm-8 py-4'>
<div className="form-group row">
<label className="my-2">Lables</label>
<label className="btn opt mx-2 col-2 active"style={{backgroundColor: "blue",borderColor: "#449D44"}}>
<input type="radio" id="lableType" hidden name="lableType" autocomplete="off" checked="checked"/> None
</label>
<label className="btn opt col-2 mx-2"style={{backgroundColor: "#449D44",borderColor: "#449D44"}}>
<input type="radio" hidden id="lableType" name="lableType" value="veg" autocomplete="off" checked="checked"/> veg
</label>
<label className="btn opt mx-2 col-3" style={{backgroundColor: "#C9302C",borderColor: "#C9302C"}}>
<input type="radio" hidden id="lableType" name="lableType" value="None Veg" autocomplete="off" checked="checked"/> None Veg
</label>
</div>
</div>
<div className='col-sm-12'>
<div className="form-group">
<label htmlFor="inputPassword5" class="form-label">Tags</label>
{/* <input type="text" id="inputPassword5" class="w3-input w3-border form-control" aria-describedby="passwordHelpBlock"/> */}
<TagsEditor setStateOfTags={this.setStateOfTags} />
</div>
</div><br></br>
<div className='col py-4'>
<div className="form-group">
<input type="checkbox" name="isTex"value={this.state.isTex} id="isTex" data-toggle="switchbutton" checked data-onlabel="true" data-offlabel="false" data-onstyle="success" data-offstyle="danger" />
</div>
<label htmlFor="isTex" class="form-label">is Taxt Enable</label>
</div>
<div className='row'>
<div className='col-sm-4'>
<div className="form-group">
<label className="form-label">GST Rate<em style={{ color: "tomato" }}>*</em></label>
<input type="number" value={this.state.GSTrate} className=" w3-input w3-border form-control" name="GSTrate" id="GSTrate" />
</div>
</div>
<div className='col-sm-4'>
<div className="form-group">
<label className="form-label">GST Rate Type <em style={{ color: "tomato" }}>*</em></label>
<select id="GSTtyp" value={this.state.GSTtyp} name="GSTtyp" className=" w3-input w3-border form-control">
<option value={1}>Inclusive</option>
<option value={0}>Exclusive</option>
</select>
</div>
</div>
</div>
<div className='col-sm-4 py-2'>
<div className="form-group">
<label htmlFor="HSNcode" class="form-label">HSN Code</label>
<input type="text" value={this.state.HSNcode} name="HSNcode" className='w3-input w3-border form-control' id="HSNcode" aria-describedby="passwordHelpBlock" />
</div>
</div><br></br>
</div>
{/* now we are using varient dynamic form */}
<div className='varientheader py-4' style={{ paddingBottom: "15px" }}>
<a onClick={this.addNewRow} className="btn" style={{ float: 'right', color: "Tomato" }}><i class="fas fa-plus"></i>Add More</a>
<h3 style={{ float: 'left', }}>Varients</h3>
</div>
<hr style={{ padding: "2px", border: "2 px solid black" }}></hr>
<div className="container py-4" style={{ border: "lightgray" }}>
<VarientDetailEdit add={this.addNewRow} delete={this.clickOnDelete.bind(this)} varientDetails={varientDetails} />
</div>
<div className='recomended product'>
<hr></hr>
<h3>Recommended Products</h3>
<hr></hr>
<div className='ex1'>
<ReccomendedFormList rowRcData={reccomendedProduct} setStaterecomended={this.setStaterecomended} />
</div>
</div>
</div>
{/* right section cotegory */}
<div className='col-sm-4'>
<div>
<h3>Category <em style={{ color: "tomato" }}>*</em></h3>
<div className='mx-4 my-2'>
<div className='categorycontainer'>
<CategoryListEdit data={categoryId} sdata={subCategoryId} setStateOfCategory={this.setStateOfCategory} />
<hr></hr>
</div>
{/* file upload */}
<div className='imagecontainer'>
<h3>Upload Images</h3>
<hr />
<div className="wrapper">
<div className="drop">
<div className="cont">
<i className="fas fa-cloud-upload-alt"></i>
<div className="tit">
Drag & Drop
</div>
<div className="desc">
your files to Assets, or
</div>
<div className="browse">
click here to browse
</div>
</div>
<input id="files" multiple name="files[]" onChange={this.fileSelectedHandler} type="file" />
</div>
<ToastContainer autoClose={1500} />
</div>
{this.state.filselected ? <div><i>{this.state.filselected}</i>
{/* <div className="form-group">
<button className="save-btn hover-btn" type="submit" onClick={this.handleSubmitPhoto} disabled={loading}>
{loading && <i className="fa fa-refresh fa-spin" />}
{loading && <span>Upload</span>}
{!loading && <span>Upload</span>}
</button>
<ToastContainer autoClose={1500} />
</div> */}
</div>:
<p>Drag & Drop files here or click to browse.
Note: Max 4 images are allowed.</p>
}
<div style={{display:"flex",margin:"10px"}} >
{ productphotos.map((item,i)=>(
<div className="img_wrp mx-2">
<img width="60px" height="55px" value ={item.imgUrl} src={item.imgUrl} alt="video not found "/><i onClick={(e) =>this.handlawsDeleteById(item.id,item.imgUrl)} className="fa fa-close close"></i>
</div>
))}
</div>
<hr></hr>
</div>
<div className='uploadfile'>
<h3>Upload Video </h3>
<input type="file" className="form-control" onChange={this.VideoUploadFile} />
<p style={{ color: "blue",fontStyle:"italic",fontWeight:"bold" }}>{this.state.msgvideoUpload}</p>
<div className="img_wrp">
<img width="200px" height="150px" src={this.state.videoUpload} alt="video not found "/><i onClick={this.deletePhotoStaticVideo} className="fa fa-close close"></i>
</div>
{/* { this.state.uploadPercentage > 0 && <ProgressBar variant="danger" now={this.state.uploadPercentage} active label={`${this.state.uploadPercentage}%`} /> }<br></br> */}
<div className='upload thambnail my-4'>
<h3>Video Thumbnail Image</h3>
<div className="file-area">
<div className="form-group">
<input type="file" className="form-control" onChange={this.ThumbnainVideoUpload} />
<div className="file-dummy">
<i className="fas fa-plus mx-4 my-4"></i><br></br>
<span className="default">Click to select a file, or drag it here</span>
<span className="success">Great, your file is selected</span>
</div>
<p style={{ color: "blue",fontStyle:"italic",fontWeight:"bold" }}>{this.state.msgThumb}</p>
<div className="img_wrp">
<img width="200px" height="150px" src={this.state.thumbNailphoto} alt="thumbnail not found"/><i className="fa fa-close close" onClick={this.deletePhotoStaticThumb} ></i>
</div>
{/* {(() => {
if (!this.state.photo)
return <button onClick={this.handleCanclePhoto}>delete</button>
}
)} */}
{/* { this.state.uploadPercentage > 0 && <ProgressBar variant="danger" now={this.state.uploadPercentage} active label={`${this.state.uploadPercentage}%`} /> }<br></br> */}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
)
}
i have solve my problem.we have to use defaultValue for solve his problem
<input type="text" defaultValue={this.props.value || ''} />
How do I add the verification of my fields!
I'm trying to send emails like this [emailjs][1], but I realise that I can also submit my empty form! So I'm wondering how to adjust my code so that it takes into account the verification of fields!
I have followed the documentation on emailjs about submitting a form with a name, email, subject, and message but there is one last problem! I've been following the documentation on emailjs regarding the submission of a form with a name, email, subject, and message, but there is still a problem: I am able to send my message successfully and I receive the data on emailjs and in my gmail mailbox, but I can also submit the empty form! How can I fix this? thank you
import React, { Fragment, useRef } from 'react';
import emailjs from 'emailjs-com';
import { Link } from 'react-router-dom';
import { NotificationContainer, NotificationManager } from 'react-notifications';
function Contact() {
const form = useRef();
const sendEmail = (e) => {
e.preventDefault()
emailjs
.sendForm(
'service_yyyyy',
'template_zzzz',
form.current,
'user_ttttt'
)
.then(
(result) => {
NotificationManager.success('Thank you for trusting us, we come back to you sooner.', 'Successful!', 2000);
}, (error) => {
NotificationManager.error('erreur dans le formulaire!', 'erreurs');
});
e.target.reset()
}
return (
<Fragment>
<div className="regular-page-area section-padding-100">
<div className="container">
<div className="row">
<div className="col-12">
<div className="page-content" style= {{backgroundColor:'white'}}>
<h4>text</h4>
<p>text</p>
</div>
</div>
</div>
</div>
</div>
<section className="medium-padding120 bg-body contact-form-animation scrollme">
<div className="container">
<div className="row">
<div className="col col-xl-10 col-lg-10 col-md-12 col-sm-12 m-auto">
<div className="contact-form-wrap">
<div className="contact-form-thumb">
<div className="col-12">
<div className="section-heading">
<h3 style= {{color:'white'}}>Contact form</h3>
</div>
</div>
<h2 className="title"><span>SEND</span> <span>US YOUR</span><span>MESSAGE</span></h2>
<p>text</p>
<img src={require('../../images/crew.png')} alt="crew" className="crew" />
</div>
<form ref={form} onSubmit={sendEmail} className="contact-form">
<div className="col col-12 col-xl-12 col-lg-12 col-md-12 col-sm-12">
<div className="form-group label-floating">
<label className="control-label"> Name</label>
<input
type="text"
className='form-control'
placeholder='Name'
name='name'
/>
</div>
</div>
<div className="col col-12 col-xl-12 col-lg-12 col-md-12 col-sm-12">
<div className="form-group label-floating">
<label className="control-label"> Email</label>
<input
type="email"
className="form-control"
placeholder="youremail#gmail.com"
name='email'
/>
</div>
<div className="form-group label-floating">
<label className="control-label"> Subject</label>
<input
type='text'
className="form-control"
placeholder="Subject"
name='subject'
/>
</div>
<div className="form-group">
<textarea
name="message"
className="form-control"
placeholder="Your Message"
></textarea>
</div>
<button type="submit" className="btn btn-purple btn-lg full-width">Send Message</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div className="half-height-bg bg-white"></div>
</section>
<NotificationContainer/>
<Footer />
</Fragment>
)
}
export default Contact;
I am working on a project where if the login detail is valid, we move to the next page ("/home"). But in my case, while it works perfectly good when the email is invalid, it does not go the expected page when the email is valid. Instead, the page only reloads. Although I have done the necessary in the onSubmit function. Please help
class Test extends React.Component {
constructor(){
super();
this.state = emailState;
this.onChange = this.onChange.bind(this);
}
onChange(e) {
this.setState({
email : e.target.value
});
}
emailValidation(){
const regex = /^(([^<>()[\]\.,;:\s#\"]+(\.[^<>()[\]\.,;:\s#\"]+)*)|(\".+\"))#(([^<>()[\]\.,;:\s#\"]+\.)+[^<>()[\]\.,;:\s#\"]{2,})$/i;
if(!this.state.email || regex.test(this.state.email) === false){
this.setState({
error: "Email is not valid"
});
return false;
}
return true;
}
onSubmit(){
if(this.emailValidation()){
console.log(this.state);
this.props.history.push('/home');
}
}
render(){
return (
<div className="login-cot bg-danger" id="layoutAuthentication">
<div id="layoutAuthentication_content">
<main>
<div className="container ">
<div className="row justify-content-center ">
<div className="col-lg-5 ">
<div className="card shadow-lg border-0 rounded-lg mt-5 bg-secondary">
<center><h1 className="bg-warning" style={{padding:"10px",}}><b><BsBugFill /><BsTools /> <BsColumns /> BFP</b></h1></center>
<div className="card-header"><h3 className="text-center my-1"><b>Login</b></h3></div>
<div className="card-body">
<form>
<div className="form-floating mb-3">
<input className="form-control" id="email" type="email"
placeholder="name#example.com"
value={this.state.email}
onChange={this.onChange}
/>
<label for="inputEmail">Email address</label>
<span className="text-danger">{this.state.error}</span>
</div>
<button type ="submit" className="btn btn-success" onClick={()=>this.onSubmit()}>Login</button>
</form>
</div>
<div className="card-footer text-center py-3">
<div className="small"><Link className="text-light" to="/signup">Need an account? Sign up!</Link></div>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
</div>
)
}
}
Try to use withRouter() function with react , which helps to access the history parameter.
For e.g in your case : export default withRouter(Test);
My input is also like a searchbox: I want to be able to search for names on the input but then I want to be able to click a name from the dropdown search results and set the input with that value. I then want to be able to search again if I want to change that value.
Tried using DefaultValue and uncontrolled components, but neither worked. Not sure if I used them right though.
class PublishTest extends Component {
constructor() {
super();
this.state = {
showRows: false,
numberOfRows: ["row"],
search: "",
searchResults: [],
insightListActive: false,
insightTagsActive: false
};
this.hideOrShowRows = this.hideOrShowRows.bind(this);
this.addNewRow = this.addNewRow.bind(this);
this.searchAllUsers = this.searchAllUsers.bind(this);
this.onChangeInsight = this.onChangeInsight.bind(this);
this.clearInput = this.clearInput.bind(this);
this.clearInsightList = this.clearInsightList.bind(this);
this.searchInsightTags = this.searchInsightTags.bind(this);
this.clearTagList = this.clearTagList.bind(this);
}
componentDidMount() {
this.props.getLoginCredential();
this.props.getAllRoles();
}
hideOrShowRows() {
this.setState({
showRows: !this.state.showRows
});
}
addNewRow() {
this.setState({
numberOfRows: [...this.state.numberOfRows, "row"]
});
}
searchAllUsers(e) {
this.setState({
search: e.target.value
});
const searchOption = this.state.search;
fetch("http://localhost:3500/soiapi/", {
method: "POST",
headers: {
"content-type": "application/json"
},
body: JSON.stringify({
data: [
{
name: "searchUser",
urlparameter: { search: searchOption, appId: "1" },
parameter: ""
}
]
})
})
.then(res => res.json())
.then(data => {
this.setState({
searchResults: data[0]
});
});
}
onChangeInsight = e => {
this.props.insightOnChangeValue(e.target.value);
this.props.searchInsights(e.target.value);
this.setState({
insightListActive: true
});
};
clearInput() {
this.setState({
search: "",
searchResults: []
});
}
clearInsightList() {
this.setState({
insightListActive: false
});
}
searchInsightTags(e) {
this.props.getInsightTags(e.target.value);
this.setState({
insightTagsActive: true
});
}
clearTagList() {
this.setState({
insightTagsActive: false
});
}
render() {
const { searchResults } = this.state;
let rows;
let button;
let icon;
if (this.state.showRows) {
rows = this.state.numberOfRows.map((row, i) => (
<div>
<Row index={i} />
</div>
));
button = (
<button
onClick={this.addNewRow}
className="Button--secondary float-right"
>
Add Row
</button>
);
icon = (
<i aria-hidden="true" className="Icon Icon--minus-small iconFont"></i>
);
} else if (!this.state.showRows) {
icon = (
<i aria-hidden="true" className="Icon Icon--plus-small iconFont"></i>
);
}
if (this.props.user.userDTO) {
const { userDTO } = this.props.user;
const insightSearchResults = this.props.insightReducerValue
.insightList[0];
return (
<div style={{ padding: "5px" }} className="publish-container">
<h4 className="publish-h4">Publish Insights</h4>
<h6 className="publish-h6">Insight Details</h6>
<hr className="line-style" />
<section id="publish-section-1">
<div class="Grid">
<div class="Col Col--3">
<div class="grid-block">
<div className="Form-group publish-insights-input">
<label className="Form-label insight-label">
Insight Name <span className="asterisk">*</span>:
</label>
<div id="insight-container">
<input
type="text"
placeholder="Insight Name"
onChange={this.onChangeInsight}
onFocus={this.clearInsightList}
onBlur={this.clearInsightList}
className="Form-input"
value={this.props.insightReducerValue.insightValue}
/>
{this.state.insightListActive ? (
<InsightList insights={insightSearchResults} />
) : null}
</div>
</div>
</div>
</div>
<div class="Col Col--3">
<div class="grid-block">
<div class="Form-group publish-insights-input">
<label class="Form-label">
Insight Source <span className="asterisk">*</span>:
</label>
<select
id="insight-source"
role="combobox"
class="Form-input"
>
<option
disabled="disabled"
selected="selected"
aria-disabled="true"
>
Choose one
</option>
<option>Tableau</option>
<option>Qlik</option>
<option>D3JS</option>
<option>CXI</option>
</select>
</div>
</div>
</div>
</div>
</section>
<section id="publish-section-2">
<div class="Grid">
<div class="Col Col--6">
<div class="grid-block">
<div className="Form-group publish-insights-input">
<label class="Form-label">
URL <span className="asterisk">*</span>:
</label>
<input type="text" placeholder="URL" class="Form-input" />
</div>
</div>
</div>
</div>
</section>
<section id="publish-section-3">
<div class="Grid">
<div class="Col Col--6">
<div class="grid-block">
<div className="publish-insights-input">
<label class="Form-label">
Description <span className="asterisk">*</span>:
</label>
<textarea
placeholder="Description"
class="Form-input"
></textarea>
</div>
</div>
</div>
</div>
</section>
<section id="publish-section-4">
<div class="Grid">
<div class="Col Col--3">
<div class="grid-block">
<div className="Form-group publish-insights-input">
<label className="Form-label third-div-p">
POC Name <span className="asterisk">*</span>:
</label>
<input
type="text"
placeholder="Name"
className="Form-input"
value={`${userDTO.firstName} ${userDTO.lastName}`}
/>
</div>
</div>
</div>
<div class="Col Col--3">
<div class="grid-block">
<div className="Form-group publish-insights-input">
<label className="Form-label third-div-p">
Group Distro (E-mail Address)
<span className="asterisk">*</span>:
</label>
<input
type="text"
placeholder="Email"
class="Form-input"
value={userDTO.emailAddress}
/>
</div>
</div>
</div>
</div>
</section>
<section id="publish-section-5">
<div class="Grid">
<div class="Col Col--6">
<div class="grid-block">
<div class="Form-group publish-insights-input">
<div class="Form-checkbox is-restricted">
<input
id="restricted"
name="checkboxDefault"
type="checkbox"
/>
<label for="restricted">Is Restricted</label>
</div>
</div>
</div>
</div>
</div>
</section>
<section id="publish-section-6">
<div class="Grid">
<div class="Col Col--2">
<div class="grid-block">
<div id="tree-section">
<label id="category-label" className="Form-label">
Category <span className="asterisk">*</span>
</label>
<div id="tree-container">
<PublishInsightsTree />
</div>
</div>
</div>
</div>
<div class="Col Col--4">
<div class="grid-block">
<div className="Form-group publish-insights-input">
<label className="Form-label third-div-p">
Add Insight Tags <span className="asterisk">*</span>:
</label>
<input
type="text"
onChange={e => this.searchInsightTags(e)}
onFocus={this.clearTagList}
onBlur={this.clearTagList}
placeholder="Write some insight tags"
className="Form-input"
/>
</div>
{
this.state.insightTagsActive ?
<div>
{
this.props.insightTags ?
<InsightTags tags={this.props.insightTags[0]} />
: null
}
</div>
: null
}
</div>
<div class="grid-block">
<div class="Grid">
<div class="Col Col--7 img-url-input">
<div class="grid-block">
<div
id="file-div"
class="Form-group publish-insights-input"
>
<label class="Form-label">
Image URL <span className="asterisk">*</span>:
</label>
<input
type="text"
placeholder="Insight Name"
class="Form-input"
/>
</div>
</div>
</div>
<div class="Col Col--5">
<div class="grid-block">
<button class="Button--secondary upload-image-button">
Upload Image
</button>
</div>
</div>
<div class="Col Col--7 url-description">
<div class="grid-block">
<p>
Please copy paste the generated URL after uploading
image file.
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<section id="publish-section-7">
<h6 className="publish-h6">Role Details</h6>
<hr className="line-style" />
</section>
<section id="publish-section-8">
<div class="Grid">
<div class="Col Col--2">
<div class="grid-block">
<label id="roles-label" className="Form-label">
Assign to Role <span className="asterisk">*</span>
</label>
<div id="all-roles">
{this.props.listOfRoles ? (
<ListOfRoles roles={this.props.listOfRoles} />
) : null}
</div>
</div>
</div>
<div class="Col Col--4">
<div class="grid-block assign-user-div">
<label className="Form-label label-spacing">
Assign to Individual User:
</label>
<div className="Form-group">
<textarea
onChange={this.searchAllUsers}
type="text"
placeholder="Look up by EID/Name"
onFocus={this.clearInput}
onBlur={this.clearInput}
className="Form-input assign-user-textarea"
value={this.state.search}
></textarea>
{searchResults.length > 0 ? (
<div id="user-list">
{searchResults ? (
<UserList searchResults={this.state.searchResults} />
) : null}
</div>
) : null}
</div>
</div>
</div>
</div>
</section>
<section id="publish-section-9">
<h6 className="publish-h6 metadata-heading" onClick={this.hideOrShowRows}>
<span id="metadata-icon">{icon}</span>
Metadata Info
</h6>
<hr className="line-style color" />
</section>
<section id="publish-section-10">
<div class="Grid">
<div class="Col Col--12 add-row-col">
<div class="grid-block">{button}</div>
</div>
</div>
{rows}
</section>
</div>
);
} else {
return null;
}
}
}
const mapStateToProps = state => ({
user: state.LoginReducer.loginInfo,
searchUser: state.LoginReducer.searchUser,
insightReducerValue: state.SideDrawerReducer,
listOfRoles: state.LoginReducer.listOfRoles,
insightTags: state.SideDrawerReducer.insightTags
});
export default connect(
mapStateToProps,
{
getLoginCredential,
searchUser,
insightOnChangeValue,
searchInsights,
getAllRoles,
getInsightTags
}
)(PublishTest);
This is the part of the code I need help with:
<input
type="text"
placeholder="Insight Name"
onChange={this.onChangeInsight}
onFocus={this.clearInsightList}
onBlur={this.clearInsightList}
className="Form-input"
value={this.props.insightReducerValue.insightValue}
/>
{this.state.insightListActive ? (
<InsightList insights={insightSearchResults} />
) : null}
Since your code is a little messy, I made a sandbox that fetches some data from a dummy API, stores that data to our local component state. We have a text field where we can type in usernames and a list of matching usernames will appear as a dummy drop, clicking any one of those usernames will set the value in the text field. It's pretty straight forward will give you an idea on how to get started.
EDIT:
Sandbox Link: https://codesandbox.io/s/eloquent-pascal-pf3hd?fontsize=14
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
class App extends React.Component {
state = {
input: "",
users: [],
dropdown: []
};
async componentDidMount() {
let users = await fetch("https://jsonplaceholder.typicode.com/users");
users = await users.json();
this.setState({ users });
}
handleChange = e => {
this.setState({ input: e.target.value }, () => {
let results = this.state.users.filter(user => {
return user.username.indexOf(this.state.input) > -1;
});
this.setState({ dropdown: results });
});
};
handleSelect = username => e => {
this.setState({ input: username }, () => this.setState({ dropdown: [] }));
};
render() {
return (
<div className="App">
<h1>Search</h1>
<input
type="text"
name="input"
onChange={this.handleChange}
value={this.state.input}
/>
{this.state.dropdown.map(d => (
<h3 onClick={this.handleSelect(d.username)} key={d.id}>
{d.username}
</h3>
))}
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Could you start off by loading all possible search results into state or props (e.g. under this.props.searchResults)? Then you could try using the datalist tag. Not quite sure if this was what you were going for, but it looked like something like that could work for you.
<input type="text"
defaultValue={this.props.insightReducerValue.insightValue}
list="inputOptions"
onChange={(e) => console.log("Current input field value: ", e.target.value)} />
<datalist id="inputOptions">
{this.props.searchResults.map((item, key) =>
<option key={key} value={item} />
)}
</datalist>
P.S. Check the supported browsers list under the link.
I want to send that state of a component to the actions file.
My component is a <form> where the user can capture some config that later i want to apply that config to the actions file.
Component Code:
import React, { Component } from 'react';
class AdminConfig extends Component{
constructor(props){
super(props);
this.state=({
baseURL:'BASE_URL',
hospitalName: '',
hospitalExternalID:'1000849',
payerName:'',
payerAddress:''
})
this.onBaseURLChange = this.onBaseURLChange.bind(this);
this.onHospitalNameChange = this.onHospitalNameChange.bind(this);
this.onHospitalExIDChange = this.onHospitalExIDChange.bind(this);
this.onPayerNameChange = this.onPayerNameChange.bind(this);
this.onPayerAddressChange = this.onPayerAddressChange.bind(this);
this.onAdminFormSubmit = this.onAdminFormSubmit.bind(this);
}
onBaseURLChange(e){
this.setState({
baseURL: e.target.value
})
}
onHospitalNameChange(e){
this.setState({
hospitalName: e.target.value
})
}
onHospitalExIDChange(e){
}
onPayerNameChange(e){
this.setState({
payerName: e.target.value
})
}
onPayerAddressChange(e){
this.setState({
payerAddress: e.target.value
})
}
onAdminFormSubmit(e){
e.preventDefault()
// here is where i need to send something like this:
this.props.fetchAdminConfig(this.state.baseURL)
}
render(){
return(
<div className="container ">
<form className="admin-form" onSubmit={this.onAdminFormSubmit}>
<div className="row">
<div className="jumbotron col-md-12">
<h4>API CONFIGURATION</h4>
</div>
<div className="col-md-12">
<div className="panel panel-primary">
<div className="panel-heading">BASE URL</div>
<div className="panel-body">
<input
onChange={this.onBaseURLChange}
type="text"
className="form-control"
id="baseURL"
placeholder="Base URL" />
<div className="panel-body" id="getResult"> <p className="">Base URL: http://{this.state.baseURL}/trucare-api-6.2.1.TC621/6.2.1/api</p></div>
</div>
</div>
</div>
</div>
<div className="row">
<div className="jumbotron col-md-12">
<h4>HOSPITAL INFORMATION</h4>
</div>
<div className="col-md-6">
<div className="panel panel-primary">
<div className="panel-heading">Hospital Name</div>
<div className="panel-body">
<input
onChange={this.onHospitalNameChange}
type="text"
className="form-control"
id="hospitalName"
placeholder="Hospital Name" />
<div className="panel-body" id="getResult"><p className="">Hospital name: {this.state.hospitalName}</p></div>
</div>
</div>
</div>
<div className="col-md-6">
<div className="panel panel-primary">
<div className="panel-heading">Hospital External ID</div>
<div className="panel-body">
<input
onChange={this.onHospitalExIDChange}
type="text"
className="form-control"
id="hospitalEXID"
placeholder="Hospital Name" disabled />
<div className="panel-body" id="getResult"><p>Hospital External ID: {this.state.hospitalExternalID}</p></div>
</div>
</div>
</div>
</div>
<div className="row">
<div className="jumbotron col-md-12">
<h4>PAYER INFORMATION</h4>
</div>
<div className="col-md-6">
<div className="panel panel-primary">
<div className="panel-heading">Payer Name</div>
<div className="panel-body">
<input
onChange={this.onPayerNameChange}
type="text"
className="form-control"
id="payerName"
placeholder="Payer Name" />
<div className="panel-body" id="getResult"><p>Payer Name: {this.state.payerName}</p></div>
</div>
</div>
</div>
<div className="col-md-6">
<div className="panel panel-primary">
<div className="panel-heading">Payer Address</div>
<div className="panel-body">
<input
onChange={this.onPayerAddressChange}
type="text"
className="form-control"
id="payerAddress"
placeholder="Payer Address" />
<div className="panel-body" id="getResult"><p>Payer Address: {this.state.payerAddress}</p></div>
</div>
</div>
</div>
</div>
<button type="submit" className="btn btn-primary btn-lg">Apply config</button>
</form>
</div>
);
}
}
export default AdminConfig
Then on my actions file I have this:
export function fetchAdminConfig(BASE_URL){
...
}
const BASE_URL = //this is where I want to apply the state that I captued on my form
export function fetchUsers() {
const request = axios.post(`${BASE_URL}/endpoint`)
return {
type: FETCH_USERS,
payload: request
};
}
How Can I accomplish this?
Just add a parameter to your action creator function and pass it in!
export function fetchAdminConfig(BASE_URL) {
const request = axios.post(`${BASE_URL}/endpoint`)
return {
type: FETCH_USERS,
payload: request
};
}