lib/netzke/basepack/grid_panel/columns.rb in netzke-basepack-0.6.2 vs lib/netzke/basepack/grid_panel/columns.rb in netzke-basepack-0.6.3

- old
+ new

@@ -64,10 +64,15 @@ initial_columns(only_included) end end end + # Columns as a hash, for easier access to a specific column + def columns_hash + @columns_hash ||= columns.inject({}){|r,c| r.merge(c[:name].to_sym => c)} + end + # Columns that we fall back to when neither persistent columns, nor configured columns are present. # If there's a model-level field configuration, it's being used. # Otherwise the defaults straight from the ActiveRecord model ("netzke_attributes"). # Override this method if you want to provide a fix set of columns in your subclass. def default_columns @@ -99,10 +104,11 @@ filter_out_excluded_columns(columns_for_create) if only_included # Make the column config complete with the defaults columns_for_create.each do |c| detect_association(c) + set_default_virtual(c) set_default_header(c) set_default_editor(c) set_default_width(c) set_default_hidden(c) set_default_editable(c) @@ -112,10 +118,11 @@ columns_for_create end private + def filter_out_excluded_columns(cols) cols.reject!{ |c| c[:included] == false } end # Stores modified columns in persistent storage @@ -130,11 +137,11 @@ def load_model_level_attrs # NetzkeModelAttrList.read_list(data_class.name) if persistent_config_enabled? end def set_default_header(c) - c[:label] ||= c[:name].humanize + c[:label] ||= data_class.human_attribute_name(c[:name]) end def set_default_editor(c) c[:editor] ||= editor_for_attr_type(c[:attr_type]) c[:editor] = {:xtype => c[:editor]} if c[:editor].is_a?(Symbol) @@ -148,12 +155,19 @@ def set_default_hidden(c) c[:hidden] = true if primary_key_attr?(c) && c[:hidden].nil? end def set_default_editable(c) - c[:editable] = c[:read_only].nil? ? !(primary_key_attr?(c) || c[:virtual]) : !c[:read_only] - c.delete(:read_only) + not_editable_if = primary_key_attr?(c) + not_editable_if ||= c[:virtual] + not_editable_if ||= c.delete(:read_only) + + editable_if = data_class.column_names.include?(c[:name]) + editable_if ||= data_class.instance_methods.map(&:to_s).include?("#{c[:name]}=") + editable_if ||= association_attr?(c[:name]) + + c[:editable] = editable_if && !not_editable_if if c[:editable].nil? end def set_default_sortable(c) c[:sortable] = !c[:virtual] if c[:sortable].nil? end @@ -162,11 +176,11 @@ c[:filterable] = !c[:virtual] if c[:filterable].nil? end # Returns editor's xtype for a column type def editor_for_attr_type(type) - attr_type_to_editor_map[type] + attr_type_to_editor_map[type] || :textfield end def editor_for_association :combobox end @@ -183,27 +197,38 @@ } end # Detects an association column and sets up the proper editor. def detect_association(c) - # double-underscore notation? surely an association column - if c[:name].index('__') - assoc_name, assoc_method = c[:name].split('__') - if assoc_method && assoc = data_class.reflect_on_association(assoc_name.to_sym) - assoc_column = assoc.klass.columns_hash[assoc_method] - assoc_method_type = assoc_column.try(:type) + assoc, assoc_method = get_assoc_and_method(c) + if assoc + assoc_column = assoc.klass.columns_hash[assoc_method] + assoc_method_type = assoc_column.try(:type) - # if association column is boolean, display a checkbox (or alike), otherwise - a combobox (or alike) + # if association column is boolean, display a checkbox (or alike), otherwise - a combobox (or alike) + if c[:nested_attribute] + c[:editor] ||= editor_for_attr_type(assoc_method_type) + else c[:editor] ||= assoc_method_type == :boolean ? editor_for_attr_type(:boolean) : editor_for_association end end end + def get_assoc_and_method(c) + if c[:name].index("__") + assoc_name, assoc_method = c[:name].split('__') + assoc = data_class.reflect_on_association(assoc_name.to_sym) + [assoc, assoc_method] + else + [nil, nil] + end + end + # Default fields that will be displayed in the Add/Edit/Search forms + # When overriding this method, keep in mind that the fields inside the layout must be expanded (each field represented by a hash, not just a symbol) def default_fields_for_forms - form_klass = "Netzke::ModelExtensions::#{config[:model]}ForFormPanel".constantize rescue nil - form_klass ||= original_data_class + form_klass = constantize_class_name("Netzke::ModelExtensions::#{config[:model]}ForFormPanel") || original_data_class # Select only those fields that are known to the form_klass selected_columns = columns.select do |c| form_klass.column_names.include?(c[:name]) || form_klass.instance_methods.include?("#{c[:name]}=") || @@ -218,14 +243,34 @@ field_config end end + # default_fields_for_forms extended with default values (for new-record form) + def default_fields_for_forms_with_default_values + res = default_fields_for_forms.dup + each_attr_in(res) do |a| + attr_name = a[:name].to_sym + a[:value] = a[:default_value] || columns_hash[attr_name].try(:fetch, :default_value, nil) || data_class.netzke_attribute_hash[attr_name].try(:fetch, :default_value, nil) + end + res + end + + # Recursively traversess items (an array) and yields each found field (a hash with :name set) + def each_attr_in(items) + items.each do |item| + if item.is_a?(Hash) + each_attr_in(item[:items]) if item[:items].is_a?(Array) + yield(item) if item[:name] + end + end + end + # Receives 2 arrays of columns. Merges the missing config from the +source+ into +dest+, matching columns by name def reverse_merge_equally_named_columns(dest, source) dest.each{ |dc| dc.reverse_merge!(source.detect{ |sc| sc[:name] == dc[:name] } || {}) } end end end end -end \ No newline at end of file +end