I have a string , in certain places I need to insert input tags with values. Everything displays fine , but I can't delete or edit values in input. What is wrong with that input?
editModalText() {
let modalMessage="Hello, my name is /# Ann #/. I'm working for /# IStaff #/, could you please call me back"
return (
<div>
{modalMessage
.split("/")
.map((text, idx) =>
text.includes("#") ? this.replaceCharacter(idx, text) : text,
)}
</div>
)
}
replaceCharacter(idx, text) {
let formattedText = text.replace(/#/g, " ")
return (
<input
key={idx}
value={formattedText}
onChange={e => this.setState({input:e.target.value})}
/>
)
}
replace value={formattedText} with defaultValue={formattedText}
this way input will be editable. it will show default value on first render and as you type you'll store that value in your state.
you can read more about controlled and uncontrolled components in the docs
I think you need to bind the input value and the state together. I am not sure how you're currently calling replaceCharacter but I would do something like this :
replaceCharacter(idx) {
return (
<input
key={idx}
value={this.state.input.replace(/#/g, " ")}
onChange={e => this.setState({input:e.target.value})}
/>
)
}
This way when you update your state with the onChange event the value of the state will be populated in the input.
Related
I have a set of a input fields, dynamically generated by an array that are intended to be populated by default with a '?'. Once a user enters a letter into one of the inputs, the onchange event should fire and the array updates successfully, repopulating the inputs with the updated values. As of now, if I provide a value={letter} as an attribute, the inputs populate as expected, but the array that populates the inputs does not update. If I take value={letter} out, the array updates as expected, but the inputs of course, don't populate.
const [letters, setLetters] = useState(workLetters);
function inputChangeHandler(event) {
const incomingLetter = event.target.value;
const nextLetters = [...letters];
letters.forEach((letter, idx) => {
if (letters_rec_of_truth[idx] === incomingLetter) {
nextLetters[idx] = incomingLetter;
}
});
console.log("next letters is now " + nextLetters);
setLetters(nextLetters);
}
useEffect(() => {}, [letters]);
console.log("letters is now " + letters);
// console.log(evt);
return (
<div>
{letters.map((letter, idx) => {
return (
<input
type="text"
key={idx}
value={letter}
onChange={inputChangeHandler}
></input>
);
})}
</div>
);
Why instead of 'value' dont you use 'defaultValue' for the 'input' tag?
I am stuck on this issue with onChange handler being fired on a wrong element after .map function. I have a component, which I use to display mapped values, which looks like this:
const Step: React.FC<StepProps> = ({ status, title, text, onClick, onChange }) => {
return (
<button disabled={status === CompletionStatus.Completed} className={Styles.item} onClick={onClick}>
<mui.IconButton css={css.completionIcon} disabled={status === CompletionStatus.Completed}>
{status === CompletionStatus.Completed ? <muiIcons.Check /> : <Plus />}
</mui.IconButton>
<div className={Styles.content}>
<span className={status === CompletionStatus.Completed ? Styles.titleCompleted : Styles.title}>{title}</span>
<span className={status === CompletionStatus.Completed ? Styles.textCompleted : Styles.text}>{text}</span>
</div>
{onChange && (
<>
<label htmlFor="file-button" className={Styles.inputLabel} />
<input id="file-button" className={Styles.input} type={'file'} onChange={onChange} />
</>
)}
</button>
);
};
So, some of the mapped elements are being used with onClick, and two use onChange to gain photos from the user.
The issue is, that every time I trigger the onChange event on any of those inputs, only the first ones fires, e.g (I added this onChange function to test the name of the element that is being fired, and every time only the first one in the list is being console.logged)
onChange={(event: any)=> {
console.log(event, step);
event.target.value = null;
}}
So, I have figured out the issue here, maybe someone finds this helpful.
Having input with type file only having one id (file-button) was causing only the first such input to work
<label htmlFor="file-button" className={Styles.inputLabel} />
<input id="file-button" className={Styles.input} type={'file'} onChange={onChange} />
The way I fixed this, was basically having that id property unique, so I passed an index to the component and changed the id to
id={`file-button-${index}`}
Sounds like you may not have set a key for each item in your mapping function.
{yourData.map((item, index) => <Component key={`item-${index}`} item={item} />)}
I have a search text box I need to get the value onchange send the request to API when I use the normal event.target method it shows error. how to rectify it as in onchange I need to call a function with some arguments so I cannot go by ease.
my text box is :
<input className="ReactSearchBox" name="search" placeholder="Search Doctors"
onClick={() => {
this.onProviderListing(this.state.skip,0);
this.onEnable();
}}
onChange={() =>this.onSearchProvider(this.state.skip,0)} />
my function where i need the onchange value is:
onSearchProvider(nSkip,nLimit,e){
this.setState({
limit:nLimit,
skip:nSkip,
listing: this.state.listing,
searching: !this.state.searching
})
//console.log(nlimit);
var headers = {
"Content-Type":"application/json",
"AccessToken":localStorage.TOKEN,
}
var _calObj = {initiatorId:localStorage.userid,visitType: "office", skip:nSkip,limit:"5", includeOfflineProviders:"true",searchQuery:"lo"}
I need to give my input values in search query onchange correspondingly, sort it out plz.
You're not passing event from input. Change the onChange prop to:
<input className="ReactSearchBox" name="search"
placeholder="Search Doctors"
onClick={() => {
this.onProviderListing(this.state.skip,0);
this.onEnable();
}}
onChange={(e) =>this.onSearchProvider(this.state.skip,0, e)}
/>
onSearchProvider(nSkip,nLimit,e){
const value = e.target.value; // text box value
}
You can update the onChange in jsx by passing the e event object also like:
onChange={(e) => this.onSearchProvider(this.state.skip,0,e)}
and in onSearchProvider you can access it like:
onSearchProvider(nSkip, nLimit, {target}){
// you can see search box text here on change
console.log(target.value)
}
You don't need to pass state values on onChange method call.
State will be consistent throughout component.
<input className="ReactSearchBox" name="search" placeholder="Search Doctors"
onChange={() =>this.onSearchProvider(0)}
/>
And you can get value from event of that input as event.target.value
onSearchProvider(nLimit,e){
// access your state values directly here like this.state.skip
const searching = e.target.value;
}
I am preparing a demo of add function where user enter two values in input field and result will be display on third field
But I am not able to show that result
Here is my code
https://codesandbox.io/s/flamboyant-smoke-ewkbd
return (
<div className="App">
Add Demo
<br />
<br />
<br />
{state.map(({ type, label, name }) => {
if (type === "text") {
return (
<div>
<label>{label}</label>
<input type="text" onChange={handleChange} name={name} />
</div>
);
}
})}
</div>
);
When I entered 2 in first field and 2 in second field .Expected output will be 4 in result field
I agree with your idea of using State, but better use form value where you can freely update your values.
If you need calculation, you can use number type rather than text
Use setForm for update value
Provide value with form values and show result with combination of first and second.
https://codesandbox.io/s/nice-violet-tv0vw
I am displaying cards with data mapped with a price and location
return data.map( FD1 => (
<Row>
<Card className="card">
<Card body className="text-center">
<CardTitle data-es-label="location"> Location:
{FD1.Departure}
</CardTitle>
<CardText data-es-label="Price">Price
{FD1.price}
</CardText>
<label>
<Checkbox
id={FD1.FlightID}
name={FD1.FlightID}
checked={this.state.checked === FD1.FlightID}
onChange={this.handleCheckboxChange}/>
<span>Select</span>
</label>
<CardActions>'
Each card has a check box and my idea was when the check box is selected and submitted - the information mapped to that card will be sent to be 'booked'.
Is it possible to filter data from the mapped data. Each 'card' with the data has a unique id. How do I filter the data by card and send to a booking page with the details?
At the moment when I select a checked box they all select.
handleCheckboxChange = event =>
this.setState({ checked: event.target.checked });
EDIT: attempt - this is what I have tried
handleCheckboxChange = event =>
this.setState({ checked: event.target.checked });
Select(FD) {
this.state={checked:FD.FlightID};
return(
<label>
<Checkbox id={FD.FlightID}
name={FD.FlightID}
checked={this.state.checked}
onChange={this.handleCheckboxChange}
/>
<span>Select</span>
</label>
)
}
Do you know where I have gone wrong?
into the checked state save the FD1.FlightID instead of true/false and you will know exactly which card had been checked.
and then on submit you can send the appropriate data using this.state.checked (the id of checked card)
In the code inside your "map" function, "this" is still referring to the parent component. So you only have one checked state. That's why all your checkboxes show the same behaviour.
A cleaner solution would be to define a new stateful component "CardRow" that has everything inside the map plus it's own state and handleCheckboxChange function.