Есть таблица с несколькими столбцами, и теперь можно искать столбец. Когда текст вводится в поле поиска, выполняется фильтр, и отображаются только строки, содержащие это слово в этом столбце.
Например, есть 3 столбца: имя , бренд , продажи . Поиск ведется по столбцу имя . Я хочу, чтобы он выполнял поиск по всем столбцам, но не знаю, как это сделать.
Вот как это работает сейчас.
Файл реакции:
import React from 'react';
import { connect } from 'react-redux';
import { Creators } from '../../../actions';
import Layout from '../../../components/Layout/Layout';
import ContentContainer from '../../../components/Layout/ContentContainer';
import GenericTable from '../../../components/Table/GenericTable';
import OneColumn from '../../../components/Layout/OneColumn';
import SearchBox from '../../../components/SearchBox/SearchBox.component';
import TabContainer from '../../../components/Layout/TabContainer';
class Products extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
query: {
name: '',
brand: '',
sales: '',
},
};
}
componentDidMount() {
const { getProducts, getProviders } = this.props;
getProducts(this.state.query);
getProviders();
}
searchHandler = event => { // here is the search function
const { getProducts } = this.props;
getProducts({
name: event.target.value, // it works for only for name column now
brand: this.props.query.brand,
sales: this.props.query.sales,
});
};
render() {
const listHeaders = ['ID', 'Name', 'Brand', 'Sales'];
const listTab = (
<ContentContainer>
<div>
<div>
<SearchBox
placeholder="Search product"
onChange={this.searchHandler} // here is the search box
/>
</div>
<GenericTable // the table
id="products-table"
headers={listHeaders}
rows={listRows}
entityName="products"
idList={listIdList}
/>
</div>
</ContentContainer>
);
return (
<Layout>
<OneColumn>
<TabContainer>
<Tab.Pane>{listTab}</Tab.Pane>
</TabContainer>
</OneColumn>
</Layout>
);
}
}
const mapStateToProps = state => ({
products: state.products.products,
query: state.products.query,
});
const mapDispatchToProps = {
getProducts: Creators.getProductsRequest,
};
export default connect(mapStateToProps, mapDispatchToProps)(Products);
запрос построен с помощью redux-saga:
const api = API.create();
export function* getProducts({ query }) {
let urlQuery = '';
if (query && query.name) {
urlQuery += `&name=${query.name}`;
}
if (query && query.brand) {
urlQuery += `&brand=${query.brand}`;
}
if (query && query.sales) {
urlQuery += `&price=${query.sales}`;
}
try {
const response = yield call(api.getProducts, urlQuery);
yield put(Creators.getProductsSuccess(response.data));
} catch (error) {
yield put(Creators.getProductsFailure(error));
}
}
В Node.js есть 3 метода для 3 вариантов поиска, возможно, их нужно объединить в один, но не знаю как:
findAll: (req, res) => {
const aggregateOptions = [];
// search by name
if (req.query.name) {
aggregateOptions.push({ $match: { name: { $regex: req.query.name, $options: 'i' } } });
}
// search by brand
if (req.query.brand) {
aggregateOptions.push({ $match: { brand: { $regex: req.query.brand, $options: 'i' } } });
}
// search by sales
if (req.query.sales) {
aggregateOptions.push({ $match: { brand: { $regex: req.query.sales, $options: 'i' } } });
}
aggregateOptions.push({
$project: {
productId: 1,
name: 1,
brand: 1,
sales: 1,
},
});
const myAggregate = Product.aggregate(aggregateOptions);
Product.aggregatePaginate(myAggregate, options)
.then(function(results) {
return res.send(results);
})
.catch(function(err) {
return res.status(400).send({ message: err.message });
});
}
Итак, когда я пишу «s» в поле поиска, это вызов API: http://localhost:5000/products&name=s
.
Я не знаю, можно ли сделать что-то вроде http://localhost:5000/products&name=s || brand=s || sales=s
или как это можно сделать для поиска из одного окна поиска по всем 3 столбцам.