mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Add first stimulus controllers to display elements
1. Introduce a stimulus toggle_controller
- controller: { "data-controller": "toggle" }
- action: { "data-action": "toggle#toggle" }
- show or not: { "data-toggle-show": true || false }
- targets: { "data-toggle-target": "content", style: "display: none" }
Display payment method price
2. States are populated via a new dependant_select_controller by stimulus.
Usage:
- controller : { "data-controller": "dependant-select", "data-dependant-select-options-value": [ [1: ["option", "for", "1"], [2: ["option", "for", "2"] ] }
- target (on the populating target): { "data-dependant-select-target": "select" }
- source and action (on the input that leads the dependant select): {"data-dependant-select-target": "source", "data-action": "dependant-select#handleSelectChange"}
Some improvements on readability
3. Populate ShippingMethod description thanks to "shippingmethod_controller"
+
- Add countries and states
This commit is contained in:
@@ -6,6 +6,7 @@ class SplitCheckoutController < ::BaseController
|
||||
layout 'darkswarm'
|
||||
|
||||
include OrderStockCheck
|
||||
include Spree::BaseHelper
|
||||
|
||||
helper 'terms_and_conditions'
|
||||
helper 'checkout'
|
||||
@@ -19,7 +20,7 @@ class SplitCheckoutController < ::BaseController
|
||||
prepend_before_action :require_order_cycle
|
||||
prepend_before_action :require_distributor_chosen
|
||||
|
||||
before_action :load_order, :load_shipping_methods
|
||||
before_action :load_order, :load_shipping_methods, :load_countries
|
||||
|
||||
before_action :ensure_order_not_completed
|
||||
before_action :ensure_checkout_allowed
|
||||
@@ -95,6 +96,11 @@ class SplitCheckoutController < ::BaseController
|
||||
@shipping_methods = Spree::ShippingMethod.for_distributor(@order.distributor).order(:name)
|
||||
end
|
||||
|
||||
def load_countries
|
||||
@countries = available_countries.map { |c| [c.name, c.id] }
|
||||
@countries_with_states = available_countries.map { |c| [c.id, c.states.map { |s| [s.name, s.id] }] }
|
||||
end
|
||||
|
||||
def load_order
|
||||
@order = current_order
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
= bill_address.text_field :phone, { placeholder: t("split_checkout.step1.your_details.phone.placeholder") }
|
||||
= f.error_message_on "bill_address.phone"
|
||||
|
||||
%div.checkout-substep
|
||||
%div.checkout-substep{ "data-controller": "dependant-select", "data-dependant-select-options-value": @countries_with_states }
|
||||
-# BILLING ADDRESS
|
||||
%div.checkout-title
|
||||
= t("split_checkout.step1.billing_address.title")
|
||||
@@ -52,8 +52,7 @@
|
||||
%div.checkout-input
|
||||
= fields_for :bill_address, @order.bill_address do |bill_address|
|
||||
= bill_address.label :state_id, t("split_checkout.step1.billing_address.state_id.label")
|
||||
-# todo: get state // values: s.id as s.name for s in countriesById[order.bill_address.country_id].states // defaultvalue: {}
|
||||
= bill_address.select :state_id, []
|
||||
= bill_address.select :state_id, @countries_with_states, { }, { "data-dependant-select-target": "select" }
|
||||
|
||||
%div.checkout-input
|
||||
= fields_for :bill_address, @order.bill_address do |bill_address|
|
||||
@@ -64,51 +63,48 @@
|
||||
%div.checkout-input
|
||||
= fields_for :bill_address, @order.bill_address do |bill_address|
|
||||
= bill_address.label :country_id, t("split_checkout.step1.billing_address.country_id.label")
|
||||
-# todo: get countries // values: c.id as c.name for c in countries // defaultvalue: order.bill_address.country_id = order.bill_address.country_id || #{DefaultCountry.id}
|
||||
= bill_address.select :country_id, []
|
||||
= bill_address.select :country_id, @countries, { selected: @order.bill_address.country_id || DefaultCountry.id }, {"data-dependant-select-target": "source", "data-action": "dependant-select#handleSelectChange"}
|
||||
|
||||
- if spree_current_user||true
|
||||
%div.checkout-input
|
||||
= f.check_box :checkout_default_bill_address
|
||||
= f.label :checkout_default_bill_address, t(:checkout_default_bill_address)
|
||||
|
||||
%div.checkout-substep
|
||||
%div.checkout-substep{ "data-controller": "toggle shippingmethod" }
|
||||
-# DELIVERY ADDRESS
|
||||
%div.checkout-title
|
||||
= t("split_checkout.step1.delivery_address.title")
|
||||
|
||||
= @shipping_methods.each do |shipping_method|
|
||||
- @shipping_methods.each do |shipping_method|
|
||||
%div.checkout-input
|
||||
= fields_for shipping_method do |shipping_method_form|
|
||||
= shipping_method_form.check_box :name, {id: "shipping_method_" + shipping_method.id.to_s }, shipping_method.id, 0
|
||||
= shipping_method_form.label :name, shipping_method.name, {for: "shipping_method_" + shipping_method.id.to_s }
|
||||
= shipping_method_form.radio_button :name, shipping_method.id,
|
||||
id: "shipping_method_#{shipping_method.id}",
|
||||
"data-description": shipping_method.description,
|
||||
"data-action": "toggle#toggle shippingmethod#selectShippingMethod",
|
||||
"data-toggle-show": shipping_method.require_ship_address
|
||||
= shipping_method_form.label shipping_method.id, shipping_method.name, {for: "shipping_method_" + shipping_method.id.to_s }
|
||||
%em.light
|
||||
-# todo: display method price | localizeCurrency // How to retrive shipping method price?
|
||||
= if shipping_method.price && shipping_method.price != 0
|
||||
= method.price
|
||||
- else
|
||||
= t(:checkout_method_free)
|
||||
= payment_method_price(shipping_method, @order)
|
||||
|
||||
|
||||
- if true # todo: Checkout.requireShipAddress() // requireShipAddress: -> @shippingMethod()?.require_ship_address
|
||||
%div.checkout-input
|
||||
= f.check_box "Checkout.ship_address_same_as_billing", { id: "Checkout.ship_address_same_as_billing" } # "ng-model": "Checkout.ship_address_same_as_billing"}s
|
||||
= f.label "Checkout.ship_address_same_as_billing", t(:checkout_address_same), { for: "Checkout.ship_address_same_as_billing" }
|
||||
|
||||
- if spree_current_user || true # todo: && Checkout.requireShipAddress() // requireShipAddress: -> @shippingMethod()?.require_ship_address
|
||||
%div.checkout-input
|
||||
%div.checkout-input{ "data-toggle-target": "content", style: "display: none" }
|
||||
= f.check_box "Checkout.ship_address_same_as_billing", { id: "Checkout.ship_address_same_as_billing" }
|
||||
= f.label "Checkout.ship_address_same_as_billing", t(:checkout_address_same), { for: "Checkout.ship_address_same_as_billing" }
|
||||
|
||||
- if spree_current_user
|
||||
%div.checkout-input{ "data-toggle-target": "content", style: "display: none" }
|
||||
= f.check_box "Checkout.default_ship_address", { id: "Checkout.default_ship_address" }
|
||||
= f.label "Checkout.default_ship_address", t(:checkout_default_ship_address), { for: "Checkout.default_ship_address" }
|
||||
|
||||
- if true # todo: Checkout.shippingMethod().description
|
||||
.div.checkout-input
|
||||
#distributor_address.panel
|
||||
%span{}{{ Checkout.shippingMethod().description }}
|
||||
%br/
|
||||
%br/
|
||||
- if @order.order_cycle.pickup_time_for(@order.distributor)
|
||||
= t :checkout_ready_for
|
||||
= @order.order_cycle.pickup_time_for(@order.distributor)
|
||||
%div.checkout-input{"data-shippingmethod-target": "shippingMethodDescription"}
|
||||
#distributor_address.panel
|
||||
%span{"data-shippingmethod-target": "shippingMethodDescriptionContent"}
|
||||
%br/
|
||||
%br/
|
||||
- if @order.order_cycle.pickup_time_for(@order.distributor)
|
||||
= t :checkout_ready_for
|
||||
= @order.order_cycle.pickup_time_for(@order.distributor)
|
||||
|
||||
.div.checkout-input
|
||||
= f.label :special_instructions, t(:checkout_instructions)
|
||||
|
||||
27
app/webpacker/controllers/dependant_select_controller.js
Normal file
27
app/webpacker/controllers/dependant_select_controller.js
Normal file
@@ -0,0 +1,27 @@
|
||||
import { Controller } from "stimulus";
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ["source", "select"];
|
||||
static values = { options: Array };
|
||||
|
||||
connect() {
|
||||
this.populateSelect(parseInt(this.sourceTarget.value));
|
||||
}
|
||||
|
||||
handleSelectChange() {
|
||||
this.populateSelect(parseInt(this.sourceTarget.value));
|
||||
}
|
||||
|
||||
populateSelect(sourceId) {
|
||||
const allOptions = this.optionsValue;
|
||||
const options = allOptions.find((option) => option[0] === sourceId)[1];
|
||||
const selectBox = this.selectTarget;
|
||||
selectBox.innerHTML = "";
|
||||
options.forEach((item) => {
|
||||
const opt = document.createElement("option");
|
||||
opt.value = item[1];
|
||||
opt.innerHTML = item[0];
|
||||
selectBox.appendChild(opt);
|
||||
});
|
||||
}
|
||||
}
|
||||
24
app/webpacker/controllers/shippingmethod_controller.js
Normal file
24
app/webpacker/controllers/shippingmethod_controller.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import { Controller } from "stimulus";
|
||||
export default class extends Controller {
|
||||
static targets = [
|
||||
"shippingMethodDescription",
|
||||
"shippingMethodDescriptionContent",
|
||||
];
|
||||
connect() {
|
||||
// Hide shippingMethodDescription by default
|
||||
this.shippingMethodDescriptionTarget.style.display = "none";
|
||||
}
|
||||
selectShippingMethod(event) {
|
||||
const input = event.target;
|
||||
if (input.tagName === "INPUT") {
|
||||
if (input.dataset.description.length > 0) {
|
||||
this.shippingMethodDescriptionTarget.style.display = "block";
|
||||
this.shippingMethodDescriptionContentTarget.innerText =
|
||||
input.dataset.description;
|
||||
} else {
|
||||
this.shippingMethodDescriptionTarget.style.display = "none";
|
||||
this.shippingMethodDescriptionContentTarget.innerText = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
app/webpacker/controllers/toggle_controller.js
Normal file
12
app/webpacker/controllers/toggle_controller.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import { Controller } from "stimulus";
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ["content"];
|
||||
|
||||
toggle(event) {
|
||||
const input = event.currentTarget;
|
||||
this.contentTargets.forEach((t) => {
|
||||
t.style.display = input.dataset.toggleShow === "true" ? "block" : "none";
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user