Created
July 22, 2024 17:11
-
-
Save abinoam/334379c37c13dc4f5646196a4fdf9543 to your computer and use it in GitHub Desktop.
IMasks through Stimulus (Hotwire)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/views/price_versions/_form.html.erb | |
# Shorted to only the main parts. | |
# I hook into the stimulus controller with "html: { data: { controller: :imask } }" at the form. | |
# I trigger the mask in each input field by using "as: masked_priced" (that will be rendered by MaskedPriceInput custom SimpleForm input. | |
<%= simple_form_for [versionable, price_version], | |
wrapper: :half_horizontal_form_bs5, | |
html: { data: { controller: :imask } } do |f| %> | |
<%= f.simple_fields_for :size_prices, size_prices do |spf| %> | |
<%= spf.input_field :value, as: :masked_price, class: 'form-control' %> | |
<% end %> | |
<% end %> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/javascript/controllers/imask_controller.js | |
import { Controller } from "@hotwired/stimulus" | |
// Connects to data-controller="imask" | |
export default class extends Controller { | |
static targets = ['price']; | |
connect() { | |
// console.log('Connected to imask controller at element: ', this.element); | |
} | |
priceTargetConnected(element) { | |
this.#maskPrice(element); | |
} | |
#maskPrice(element) { | |
const maskOptions = { | |
mask: Number, // enable number mask | |
// other options are optional with defaults below | |
scale: 2, // digits after point, 0 for integers | |
thousandsSeparator: '.', // any single char | |
padFractionalZeros: true, // if true, then pads zeros at end to the length of scale | |
normalizeZeros: true, // appends or removes zeros at ends | |
radix: ',', // fractional delimiter | |
mapToRadix: ['.'], // symbols to process as radix | |
// additional number interval options (e.g.) | |
min: 0, | |
max: 99999.99, | |
autofix: false, // if true it jumps back to 99999 when exceeds max | |
}; | |
IMask(element, maskOptions); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/inputs/masked_price_input.rb | |
# As I was already using a custom SimpleForm input | |
# I made it inject "data-imask-target='price'" into each field to be masked. | |
class MaskedPriceInput < SimpleForm::Inputs::Base | |
include ActionView::Helpers::NumberHelper | |
def input(wrapper_options) | |
merged_input_options = merge_wrapper_options(input_html_options, wrapper_options) | |
original_value = object.send(attribute_name) | |
if original_value | |
merged_input_options[:value] = number_to_currency(original_value, unit: "").strip | |
end | |
merged_input_options["data-imask-target"] = :price | |
"#{@builder.text_field(attribute_name, merged_input_options)}".html_safe | |
end | |
def input_html_classes | |
super.push('masked-price') | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment