partial search component

This commit is contained in:
Sergey Yarkov 2019-12-28 21:57:47 +03:00
parent 5f90fd0a8a
commit 2fa5c40bd3
8 changed files with 99 additions and 35 deletions

View File

@ -2,28 +2,34 @@ const fs = require('fs');
module.exports = function(server, db) { module.exports = function(server, db) {
server.get('/api/items', async (req, res) => { server.get('/api/items', async (req, res) => {
const items = await db.collection('items').find({}).toArray(), if (req.query.q) {
sortBy = req.query.sorting; const items = await db.collection('items').find({title: {$regex: req.query.q, $options: "i"}}, {limit: 5}).toArray();
res.json(items);
} else {
const items = await db.collection('items').find({}).toArray(),
sortBy = req.query.sorting;
if (items.length > 0) { if (items.length > 0) {
switch (sortBy) { switch (sortBy) {
case 'ascending': case 'ascending':
res.json(items.sort((a, b) => a.price - b.price)); res.json(items.sort((a, b) => a.price - b.price));
break; break;
case 'descending': case 'descending':
res.json(items.sort((a, b) => b.price - a.price)); res.json(items.sort((a, b) => b.price - a.price));
break; break;
case 'newer': case 'newer':
res.json(items.sort((a, b) => b.date - a.date)); res.json(items.sort((a, b) => b.date - a.date));
break; break;
case 'older': case 'older':
res.json(items.sort((a, b) => a.date - b.date)); res.json(items.sort((a, b) => a.date - b.date));
break; break;
default: default:
res.json(items); res.json(items);
break; break;
} }
} else res.send({error: 'Товаров в магазине пока что нет.'}); } else res.send({error: 'Товаров в магазине пока что нет.'});
}
}); });
server.get('/api/items/page/:page', async (req, res) => { server.get('/api/items/page/:page', async (req, res) => {
@ -36,6 +42,11 @@ module.exports = function(server, db) {
res.render('main/404'); res.render('main/404');
} }
}); });
server.get('/api/items/search/:query', (req, res) => {
const query = req.query.q;
console.log(query);
})
server.get('/api/items/:category', async (req, res) => { server.get('/api/items/:category', async (req, res) => {
const items = await db.collection('items').find({category: req.params.category}).toArray(), const items = await db.collection('items').find({category: req.params.category}).toArray(),

View File

@ -13,8 +13,8 @@ body.has-fixed-sidenav
.search-field .search-field
.nav-wrapper .nav-wrapper
.input-field .input-field
input#search(type="search" required placeholder="Введите название товара") input#search(type="search" required placeholder="Введите название товара и нажмите enter")
label.label-icon(for="search") label.label-icon(for="search" style="cursor: pointer;")
i.material-icons search i.material-icons search
i.material-icons close i.material-icons close
#edit.table-items.table #edit.table-items.table

View File

@ -3,16 +3,24 @@ import { apiService } from "../services/api.service";
import { renderItems } from "../templates/items.template"; import { renderItems } from "../templates/items.template";
export class ItemsComponent extends Component { export class ItemsComponent extends Component {
constructor(id, {pagination}) { constructor(id, {pagination}, {search}) {
super(id); super(id);
this.pagination = pagination; this.pagination = pagination;
this.search = search;
} }
async init() { async init() {
const items = await apiService.getItems(); const items = await apiService.getItems();
this.$table = this.$el.querySelector('table tbody'); this.$table = this.$el.querySelector('table tbody');
this.search.initialize(this.$table, this.getItemsByText);
this.pagination.initialize(items.length, this.$table, this.getItemsByPage); this.pagination.initialize(items.length, this.$table, this.getItemsByPage);
} }
async getItemsByText(text) {
const items = await apiService.getItemsQuery(text),
categories = await apiService.getCategories();
return renderItems(items, categories);
}
async getItemsByPage(page) { async getItemsByPage(page) {
const items = await apiService.getItemsOffset(page), const items = await apiService.getItemsOffset(page),

View File

@ -90,4 +90,8 @@ export class PaginationComponent extends Component {
html += '<li><a class="disabled" href="#" data-type="next"><i class="material-icons">chevron_right</i></a></li>'; html += '<li><a class="disabled" href="#" data-type="next"><i class="material-icons">chevron_right</i></a></li>';
this.$el.insertAdjacentHTML('afterbegin', html); this.$el.insertAdjacentHTML('afterbegin', html);
} }
hide() {
this.$el.classList.add('hide');
}
} }

View File

@ -0,0 +1,29 @@
import { Component } from "../core/component";
export class SearchComponent extends Component {
constructor(id, {loader}) {
super(id);
this.loader = loader;
}
initialize(insertTo, request) {
this.$el.onchange = (e) => {
this.search(e, insertTo, request);
}
}
async search(e, insertTo, request) {
try {
insertTo.innerHTML = '';
this.loader.show();
const query = e.target.value.trim(),
items = await request(query);
items != '' ? insertTo.insertAdjacentHTML('afterbegin', items) : insertTo.innerHTML = `По запросу "${query}" ничего не найдено...`;
e.target.value = '';
this.loader.hide();
} catch (error) {
console.error('Произошла ошибка.');
}
}
}

View File

@ -6,11 +6,13 @@ import { LoaderComponent } from "./components/loader.component.js";
import { PaginationComponent } from "./components/pagination.component.js"; import { PaginationComponent } from "./components/pagination.component.js";
import { editItemModal } from "./modals/editItem.modal.js"; import { editItemModal } from "./modals/editItem.modal.js";
import { deleteItemModal } from "./modals/deleteItem.modal.js"; import { deleteItemModal } from "./modals/deleteItem.modal.js";
import { SearchComponent } from "./components/search.component.js";
const loader = new LoaderComponent('loader'); const loader = new LoaderComponent('loader');
const pagination = new PaginationComponent('pagination', {loader}); const pagination = new PaginationComponent('pagination', {loader});
const search = new SearchComponent('search', {loader});
const categories = new CategoriesComponent('categories'); const categories = new CategoriesComponent('categories');
const items = new ItemsComponent('items', {pagination}); const items = new ItemsComponent('items', {pagination}, {search});
const editCategory = new editCategoryModal('editCategoryModal', 'editCategory_select', 'editCategoryClose'); const editCategory = new editCategoryModal('editCategoryModal', 'editCategory_select', 'editCategoryClose');
const editItem = new editItemModal('editItemModal', 'edit', 'editItemClose'); const editItem = new editItemModal('editItemModal', 'edit', 'editItemClose');

View File

@ -15,22 +15,23 @@ export class deleteItemModal extends Modal {
} }
setElems() { setElems() {
this.$content = this.$el.querySelector('.modal-content__form'); this.$content = this.$el.querySelector('.modal-content__form p');
} }
openHandler(e) { openHandler(e) {
const data = JSON.parse(e.target.parentNode.parentNode.dataset.info); const data = JSON.parse(e.target.parentNode.parentNode.dataset.info);
this.$content.innerHTML = `Вы действительно хотите удалить товар: <br> "${data.title}"?`;
this.$el.querySelector('.delete-item').onclick = this.deleteHandler.bind(this, data.id); this.$el.querySelector('.delete-item').onclick = this.deleteHandler.bind(this, data.id);
} }
deleteHandler(id) { async deleteHandler(id) {
axios.post('/control-panel/items/delete', {id}) try {
.then(() => { this.$content.innerHTML = '<div class="progress"><div class="indeterminate"></div></div>'
alert('Товар был успешно удален.'); await axios.post('/control-panel/items/delete', {id});
document.location.reload(true); alert('Товар был успешно удален.');
}) document.location.reload(true);
.catch(() => { } catch (error) {
alert('Невозможно выполнить запрос.'); alert('Невозможно выполнить запрос.');
}); }
} }
} }

View File

@ -47,6 +47,15 @@ class ApiService {
} }
} }
async getItemsQuery(text) {
try {
const request = `${this.url}/api/items?q=${text}`;
return useRequest(request);
} catch (err) {
console.error(err);
}
}
async getItemsOne(category, sorting) { async getItemsOne(category, sorting) {
try { try {
if (sorting) { if (sorting) {