From 81cc8e528bae50fcf2992e46c27c46b49a479556 Mon Sep 17 00:00:00 2001 From: Thiago Youssef <43591948+thiagoyoussef@users.noreply.github.com> Date: Tue, 19 Nov 2024 13:53:34 -0300 Subject: [PATCH] feature: additional html attributes on fields --- .../fields/area_field/edit_component.html.erb | 4 ++- .../belongs_to_field/edit_component.html.erb | 9 ++++--- .../boolean_field/edit_component.html.erb | 3 ++- .../edit_component.html.erb | 3 ++- .../fields/code_field/edit_component.html.erb | 3 ++- .../country_field/edit_component.html.erb | 3 ++- .../fields/date_field/edit_component.html.erb | 6 +++-- .../date_time_field/edit_component.html.erb | 6 +++-- .../edit_component.html.erb | 3 ++- .../fields/file_field/edit_component.html.erb | 3 ++- .../files_field/edit_component.html.erb | 3 ++- .../hidden_field/edit_component.html.erb | 3 ++- .../location_field/edit_component.html.erb | 9 ++++--- .../markdown_field/edit_component.html.erb | 3 ++- .../number_field/edit_component.html.erb | 3 ++- .../password_field/edit_component.html.erb | 3 ++- .../edit_component.html.erb | 3 ++- .../select_field/edit_component.html.erb | 3 ++- .../status_field/edit_component.html.erb | 3 ++- .../fields/tags_field/edit_component.html.erb | 3 ++- .../fields/text_field/edit_component.html.erb | 3 ++- .../textarea_field/edit_component.html.erb | 3 ++- .../fields/time_field/edit_component.html.erb | 6 +++-- .../tiptap_field/edit_component.html.erb | 3 ++- .../fields/trix_field/edit_component.html.erb | 3 ++- .../fields/concerns/has_html_attributes.rb | 27 ++++++++++++++++++- spec/dummy/app/avo/resources/user.rb | 2 +- spec/features/avo/text_field_spec.rb | 1 + 28 files changed, 93 insertions(+), 34 deletions(-) diff --git a/app/components/avo/fields/area_field/edit_component.html.erb b/app/components/avo/fields/area_field/edit_component.html.erb index 28ffcb87e8..06f5c5a3ec 100644 --- a/app/components/avo/fields/area_field/edit_component.html.erb +++ b/app/components/avo/fields/area_field/edit_component.html.erb @@ -4,5 +4,7 @@ class: classes("w-full"), placeholder: field.placeholder, disabled: disabled?, - autofocus: @autofocus %> + autofocus: @autofocus, + **field.edit_input_additional_attributes + %> <% end %> diff --git a/app/components/avo/fields/belongs_to_field/edit_component.html.erb b/app/components/avo/fields/belongs_to_field/edit_component.html.erb index b38be635bd..94c069a5b9 100644 --- a/app/components/avo/fields/belongs_to_field/edit_component.html.erb +++ b/app/components/avo/fields/belongs_to_field/edit_component.html.erb @@ -18,7 +18,8 @@ action: "change->belongs-to-field#changeType #{field_html_action}", 'belongs-to-field-target': "select", }, - disabled: disabled + disabled: disabled, + **@field.edit_input_additional_attributes } %> <% @@ -59,7 +60,8 @@ { class: classes("w-full"), data: @field.get_html(:data, view: view, element: :input), - disabled: disabled + disabled: disabled, + **@field.edit_input_additional_attributes } %> <% @@ -110,7 +112,8 @@ class: classes("w-full"), data: @field.get_html(:data, view: view, element: :input), disabled: disabled, - style: @field.get_html(:style, view: view, element: :input) + style: @field.get_html(:style, view: view, element: :input), + **@field.edit_input_additional_attributes } %> <% diff --git a/app/components/avo/fields/boolean_field/edit_component.html.erb b/app/components/avo/fields/boolean_field/edit_component.html.erb index fd3327649a..3fecd7faf3 100644 --- a/app/components/avo/fields/boolean_field/edit_component.html.erb +++ b/app/components/avo/fields/boolean_field/edit_component.html.erb @@ -7,7 +7,8 @@ data: @field.get_html(:data, view: view, element: :input), disabled: disabled?, autofocus: @autofocus, - style: @field.get_html(:style, view: view, element: :input) + style: @field.get_html(:style, view: view, element: :input), + **@field.edit_input_additional_attributes %> <% end %> diff --git a/app/components/avo/fields/boolean_group_field/edit_component.html.erb b/app/components/avo/fields/boolean_group_field/edit_component.html.erb index 7b0991b0ac..4f1039c594 100644 --- a/app/components/avo/fields/boolean_group_field/edit_component.html.erb +++ b/app/components/avo/fields/boolean_group_field/edit_component.html.erb @@ -11,7 +11,8 @@ id: "#{@form_scope}_#{@field.id}_#{id}", style: @style, multiple: true, - checked: checked?(id) + checked: checked?(id), + **@field.edit_input_additional_attributes }, id, "" diff --git a/app/components/avo/fields/code_field/edit_component.html.erb b/app/components/avo/fields/code_field/edit_component.html.erb index fc424d7523..8764d7fb58 100644 --- a/app/components/avo/fields/code_field/edit_component.html.erb +++ b/app/components/avo/fields/code_field/edit_component.html.erb @@ -17,7 +17,8 @@ disabled: disabled?, placeholder: @field.placeholder, autofocus: @autofocus, - style: @field.get_html(:style, view: view, element: :input) + style: @field.get_html(:style, view: view, element: :input), + **@field.edit_input_additional_attributes %> <% end %> diff --git a/app/components/avo/fields/country_field/edit_component.html.erb b/app/components/avo/fields/country_field/edit_component.html.erb index eceb336c1b..2106e9ec20 100644 --- a/app/components/avo/fields/country_field/edit_component.html.erb +++ b/app/components/avo/fields/country_field/edit_component.html.erb @@ -12,6 +12,7 @@ disabled: disabled?, style: @field.get_html(:style, view: view, element: :input), placeholder: @field.include_blank.present? ? nil : @field.placeholder, - autocomplete: @field.autocomplete + autocomplete: @field.autocomplete, + **@field.edit_input_additional_attributes %> <% end %> diff --git a/app/components/avo/fields/date_field/edit_component.html.erb b/app/components/avo/fields/date_field/edit_component.html.erb index 9b531b5ed2..9d6e48787f 100644 --- a/app/components/avo/fields/date_field/edit_component.html.erb +++ b/app/components/avo/fields/date_field/edit_component.html.erb @@ -20,7 +20,8 @@ }, disabled: disabled?, placeholder: @field.placeholder, - style: @field.get_html(:style, view: view, element: :input) + style: @field.get_html(:style, view: view, element: :input), + **@field.edit_input_additional_attributes %> <%= datetime_field "fake_#{@field.id}", "fake", value: @field.edit_formatted_value, @@ -32,7 +33,8 @@ }, disabled: disabled?, placeholder: @field.placeholder, - style: @field.get_html(:style, view: view, element: :input) + style: @field.get_html(:style, view: view, element: :input), + **@field.edit_input_additional_attributes %> <% end %> <% end %> diff --git a/app/components/avo/fields/date_time_field/edit_component.html.erb b/app/components/avo/fields/date_time_field/edit_component.html.erb index d255673ded..5bd1fb5427 100644 --- a/app/components/avo/fields/date_time_field/edit_component.html.erb +++ b/app/components/avo/fields/date_time_field/edit_component.html.erb @@ -22,7 +22,8 @@ }, disabled: disabled?, placeholder: @field.placeholder, - style: @field.get_html(:style, view: view, element: :input) + style: @field.get_html(:style, view: view, element: :input), + **@field.edit_input_additional_attributes %> <%= datetime_field "fake_#{@field.id}", "fake", value: @field.edit_formatted_value, @@ -34,7 +35,8 @@ }, disabled: disabled?, placeholder: @field.placeholder, - style: @field.get_html(:style, view: view, element: :input) + style: @field.get_html(:style, view: view, element: :input), + **@field.edit_input_additional_attributes %> <%= content_tag :button, class: "absolute right-0 self-center mr-4 uppercase font-semibold text-xs", diff --git a/app/components/avo/fields/external_image_field/edit_component.html.erb b/app/components/avo/fields/external_image_field/edit_component.html.erb index 01cadfbaff..1928618560 100644 --- a/app/components/avo/fields/external_image_field/edit_component.html.erb +++ b/app/components/avo/fields/external_image_field/edit_component.html.erb @@ -5,6 +5,7 @@ disabled: disabled?, placeholder: @field.placeholder, autofocus: @autofocus, - style: @field.get_html(:style, view: view, element: :input) + style: @field.get_html(:style, view: view, element: :input), + **@field.edit_input_additional_attributes %> <% end %> diff --git a/app/components/avo/fields/file_field/edit_component.html.erb b/app/components/avo/fields/file_field/edit_component.html.erb index f43a354b44..0a17f2ebe7 100644 --- a/app/components/avo/fields/file_field/edit_component.html.erb +++ b/app/components/avo/fields/file_field/edit_component.html.erb @@ -19,7 +19,8 @@ disabled: disabled?, style: @field.get_html(:style, view: view, element: :input), autofocus: @autofocus, - class: "w-full" + class: "w-full", + **@field.edit_input_additional_attributes %> <%= content_tag :button, diff --git a/app/components/avo/fields/files_field/edit_component.html.erb b/app/components/avo/fields/files_field/edit_component.html.erb index 78416306f3..897c665950 100644 --- a/app/components/avo/fields/files_field/edit_component.html.erb +++ b/app/components/avo/fields/files_field/edit_component.html.erb @@ -15,7 +15,8 @@ disabled: disabled?, multiple: true, style: @field.get_html(:style, view: view, element: :input), - autofocus: @autofocus + autofocus: @autofocus, + **@field.edit_input_additional_attributes %> <%= content_tag :button, diff --git a/app/components/avo/fields/hidden_field/edit_component.html.erb b/app/components/avo/fields/hidden_field/edit_component.html.erb index 8f8fb500b2..fb9d9e66a4 100644 --- a/app/components/avo/fields/hidden_field/edit_component.html.erb +++ b/app/components/avo/fields/hidden_field/edit_component.html.erb @@ -2,5 +2,6 @@ class: @field.get_html(:classes, view: view, element: :input), data: @field.get_html(:data, view: view, element: :input), style: @field.get_html(:style, view: view, element: :input), - value: @field.value + value: @field.value, + **@field.edit_input_additional_attributes %> diff --git a/app/components/avo/fields/location_field/edit_component.html.erb b/app/components/avo/fields/location_field/edit_component.html.erb index 671e2e549c..674f334173 100644 --- a/app/components/avo/fields/location_field/edit_component.html.erb +++ b/app/components/avo/fields/location_field/edit_component.html.erb @@ -5,12 +5,14 @@ <%= coordinates_form.text_field @field.as_lat_long_field_id(:lat), value: @field.as_lat_long_value(:lat), class: classes("w-full"), - placeholder: @field.as_lat_long_placeholder(:lat) + placeholder: @field.as_lat_long_placeholder(:lat), + **@field.edit_input_additional_attributes %> <%= coordinates_form.text_field @field.as_lat_long_field_id(:long), value: @field.as_lat_long_value(:long), class: classes("w-full"), - placeholder: @field.as_lat_long_placeholder(:long) + placeholder: @field.as_lat_long_placeholder(:long), + **@field.edit_input_additional_attributes %> <% end %> @@ -18,7 +20,8 @@ <%= @form.text_field @field.id, value: @field.value, class: classes("w-full"), - placeholder: @field.placeholder + placeholder: @field.placeholder, + **@field.edit_input_additional_attributes %> <% end %> <% end %> diff --git a/app/components/avo/fields/markdown_field/edit_component.html.erb b/app/components/avo/fields/markdown_field/edit_component.html.erb index 51724f4e2d..033c78a75d 100644 --- a/app/components/avo/fields/markdown_field/edit_component.html.erb +++ b/app/components/avo/fields/markdown_field/edit_component.html.erb @@ -11,7 +11,8 @@ disabled: disabled?, placeholder: @field.placeholder, autofocus: @autofocus, - style: @field.get_html(:style, view: view, element: :input) + style: @field.get_html(:style, view: view, element: :input), + **@field.edit_input_additional_attributes %> <% end %> diff --git a/app/components/avo/fields/number_field/edit_component.html.erb b/app/components/avo/fields/number_field/edit_component.html.erb index 663e76a076..a6e6afb630 100644 --- a/app/components/avo/fields/number_field/edit_component.html.erb +++ b/app/components/avo/fields/number_field/edit_component.html.erb @@ -10,6 +10,7 @@ step: @field.step, style: @field.get_html(:style, view: view, element: :input), autocomplete: @field.autocomplete, - autofocus: @autofocus + autofocus: @autofocus, + **@field.edit_input_additional_attributes %> <% end %> diff --git a/app/components/avo/fields/password_field/edit_component.html.erb b/app/components/avo/fields/password_field/edit_component.html.erb index 5a102a784d..1ad1058f1d 100644 --- a/app/components/avo/fields/password_field/edit_component.html.erb +++ b/app/components/avo/fields/password_field/edit_component.html.erb @@ -8,7 +8,8 @@ placeholder: @field.placeholder, style: @field.get_html(:style, view: view, element: :input), autocomplete: @field.autocomplete, - autofocus: @autofocus + autofocus: @autofocus, + **@field.edit_input_additional_attributes %> <% if @field.revealable %> diff --git a/app/components/avo/fields/progress_bar_field/edit_component.html.erb b/app/components/avo/fields/progress_bar_field/edit_component.html.erb index 09e878e737..aa3c1417a3 100644 --- a/app/components/avo/fields/progress_bar_field/edit_component.html.erb +++ b/app/components/avo/fields/progress_bar_field/edit_component.html.erb @@ -18,7 +18,8 @@ placeholder: @field.placeholder, step: @field.step, autofocus: @autofocus, - style: @field.get_html(:style, view: view, element: :input) + style: @field.get_html(:style, view: view, element: :input), + **@field.edit_input_additional_attributes %> <% end %> <% end %> diff --git a/app/components/avo/fields/select_field/edit_component.html.erb b/app/components/avo/fields/select_field/edit_component.html.erb index 6247150377..5c6fbc69f0 100644 --- a/app/components/avo/fields/select_field/edit_component.html.erb +++ b/app/components/avo/fields/select_field/edit_component.html.erb @@ -12,6 +12,7 @@ value: @field.record.present? ? @field.record[@field.id] : @field.value, placeholder: @field.include_blank.present? ? nil : @field.placeholder, autocomplete: @field.autocomplete, - autofocus: @autofocus + autofocus: @autofocus, + **@field.edit_input_additional_attributes %> <% end %> diff --git a/app/components/avo/fields/status_field/edit_component.html.erb b/app/components/avo/fields/status_field/edit_component.html.erb index f2b39f75cf..6baab038c0 100644 --- a/app/components/avo/fields/status_field/edit_component.html.erb +++ b/app/components/avo/fields/status_field/edit_component.html.erb @@ -6,6 +6,7 @@ placeholder: @field.placeholder, style: @field.get_html(:style, view: view, element: :input), value: @field.value, - autofocus: @autofocus + autofocus: @autofocus, + **@field.edit_input_additional_attributes %> <% end %> diff --git a/app/components/avo/fields/tags_field/edit_component.html.erb b/app/components/avo/fields/tags_field/edit_component.html.erb index e863a636b4..dbc321563b 100644 --- a/app/components/avo/fields/tags_field/edit_component.html.erb +++ b/app/components/avo/fields/tags_field/edit_component.html.erb @@ -30,6 +30,7 @@ disabled: disabled?, placeholder: @field.placeholder, style: @field.get_html(:style, view: view, element: :input), - value: @field.field_value.to_json + value: @field.field_value.to_json, + **@field.edit_input_additional_attributes %> <% end %> diff --git a/app/components/avo/fields/text_field/edit_component.html.erb b/app/components/avo/fields/text_field/edit_component.html.erb index 540ee3bd1c..70ae494fd2 100644 --- a/app/components/avo/fields/text_field/edit_component.html.erb +++ b/app/components/avo/fields/text_field/edit_component.html.erb @@ -8,6 +8,7 @@ style: @field.get_html(:style, view: view, element: :input), multiple: multiple, autocomplete: @field.autocomplete, - autofocus: @autofocus + autofocus: @autofocus, + **@field.edit_input_additional_attributes %> <% end %> diff --git a/app/components/avo/fields/textarea_field/edit_component.html.erb b/app/components/avo/fields/textarea_field/edit_component.html.erb index e4d5382164..b79d25a22f 100644 --- a/app/components/avo/fields/textarea_field/edit_component.html.erb +++ b/app/components/avo/fields/textarea_field/edit_component.html.erb @@ -7,6 +7,7 @@ placeholder: @field.placeholder, rows: @field.rows, autofocus: @autofocus, - style: @field.get_html(:style, view: view, element: :input) + style: @field.get_html(:style, view: view, element: :input), + **@field.edit_input_additional_attributes %> <% end %> diff --git a/app/components/avo/fields/time_field/edit_component.html.erb b/app/components/avo/fields/time_field/edit_component.html.erb index 5fb2fe741f..6ef7697bf5 100644 --- a/app/components/avo/fields/time_field/edit_component.html.erb +++ b/app/components/avo/fields/time_field/edit_component.html.erb @@ -22,7 +22,8 @@ }, disabled: disabled?, placeholder: @field.placeholder, - style: @field.get_html(:style, view: view, element: :input) + style: @field.get_html(:style, view: view, element: :input), + **@field.edit_input_additional_attributes %> <%= datetime_field "fake_#{@field.id}", "fake", value: @field.edit_formatted_value, @@ -34,7 +35,8 @@ }, disabled: disabled?, placeholder: @field.placeholder, - style: @field.get_html(:style, view: view, element: :input) + style: @field.get_html(:style, view: view, element: :input), + **@field.edit_input_additional_attributes %> <%= content_tag :button, class: "absolute right-0 self-center mr-4 uppercase font-semibold text-xs", diff --git a/app/components/avo/fields/tiptap_field/edit_component.html.erb b/app/components/avo/fields/tiptap_field/edit_component.html.erb index c57f3e19d4..0c8d5875e2 100644 --- a/app/components/avo/fields/tiptap_field/edit_component.html.erb +++ b/app/components/avo/fields/tiptap_field/edit_component.html.erb @@ -75,7 +75,8 @@ disabled: disabled?, id: tiptap_id, placeholder: @field.placeholder, - style: @field.get_html(:style, view: view, element: :input) + style: @field.get_html(:style, view: view, element: :input), + **@field.edit_input_additional_attributes %> <% end %> <% end %> diff --git a/app/components/avo/fields/trix_field/edit_component.html.erb b/app/components/avo/fields/trix_field/edit_component.html.erb index 01fdae224e..3f2516d9bc 100644 --- a/app/components/avo/fields/trix_field/edit_component.html.erb +++ b/app/components/avo/fields/trix_field/edit_component.html.erb @@ -23,7 +23,8 @@ disabled: disabled?, id: trix_id, placeholder: @field.placeholder, - style: @field.get_html(:style, view: view, element: :input) + style: @field.get_html(:style, view: view, element: :input), + **@field.edit_input_additional_attributes %> <% end %> <% end %> diff --git a/lib/avo/fields/concerns/has_html_attributes.rb b/lib/avo/fields/concerns/has_html_attributes.rb index 2f052f97f8..e818a58648 100644 --- a/lib/avo/fields/concerns/has_html_attributes.rb +++ b/lib/avo/fields/concerns/has_html_attributes.rb @@ -4,6 +4,14 @@ module Concerns module HasHTMLAttributes extend ActiveSupport::Concern + # The default attributes can be used within any + # view: (index, show, or edit) + # element: (wrapper, label, content or input) + # + # Additional attributes not included in DEFAULT_ATTRIBUTES + # are used only on edit (view) input (element) + DEFAULT_ATTRIBUTES = %i[style classes data] + attr_reader :html # Used to get attributes for elements and views @@ -11,7 +19,7 @@ module HasHTMLAttributes # examples: # get_html :data, view: :edit, element: :input # get_html :classes, view: :show, element: :wrapper - # get_html :styles, view: :index, element: :wrapper + # get_html :style, view: :index, element: :wrapper def get_html(name = nil, element:, view:) view = view.to_sym if view.present? @@ -36,6 +44,15 @@ def get_html(name = nil, element:, view:) value_or_default name, attributes end + def edit_input_additional_attributes + view = :edit + element = :input + + additional_attributes(view, element).each_with_object({}) do |attribute, hash| + hash[attribute] = get_html(attribute, element:, view:) + end + end + private def value_or_default(name, attributes) @@ -55,6 +72,14 @@ def parse_html end end + def additional_attributes(view, element) + parsed = parse_html + + return [] unless parsed.is_a? Hash + + (parsed.dig(view, element) || {}).keys - DEFAULT_ATTRIBUTES + end + def default_attribute_value(name) (name == :data) ? {} : "" end diff --git a/spec/dummy/app/avo/resources/user.rb b/spec/dummy/app/avo/resources/user.rb index cfb603cc69..59560a0be3 100644 --- a/spec/dummy/app/avo/resources/user.rb +++ b/spec/dummy/app/avo/resources/user.rb @@ -221,7 +221,7 @@ def panel_test_sidebars def stacked_name with_options as: :text, stacked: true do - field :first_name, placeholder: "John" + field :first_name, placeholder: "John", html: {edit: {input: {spellcheck: true}}} field :last_name, placeholder: "Doe" end end diff --git a/spec/features/avo/text_field_spec.rb b/spec/features/avo/text_field_spec.rb index 20e6b0674f..0ec9d7c45e 100644 --- a/spec/features/avo/text_field_spec.rb +++ b/spec/features/avo/text_field_spec.rb @@ -51,6 +51,7 @@ it "changes the users name" do visit "/admin/resources/users/#{user.id}/edit" + expect(page).to have_selector('input[spellcheck="true"]') fill_in "user_first_name", with: "Jack Jack Jack" save