Аааа ... так как у вас есть панель поиска и фильтры, вот как вы можете объединить все в один JSON array
и ограничить поиск и отдельные фильтры своими object
с.
Рабочий пример: https://codesandbox.io/s/lx8n5x4w4z
компоненты / SearchForm.js
import filter from "lodash/filter";
import map from "lodash/map";
import React, { Component } from "react";
import ParsedURI from "./parsedURI";
import FilterField from "./filterField";
import SearchField from "./searchField";
// initial form state
const initialState = {
fieldsCount: 1,
search: { value: "", type: "search" },
filters: [{ id: 1, dataIndex: "", value: "", type: "" }]
};
export default class SearchForm extends Component {
state = { ...initialState };
// handles search input changes
handleSearchChange = ({ target: { name, value } }) => {
this.setState(prevState => ({
search: { ...prevState.search, [name]: value }
}));
};
// handles all filter changes (select, select and input) by their id
handleFilterChange = ({ target: { id, name, value } }) => {
this.setState(prevState => ({
filters: map(
prevState.filters,
item =>
parseInt(id, 10) === item.id
? { ...item, [name]: value }
: { ...item }
)
}));
};
// adds a new field to filters and updates a field counter
addField = () => {
this.setState(prevState => ({
filters: [
...this.state.filters,
{
id: this.state.fieldsCount + 1,
dataIndex: "",
value: "",
type: ""
}
],
fieldsCount: this.state.fieldsCount + 1
}));
};
// removes selected filter field by id
deleteField = id => {
this.setState(prevState => ({
filters: filter(this.state.filters, field => field.id !== id)
}));
};
// resets form to initial state and updates the URL
handleReset = () =>
this.setState(
{
encodedJSON: "",
filtersJSON: "",
...initialState
},
() => this.props.history.replace("/search/")
);
// handles form submission
handleSubmit = e => {
e.preventDefault();
const { search, filters } = this.state;
const arr = [];
// flatten search and filter options into a single array
arr.push({ ...search }, ...filters);
// convert that array to a JSON array
const filtersJSON = JSON.stringify(arr);
// convert JSON array to an encodedURI
const encodedJSON = `filters=${encodeURI(filtersJSON)}`;
// set to state and push to URL
this.setState(
{
encodedJSON,
filtersJSON: arr,
...initialState
},
() => this.props.history.push(`/search/filters?${encodedJSON}`)
);
};
render = () => (
<div style={{ padding: "5px 20px" }}>
<form onSubmit={this.handleSubmit}>
<SearchField
value={this.state.search.value}
handleSearchChange={this.handleSearchChange}
/>
<p>Select a filter, option, and input a value:</p>
{map(this.state.filters, ({ id, ...rest }) => (
<FilterField
key={id}
id={id}
deleteField={this.deleteField}
filtersLength={this.state.filters.length}
handleFilterChange={this.handleFilterChange}
{...rest}
/>
))}
<br />
<button
type="button"
style={{ marginRight: 20, marginBottom: 20 }}
className="uk-button uk-button-primary"
onClick={this.addField}
>
Add Filter
</button>
<br />
<div style={{ marginTop: 40 }}>
<button
type="button"
style={{ marginRight: 20, marginBottom: 20, float: "left" }}
className="uk-button uk-button-danger"
onClick={this.handleReset}
>
Reset Form
</button>
<button className="uk-button uk-button-secondary" type="submit">
Submit
</button>
</div>
</form>
{this.state.encodedJSON && this.state.filtersJSON ? (
<ParsedURI
encodedJSON={this.state.encodedJSON}
filtersJSON={this.state.filtersJSON}
/>
) : null}
</div>
);
}
Пример закодированной строки URI:
%5B%7B%22value%22:%22Test%20ing%22,%22type%22:%22search%22%7D,%7B%22id%22:1,%22dataIndex%22:%22topic%22,%22value%22:%22React%20Local%20State%22,%22type%22:%22name%22%7D,%7B%22id%22:2,%22dataIndex%22:%22subcategory%22,%22value%22:%22123456789%22,%22type%22:%22oid%22%7D%5D
Пример декодированной строки URL JSON.stringify(filtersJSON, null, 4)
:
[
{
"value": "Test ing",
"type": "search"
},
{
"id": 1,
"dataIndex": "topic",
"value": "React Local State",
"type": "name"
},
{
"id": 2,
"dataIndex": "subcategory",
"value": "123456789",
"type": "oid"
}
]