# frozen_string_literal: true
class HtmlInput
# if you call .memo which is not existant, it translates to .as_memo with opts_prepare first
# def method_missing(meth, *args, &block)
# opts_prepare *args
# send "as_#{meth}"
# end
#############################
# custom fields definitions #
#############################
def as_string
@opts[:type] = 'text'
@opts[:autocomplete] ||= 'off'
@opts.tag(:input)
end
alias :as_text :as_string
def as_password
@opts[:type] = 'password'
@opts.tag(:input)
end
def as_hidden
@opts[:type] = 'hidden'
@opts.tag(:input)
end
def as_file
@opts[:type] = 'file'
@opts.tag(:input)
end
def as_textarea
val = @opts.delete(:value) || ''
val = val.join($/) if val.is_array?
comp_style = val.split(/\n/).length + val.length/100
comp_style = 6 if comp_style < 6
comp_style = 15 if comp_style > 15
@opts[:style] = "height:#{comp_style*20}px; #{@opts[:style]};"
@opts.tag(:textarea, val)
end
alias :as_memo :as_textarea
def as_checkbox
id = Lux.current.uid
hidden = { :name=>@opts.delete(:name), :type=>:hidden, :value=>@opts[:value] ? 1 : 0, :id=>id }
@opts[:type] = :checkbox
@opts[:onclick] = "document.getElementById('#{id}').value=this.checked ? 1 : 0; #{@opts[:onclick]}"
@opts[:checked] = @opts.delete(:value) ? 1 : nil
@opts.tag(:input)+hidden.tag(:input)
end
def as_checkboxes
body = []
collection = @opts.delete(:collection)
@opts[:type] = :checkbox
null = @opts.delete(:null)
value = @opts.delete(:value).to_s
body.push %[] if null
prepare_collection(collection).each do |el|
opts = @opts.dup
opts[:value] = el[0]
opts[:checked] = true if value == el[0].to_s
body.push %[]
end
'
%s
' % body.join("\n")
end
def as_select
body = []
collection = @opts.delete(:collection)
@opts[:class] ||= 'form-select'
if nullval = @opts.delete(:null)
body.push %[] if nullval
end
for el in prepare_collection(collection)
body.push(%[])
end
body = body.join("\n")
@opts.tag(:select, body)
end
def as_radio
return as_radios if @opts[:collection]
@opts[:type] = :radio
@opts[:checked] = @opts[:value] == @object.send(@name) ? true : nil
@opts.tag(:input)
end
def as_radios
body = []
collection = @opts.delete(:collection)
@opts[:type] = :radio
null = @opts.delete(:null)
value = @opts.delete(:value).to_s
body.push %[] if null
prepare_collection(collection).each do |el|
opts = @opts.dup
opts[:value] = el[0]
opts[:checked] = true if value == el[0].to_s
body.push %[]
end
'
%s
' % body.join("\n")
end
def as_tag
@opts[:value] = @opts[:value].or([]).join(', ') if ['Array', 'Sequel::Postgres::PGArray'].index(@opts[:value].class.name)
@opts[:id] ||= Lux.current.uid
@opts[:type] = :text
@opts[:onkeyup] = %[draw_tag('#{@opts[:id]}')]
@opts[:autocomplete] ||= 'off'
@opts[:style] = ['display: block; width: 100%;', @opts[:style]].join(';')
ret = %[
]
ret += @opts.tag(:input)
ret += %[]
ret += %[]
ret
end
def as_date
@opts[:type] = 'text'
@opts[:style] = 'width: 120px; display: inline;'
@opts[:value] = @opts[:value].strftime('%d.%m.%Y') rescue @opts[:value]
@opts[:autocomplete] = :off
ret = @opts.tag(:input)
ret += ' • %s' % Time.ago(Time.parse(@opts[:value])) if @opts[:value].present? && !@opts.delete(:no_ago)
# ret += ' • %s' % @opts[:hint]
ret + %[]
end
def as_datetime
value = @opts[:value]
id = @opts[:id]
value_day = value ? value.strftime('%Y-%m-%d') : ''
value_time = value ? value.strftime('%H:%M') : ''
value_all = value ? value.strftime('%H:%M') : ''
base = { class: 'form-control', onchange: "datetime_set('#{id}');", style: 'width: 160px; display: inline;' }
input_day = base.merge({ type: :date, id: '%s_day' % id, value: value_day }).tag :input
input_time = base.merge({ style: 'width: 110px; display: inline;', type: :time, id: '%s_time' % id, value: value_time }).tag :input
input_all = base.merge({ style: 'width: 150px; display: inline;', type: :text, id: id, name: @opts[:name], onfocus: 'blur();' }).tag :input
script = %[]
desc = value ? '—' + Time.ago(value) : ''
[input_day, input_time, input_all, script, desc].join(' ')
end
def as_datebuttons
@opts[:type] = 'text'
@opts[:style] = 'width:100px; display:inline;'
@opts[:id] = "date_#{Lux.current.uid}"
id = "##{@opts[:id]}"
ret = @opts.tag(:input)
ret += %[ ]
for el in [1, 3, 7, 14, 30]
date = DateTime.now+el.days
name = el.to_s
name += " (#{date.strftime('%a')})" if el < 7
ret += %[ ]
end
ret
end
def as_user
button_text = if @opts[:value].to_i > 0
usr = User.find(@opts[:value])
"#{usr.name} (#{usr.email})"
else
'Select user'
end
@opts[:style] = "width:auto;#{@opts[:style]};"
@opts[:onclick] = %[Dialog.render(this,'Select user', '/part/users/single_user?product_id=#{@object.bucket_id}');return false;]
@opts.tag :button, button_text
end
def as_photo
@opts[:type] = 'hidden'
if @opts[:value].present?
img = Photo.find(@opts[:value])
@image = %[ ×]
end
picker = @opts.tag(:input)
%[Select photo#{picker}#{@image}]
end
def as_photos
@opts[:type] = 'text'
@opts[:style] = 'width:150px; display:inline;'
@opts[:class] += ' mutiple'
@images = []
if @opts[:value].present?
for el in @opts[:value].split(',').uniq
img = Photo.find(el.to_i) rescue next
@images.push %[ ]
end
end
picker = @opts.tag(:input)
%[Add photo #{picker}
#{@images.join(' ')}
]
end
def as_admin_password
@opts[:type] = 'text'
@opts[:style] = 'display:none;'
@opts[:value] = ''
ret = @opts.tag(:input)
%[Set pass #{ret}]
end
def as_color
value = @opts[:value]
@opts[:style] ||= 'width:150px; float: left; margin-right: 10px;'
as_text + %[]
end
def as_array_values
name = @opts[:name]
ret = []
values = @opts[:value].kind_of?(String) ? @opts[:value].split(',') : @opts[:value]
for el in @opts[:collection]
ret.push %[]
end
ret.join('')
end
def as_pass
value = @opts[:value]
id = @opts[:id]
@opts[:value] = ''
@opts[:style] = 'width:200px; display:inline;'
ret = @opts.tag(:input)
%[#{value.present? ? 'Change' : 'Set'} password#{ret} or cancel]
end
def as_image
@opts[:type] = 'text'
@opts[:style] = 'width:350px; float:left;'
@opts[:autocomplete] ||= 'off'
input = @opts.tag(:input)
path_name = 'image_upload_dialog'
input += %[upload]
if @opts[:value].present?
input = %[ #{input}]
input += %[
...]
end
'' + input
end
def as_geo
@opts[:type] = 'text'
@opts[:style] = 'width:200px; float:left;'
ret = @opts.tag(:input)
ret += %[ Show on map]
end
def as_html_trix
%[
]
end
def as_button_select
body = ['
']
collection = @opts.delete(:collection)
for el in prepare_collection(collection)
opts = { class:'btn btn-sm' }
ap "#{@opts[:name]} - #{@opts[:value]} == #{el[0]}"
opts[:class] += ' btn-primary' if @opts[:value].to_s == el[0].to_s
opts[:onclick] = "$(this).parent().find('.btn').removeClass('btn-primary'); $(this).addClass('btn-primary').blur(); $(this).addClass('btn-primary').blur();"
opts[:onclick] += @opts[:onclick] ? "(#{@opts[:onclick].sub(/;\s*$/,'')})('#{el[0]}')" : "$('##{@opts[:id]}').val('#{el[0]}')"
opts[:onclick] += '; return false;'
body.push opts.tag(:button, el[1])
end
body.push '
'
body.push @opts.pluck(:name, :id, :value).merge(type: :hidden).tag(:input)
body.join('')
end
def as_address
val = @opts[:value]
@opts[:style] ||= 'height:55px; width:250px; float: left; margin-right:5px;'
ret = as_textarea
ret += %[
] if val.to_s.length > 5
ret
end
def as_images
path_name = defined?(Storage) ? :storages : :images
val = @opts[:value].to_s
ret = as_memo
ret += ''
ret += val.split("\n").map{ |url| %[] }.join(' ')
ret += %[add image]
ret
end
def as_disabled
@opts[:disabled] = true
@opts.delete(:name)
as_text
end
end