mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Replace quantity input with add-remove buttons
The new mobile friendly design contains a nice "Add" button to add variants to your cart. Once you have the variant in you cart, it's replaced by plus and minus buttons to adjust the quantity. Other languages have longer words than "Add" which need to fit on the button. Since the add button and the +/- buttons should have the same width, I widened them a little bit so that they fit the longest words Aggiungi and Добавить.
This commit is contained in:
@@ -11,3 +11,11 @@ Darkswarm.directive "shopVariant", ->
|
||||
], (new_value, old_value) ->
|
||||
return if old_value[0] == null && new_value[0] == null
|
||||
Cart.adjust($scope.variant.line_item)
|
||||
|
||||
$scope.add = (quantity) ->
|
||||
$scope.variant.line_item.quantity += quantity
|
||||
|
||||
$scope.canAdd = (quantity) ->
|
||||
variant = $scope.variant
|
||||
wantedQuantity = variant.line_item.quantity + quantity
|
||||
variant.on_demand || wantedQuantity <= variant.on_hand
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
.small-5.medium-3.large-3.columns.text-right{"ng-if" => "::!variant.product.group_buy"}
|
||||
|
||||
%input{type: :number,
|
||||
integer: true,
|
||||
value: nil,
|
||||
min: 0,
|
||||
placeholder: "0",
|
||||
"ofn-disable-scroll" => true,
|
||||
"ng-debounce" => "500",
|
||||
onwheel: "this.blur()",
|
||||
"ng-model" => "variant.line_item.quantity",
|
||||
"ofn-on-hand" => "{{variant.on_demand && 9999 || variant.on_hand }}",
|
||||
"ng-disabled" => "!variant.on_demand && variant.on_hand == 0",
|
||||
name: "variants[{{::variant.id}}]", id: "variants_{{::variant.id}}"}
|
||||
%button.add-variant{type: "button", ng: {if: "!variant.line_item.quantity", click: "add(1)", disabled: "!canAdd(1)"}}
|
||||
{{ "js.shop_variant_no_group_buy.add" | t }}
|
||||
%button.variant-quantity{type: "button", ng: {if: "variant.line_item.quantity", click: "add(-1)"}}>
|
||||
{{ "js.shop_variant_no_group_buy.decrement" | t }}
|
||||
%button.variant-quantity{type: "button", ng: {if: "variant.line_item.quantity", click: "add(1)", disabled: "!canAdd(1)"}}
|
||||
{{ "js.shop_variant_no_group_buy.increment" | t }}
|
||||
%br
|
||||
.variant-quantity-display{ng: {class: "{visible: variant.line_item.quantity}"}}
|
||||
{{ "js.shop_variant_no_group_buy.in_cart" | t:{quantity: variant.line_item.quantity} }}
|
||||
%input{type: :hidden,
|
||||
name: "variants[{{::variant.id}}]",
|
||||
ng: {model: "variant.line_item.quantity"}}
|
||||
|
||||
@@ -9,54 +9,6 @@
|
||||
|
||||
// ordering
|
||||
product {
|
||||
input {
|
||||
@include border-radius(0);
|
||||
|
||||
@include csstrans;
|
||||
|
||||
margin: 0;
|
||||
width: 10rem;
|
||||
display: inline;
|
||||
|
||||
@include box-shadow(none);
|
||||
|
||||
border-color: #b3b3b3;
|
||||
text-align: right;
|
||||
|
||||
@include breakpoint(desktop) {
|
||||
width: 8rem;
|
||||
}
|
||||
|
||||
@include breakpoint(tablet) {
|
||||
width: 7rem;
|
||||
}
|
||||
|
||||
@include breakpoint(phablet) {
|
||||
float: left !important;
|
||||
font-size: 0.75rem;
|
||||
padding-left: 0.25rem;
|
||||
padding-right: 0.25rem;
|
||||
}
|
||||
|
||||
@include breakpoint(mobile) {
|
||||
width: 5.8rem;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@include box-shadow(none);
|
||||
|
||||
border-color: #888;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
&:active, &:focus, &.active {
|
||||
@include box-shadow(none);
|
||||
|
||||
background-color: #f9f4b9;
|
||||
border-color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
// BULK
|
||||
|
||||
input.bulk {
|
||||
@@ -96,3 +48,61 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Components to add variants to cart and change quanities
|
||||
//
|
||||
// They are not nested so that they can be used in modals.
|
||||
button.add-variant, button.variant-quantity {
|
||||
height: 2.5rem;
|
||||
border-radius: 0;
|
||||
background-color: $orange-500;
|
||||
color: white;
|
||||
// Override foundation button styles:
|
||||
font-size: 1rem;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
transition: none;
|
||||
|
||||
&[disabled] {
|
||||
&:hover, &:focus {
|
||||
background-color: $orange-500;
|
||||
}
|
||||
}
|
||||
&:nth-of-type(1) {
|
||||
border-bottom-left-radius: 0.25em;
|
||||
border-top-left-radius: 0.25em;
|
||||
}
|
||||
&:nth-last-of-type(1) {
|
||||
border-top-right-radius: 0.25em;
|
||||
border-bottom-right-radius: 0.25em;
|
||||
}
|
||||
}
|
||||
button.add-variant {
|
||||
min-width: 6rem;
|
||||
padding: 0 1em;
|
||||
|
||||
&[disabled] {
|
||||
&:hover, &:focus {
|
||||
background-color: $orange-500;
|
||||
}
|
||||
}
|
||||
}
|
||||
button.variant-quantity {
|
||||
width: 3rem;
|
||||
|
||||
&:nth-of-type(1) {
|
||||
border-right: .1em solid $orange-400;
|
||||
}
|
||||
}
|
||||
.variant-quantity-display {
|
||||
display: inline-block;
|
||||
font-size: 0.875em;
|
||||
margin-top: 0.25em;
|
||||
text-align: center;
|
||||
width: 6rem;
|
||||
visibility: hidden;
|
||||
|
||||
&.visible {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2726,6 +2726,11 @@ See the %{link} to find out more about %{sitename}'s features and to start using
|
||||
in your cart have reduced. Here's what's changed:
|
||||
now_out_of_stock: is now out of stock.
|
||||
only_n_remainging: "now only has %{num} remaining."
|
||||
shop_variant_no_group_buy:
|
||||
add: "Add"
|
||||
increment: "+" # U+FF0B Fullwidth Plus Sign
|
||||
decrement: "-" # U+FF0D Fullwidth Hyphen-Minus
|
||||
in_cart: "%{quantity} in cart"
|
||||
variants:
|
||||
on_demand:
|
||||
"yes": "On demand"
|
||||
|
||||
@@ -294,19 +294,21 @@ feature "As a consumer I want to shop with a distributor", js: true do
|
||||
|
||||
click_add_to_cart variant, 10
|
||||
|
||||
expect(page).to have_field "variants[#{variant.id}]", with: '10'
|
||||
within_variant(variant) do
|
||||
expect(page).to have_content "10 in cart"
|
||||
end
|
||||
end
|
||||
|
||||
it "alerts us when we enter a quantity greater than the stock available" do
|
||||
variant.update on_hand: 5
|
||||
visit shop_path
|
||||
|
||||
|
||||
accept_alert 'Insufficient stock available, only 5 remaining' do
|
||||
fill_in "variants[#{variant.id}]", with: '10'
|
||||
end
|
||||
click_add_to_cart variant, 5
|
||||
|
||||
expect(page).to have_field "variants[#{variant.id}]", with: '5'
|
||||
within_variant(variant) do
|
||||
expect(page).to have_content "5 in cart"
|
||||
expect(page).to have_button "+", disabled: true
|
||||
end
|
||||
end
|
||||
|
||||
describe "when a product goes out of stock just before it's added to the cart" do
|
||||
@@ -325,8 +327,13 @@ feature "As a consumer I want to shop with a distributor", js: true do
|
||||
|
||||
# -- Page updates
|
||||
# Update amount in cart
|
||||
expect(page).to have_field "variants[#{variant.id}]", with: '0', disabled: true
|
||||
expect(page).to have_field "variants[#{variant2.id}]", with: ''
|
||||
within_variant(variant) do
|
||||
expect(page).to have_button "Add", disabled: true
|
||||
expect(page).to have_no_content "in cart"
|
||||
end
|
||||
within_variant(variant2) do
|
||||
expect(page).to have_button "Add", disabled: false
|
||||
end
|
||||
|
||||
# Update amount available in product list
|
||||
# If amount falls to zero, variant should be greyed out and input disabled
|
||||
@@ -352,7 +359,11 @@ feature "As a consumer I want to shop with a distributor", js: true do
|
||||
variant.update! on_hand: 0
|
||||
|
||||
# -- Messaging
|
||||
click_add_bulk_max_to_cart variant
|
||||
within(".reveal-modal") do
|
||||
page.all("button", text: "+").last.click
|
||||
end
|
||||
close_modal
|
||||
wait_for_cart
|
||||
|
||||
within(".out-of-stock-modal") do
|
||||
expect(page).to have_content "stock levels for one or more of the products in your cart have reduced"
|
||||
@@ -390,6 +401,7 @@ feature "As a consumer I want to shop with a distributor", js: true do
|
||||
it "does not update max_quantity" do
|
||||
click_add_bulk_to_cart variant, 2
|
||||
click_add_bulk_max_to_cart variant, 3
|
||||
close_modal
|
||||
|
||||
variant.update! on_hand: 1
|
||||
|
||||
@@ -554,9 +566,10 @@ feature "As a consumer I want to shop with a distributor", js: true do
|
||||
end
|
||||
|
||||
# Removes the item from the client-side cart and marks the variant as unavailable
|
||||
expect(page).to have_field "variants[#{variant.id}]", with: '0', disabled: true
|
||||
expect(page).to have_selector "#variant-#{variant.id}.out-of-stock"
|
||||
expect(page).to have_selector "#variants_#{variant.id}[ofn-on-hand='0']"
|
||||
expect(page).to have_selector "#variants_#{variant.id}[disabled='disabled']"
|
||||
within_variant(variant) do
|
||||
expect(page).to have_button "Add", disabled: true
|
||||
expect(page).to have_no_content "in cart"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -50,28 +50,17 @@ module ShopWorkflow
|
||||
end
|
||||
|
||||
# Add an item to the cart
|
||||
#
|
||||
# At the moment, the user enters the quantity into an input field.
|
||||
# But with the coming mobile-friendly UX, the user will click a button to
|
||||
# add an item, hence the naming.
|
||||
#
|
||||
# This is temporary code. The duplication will be removed by the mobile
|
||||
# product listings feature. This has been backported to avoid merge
|
||||
# conflicts and to make the current build more stable.
|
||||
def click_add_to_cart(variant = nil, quantity = 1)
|
||||
within_variant(variant) do
|
||||
input = page.find("input")
|
||||
new_quantity = input.value.to_i + quantity
|
||||
fill_in input[:name], with: new_quantity
|
||||
click_button "Add"
|
||||
(quantity - 1).times { click_button "+" }
|
||||
end
|
||||
wait_for_cart
|
||||
end
|
||||
|
||||
def click_remove_from_cart(variant = nil, quantity = 1)
|
||||
within_variant(variant) do
|
||||
input = page.find("input")
|
||||
new_quantity = input.value.to_i - quantity
|
||||
fill_in input[:name], with: new_quantity
|
||||
quantity.times { click_button "-" }
|
||||
end
|
||||
wait_for_cart
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user