Class: Jav::Fields::BaseField

Inherits:
Object
  • Object
show all
Extended by:
ActiveSupport::DescendantsTracker, FieldExtensions::HasFieldName
Includes:
ActionView::Helpers::UrlHelper, Concerns::HandlesFieldArgs, Concerns::HasHTMLAttributes, Concerns::IsResourceItem, Concerns::HasDefault, Concerns::IsDisabled, Concerns::IsReadonly, Concerns::IsRequired, FieldExtensions::VisibleInDifferentViews
Defined in:
lib/jav/fields/base_field.rb

Instance Attribute Summary collapse

Attributes included from Concerns::IsDisabled

#disabled

Attributes included from Concerns::HasHTMLAttributes

#html

Attributes included from FieldExtensions::VisibleInDifferentViews

#show_on_edit, #show_on_index, #show_on_new, #show_on_show

Instance Method Summary collapse

Methods included from FieldExtensions::HasFieldName

field_name, field_name=

Methods included from Concerns::HasDefault

#computed_default_value

Methods included from Concerns::IsDisabled

#is_disabled?

Methods included from Concerns::IsReadonly

#is_readonly?

Methods included from Concerns::IsRequired

#is_required?

Methods included from Concerns::HasHTMLAttributes

#get_html

Methods included from FieldExtensions::VisibleInDifferentViews

#except_on, #hide_on, #only_on, #show_on, #show_on_create, #show_on_update, #visible_on?

Methods included from Concerns::IsResourceItem

#is_field?, #is_main_panel?, #is_panel?, #is_row?, #is_sidebar?, #is_tab?, #is_tab_group?, #is_tool?

Constructor Details

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

Returns a new instance of BaseField.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/jav/fields/base_field.rb', line 36

def initialize(id, **args, &block)
  super
  @id = id
  @name = args[:name]
  @translation_key = args[:translation_key]
  @block = block
  @required = args[:required] # Value if :required present on args, nil otherwise
  @readonly = args[:readonly] || false
  @disabled = args[:disabled] || false
  @sortable = args[:sortable] || false
  @nullable = args[:nullable] || false
  @null_values = args[:null_values] || [nil, ""]
  @format_using = args[:format_using] || nil
  @update_using = args[:update_using] || nil
  @placeholder = args[:placeholder]
  @autocomplete = args[:autocomplete] || nil
  @help = args[:help] || nil
  @default = args[:default] || nil
  @visible = args[:visible]
  @as_label = args[:as_label] || false
  @as_avatar = args[:as_avatar] || false
  @as_description = args[:as_description] || false
  @index_text_align = args[:index_text_align] || :left
  @html = args[:html] || nil
  @view = args[:view] || nil
  @value = args[:value] || nil
  @stacked = args[:stacked] || nil
  @resource = args[:resource]
  @action = args[:action]
  @in_sidebar = args[:in_sidebar]

  @args = args

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

  # Set the visibility
  show_on args[:show_on] if args[:show_on].present?
  hide_on args[:hide_on] if args[:hide_on].present?
  only_on args[:only_on] if args[:only_on].present?
  except_on args[:except_on] if args[:except_on].present?
end

Instance Attribute Details

#actionObject (readonly)

Returns the value of attribute action.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def action
  @action
end

#as_avatarObject (readonly)

Returns the value of attribute as_avatar.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def as_avatar
  @as_avatar
end

#as_descriptionObject (readonly)

Returns the value of attribute as_description.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def as_description
  @as_description
end

#as_labelObject (readonly)

Returns the value of attribute as_label.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def as_label
  @as_label
end

#autocompleteObject (readonly)

Returns the value of attribute autocomplete.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def autocomplete
  @autocomplete
end

#blockObject (readonly)

Returns the value of attribute block.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def block
  @block
end

#computableObject (readonly)

Private options



28
29
30
# File 'lib/jav/fields/base_field.rb', line 28

def computable
  @computable
end

#computedObject (readonly)

Returns the value of attribute computed.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def computed
  @computed
end

#computed_valueObject (readonly)

Returns the value of attribute computed_value.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def computed_value
  @computed_value
end

#defaultObject (readonly)

Returns the value of attribute default.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def default
  @default
end

#format_usingObject (readonly)

Returns the value of attribute format_using.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def format_using
  @format_using
end

#helpObject (readonly)

Returns the value of attribute help.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def help
  @help
end

#idObject (readonly)

Returns the value of attribute id.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def id
  @id
end

#in_sidebarObject (readonly)

Returns the value of attribute in_sidebar.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def in_sidebar
  @in_sidebar
end

#index_text_alignObject (readonly)

Returns the value of attribute index_text_align.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def index_text_align
  @index_text_align
end

#modelObject (readonly)

Hydrated payload



31
32
33
# File 'lib/jav/fields/base_field.rb', line 31

def model
  @model
end

#null_valuesObject (readonly)

Returns the value of attribute null_values.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def null_values
  @null_values
end

#nullableObject (readonly)

Returns the value of attribute nullable.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def nullable
  @nullable
end

#panel_nameObject (readonly)

Returns the value of attribute panel_name.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def panel_name
  @panel_name
end

#readonlyObject (readonly)

Returns the value of attribute readonly.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def readonly
  @readonly
end

#requiredObject (readonly)

Returns the value of attribute required.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def required
  @required
end

#resourceObject (readonly)

Returns the value of attribute resource.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def resource
  @resource
end

#sortableObject (readonly)

Returns the value of attribute sortable.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def sortable
  @sortable
end

#stackedObject (readonly)

Returns the value of attribute stacked.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def stacked
  @stacked
end

#userObject (readonly)

Returns the value of attribute user.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def user
  @user
end

#viewObject (readonly)

Returns the value of attribute view.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def view
  @view
end

#visibleObject (readonly)

Returns the value of attribute visible.



25
26
27
# File 'lib/jav/fields/base_field.rb', line 25

def visible
  @visible
end

Instance Method Details

#assign_value(record:, value:) ⇒ Object

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



269
270
271
272
273
274
275
# File 'lib/jav/fields/base_field.rb', line 269

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

  return unless record.send(id).nil?

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

#component_for_view(view = :index) ⇒ Object

Try and build the component class or fallback to a blank one



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

def component_for_view(view = :index)
  # Use the edit variant for all "update" views
  view = :edit if view.in? %i[new create update]

  component_class = "::Jav::Fields::#{view_component_name}::#{view.to_s.camelize}Component"
  component_class.constantize
rescue StandardError
  # When returning nil, a race condition happens and throws an error in some environments.
  # See https://github.com/jav-hq/jav/pull/365
  ::Jav::BlankFieldComponent
end

#custom?Boolean

Returns:

  • (Boolean)


250
251
252
253
254
# File 'lib/jav/fields/base_field.rb', line 250

def custom?
  method(:initialize).source_location.first.exclude?("lib/jav/field")
rescue StandardError
  true
end

#custom_name?Boolean

Returns:

  • (Boolean)


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

def custom_name?
  @name.present?
end

#database_idObject

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



207
208
209
210
211
# File 'lib/jav/fields/base_field.rb', line 207

def database_id
  foreign_key
rescue StandardError
  id
end

#default_nameObject



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

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

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

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



184
185
186
187
188
189
190
191
192
# File 'lib/jav/fields/base_field.rb', line 184

def fill_field(model, key, value, params)
  return model unless model.methods.include? key.to_sym

  value = update_using(model, key, value, params) if @update_using.present?

  model.public_send(:"#{key}=", value)

  model
end

#has_own_panel?Boolean

Returns:

  • (Boolean)


213
214
215
# File 'lib/jav/fields/base_field.rb', line 213

def has_own_panel?
  false
end

#hidden_in_reflection?Boolean

Returns:

  • (Boolean)


260
261
262
# File 'lib/jav/fields/base_field.rb', line 260

def hidden_in_reflection?
  !visible_in_reflection?
end

#hydrate(**kwargs) ⇒ Object

Raises:

  • (ArgumentError)


80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/jav/fields/base_field.rb', line 80

def hydrate(**kwargs)
  # List of permitted keyword argument keys as symbols
  permited_kwargs_keys = %i[model resource action view panel_name user]

  # Check for unrecognized keys
  unrecognized_keys = kwargs.keys - permited_kwargs_keys
  raise ArgumentError, "Unrecognized argument(s): #{unrecognized_keys.join(', ')}" if unrecognized_keys.any?

  # Set instance variables with provided values
  kwargs.each do |key, value|
    instance_variable_set(:"@#{key}", value)
  end

  # Return self for method chaining, if desired
  self
end

#model_errorsObject



242
243
244
# File 'lib/jav/fields/base_field.rb', line 242

def model_errors
  model.nil? ? {} : model.errors
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



107
108
109
110
111
112
113
114
115
# File 'lib/jav/fields/base_field.rb', line 107

def name
  return @name if custom_name?

  if translation_key && ::Jav::App.translation_enabled
    t(translation_key, count: 1, default: default_name).humanize
  else
    default_name
  end
end

#placeholderObject



135
136
137
138
139
# File 'lib/jav/fields/base_field.rb', line 135

def placeholder
  return Jav::Hosts::ResourceViewRecordHost.new(block: @placeholder, record: @model, resource: @resource, view: @view).handle if @placeholder.respond_to?(:call)

  @placeholder || name
end

#plural_nameObject



117
118
119
120
121
122
123
124
125
# File 'lib/jav/fields/base_field.rb', line 117

def plural_name
  default = name.pluralize

  if translation_key && ::Jav::App.translation_enabled
    t(translation_key, count: 2, default: default).humanize
  else
    default
  end
end

#resolve_attribute(value) ⇒ Object



217
218
219
# File 'lib/jav/fields/base_field.rb', line 217

def resolve_attribute(value)
  value
end

#to_permitted_paramObject



221
222
223
# File 'lib/jav/fields/base_field.rb', line 221

def to_permitted_param
  id.to_sym
end

#translation_keyObject



97
98
99
100
101
# File 'lib/jav/fields/base_field.rb', line 97

def translation_key
  return @translation_key if @translation_key.present?

  "jav.field_translations#{@args[:translation_scope]}.#{@id}"
end

#typeObject



246
247
248
# File 'lib/jav/fields/base_field.rb', line 246

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

#updatableObject



264
265
266
# File 'lib/jav/fields/base_field.rb', line 264

def updatable
  !is_readonly? && visible?
end

#update_using(model, key, value, params) ⇒ Object



194
195
196
197
198
199
200
201
202
203
204
# File 'lib/jav/fields/base_field.rb', line 194

def update_using(model, key, value, params)
  Jav::ExecutionContext.new(
    target: @update_using,
    model: model,
    key: key,
    value: value,
    resource: resource,
    field: self,
    include: self.class.included_modules
  ).handle
end

#value(property = nil) ⇒ Object



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/jav/fields/base_field.rb', line 151

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

  property ||= id

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

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

  # Run computable callback block if present
  final_value = instance_exec(@model, @resource, @view, self, &block) if computable && block.present?

  if @format_using.present?
    # Apply the changes in the
    Jav::ExecutionContext.new(
      target: @format_using,
      model: model,
      key: property,
      value: final_value,
      resource: resource,
      view: view,
      field: self,
      delegate_missing_to: :view_context,
      include: self.class.included_modules
    ).handle
  else
    final_value
  end
end

#view_component_nameObject



225
226
227
# File 'lib/jav/fields/base_field.rb', line 225

def view_component_name
  "#{type.camelize}Field"
end

#visible?Boolean

Returns:

  • (Boolean)


141
142
143
144
145
146
147
148
149
# File 'lib/jav/fields/base_field.rb', line 141

def visible?
  return true if visible.nil?

  if visible.respond_to?(:call)
    visible.call resource: @resource
  else
    visible
  end
end

#visible_in_reflection?Boolean

Returns:

  • (Boolean)


256
257
258
# File 'lib/jav/fields/base_field.rb', line 256

def visible_in_reflection?
  true
end