Skip to content

Basket quantity field

The number between a basket line's − and + buttons can be typed into, on the basket page (Nova and Brock) and in the mini basket (Brock, Atelier, Depot, Pop, Spec and Bistro). The buttons work as before. Someone nudging 1 to 2 taps +; someone who wants 12, or a trade buyer who wants 40, types it.

Decisions

  • The stepper keeps its look. The number is a text field styled exactly like the plain number it replaced: no border, the same size, weight and colour (each stepper's own value class sets them). Hovering underlines it faintly and focus draws the theme's focus ring, so it reads as editable only when someone reaches for it. The field is a few pixels wider than the old number, enough for three digits.
  • type="text" with inputmode="numeric", not type="number". A number field adds browser spin arrows, changes with the mouse wheel, accepts e and -, and behaves differently in each browser. inputmode="numeric" still brings up the number pad on phones.
  • Saved on Enter or when the field loses focus, never per keystroke. Typing "12" must not save 1 first. Focus selects the number, so typing replaces it. An empty field, or the same number, puts the number back and sends nothing. Up and Down step by one; Escape puts the number back.
  • The server applies the limits and says so. A number above the product's maximum, the shop's maximum orderable quantity or the stock becomes the most allowed; one below the product's minimum (or 0) becomes the minimum. The line shows a one-off notice (You can buy up to 6 of these, so your basket has 6.), the same way stock limits already did. Nothing is refused for being too big or too small, and 0 doesn't remove the line: Remove is its own button.
  • 16px on touch screens. iOS zooms the page into a focused field whose text is under 16px, so a coarse pointer gets 16px; desktop keeps each theme's size.
  • Works without JavaScript. Each form puts an unnamed, visually hidden submit button ahead of the − button, so Enter in the number submits the typed number rather than pressing −.

How it fits together

Piece Where
Markup The field is input.nova-qty-input (name="quantity", data-min); the buttons send stepTo, so a button press and the typed number never arrive as two quantities. .nova-qty-default is the hidden Enter button.
Behaviour nova/js/qty-input.js, loaded by FullBasket and by each theme head with the mini basket; it runs once. It submits the form with requestSubmit(), so the mini basket posts it in the background and the basket page posts and reloads.
Styles .nova-qty-input and .nova-qty-default in Nova's bdgr.css, ahead of the steppers' own classes. Width comes from --qty-input-width on the value class (--mini-basket-step-input-width for the mini basket).
Server POST /basket/update reads stepTo, else the typed quantity (digits only; anything else changes nothing), and calls OrderService.updateLineItemQuantityLimitedToStock, which applies the limits and leaves an ABOVE_MAX or BELOW_MIN StockNotice.

The restaurant menu's basket and the legacy bootstrap theme keep their buttons only.