62. Product list and ordering Frontend
Next, we will adjust the order list page and implement order filters. To achieve this, we will make updates to the store.html
file.
These changes will enhance the functionality and usability of the order list and its filtering options.
{% extends 'base.html' %}
{% load static %}
{% block body %}
<main class="principal principal--padding-b">
<section class="loja">
<form class="menu" method="POST" action="">
{% csrf_token %}
<div class="menu__cabecalho">
<div class="menu__titulos">
<div>
<img
class="menu__icone"
src="{% static 'images/filter-big-1-svgrepo-com.svg' %}"
alt="Ícone filtrar"
/>
</div>
<p class="menu__titulo">Filtrar</p>
</div>
<p class="menu__fechar-filtro">X</p>
</div>
<div class="menu__preco">
<p class="menu__subtitulo">Faixa de Preço</p>
<div class="range_container">
<div class="sliders_control">
<input
id="fromSlider"
type="range"
value=0
min=0
max={{ max_price }}
step=0.01
/>
<input
id="toSlider"
type="range"
value={{ max_price }}
min=0
max={{ max_price }}
step=0.01
/>
</div>
<div class="menu__controles">
<div class="form_control">
<div class="form_control_container">
<input
class="form_control_container__time__input"
type="number"
name="min_price"
id="fromInput"
value=0
min=0
max={{ max_price }}
step=0.01
/>
</div>
<p>até</p>
<div class="form_control_container">
<input
class="form_control_container__time__input"
type="number"
id="toInput"
name="max_price"
value={{ max_price }}
min=0
max={{ max_price }}
step=0.01
/>
</div>
</div>
<button type="submit" class="menu__botao">Filtrar</button>
</div>
</div>
</div>
<div class="menu__expansivel">
<div
class="menu__expansivel-cabecalho menu__expansivel-cabecalho--aberto"
>
<p class="menu__subtitulo">Tamanho</p>
</div>
<div class="menu__expansivel-conteudo">
<div class="menu__tamanhos">
{% for size in sizes %}
<div class="menu__tamanho">
<div class="menu__tamanho-quadrado">{{ size }}</div>
<input
class="menu__checkbox"
type="radio"
name="size"
value="{{ size }}"
/>
</div>
{% endfor %}
</div>
</div>
</div>
<div class="menu__expansivel">
<div
class="menu__expansivel-cabecalho menu__expansivel-cabecalho--aberto"
>
<p class="menu__subtitulo">Tipo</p>
</div>
<div class="menu__expansivel-conteudo">
<div class="menu__categorias">
{% for type in types %}
<div class="menu__categoria">
<div class="menu__categoria-quadrado"></div>
<div class="menu__categoria-texto">{{ type.slug }}</div>
<input
class="menu__checkbox"
type="radio"
name="type"
value="{{ type.slug }}"
/>
</div>
{% endfor %}
</div>
</div>
</div>
</form>
<div class="produtos">
<div class="produtos__cabecalho">
<button class="produtos__cabecalho-filtrar">Filtrar</button>
<div class="produtos__cabecalho-ordenarpor">
<div class="produtos__cabecalho-imgicone">
<img
class="produtos__cabecalho-icone"
src="{% static 'images/sort-vertical-svgrepo-com.svg' %}"
alt=""
/>
</div>
<p class="produtos__subtitulo">Ordenar por:</p>
<select class="produtos__select" onchange="redirectToPage()">
{% if order == "highest-price" %}
<option value="" selected>Maior preço</option> <!-- Necessary to start by default -->
{% elif order == "lowest-price" %}
<option value="" selected>Menor preço</option> <!-- Necessary to start by default -->
{% elif order == "most-sold" %}
<option value="" selected>Mais Vendidos</option> <!-- Necessary to start by default -->
{% else %}
<option value="" selected>Selecone uma opção</option> <!-- Necessary to start by default -->
{% endif %}
<option class="item-order" value="highest-price">Maior preço</option> <!--Used in the main.js javascript, it returns the value used in the js-->
<option class="item-order" value="lowest-price">Menor preço</option>
<option class="item-order" value="most-sold">Mais Vendidos</option>
</select>
</div>
</div>
<div class="produtos__grade">
{% for product in products %}
<a
href="{% url 'view_product' product.id %}"
class="produto"
>
<div class="produto__imagem">
<img
src="{{ product.image.url }}"
alt="Imagem do Produto"
/>
</div>
<div class="produto__textos">
<p class="produto__titulo">{{ product.name }}</p>
<div class="produto__preco">
<p class="produto__avista">R$ {{ product.price }}</p>
</div>
</div>
</a>
{% endfor %}
</div>
</div>
</section>
</main>
{% endblock %}
In the store
view function, include the order
variable in the context to ensure the selected order option is passed to the template.
context = {"products" : products, "min_price" : min_price, "max_price" : max_price, "sizes" : sizes, "categories" : categories, "types" : types, "order" : order}
The updates above added the final product section to the HTML file, using the appropriate CSS classes for styling.
Notably, the href
of the filter was replaced with a select
element, and URLs are now passed through the value
attribute instead of the name
attribute. Consequently, the main.js
file will be updated to reflect these changes, as the filter functionality for altering the URL is handled via JavaScript.
/*
the url is a instance of the URL class
document.URL gets the current URL
*/
var url = new URL(document.URL);
var items = document.getElementsByClassName("item-order"); //returns a list of the three href elements
for (i = 0; i < items.length; i++)
{
url.searchParams.set("order", items[i].value); //(name, value)
items[i].value = url.href;
};

Last updated