mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-03 02:21:33 +00:00
Use label as a placeholder that move above the input when focused
Couldn't make a pure CSS version because of the way rails generates its errors (it add `<span />` over the element, either `input` or `label`, itself)
This commit is contained in:
@@ -6,14 +6,14 @@
|
||||
= t("split_checkout.step1.contact_information.title")
|
||||
|
||||
.two-columns-inputs
|
||||
%div.checkout-input
|
||||
%div.checkout-input.with-floating-label{ "data-controller": "floating-label" }
|
||||
= f.label :email, t("split_checkout.step1.contact_information.email.label")
|
||||
= f.text_field :email, { placeholder: t("split_checkout.step1.contact_information.email.placeholder") }
|
||||
= f.text_field :email, { placeholder: " " }
|
||||
= f.error_message_on :email
|
||||
|
||||
%div.checkout-input
|
||||
%div.checkout-input.with-floating-label{ "data-controller": "floating-label" }
|
||||
= bill_address.label :phone, t("split_checkout.step1.contact_information.phone.label")
|
||||
= bill_address.text_field :phone, { placeholder: t("split_checkout.step1.contact_information.phone.placeholder") }
|
||||
= bill_address.text_field :phone, { placeholder: " " }
|
||||
= f.error_message_on "bill_address.phone"
|
||||
|
||||
%div.checkout-substep
|
||||
@@ -22,34 +22,34 @@
|
||||
= t("split_checkout.step1.billing_address.title")
|
||||
|
||||
.two-columns-inputs
|
||||
%div.checkout-input
|
||||
%div.checkout-input.with-floating-label{ "data-controller": "floating-label" }
|
||||
= bill_address.label :firstname, t("split_checkout.step1.billing_address.first_name.label")
|
||||
= bill_address.text_field :firstname, { placeholder: t("split_checkout.step1.billing_address.first_name.placeholder") }
|
||||
= bill_address.text_field :firstname, { placeholder: " " }
|
||||
= f.error_message_on "bill_address.firstname"
|
||||
|
||||
%div.checkout-input
|
||||
%div.checkout-input.with-floating-label{ "data-controller": "floating-label" }
|
||||
= bill_address.label :lastname, t("split_checkout.step1.billing_address.last_name.label")
|
||||
= bill_address.text_field :lastname, { placeholder: t("split_checkout.step1.billing_address.last_name.placeholder") }
|
||||
= bill_address.text_field :lastname, { placeholder: " " }
|
||||
= f.error_message_on "bill_address.lastname"
|
||||
|
||||
%div.checkout-input
|
||||
%div.checkout-input.with-floating-label{ "data-controller": "floating-label"}
|
||||
= bill_address.label :address1, t("split_checkout.step1.address.address1.label")
|
||||
= bill_address.text_field :address1, { placeholder: t("split_checkout.step1.address.address1.placeholder") }
|
||||
= bill_address.text_field :address1, { placeholder: " " }
|
||||
= f.error_message_on "bill_address.address1"
|
||||
|
||||
%div.checkout-input
|
||||
%div.checkout-input.with-floating-label{ "data-controller": "floating-label"}
|
||||
= bill_address.label :address2, t("split_checkout.step1.address.address2.label")
|
||||
= bill_address.text_field :address2, { placeholder: t("split_checkout.step1.address.address2.placeholder") }
|
||||
= bill_address.text_field :address2, { placeholder: " " }
|
||||
= f.error_message_on "bill_address.address2"
|
||||
|
||||
%div.checkout-input
|
||||
%div.checkout-input.with-floating-label{ "data-controller": "floating-label"}
|
||||
= bill_address.label :city, t("split_checkout.step1.address.city.label")
|
||||
= bill_address.text_field :city, { placeholder: t("split_checkout.step1.address.city.placeholder") }
|
||||
= bill_address.text_field :city, { placeholder: " " }
|
||||
= f.error_message_on "bill_address.city"
|
||||
|
||||
%div.checkout-input
|
||||
%div.checkout-input.with-floating-label{ "data-controller": "floating-label"}
|
||||
= bill_address.label :zipcode, t("split_checkout.step1.address.zipcode.label")
|
||||
= bill_address.text_field :zipcode, { placeholder: t("split_checkout.step1.address.zipcode.placeholder") }
|
||||
= bill_address.text_field :zipcode, { placeholder: " " }
|
||||
= f.error_message_on "bill_address.zipcode"
|
||||
|
||||
%div{ "data-controller": "dependent-select", "data-dependent-select-options-value": countries_with_states }
|
||||
@@ -112,24 +112,24 @@
|
||||
|
||||
%div{"data-shippingmethod-target": "shippingMethodAddress", style: "display: #{!display_ship_address || shipping_and_billing_match?(@order) ? 'none' : 'block'}" }
|
||||
= f.fields :ship_address, model: @order.ship_address do |ship_address|
|
||||
%div.checkout-input
|
||||
%div.checkout-input.with-floating-label{ "data-controller": "floating-label"}
|
||||
= ship_address.label :address1, t("split_checkout.step1.address.address1.label")
|
||||
= ship_address.text_field :address1, { placeholder: t("split_checkout.step1.address.address1.placeholder") }
|
||||
= ship_address.text_field :address1, { placeholder: " " }
|
||||
= f.error_message_on "ship_address.address1"
|
||||
|
||||
%div.checkout-input
|
||||
%div.checkout-input.with-floating-label{ "data-controller": "floating-label"}
|
||||
= ship_address.label :address2, t("split_checkout.step1.address.address2.label")
|
||||
= ship_address.text_field :address2, { placeholder: t("split_checkout.step1.address.address2.placeholder") }
|
||||
= ship_address.text_field :address2, { placeholder: " " }
|
||||
= f.error_message_on "ship_address.address2"
|
||||
|
||||
%div.checkout-input
|
||||
%div.checkout-input.with-floating-label{ "data-controller": "floating-label"}
|
||||
= ship_address.label :city, t("split_checkout.step1.address.city.label")
|
||||
= ship_address.text_field :city, { placeholder: t("split_checkout.step1.address.city.placeholder") }
|
||||
= ship_address.text_field :city, { placeholder: " " }
|
||||
= f.error_message_on "ship_address.city"
|
||||
|
||||
%div.checkout-input
|
||||
%div.checkout-input.with-floating-label{ "data-controller": "floating-label"}
|
||||
= ship_address.label :zipcode, t("split_checkout.step1.address.zipcode.label")
|
||||
= ship_address.text_field :zipcode, { placeholder: t("split_checkout.step1.address.zipcode.placeholder") }
|
||||
= ship_address.text_field :zipcode, { placeholder: " " }
|
||||
= f.error_message_on "ship_address.zipcode"
|
||||
|
||||
%div{ "data-controller": "dependent-select", "data-dependent-select-options-value": countries_with_states }
|
||||
|
||||
30
app/webpacker/controllers/floating_label_controller.js
Normal file
30
app/webpacker/controllers/floating_label_controller.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import { Controller } from "stimulus";
|
||||
|
||||
export default class extends Controller {
|
||||
connect() {
|
||||
const input = this.element.querySelector("input");
|
||||
input.addEventListener("focus", this.focus.bind(this));
|
||||
input.addEventListener("blur", this.blur.bind(this));
|
||||
if (input.value.length > 0) {
|
||||
this.focus();
|
||||
}
|
||||
|
||||
const label = this.element.querySelector("label");
|
||||
// Add transition class to the label and display the label
|
||||
// after a short delay to avoid flickering
|
||||
setTimeout(() => {
|
||||
label.classList.add("with-transition");
|
||||
label.style.display = "block";
|
||||
}, 100);
|
||||
}
|
||||
|
||||
focus() {
|
||||
this.element.classList.add("active");
|
||||
}
|
||||
|
||||
blur(e) {
|
||||
if (e.target.value.length === 0) {
|
||||
this.element.classList.remove("active");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -331,3 +331,35 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shows label as a placeholder, inside the input and when the input is focused shows the label above the input
|
||||
.checkout-input.with-floating-label {
|
||||
position: relative;
|
||||
|
||||
label {
|
||||
display: none; // Display none by default, and shown by floating_label_controller
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
font-size: 0.875rem;
|
||||
padding: 8px;
|
||||
padding-left: 9px;
|
||||
color: $min-accessible-grey;
|
||||
pointer-events: none;
|
||||
transform: translateY(0);
|
||||
transform-origin: top left;
|
||||
&.with-transition {
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
}
|
||||
&.active {
|
||||
label {
|
||||
transform: translateY(-9px) translateX(10px) scale(0.9);
|
||||
background-color: white;
|
||||
padding-left: 3px;
|
||||
padding-right: 3px;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1919,33 +1919,25 @@ en:
|
||||
title: Contact information
|
||||
email:
|
||||
label: Email
|
||||
placeholder: e.g. Janedoe@email.com
|
||||
phone:
|
||||
label: Phone number
|
||||
placeholder: e.g. 07987654321
|
||||
billing_address:
|
||||
title: Billing address
|
||||
first_name:
|
||||
label: First Name
|
||||
placeholder: e.g. Jane
|
||||
last_name:
|
||||
label: Last Name
|
||||
placeholder: e.g. Doe
|
||||
address:
|
||||
address1:
|
||||
label: Address (Street + House Number)
|
||||
placeholder: e.g. Flat 1 Elm apartments
|
||||
address2:
|
||||
label: Additional address info (optional)
|
||||
placeholder: e.g. Cavalier avenur
|
||||
city:
|
||||
label: City
|
||||
placeholder: e.g. London
|
||||
state_id:
|
||||
label: State
|
||||
zipcode:
|
||||
label: Postcode
|
||||
placeholder: e.g. SW11 3QN
|
||||
country_id:
|
||||
label: Country
|
||||
shipping_info:
|
||||
|
||||
Reference in New Issue
Block a user