Module: Brick::Rails::FormBuilder
- Defined in:
- lib/brick/frameworks/rails/form_builder.rb
Constant Summary collapse
- DT_PICKERS =
{ datetime: 'datetimepicker', timestamp: 'datetimepicker', time: 'timepicker', date: 'datepicker' }
Class Method Summary collapse
- .hide_bcrypt(val, is_xml = nil, max_len = 200) ⇒ Object
-
.is_bcrypt?(val) ⇒ Boolean
— CLASS METHODS —.
Instance Method Summary collapse
-
#brick_field(method, html_options = {}, val = nil, col = nil, bt = nil, bt_class = nil, bt_name = nil, bt_pair = nil) ⇒ Object
When this field is one of the appropriate types, will set one of these instance variables accordingly: @_text_fields_present - To include trix editor @_date_fields_present - To include flatpickr date / time editor @_json_fields_present - To include JSONEditor.
Class Method Details
.hide_bcrypt(val, is_xml = nil, max_len = 200) ⇒ Object
138 139 140 141 142 143 144 145 146 147 148 149 150 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 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/brick/frameworks/rails/form_builder.rb', line 138 def self.hide_bcrypt(val, is_xml = nil, max_len = 200) if ::Brick::Rails::FormBuilder.is_bcrypt?(val) '(hidden)' else if val.is_a?(String) val = val.dup.force_encoding('UTF-8').strip return CGI.escapeHTML(val) if is_xml if val.length > max_len if val[0] == '<' # Seems to be HTML? cur_len = 0 cur_idx = 0 # Find which HTML tags we might be inside so we can apply ending tags to balance element_name = nil in_closing = nil elements = [] val.each_char do |ch| case ch when '<' element_name = +'' when '/' # First character of tag is '/'? in_closing = true if element_name == '' when '>' if element_name if in_closing if (idx = elements.index { |tag| tag.downcase == element_name.downcase }) elements.delete_at(idx) end elsif (tag_name = element_name.split.first).present? elements.unshift(tag_name) end element_name = nil in_closing = nil end else element_name << ch if element_name end cur_idx += 1 # Unless it's inside wickets then this is real text content, and see if we're at the limit break if element_name.nil? && ((cur_len += 1) > max_len) end val = val[0..cur_idx] # Somehow still in the middle of an opening tag right at the end? (Should never happen) if !in_closing && (tag_name = element_name&.split&.first)&.present? elements.unshift(tag_name) val << '>' end elements.each do |closing_tag| val << "</#{closing_tag}>" end else # Not HTML, just cut it at the length val = val[0...max_len] end val = "#{val}..." end val else val.to_s end end end |
.is_bcrypt?(val) ⇒ Boolean
— CLASS METHODS —
134 135 136 |
# File 'lib/brick/frameworks/rails/form_builder.rb', line 134 def self.is_bcrypt?(val) val.is_a?(String) && val.length == 60 && val.start_with?('$2a$') end |
Instance Method Details
#brick_field(method, html_options = {}, val = nil, col = nil, bt = nil, bt_class = nil, bt_name = nil, bt_pair = nil) ⇒ Object
When this field is one of the appropriate types, will set one of these instance variables accordingly:
@_text_fields_present - To include trix editor
@_date_fields_present - To include flatpickr date / time editor
@_json_fields_present - To include JSONEditor
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 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 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 126 127 128 129 130 |
# File 'lib/brick/frameworks/rails/form_builder.rb', line 8 def brick_field(method, = {}, val = nil, col = nil, bt = nil, bt_class = nil, bt_name = nil, bt_pair = nil) model = self.object.class col ||= model.columns_hash[method] out = +'<table><tr><td>' [:class] = 'dimmed' unless val is_revert = true template = instance_variable_get(:@template) if bt bt_class ||= bt[1].first.first bt_name ||= bt[1].map { |x| x.first.name }.join('/') bt_pair ||= bt[1].first [:prompt] = "Select #{bt_name}" out << self.select(method.to_sym, bt[3], { value: val || '^^^brick_NULL^^^' }, ) bt_obj = nil begin bt_obj = bt_class&.find_by(bt_pair[1] => val) rescue ActiveRecord::SubclassNotFound => e # %%% Would be cool to indicate to the user that a subclass is missing. # Its name starts at: e.message.index('failed to locate the subclass: ') + 31 end bt_link = if bt_obj bt_path = template.send( "#{bt_class.base_class._brick_index(:singular)}_path".to_sym, bt_obj.send(bt_class.primary_key.to_sym) ) template.link_to('⇛', bt_path, { class: 'show-arrow' }) elsif val "<span class=\"orphan\">Orphaned ID: #{val}</span>".html_safe end out << bt_link if bt_link elsif @_brick_monetized_attributes&.include?(method) out << self.text_field(method.to_sym, .merge({ value: Money.new(val.to_i).format })) else col_type = if model.json_column?(col) || val.is_a?(Array) :json elsif col&.sql_type == 'geography' col.sql_type else col&.type end case (col_type ||= col&.sql_type) when :string, :text, :citext if ::Brick::Rails::FormBuilder.is_bcrypt?(val) # || .readonly? is_revert = false out << ::Brick::Rails::FormBuilder.hide_bcrypt(val, nil, 1000) elsif col_type == :string if model.respond_to?(:enumerized_attributes) && (opts = (attr = model.enumerized_attributes[method])&.).present? = attr.kind_of?(Enumerize::Multiple) ? .merge({ multiple: true, size: opts.length + 1 }) : out << self.select(method.to_sym, [["(No #{method} chosen)", '^^^brick_NULL^^^']] + opts, { value: val || '^^^brick_NULL^^^' }, ) else out << self.text_field(method.to_sym, ) end else template.instance_variable_set(:@_text_fields_present, true) out << self.hidden_field(method.to_sym, ) out << "<trix-editor input=\"#{self.field_id(method)}\"></trix-editor>" end when :boolean out << self.check_box(method.to_sym) when :integer, :decimal, :float if model.respond_to?(:attribute_types) && (enum_type = model.attribute_types[method]).is_a?(ActiveRecord::Enum::EnumType) opts = enum_type.send(:mapping)&.each_with_object([]) { |v, s| s << [v.first, v.first] } || [] out << self.select(method.to_sym, [["(No #{method} chosen)", '^^^brick_NULL^^^']] + opts, { value: val || '^^^brick_NULL^^^' }, ) else digit_pattern = col_type == :integer ? '\d*' : '\d*(?:\.\d*|)' # Used to do this for float / decimal: self.number_field method.to_sym out << self.text_field(method.to_sym, { pattern: digit_pattern, class: 'check-validity' }) end when *DT_PICKERS.keys template.instance_variable_set(:@_date_fields_present, true) out << self.text_field(method.to_sym, { class: DT_PICKERS[col_type] }) when :uuid is_revert = false # Postgres naturally uses the +uuid_generate_v4()+ function from the uuid-ossp extension # If it's not yet enabled then: create extension \"uuid-ossp\"; # ActiveUUID gem created a new :uuid type out << val if val when :ltree # In Postgres labels of data stored in a hierarchical tree-like structure # If it's not yet enabled then: create extension ltree; out << val if val when :binary is_revert = false if val # %%% This same kind of geography check is done two other times in engine.rb ... would be great to DRY it up. out << if val.length < 31 && (val.length - 6) % 8 == 0 && val[0..5].bytes == [230, 16, 0, 0, 1, 12] ::Brick::Rails.display_value('geography', val) else ::Brick::Rails.display_binary(val) end end when :primary_key is_revert = false when :json, :jsonb template.instance_variable_set(:@_json_fields_present, true) if val.is_a?(String) val_str = val else eheij = ActiveSupport::JSON::Encoding.escape_html_entities_in_json ActiveSupport::JSON::Encoding.escape_html_entities_in_json = false if eheij val_str = val&.to_json ActiveSupport::JSON::Encoding.escape_html_entities_in_json = eheij end # Because there are so danged many quotes in JSON, escape them specially by converting to backticks. # (and previous to this, escape backticks with our own goofy code of ^^br_btick__ ) out << (json_field = self.hidden_field(method.to_sym, { class: 'jsonpicker', value: val_str&.gsub('`', '^^br_btick__')&.tr('\"', '`')&.html_safe })) out << "<div id=\"_br_json_#{self.field_id(method)}\"></div>" else is_revert = false out << (::Brick::Rails.display_value(col_type, val)&.html_safe || '') end end if is_revert out << "</td> " out << '<td><svg class="revert" width="1.5em" viewBox="0 0 512 512"><use xlink:href="#revertPath" /></svg>' end out << "</td></tr></table> " out.html_safe end |