Merge pull request #1412 from ae-utbm/improve-mobile-counter

Improve counter click on smartphones
This commit is contained in:
thomas girod
2026-05-31 11:48:07 +02:00
committed by GitHub
5 changed files with 60 additions and 31 deletions
+4
View File
@@ -46,6 +46,10 @@ details.accordion>.accordion-content {
border-bottom-right-radius: 3px;
border-bottom-left-radius: 3px;
overflow: hidden;
@media screen and (max-width: 600px) {
padding: .75em 1.5em;
}
}
@mixin animation($selector) {
@@ -1,6 +1,6 @@
import type { RecursivePartial, TomSettings } from "tom-select/dist/types/types";
import { AutoCompleteSelectBase } from "#core:core/components/ajax-select-base.ts";
import { registerComponent } from "#core:utils/web-components.ts";
import type { RecursivePartial, TomSettings } from "tom-select/src/types";
import { AutoCompleteSelectBase } from "#core:core/components/ajax-select-base";
import { registerComponent } from "#core:utils/web-components";
const productParsingRegex = /^(\d+x)?(.*)/i;
const codeParsingRegex = / \((\w+)\)$/;
@@ -63,13 +63,6 @@ export class CounterProductSelect extends AutoCompleteSelectBase {
);
},
);
this.widget.hook("after", "onOptionSelect", () => {
/* Focus the next element if it's an input */
if (this.nextElementSibling.nodeName === "INPUT") {
(this.nextElementSibling as HTMLInputElement).focus();
}
});
}
protected tomSelectSettings(): RecursivePartial<TomSettings> {
/* We disable the dropdown on focus because we're going to always autofocus the widget */
@@ -80,9 +73,7 @@ export class CounterProductSelect extends AutoCompleteSelectBase {
// We need to manually set weights or it results on an inconsistent
// behavior between production and development environment
searchField: [
// @ts-expect-error documentation says it's fine, specified type is wrong
{ field: "code", weight: 2 },
// @ts-expect-error documentation says it's fine, specified type is wrong
{ field: "text", weight: 0.5 },
],
};
@@ -25,6 +25,9 @@ document.addEventListener("alpine:init", () => {
}
this.codeField = this.$refs.codeField;
this.codeField.widget.hook("after", "onOptionSelect", () => {
this.handleCode();
});
this.codeField.widget.focus();
// It's quite tricky to manually apply attributes to the management part
@@ -154,6 +157,7 @@ document.addEventListener("alpine:init", () => {
this.addToBasket(code, quantity);
}
this.codeField.widget.clear();
this.codeField.widget.setTextboxValue("");
this.codeField.widget.focus();
},
}));
+22 -1
View File
@@ -42,7 +42,28 @@
min-width: 350px;
ul {
list-style-type: none;
list-style: none;
display: flex;
flex-direction: column;
gap: .5rem;
margin-left: 0;
.basket-row {
display: flex;
align-items: center;
gap: 1rem;
.product-name {
flex: 1 2 0;
min-width: 0;
text-wrap: wrap;
}
}
}
form {
margin-top: .5rem;
margin-bottom: .5rem;
}
}
+18 -9
View File
@@ -56,10 +56,15 @@
<div class="accordion-content">
{% set counter_click_url = url('counter:click', counter_id=counter.id, user_id=customer.user_id) %}
<form method="post" action=""
class="code_form" @submit.prevent="handleCode">
<form method="post" action="" @submit.prevent="handleCode">
<counter-product-select name="code" x-ref="codeField" autofocus required placeholder="{% trans %}Select a product...{% endtrans %}">
<counter-product-select
name="code"
x-ref="codeField"
autofocus
required
placeholder="{% trans %}Select a product...{% endtrans %}"
>
<option value=""></option>
<optgroup label="{% trans %}Operations{% endtrans %}">
<option value="FIN">{% trans %}Confirm (FIN){% endtrans %}</option>
@@ -68,13 +73,11 @@
{%- for category, prices in categories.items() -%}
<optgroup label="{{ category }}">
{%- for price in prices -%}
<option value="{{ price.id }}">{{ price.full_label }}</option>
<option value="{{ price.id }}">{{ price.full_label }} ({{ price.product.code }})</option>
{%- endfor -%}
</optgroup>
{%- endfor -%}
</counter-product-select>
<input type="submit" value="{% trans %}Go{% endtrans %}"/>
</form>
{% for error in form.non_form_errors() %}
@@ -102,7 +105,9 @@
{{ form.management_form }}
</div>
<ul>
<li x-show="getBasketSize() === 0">{% trans %}This basket is empty{% endtrans %}</li>
<li x-show="getBasketSize() === 0">
<em>{% trans %}This basket is empty{% endtrans %}</em>
</li>
<template x-for="(item, index) in Object.values(basket)" :key="item.product.price.id">
<li>
<template x-for="error in item.errors">
@@ -110,12 +115,15 @@
</div>
</template>
<div class="basket-row">
<div>
<button @click.prevent="addToBasket(item.product.price.id, -1)">-</button>
<span class="quantity" x-text="item.quantity"></span>
<button @click.prevent="addToBasket(item.product.price.id, 1)">+</button>
</div>
<span x-text="item.product.name"></span> :
<span x-text="item.sum().toLocaleString(undefined, { minimumFractionDigits: 2 })"></span>
<span class="product-name" x-text="item.product.name"></span>
<span x-text="`${item.sum().toLocaleString(undefined, { minimumFractionDigits: 2 })} €`"></span>
<span x-show="item.getBonusQuantity() > 0"
x-text="`${item.getBonusQuantity()} x P`"></span>
@@ -123,6 +131,7 @@
class="remove-item"
@click.prevent="removeFromBasket(item.product.price.id)"
><i class="fa fa-trash-can delete-action"></i></button>
</div>
<input
type="hidden"