Widget & Cart: Add custom number spinners for item quantity

This commit is contained in:
Richard Schreiber
2023-05-08 11:38:44 +02:00
committed by GitHub
parent f97effd0b7
commit 1d0eb81659
10 changed files with 175 additions and 32 deletions

View File

@@ -117,6 +117,14 @@ var form_handlers = function (el) {
$(this).datetimepicker(opts);
});
el.find(".input-item-count-dec, .input-item-count-inc").on("click", function (e) {
e.preventDefault();
var step = parseFloat(this.getAttribute("data-step"));
var controls = document.getElementById(this.getAttribute("data-controls"));
var currentValue = parseFloat(controls.value);
controls.value = Math.max(controls.min, Math.min(controls.max, (currentValue || 0) + step));
});
el.find("script[data-replace-with-qr]").each(function () {
var $div = $("<div>");
$div.insertBefore($(this));

View File

@@ -15,6 +15,8 @@ Vue.component('resize-observer', VueResize.ResizeObserver)
var strings = {
'quantity': django.pgettext('widget', 'Quantity'),
'quantity_dec': django.pgettext('widget', 'Decrease quantity'),
'quantity_inc': django.pgettext('widget', 'Increase quantity'),
'price': django.pgettext('widget', 'Price'),
'select_item': django.pgettext('widget', 'Select %s'),
'select_variant': django.pgettext('widget', 'Select variant %s'),
@@ -218,10 +220,14 @@ Vue.component('availbox', {
+ ' v-bind:aria-label="label_select_item"'
+ '>'
+ '</label>'
+ '<input type="number" class="pretix-widget-item-count-multiple" placeholder="0" min="0"'
+ ' v-model="amount_selected" :max="order_max" :name="input_name"'
+ '<div :class="count_group_classes" v-else>'
+ '<button v-if="!$root.use_native_spinners" type="button" @click="on_step" data-step="-1" v-bind:data-controls="\'input_\' + input_name" class="pretix-widget-btn-default pretix-widget-item-count-dec" aria-label="' + strings.quantity_dec + '"><span>-</span></button>'
+ '<input type="number" inputmode="numeric" pattern="\d*" class="pretix-widget-item-count-multiple" placeholder="0" min="0"'
+ ' v-model="amount_selected" :max="order_max" :name="input_name" :id="\'input_\' + input_name"'
+ ' aria-label="' + strings.quantity + '"'
+ ' v-if="order_max !== 1">'
+ ' >'
+ '<button v-if="!$root.use_native_spinners" type="button" @click="on_step" data-step="1" v-bind:data-controls="\'input_\' + input_name" class="pretix-widget-btn-default pretix-widget-item-count-inc" aria-label="' + strings.quantity_inc + '"><span>+</span></button>'
+ '</div>'
+ '</div>'
+ '</div>'),
props: {
@@ -238,6 +244,11 @@ Vue.component('availbox', {
this.$root.$emit('amounts_changed')
},
computed: {
count_group_classes: function () {
return {
'pretix-widget-item-count-group': !this.$root.use_native_spinners
}
},
require_voucher: function () {
return this.item.require_voucher && !this.$root.voucher_code
},
@@ -296,6 +307,13 @@ Vue.component('availbox', {
methods: {
focus_voucher_field: function () {
this.$root.$emit('focus_voucher_field')
},
on_step: function (e) {
e.preventDefault();
var t = e.target.tagName == 'BUTTON' ? e.target : e.target.closest('button');
var step = parseFloat(t.getAttribute("data-step"));
var controls = document.getElementById(t.getAttribute("data-controls"));
this.amount_selected = Math.max(controls.min, Math.min(controls.max, (this.amount_selected || 0) + step));
}
}
});
@@ -1438,11 +1456,11 @@ Vue.component('pretix-widget', {
},
computed: {
classObject: function () {
var o = {'pretix-widget': true};
if (this.mobile) {
o['pretix-widget-mobile'] = true;
}
return o;
return {
'pretix-widget': true,
'pretix-widget-mobile': this.mobile,
'pretix-widget-use-custom-spinners': !this.$root.use_native_spinners
};
}
}
});
@@ -1588,6 +1606,7 @@ var shared_root_methods = {
root.categories = data.items_by_category;
root.currency = data.currency;
root.display_net_prices = data.display_net_prices;
root.use_native_spinners = data.use_native_spinners;
root.voucher_explanation_text = data.voucher_explanation_text;
root.error = data.error;
root.display_add_to_cart = data.display_add_to_cart;
@@ -1833,6 +1852,7 @@ var create_widget = function (element) {
variation_filter: variations,
voucher_code: voucher,
display_net_prices: false,
use_native_spinners: false,
voucher_explanation_text: null,
show_variations_expanded: !!variations,
skip_ssl: skip_ssl,

View File

@@ -54,6 +54,43 @@ a.btn, button.btn {
}
}
.input-item-count-group {
display: flex;
}
.input-item-count-group input {
border-radius: 0;
border-left: none;
border-right: none;
padding-right: 12px;
-moz-appearance: textfield;
}
.input-item-count-group input::-webkit-outer-spin-button,
.input-item-count-group input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
.input-item-count-dec {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
width: 2.5em;
z-index: 2;
}
.input-item-count-inc {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
width: 2.5em;
}
.input-group-price {
input {
-moz-appearance: textfield;
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
}
.required-legend span {
color: $brand-primary;
font-weight: bold;

View File

@@ -65,6 +65,9 @@
@include opacity(.65);
@include box-shadow(none);
}
&.pretix-widget-btn-default {
@include button-variant($btn-default-color, $btn-default-bg, $btn-default-border);
}
}
input[type="text"], input[type="number"] {
line-height: normal;
@@ -99,6 +102,15 @@
}
}
}
.pretix-widget-use-custom-spinners input[type=number] {
padding-right: $padding-base-horizontal;
-moz-appearance: textfield;
}
.pretix-widget-use-custom-spinners input[type=number]::-webkit-outer-spin-button,
.pretix-widget-use-custom-spinners input[type=number]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
.pretix-widget {
margin: 10px 0;
padding: 0 10px;
@@ -254,6 +266,34 @@
display: block;
}
.pretix-widget-item-count-group {
display: flex;
}
.pretix-widget-item-count-group input {
border-radius: 0;
border-left: none;
border-right: none;
}
.pretix-widget-item-count-group button span {
vertical-align: 25%;
line-height: 0.5;
}
.pretix-widget-item-count-dec {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
width: 2.5em;
z-index: 2;
}
.pretix-widget-item-count-inc {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
width: 2.5em;
}
.pretix-widget-item-count-multiple {
display: block;
width: 100%;