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