Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 184 additions & 0 deletions basket_script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
'use strict';

// класс товара в корзине
class BasketItem {
constructor(title, price, quantity, picture) {
this.title = title;
this.price = price;
this.picture = picture;
this.quantity = quantity;
}

render() {
return `<div class="basket_record">
${this.picture}
<span class="product_name">${this.title}</span>
<span class="product_price">${this.price}&nbspруб</span>
<input type="number" name="quantity" min="0" value="${this.quantity}" class="change_quantity">
<span class="product_cost">${this.quantity*this.price}&nbspруб</span>
<div class="basket_delete">
<a href="#" class="product_delete">удалить</a>
</div>
</div>`;
}
}

// класс Корзины товаров
class BasketList {
constructor() {
this.shopCartList = [];
}

#makeGETRequest(url) {
console.log('Направляю запрос корзины')
return new Promise((resolve, reject) => {
let xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else if (window .ActiveXObject) {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}

xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log('корзина получена')
resolve(xhr.response);
} else {
reject();
}
}
}

xhr.open( 'GET' , url, true );
xhr.send();
});
}

#makePOSTRequest(url, data) {
return new Promise((resolve, reject) => {
let xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
resolve(xhr.response);
} else {
reject();
}
}
}
xhr.open('POST', `/${url}`, true);
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
xhr.send(data);
});
}

getShopCartList() {
this.#makeGETRequest(`/shopCartData`)
.then((data) => {
this.shopCartList = JSON.parse(data);
this.render();
})
.catch(() => {
console.log('Error: data not found');
});
}

toggle() {
document.querySelector('.basket_container').classList.toggle('hidden');
}

showSummary() {
let totalPrice = 0;
let totalQuantity = 0;

this.shopCartList.forEach(({ price, quantity }) => {
totalPrice += price*quantity;
totalQuantity += quantity;
});

document.querySelector('.total_quantity').innerHTML = `<i>${totalQuantity}</i>`;
document.querySelector('.total_price').innerHTML = `<i>${totalPrice}</i>`;
}

render() {
let html = '';

this.shopCartList.forEach(({ title, price, quantity, picture }) => {
const basketItem = new BasketItem(title, price, quantity, picture);
html += basketItem.render();
});

document.querySelector('.basket_list').innerHTML = html;

this.showSummary();

// для инициализации возможности удаления изменения количесвта товара при "раскрытии" корзины
if (this.shopCartList.length > 0) {
let changeShopCart = document.querySelector('.basket_container');
changeShopCart.addEventListener('click', (event) => {
// console.log('click');
event.stopImmediatePropagation(); //для предотвращения повторных запросов при ререндеринге корзины

if (event.target.className == 'product_delete') {
let name = event.target.parentNode.parentNode.childNodes[3].innerText;
const productToDelete = {"title": name};
this.delete(JSON.stringify(productToDelete));
} else if (event.target.className == 'change_quantity') {
let newQuantity = +event.target.value;
let name = event.target.parentNode.childNodes[3].innerText;
const productToChange = {"title": name, "quantity": newQuantity};

if (newQuantity < 1) {
this.delete(JSON.stringify(productToChange));
} else {
this.changeQuantity(JSON.stringify(productToChange));
}
}
});
}
}

// добавление товара
add(item) {
this.#makePOSTRequest('addToCart', item)
.then((data) => {
console.log('товар добавлен');
})
.catch(() => {
console.log('Error: data not found');
});
}

// удаление товара
delete(item) {
this.#makePOSTRequest('deleteFromCart', item)
.then((data) => {
this.shopCartList = JSON.parse(data);
if (this.shopCartList.length == 0) {
this.shopCartList = [];
}
this.render();
})
.catch(() => {
console.log('Error: data not found');
});
}

// изменение количества товара внутри корзины
changeQuantity(item) {
this.#makePOSTRequest('changeQuantity', item)
.then((data) => {
this.shopCartList = JSON.parse(data);
this.render();
})
.catch(() => {
console.log('Error: data not found');
});
}
}
33 changes: 33 additions & 0 deletions catalog_script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use strict';

class ProductsList {
constructor() {
this.products = [];
this.filteredProducts = [];
}

makeGETRequest(url) {
return new Promise((resolve, reject) => {
let xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else if (window .ActiveXObject) {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}

xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log('католог получен')
resolve(xhr.response);
} else {
reject();
}
}
}

xhr.open( 'GET' , url, true );
xhr.send();
});
}
}
1 change: 1 addition & 0 deletions data/cart.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"title":"Rollerblade Twister Edge","price":150,"picture":"<img src=\"image/twister_edge.jpg\" alt=\"\" width=\"120\" height=\"120\">","quantity":1}]
2 changes: 1 addition & 1 deletion responses/catalog.json → data/catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"image": "image/k2_alexis_80_pro.jpg"
},
{
"title": "FRX 80",
"title": "Seba FRX 80",
"price": 350,
"link": "seba_frx_80",
"image": "image/seba_frx_80.jpg"
Expand Down
Binary file added image/heder.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image/k2_alexis_80_pro.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image/logo_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image/rollerblade_macroblade_84W.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image/seba_frx_80.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image/twister_edge.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 51 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Rollerskates</title>
<link rel="stylesheet" href="style.css">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div class="wraper">
<div class="header">
<div id="logo">
<img src="image/logo_2.png" alt="logo">
</div>
<div class="main_menu">
<ul class="menulist">
<li><a href="index.html">Главная</a></li>
<li><a href="#">Каталог</a></li>
<li><a href="contacts.html">Контакты</a></li>
</ul>
<cart></cart>
</div>
</div>
<hr>
<h1>Роликовые коньки</h1>
<div class="catalog-menu">
<ul>
<li class="catalog-menu-list catalog-active"><a href="catalog.html" class="catalog-link">ВСЕ</a></li>
<li class="catalog-menu-list"><a href="#" class="catalog-link">ФИТНЕС</a></li>
<li class="catalog-menu-list"><a href="#" class="catalog-link">ФРИСКЕЙТ</a></li>
<li class="catalog-menu-list"><a href="#" class="catalog-link">АГРЕССИВ</a></li>
<li class="catalog-menu-list"><a href="#" class="catalog-link">ДЕТСКИЕ</a></li>
</ul>
</div>
<search-field :searchName="productName" @change="filter"></search-field>

<catalog-list :products="filteredProducts"></catalog-list>

<basket-list></basket-list>

<div class="forfooter"></div>
</div>
<div class="footer">
<hr>
<p><i>Все права защищены &copy;</i></p>
</div>
<script src="catalog_script.js" type="text/javascript"></script>
<script src="basket_script.js" type="text/javascript"></script>
<script src="main.js" type="text/javascript"></script>
</body>
</html>
Loading