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?.