PageSourceSearch

https://tadaaa.co.uk/assets/controllers/mini_cart_widget_controller-57f6b23d.js

js tadaaa.co.uk collected 2026-10-01 02:55:49 UTC 3,389 bytes, 123 lines download raw bytes

1import BaseController from "controllers/base_controller"
2
3const MIN_GUESTS = 1
4const MAX_GUESTS = 100
5
6export default class extends BaseController {
7  static targets = ["cartForm", "guestForm", "guestInput", "subtotal", "perGuest", "submitButton", "successMessage", "pulse", "guestsDisplay"]
8  static outlets = ["mini-cart-item"]
9  static values = {
10    guests: Number
11  }
12
13  connect() {
14    if (this.hasGuestFormTarget) {
15      this.debouncedSubmitGuestForm = this.debounce(() => this.guestFormTarget.requestSubmit(), 500)
16    }
17  }
18
19  increment(event) {
20    event.preventDefault()
21    if (!this.hasGuestFormTarget) return
22    const value = this.currentGuestValue()
23    if (value >= MAX_GUESTS) return
24    this.setGuestValue(value + 1)
25    this.addPulse()
26    this.debouncedSubmitGuestForm()
27  }
28
29  decrement(event) {
30    event.preventDefault()
31    if (!this.hasGuestFormTarget) return
32    const value = this.currentGuestValue()
33    if (value <= MIN_GUESTS) return
34    this.setGuestValue(value - 1)
35    this.addPulse()
36    this.debouncedSubmitGuestForm(
36)
37  }
38
39  commitGuestCount(event) {
40    if (!this.hasGuestFormTarget) return
41    const raw = event?.target?.value
42    const n = parseInt(raw, 10)
43    this.setGuestValue(isNaN(n) ? MIN_GUESTS : n)
44    this.addPulse()
45    this.debouncedSubmitGuestForm()
46  }
47
48  handleGuestInputKeydown(event) {
49    if (event.key !== "Enter") return
50    event.preventDefault()
51    this.commitGuestCount(event)
52  }
53
54  currentGuestValue() {
55    if (this.hasGuestsDisplayTarget) {
56      const n = parseInt(this.guestsDisplayTarget.value, 10)
57      if (!isNaN(n)) return n
58    }
59    if (!this.hasGuestInputTarget) return MIN_GUESTS
60    const n = parseInt(this.guestInputTarget.value, 10)
61    return isNaN(n) ? MIN_GUESTS : n
62  }
63
64  setGuestValue(n) {
65    const clamped = Math.max(MIN_GUESTS, Math.min(MAX_GUESTS, n))
66    if (this.hasGuestInputTarget) {
67      this.guestInputTarget.value = clamped
68    }
69    if (this.hasGuestsDisplayTarget) {
70      this.guestsDisplayTargets.forEach((el) => { el.value = clamped })
71    }
72  }
73
74  addPulse() {
75    this.pulseTargets.forEach((el) => el.classList.add("animate-pulse"))
76  }
77
78  recalculate() {
79    let totalCents = 0
80
81    this.miniCartItemOutlets.forEach((itemController) => {
82      totalCents += itemController.priceValue * itemController.quantityValue
83    })
84
85    this.subtotalTarget.textContent = this.formatPriceNoCents(totalCents)
86
87    if (this.guestsValue > 0) {
88      const perGuestCents = Math.round(totalCents / this.guestsValue)
89      this.perGuestTarget.textContent = this.formatPrice(perGuestCents)
90    }
91  }
92
93  async handleSubmit() {
94    this.showSuccessMessage()
95    this.dispatch("added")
96  }
97
98  async showSuccessMessage() {
99    this.submitButtonTarget.classList.add("hidden")
100    this.successMessageTarget.classList.remove("hidden")
101    await this.delay(5000)
102    this.successMessageTarget.classList.add("hidden")
103    this.submitButtonTarget.classList.remove("hidden")
104  }
105
106  formatPrice(cents) {
107    return new Intl.NumberFormat('en-GB', {
108      style: 'currency',
109      currency: 'GBP',
110      minimumFractionDigits: 2,
111      maximumFractionDigits: 2
112    }).format(cents / 100)
113  }
114
115  formatPriceNoCents(cents) {
116    return new Intl.NumberFormat('en-GB', {
117      style: 'currency',
118      currency: 'GBP',
119      minimumFractionDigits: 0,
120      maximumFractionDigits: 0
121    }).format(cents / 100)
122  }
123}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.