Class: Avo::Fields::BaseField

Constant Summary

Constants included from Concerns::HasResizableEditor

Concerns::HasResizableEditor::COMPATIBLE_EDITOR_SELECTORS

Instance Attribute Summary collapse

Attributes included from Concerns::IsDisabled

#disabled

Attributes included from Concerns::HasHTMLAttributes

#html

Attributes included from Concerns::VisibleInDifferentViews

#show_on_edit, #show_on_index, #show_on_new, #show_on_preview, #show_on_show

Attributes included from Concerns::IsVisible

#visible

Attributes included from Concerns::IsResourceItem

#resource, #view

Instance Method Summary collapse

Methods included from Concerns::DomId

#model_name, #to_key

Methods included from Concerns::UseViewComponents

#component_for_view, #view_component_name, #view_component_namespace

Methods included from Concerns::IsRequired

#is_required?

Methods included from Concerns::IsDisabled

#is_disabled?

Methods included from Concerns::IsReadonly

#is_readonly?

Methods included from Concerns::HasResizableEditor

#resizable_editor?, #resizable_editor_target_selector

Methods included from Concerns::HasHTMLAttributes

#get_html

Methods included from Concerns::HasDefault

#computed_default_value

Methods included from Concerns::HasHelpers

#helpers

Methods included from Concerns::VisibleInDifferentViews

#except_on, #hide_on, #initialize_views, #only_on, #post_initialize, #show_on, #show_on_create, #show_on_update, #visible_in_view?

Methods included from Concerns::IsVisible

#visible?

Methods included from Concerns::HasItemType

#is_card?, #is_collaboration?, #is_field?, #is_header?, #is_heading?, #is_panel?, #is_sidebar?, #is_tab?, #is_tab_group?, #is_tool?

Methods included from Concerns::IsResourceItem

#visible?

Methods included from Concerns::Hydration

#hydrate

Constructor Details

#initialize(id, **args, &block) ⇒ BaseField

Returns a new instance of BaseField.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/avo/fields/base_field.rb', line 70

def initialize(id, **args, &block)
  @id = id
  @name = args[:name]
  @translation_key = args[:translation_key]
  @block = block
  @required = args.dig(:required) # Value if :required present on args, nil otherwise
  @readonly = args[:readonly] || false
  @disabled = args[:disabled] || false
  @sortable = args[:sortable] || false
  @summarizable = args[:summarizable] || false
  @nullable = args[:nullable] || false
  @null_values = args[:null_values] || [nil, ""]
  @format_using = args[:format_using]
  @format_display_using = args[:format_display_using]

  @format_index_using = args[:format_index_using]
  @format_show_using = args[:format_show_using]
  @format_edit_using = args[:format_edit_using]
  @format_new_using = args[:format_new_using]
  @format_form_using = args[:format_form_using]
  @update_using = args[:update_using]
  @placeholder = args[:placeholder]
  @autocomplete = args[:autocomplete]
  @help = args[:help]
  @label_help = args[:label_help]
  @default = args[:default]
  @visible = args[:visible]
  @html = args[:html]
  @view = Avo::ViewInquirer.new(args[:view])
  @value = args[:value]
  @stacked = args[:stacked]
  @size = args[:size] || :md
  @for_presentation_only = args[:for_presentation_only] || false
  @resource = args[:resource]
  @action = args[:action]
  @components = args[:components] || {}
  @for_attribute = args[:for_attribute]
  @meta = args[:meta]
  @copyable = args[:copyable] || false
  @react_on = Array.wrap(args[:react_on]).map(&:to_s)
  @record = args[:record]

  @args = args

  @computable = true
  @computed = block.present?
  @computed_value = nil

  @width = args[:width] || 100

  if width_option.present? && width_option != 100
    @stacked = true
  end

  post_initialize if respond_to?(:post_initialize)
end

Instance Attribute Details

#actionObject

Returns the value of attribute action.



63
64
65
# File 'lib/avo/fields/base_field.rb', line 63

def action
  @action
end

#autocompleteObject (readonly)

Returns the value of attribute autocomplete.



47
48
49
# File 'lib/avo/fields/base_field.rb', line 47

def autocomplete
  @autocomplete
end

#blockObject (readonly)

Returns the value of attribute block.



33
34
35
# File 'lib/avo/fields/base_field.rb', line 33

def block
  @block
end

#computableObject (readonly)

Private options



56
57
58
# File 'lib/avo/fields/base_field.rb', line 56

def computable
  @computable
end

#computedObject (readonly)

if block is present



57
58
59
# File 'lib/avo/fields/base_field.rb', line 57

def computed
  @computed
end

#computed_valueObject (readonly)

the value after computation



58
59
60
# File 'lib/avo/fields/base_field.rb', line 58

def computed_value
  @computed_value
end

#copyableObject (readonly)

if allowed to be copyable



59
60
61
# File 'lib/avo/fields/base_field.rb', line 59

def copyable
  @copyable
end

#defaultObject (readonly)

Returns the value of attribute default.



49
50
51
# File 'lib/avo/fields/base_field.rb', line 49

def default
  @default
end

#for_attributeObject (readonly)

Returns the value of attribute for_attribute.



53
54
55
# File 'lib/avo/fields/base_field.rb', line 53

def for_attribute
  @for_attribute
end

#for_presentation_onlyObject (readonly)

Returns the value of attribute for_presentation_only.



52
53
54
# File 'lib/avo/fields/base_field.rb', line 52

def for_presentation_only
  @for_presentation_only
end

#format_display_usingObject (readonly)

Returns the value of attribute format_display_using.



41
42
43
# File 'lib/avo/fields/base_field.rb', line 41

def format_display_using
  @format_display_using
end

#format_edit_usingObject (readonly)

Returns the value of attribute format_edit_using.



44
45
46
# File 'lib/avo/fields/base_field.rb', line 44

def format_edit_using
  @format_edit_using
end

#format_form_usingObject (readonly)

Returns the value of attribute format_form_using.



46
47
48
# File 'lib/avo/fields/base_field.rb', line 46

def format_form_using
  @format_form_using
end

#format_index_usingObject (readonly)

Returns the value of attribute format_index_using.



42
43
44
# File 'lib/avo/fields/base_field.rb', line 42

def format_index_using
  @format_index_using
end

#format_new_usingObject (readonly)

Returns the value of attribute format_new_using.



45
46
47
# File 'lib/avo/fields/base_field.rb', line 45

def format_new_using
  @format_new_using
end

#format_show_usingObject (readonly)

Returns the value of attribute format_show_using.



43
44
45
# File 'lib/avo/fields/base_field.rb', line 43

def format_show_using
  @format_show_using
end

#format_usingObject (readonly)

Returns the value of attribute format_using.



40
41
42
# File 'lib/avo/fields/base_field.rb', line 40

def format_using
  @format_using
end

#idObject (readonly)

Returns the value of attribute id.



32
33
34
# File 'lib/avo/fields/base_field.rb', line 32

def id
  @id
end

#label_helpObject (readonly)

Returns the value of attribute label_help.



48
49
50
# File 'lib/avo/fields/base_field.rb', line 48

def label_help
  @label_help
end

#null_valuesObject (readonly)

Returns the value of attribute null_values.



39
40
41
# File 'lib/avo/fields/base_field.rb', line 39

def null_values
  @null_values
end

#nullableObject (readonly)

Returns the value of attribute nullable.



38
39
40
# File 'lib/avo/fields/base_field.rb', line 38

def nullable
  @nullable
end

#panel_nameObject

Returns the value of attribute panel_name.



65
66
67
# File 'lib/avo/fields/base_field.rb', line 65

def panel_name
  @panel_name
end

#readonlyObject (readonly)

Returns the value of attribute readonly.



35
36
37
# File 'lib/avo/fields/base_field.rb', line 35

def readonly
  @readonly
end

#recordObject

Hydrated payload



62
63
64
# File 'lib/avo/fields/base_field.rb', line 62

def record
  @record
end

#requiredObject (readonly)

Returns the value of attribute required.



34
35
36
# File 'lib/avo/fields/base_field.rb', line 34

def required
  @required
end

#sizeObject (readonly)

Returns the value of attribute size.



51
52
53
# File 'lib/avo/fields/base_field.rb', line 51

def size
  @size
end

#sortableObject (readonly)

Returns the value of attribute sortable.



36
37
38
# File 'lib/avo/fields/base_field.rb', line 36

def sortable
  @sortable
end

#stackedObject (readonly)

Returns the value of attribute stacked.



50
51
52
# File 'lib/avo/fields/base_field.rb', line 50

def stacked
  @stacked
end

#summarizableObject (readonly)

Returns the value of attribute summarizable.



37
38
39
# File 'lib/avo/fields/base_field.rb', line 37

def summarizable
  @summarizable
end

#userObject

Returns the value of attribute user.



64
65
66
# File 'lib/avo/fields/base_field.rb', line 64

def user
  @user
end

#widthObject

Returns the value of attribute width.



66
67
68
# File 'lib/avo/fields/base_field.rb', line 66

def width
  @width
end

Instance Method Details

#apply_update_using(record, key, value, resource) ⇒ Object



290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/avo/fields/base_field.rb', line 290

def apply_update_using(record, key, value, resource)
  return value if @update_using.nil?

  Avo::ExecutionContext.new(
    target: @update_using,
    record:,
    key:,
    value:,
    resource:,
    field: self,
    include: self.class.included_modules
  ).handle
end

#assign_value(record:, value:) ⇒ Object

Used by Avo to fill the record with the default value on :new and :edit views



358
359
360
361
362
363
364
# File 'lib/avo/fields/base_field.rb', line 358

def assign_value(record:, value:)
  id = (type == "belongs_to") ? foreign_key : database_id

  if record.send(id).nil?
    record.send(:"#{id}=", value)
  end
end

#attribute_idObject



244
# File 'lib/avo/fields/base_field.rb', line 244

def attribute_id = (@attribute_id ||= @for_attribute || @id)

#custom?Boolean

Returns:

  • (Boolean)


335
336
337
338
339
# File 'lib/avo/fields/base_field.rb', line 335

def custom?
  !method(:initialize).source_location.first.include?("lib/avo/field")
rescue
  true
end

#custom_name?Boolean

Returns:

  • (Boolean)


216
217
218
# File 'lib/avo/fields/base_field.rb', line 216

def custom_name?
  !@name.nil?
end

#database_idObject

Try to see if the field has a different database ID than it's name



309
310
311
312
313
# File 'lib/avo/fields/base_field.rb', line 309

def database_id
  foreign_key
rescue
  id
end

#default_nameObject



220
221
222
# File 'lib/avo/fields/base_field.rb', line 220

def default_name
  @id.to_s.humanize(keep_id_suffix: true)
end

#default_placeholderObject



240
241
242
# File 'lib/avo/fields/base_field.rb', line 240

def default_placeholder
  name
end

#execute_context(target, **extra_args) ⇒ Object



268
269
270
271
272
273
274
275
276
277
278
# File 'lib/avo/fields/base_field.rb', line 268

def execute_context(target, **extra_args)
  Avo::ExecutionContext.new(
    target:,
    record: @record,
    resource: @resource,
    view: @view,
    field: self,
    include: self.class.included_modules,
    **extra_args
  ).handle
end

#fill_field(record, key, value, params) ⇒ Object

Fills the record with the received value on create and update actions.



281
282
283
284
285
286
287
288
# File 'lib/avo/fields/base_field.rb', line 281

def fill_field(record, key, value, params)
  key = @for_attribute.to_s if @for_attribute.present?
  return record unless has_attribute?(record, key)

  record.public_send(:"#{key}=", apply_update_using(record, key, value, resource))

  record
end

#form_field_labelObject



366
367
368
# File 'lib/avo/fields/base_field.rb', line 366

def form_field_label
  id
end

#has_attribute?(record, attribute) ⇒ Boolean

Returns:

  • (Boolean)


304
305
306
# File 'lib/avo/fields/base_field.rb', line 304

def has_attribute?(record, attribute)
  record.methods.include? attribute.to_sym
end

#has_own_panel?Boolean

Returns:

  • (Boolean)


315
316
317
# File 'lib/avo/fields/base_field.rb', line 315

def has_own_panel?
  false
end

#helpObject



224
225
226
227
228
# File 'lib/avo/fields/base_field.rb', line 224

def help
  return @help unless @help.nil?

  translated_option(:help)
end

#hidden_in_reflection?(reflection = nil) ⇒ Boolean

Returns:

  • (Boolean)


345
346
347
# File 'lib/avo/fields/base_field.rb', line 345

def hidden_in_reflection?(reflection = nil)
  !visible_in_reflection?(reflection)
end

#metaObject



370
371
372
# File 'lib/avo/fields/base_field.rb', line 370

def meta
  Avo::ExecutionContext.new(target: @meta, record: record, resource: @resource, view: @view).handle
end

#nameObject

Getting the name of the resource (user/users, post/posts) We'll first check to see if the user passed a name Secondly we'll try to find a translation key We'll fallback to humanizing the id



176
177
178
179
180
181
182
183
184
185
186
# File 'lib/avo/fields/base_field.rb', line 176

def name
  if custom_name?
    Avo::ExecutionContext.new(target: @name).handle
  elsif name_override.present?
    name_override
  elsif name_from_translation?
    translated_name default: default_name
  else
    default_name
  end
end

#name_overrideObject



188
# File 'lib/avo/fields/base_field.rb', line 188

def name_override = nil

#options_for_filterObject



349
350
351
# File 'lib/avo/fields/base_field.rb', line 349

def options_for_filter
  options
end

#parentObject



374
375
376
# File 'lib/avo/fields/base_field.rb', line 374

def parent
  @parent ||= fetch_parent
end

#placeholderObject



230
231
232
233
234
235
236
237
238
# File 'lib/avo/fields/base_field.rb', line 230

def placeholder
  target = if !@placeholder.nil?
    @placeholder
  else
    translated_option(:placeholder).presence || default_placeholder
  end

  Avo::ExecutionContext.new(target: target, record: record, resource: @resource, view: @view).handle
end

#plural_nameObject



198
199
200
201
202
203
204
205
206
# File 'lib/avo/fields/base_field.rb', line 198

def plural_name
  default = name.pluralize

  if translation_key
    translated_plural_name default: default
  else
    default
  end
end

#record_errorsObject



327
328
329
# File 'lib/avo/fields/base_field.rb', line 327

def record_errors
  record.present? ? record.errors : {}
end

#resolve_attribute(value) ⇒ Object



319
320
321
# File 'lib/avo/fields/base_field.rb', line 319

def resolve_attribute(value)
  value
end

#resource_scoped_translation_keyObject



139
140
141
142
143
# File 'lib/avo/fields/base_field.rb', line 139

def resource_scoped_translation_key
  return if @resource.blank?

  "#{@resource.translation_key}.fields.#{@id}"
end

#sentence_nameObject

The name as it should read inside a sentence, e.g. "Attach payment method". A resolved translation is used verbatim; only the generated fallback is lowercased.



192
193
194
195
196
# File 'lib/avo/fields/base_field.rb', line 192

def sentence_name
  return name.humanize(capitalize: false) unless name_from_translation?

  translated_name(default: default_name.humanize(capitalize: false))
end

#shared_translation_keyObject



135
136
137
# File 'lib/avo/fields/base_field.rb', line 135

def shared_translation_key
  "avo.field_translations.#{@id}"
end

#table_header_classObject



212
213
214
# File 'lib/avo/fields/base_field.rb', line 212

def table_header_class
  @table_header_class ||= ""
end

#table_header_labelObject



208
209
210
# File 'lib/avo/fields/base_field.rb', line 208

def table_header_label
  @table_header_label ||= name
end

#to_permitted_paramObject



323
324
325
# File 'lib/avo/fields/base_field.rb', line 323

def to_permitted_param
  id.to_sym
end

#translated_name(default:) ⇒ Object



145
146
147
# File 'lib/avo/fields/base_field.rb', line 145

def translated_name(default:)
  translate_field_name(count: 1, default: default)
end

#translated_plural_name(default:) ⇒ Object



149
150
151
# File 'lib/avo/fields/base_field.rb', line 149

def translated_plural_name(default:)
  translate_field_name(count: 2, default: default)
end

#translation_keyObject



131
132
133
# File 'lib/avo/fields/base_field.rb', line 131

def translation_key
  @translation_key || resource_scoped_translation_key || shared_translation_key
end

#typeObject



331
332
333
# File 'lib/avo/fields/base_field.rb', line 331

def type
  @type ||= self.class.name.demodulize.to_s.underscore.gsub("_field", "")
end

#updatableObject



353
354
355
# File 'lib/avo/fields/base_field.rb', line 353

def updatable
  !is_disabled? && visible?
end

#value(property = nil) ⇒ Object



246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/avo/fields/base_field.rb', line 246

def value(property = nil)
  return @value if @value.present?

  property ||= attribute_id

  # Get record value
  final_value = @record.send(property) if is_model?(@record) && @record.respond_to?(property)

  # On new views and actions modals we need to prefill the fields with the default value if value is nil
  if final_value.nil? && should_fill_with_default_value? && @default.present?
    final_value = computed_default_value
  end

  # Run computable callback block if present
  if computable && @block.present?
    final_value = execute_context(@block)
  end

  # Format value based on available formatter
  format_value(final_value)
end

#visible_in_reflection?(reflection = nil) ⇒ Boolean

Returns:

  • (Boolean)


341
342
343
# File 'lib/avo/fields/base_field.rb', line 341

def visible_in_reflection?(reflection = nil)
  true
end

#width_classObject



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/avo/fields/base_field.rb', line 153

def width_class
  case width_option
  when 25
    "w-1/4"
  when 33
    "w-1/3"
  when 50
    "w-1/2"
  when 66
    "w-2/3"
  when 75
    "w-3/4"
  when 100
    "w-full"
  else
    "w-full"
  end
end

#width_optionObject



127
128
129
# File 'lib/avo/fields/base_field.rb', line 127

def width_option
  @width_option ||= execute_context(@width)
end