Reputation:
I am creating a UI dynamically using JSON data which renders input
or textarea
elements conditionally.
Sample JSON Data
[
{
type: "input",
val: "input text",
name: "Input Field",
editable: false
},
{
type: "text",
val: "text area text",
name: "Text area field",
editable: true
},
{
type: "text",
val: "text area text",
name: "Text area field",
editable: true
}
];
type
one is input
other is text
, So if type
property has value "input" then I am creating an input
element otherwise textarea
element.editable
, if it is set to true then user can click on edit button which which show Send
button later on.Issues
Edit
is changing to Send
I tried using index and matching with index, but that also did not work.
My code
{data.map((li, index) => (
<div className="col-12 col-sm-12 col-md-6 col-lg-6 col-xl-6">
{li.type === "input" && (
<div className="divCont">
{li.editable && disabled && (
<span onClick={editComp}>Edit</span>
)}
<input
type="text"
className="form-control"
disabled={disabled}
defaultValue={li.val}
/>
</div>
)}
{li.type === "text" && (
<div className="divCont">
{li.editable && disabled && (
<span onClick={(e) => editComp(index)}>Edit</span>
)}
{disabled === false && ind === index && (
<span onClick={editComp}>Send</span>
)}
<input
type="text"
className="form-control"
disabled={disabled}
defaultValue={li.val}
/>
</div>
)}
</div>
))}
Edit / Update
What I am trying to do
editable:true
it shows the edit button
just above the input or textarea element.Edit
button should be changed to Send
button to send data.Upvotes: 0
Views: 173
Reputation: 1989
Okay, I understand that you probably new to React and maybe even programming. Learning is good. Here some updated version of your code which does what you wanted, at least the way I have understood. Note though, I have no idea what you trying to build here, but hopefully it will give you some new start:
import React, { useState } from "react";
import "./styles.css";
import "bootstrap/dist/css/bootstrap.min.css";
function EditableArea({ val, ...rest }) {
const [disabled, setDisabled] = useState(true);
const [value, setValue] = useState(rest.value);
const handleSend = () => {
// ... send it somewhere maybe?..
console.log(value);
setDisabled(true);
};
return (
<div className="divCont">
{disabled ? (
<span onClick={() => setDisabled(false)}>Edit</span>
) : (
<span onClick={handleSend}>Send</span>
)}
<textarea
type="text"
className="form-control"
disabled={disabled}
placeholder={rest.placeholder}
onChange={(e) => setValue(e.target.value)}
value={value}
></textarea>
</div>
);
}
function Editable({ ...rest }) {
const [disabled, setDisabled] = useState(true);
const [value, setValue] = useState(rest.value || "");
const handleSend = () => {
// ... send it somewhere maybe?..
console.log(value);
setDisabled(true);
};
return (
<div className="divCont">
{disabled ? (
<span onClick={() => setDisabled(false)}>Edit</span>
) : (
<span onClick={handleSend}>Send</span>
)}
<input
type="text"
className="form-control"
disabled={disabled}
placeholder={rest.placeholder}
value={value}
onChange={(e) => setValue(e.target.value)}
/>
</div>
);
}
let data = [
{
type: "input",
val: "input text",
name: "Input Field",
editable: false
},
{
type: "text",
placeholder: "text area text",
name: "Text area field",
editable: true,
value: ""
},
{
type: "text",
placeholder: "text area text",
name: "Text area field",
editable: true,
value: ""
}
];
function redrerInput({ type, editable, ...rest }) {
switch (type) {
case "text":
return <EditableArea {...rest} />;
case "input":
return <Editable {...rest} />;
default:
return null;
}
}
export default function App() {
return (
<div className="App">
<div className="row">
{data.map((item, i) => (
<div key={i} className="col-12 col-sm-12 col-md-6 col-lg-6 col-xl-6">
{redrerInput(item)}
</div>
))}
</div>
</div>
);
}
Here is CodeSandbox fork
But I would strongly recommend to read documentation about React first.
Upvotes: -1
Reputation: 75
You are using the same flag 'disabled' to control the state of all your components. Therefore, when you click on send you change it to false for every field and that renders them all editable. The easiest fix would be to use a different flag for each field, but that may not scale well if you need it to.
Upvotes: 2