class Conjoin::FormBuilder::Fields
Public Instance Methods
association(field_name, options = {})
click to toggle source
# File lib/conjoin/form_builder.rb, line 87 def association field_name, options = {} options[:is_association] = true input field_name, options end
errors_for(attr)
click to toggle source
# File lib/conjoin/form_builder.rb, line 219 def errors_for attr mab do span class: 'has-error has-feedback form-control-feedback' do text! record.errors.messages[attr.to_sym].try :join, ', ' end end end
fields_for(field_name, options = {})
click to toggle source
# File lib/conjoin/form_builder.rb, line 159 def fields_for field_name, options = {}, &block names = [].concat models associated_record = record.send field_name if scope = options.delete(:scope) associated_record = associated_record.send(scope, *options.delete(:scope_args)) end if select = options.delete(:select) associated_record = Hash[associated_record.each_with_index.map {|a, i| [i, a]}] select.each do |key, select_array| select_array = [select_array] unless select_array.is_a? Array associated_record.select! do |k, v| select_array.include? :"#{v[key]}" end end end if name = options.delete(:name) field_name = name end names << "#{field_name}_attributes" if !associated_record.kind_of? ActiveRecord::Associations::CollectionProxy \ and !associated_record.kind_of? ActiveRecord::AssociationRelation \ and !associated_record.kind_of? Array \ and !associated_record.kind_of? Hash fields = Fields.new app, names, associated_record, block, 0 fields.render else html = '' if associated_record.kind_of? Array associated_record.each_with_index do |current_record, i| nested_names = [].concat names nested_names << i fields = Fields.new app, nested_names, current_record, block, i html += fields.render end else associated_record.each_with_index do |current_record, i| nested_names = [].concat names nested_names << i fields = Fields.new app, nested_names, current_record, block, i html += fields.render end end html end # rescue # raise "No associated record #{field_name} for #{record.class}" end
input(field_name, options = {})
click to toggle source
# File lib/conjoin/form_builder.rb, line 97 def input field_name, options = {} names = [].concat models if options.delete(:is_association) names << "#{field_name.to_s.singularize}_ids" names << '' else names << field_name end # create field names that map to the correct models nested_name = nested_names_for names begin record_class = record.class.model_name.name.constantize rescue Exception m = models.join('.').gsub(/_attributes/, '') raise "No value for #{field_name} as #{m} is nil." end if as = options.delete(:as) record_type = as.to_s.classify elsif record_class.mini_record_columns \ and mini_column = record_class.mini_record_columns[field_name] \ and input_as = mini_column[:input_as] record_type = input_as.to_s.classify elsif record_class.respond_to?(field_name) && record_class.send(field_name).is_a?(Enumerize::Attribute) record_type = 'Select' else record_type = record_class.columns_hash[field_name.to_s].type.to_s.classify end if mini_column and opts = mini_column[:input_options] options = opts.merge options end input_class = "Conjoin::FormBuilder::#{record_type}Input".constantize data = OpenStruct.new({ name: nested_name, record: record, value: record.send(field_name), options: options, errors: record.errors.messages[field_name], names: names, field_name: field_name, record_class: record_class }) new_input = input_class.new data, app, record if record_type != 'Hidden' \ and not options.key(:wrapper) and options[:wrapper] != false if !options.key(:label) and options[:label] != false wrapper field_name.to_s, nested_name, new_input, options else new_input.render end else new_input.render end end
input_field(field_name, options = {})
click to toggle source
# File lib/conjoin/form_builder.rb, line 92 def input_field field_name, options = {} options[:label] = false input field_name, options end
nested_names_for(names)
click to toggle source
# File lib/conjoin/form_builder.rb, line 80 def nested_names_for names # create field names that map to the correct models names.each_with_index.map do |field, i| i != 0 ? "[#{field}]" : field end.join end
render()
click to toggle source
# File lib/conjoin/form_builder.rb, line 59 def render html = block.call(self, index) names = [].concat models names << 'id' mab do if record.id input type: 'hidden', name: nested_names_for(names), value: record.id end text! html end end
submit(options = {})
click to toggle source
# File lib/conjoin/form_builder.rb, line 72 def submit options = {} mab do input type: 'submit', value: options[:value] || 'Submit', class: 'btn' end end
Private Instance Methods
errors?(obj, attr)
click to toggle source
# File lib/conjoin/form_builder.rb, line 259 def errors? obj, attr obj.errors.messages[attr.to_sym] end
id_for(field_name)
click to toggle source
# File lib/conjoin/form_builder.rb, line 229 def id_for field_name field_name.gsub(/[^a-z0-9]/, '_').gsub(/__/, '_').gsub(/_$/, '') end
required?(obj, attr, options)
click to toggle source
# File lib/conjoin/form_builder.rb, line 233 def required?(obj, attr, options) if options.key?(:required) options[:required] else target = (obj.class == Class) ? obj : obj.class presence = target.validators_on(attr).select { |t| t.class.to_s == 'ActiveRecord::Validations::PresenceValidator' } if presence.any? is_required = true presence.each do |p| if p.options[:if] is_required &= p.options[:if].call(record) end if p.options[:unless] is_required &= !p.options[:if].call(record) end end else is_required = false end is_required end end
wrapper(field_name, nested_name, input, options)
click to toggle source
# File lib/conjoin/form_builder.rb, line 263 def wrapper field_name, nested_name, input, options if w = options[:wrapper] and w.is_a? String label_width, input_width = w.split ',' else label_width, input_width = [3, 9] end mab do div class: "form-group #{errors?(record, field_name) ? 'has-error has-feedback' : ''}" do label for: id_for(nested_name), class: "control-label col-sm-#{label_width}" do if required? record, field_name, options abbr title: 'required' do text '*' end end i18n_s = nested_name.gsub(/.+\[([a-z\_]+)\](?:.*|)\[([a-z\_]+)\]$/, 'model.\1.\2').gsub(/_attributes/, '') i18n_name = options[:label] || R18n.t(i18n_s.gsub(/^model/, 'form.label')) | R18n.t.form.label[field_name] | R18n.t(i18n_s) | field_name.titleize text! i18n_name end div class: "col-sm-#{input_width}" do text! input.render if errors = errors?(record, field_name) span class: 'help-block has-error' do text errors.join ', ' end span class: 'fa fa-times form-control-feedback' end end end end end