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
126 127 128 129 130 131 132 133 134 135 136 137 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 |
# File 'lib/brick/frameworks/rails/form_builder.rb', line 126 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 —
122 123 124 |
# File 'lib/brick/frameworks/rails/form_builder.rb', line 122 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 |
# 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_link = if (bt_obj = bt_class&.find_by(bt_pair[1] => val)) 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 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' }) 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 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 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 |