Reputation: 1034
I think an example will best illustrate my question. Suppose I have a form to select books and their pages. The user will have one multi-select dropdown to select the books. Then, from each book, the user can select any number of pages. In the end, the data will look like a two-dimensional array. The top level is the array of books chosen, and the second level is the pages selected for each book:
books: {
"Book 1": ["page1", "page2", "page3"],
"Book 2": ["page1", "page2"]
}
The dropdown for books will be automatically populated. The options for the dropdown to select the pages for a book will be populated on loading.
Here is a hard coded example just to see the basic layout: http://codepen.io/alanqthomas/pen/JbVGzW?editors=1000
I'm doing this in React. I can't figure out a way to set these values in the component's state and display them dynamically. I'm using react-select for the multi-select selection inputs.
Upvotes: 4
Views: 2463
Reputation: 7656
Sure. Here is what you want. As you want nested pages in books then the setState I did will need modifying but here's a start for you.
If you need help with it just ask.
class Form extends React.Component {
constructor() {
super();
}
render() {
return (
<form>
<div>
<Books />
</div>
</form>
);
}
}
class Books extends React.Component {
constructor() {
super();
this.state = {
books: {
Book1: {
pages: [
{
text: Page 1,
value: Page1
},
{
text: Page 2,
value: Page2
}],
text: Book 1,
value: Book1
},
Book2: {
pages: [
{
text: Page 1,
value: Page1
},
{
text: Page 2,
value: Page2
}],
text: Book 2,
value: Book2
}
}
}
this.state.currentBookKey = this.state.books.Book1.value;
}
selectOnChange = (event) => {
this.setState((state) => ({ currentBookKey: event.target.value }))
}
render() {
return (
<div>
<label>Book</label>
<select multiple name="book" onChange={this.selectOnChange}>
{this.state.books.map(book => <Book value={book.value}}>{book.text}</Book>)}
</select>
<label>Pages to select</label>
<select multiple name="pages">
{this.state.books[this.state.currentBookKey].pages.map(page => <Page value={page.value}}>{page.text}</Page>)}
</select>
</div>
)
}
}
Stateless components:
//React.children.only gives us an exception if more than one child
const Book = ({children, value}) => (
<option value={value}>{React.Children.only(children)}</option>
);
const Page = ({children, value}) => (
<option value={value}>{React.Children.only(children)}</option>
);
Upvotes: 1