Commit c224f8a93b63bb7c02398390218daba4303a41d1

Authored by Lucas Melo
1 parent 103b7ebe

custom_forms: use rails nested forms in form partial

AI2780
Showing 36 changed files with 420 additions and 475 deletions   Show diff stats
plugins/custom_forms/controllers/custom_forms_plugin_myprofile_controller.rb
1 1 class CustomFormsPluginMyprofileController < MyProfileController
2   -
3 2 protect 'post_content', :profile
  3 +
4 4 def index
5 5 @forms = CustomFormsPlugin::Form.from(profile)
6 6 end
7 7  
  8 + def new
  9 + @form = CustomFormsPlugin::Form.new
  10 +
  11 + respond_to do |format|
  12 + format.html
  13 + end
  14 + end
  15 +
8 16 def create
9   - @form = CustomFormsPlugin::Form.new(:profile => profile)
10   - @fields = []
11   - @empty_field = CustomFormsPlugin::Field.new
12   - if request.post?
13   - begin
14   - @form.update_attributes!(params[:form])
15   - params[:fields] = format_kind(params[:fields])
16   - params[:fields] = format_choices(params[:fields])
17   - params[:fields] = set_form_id(params[:fields], @form.id)
18   - create_fields(new_fields(params))
19   - session['notice'] = _('Form created')
20   - redirect_to :action => 'index'
21   - rescue Exception => exception
22   - logger.error(exception.to_s)
23   - session['notice'] = _('Form could not be created')
  17 + params[:form][:profile_id] = profile.id
  18 + @form = CustomFormsPlugin::Form.new(params[:form])
  19 +
  20 + respond_to do |format|
  21 + if @form.save
  22 + flash[:notice] = _("Custom form #{@form.name} was successfully created.")
  23 + format.html { redirect_to(:action=>'index') }
  24 + else
  25 + format.html { render :action => 'new' }
24 26 end
25 27 end
26 28 end
27 29  
28 30 def edit
29 31 @form = CustomFormsPlugin::Form.find(params[:id])
30   - @fields = @form.fields
31   - @empty_field = CustomFormsPlugin::TextField.new
32   - if request.post?
33   - begin
34   - @form.update_attributes!(params[:form])
35   - params[:fields] = format_kind(params[:fields])
36   - params[:fields] = format_choices(params[:fields])
37   - remove_fields(params, @form)
38   - create_fields(new_fields(params))
39   - update_fields(edited_fields(params))
40   - session['notice'] = _('Form updated')
41   - redirect_to :action => 'index'
42   - rescue Exception => exception
43   - logger.error(exception.to_s)
  32 + end
  33 +
  34 + def update
  35 + @form = CustomFormsPlugin::Form.find(params[:id])
  36 +
  37 + respond_to do |format|
  38 + if @form.update_attributes(params[:form])
  39 + flash[:notice] = _("Custom form #{@form.name} was successfully updated.")
  40 + format.html { redirect_to(:action=>'index') }
  41 + else
44 42 session['notice'] = _('Form could not be updated')
  43 + format.html { render :action => 'edit' }
45 44 end
46 45 end
47 46 end
... ... @@ -67,82 +66,4 @@ class CustomFormsPluginMyprofileController &lt; MyProfileController
67 66 @form = @submission.form
68 67 end
69 68  
70   - private
71   -
72   - def new_fields(params)
73   - keys = params[:fields].keys.sort{|a, b| a.to_i <=> b.to_i}
74   - result = keys.map { |id| (hash = params[:fields][id]).has_key?(:real_id) ? nil : hash}.compact
75   - result.delete_if {|field| field[:name].blank?}
76   - result
77   - end
78   -
79   - def edited_fields(params)
80   - params[:fields].map {|id, hash| hash.has_key?(:real_id) ? hash : nil}.compact
81   - end
82   -
83   - def create_fields(fields)
84   - fields.each do |field|
85   - case field[:type]
86   - when 'text_field'
87   - CustomFormsPlugin::TextField.create!(field)
88   - when 'select_field'
89   - CustomFormsPlugin::SelectField.create!(field)
90   - else
91   - CustomFormsPlugin::Field.create!(field)
92   - end
93   - end
94   - end
95   -
96   - def update_fields(fields)
97   - fields.each do |field_attrs|
98   - field = CustomFormsPlugin::Field.find(field_attrs.delete(:real_id))
99   - field.attributes = field_attrs
100   - field.save! if field.changed?
101   - end
102   - end
103   -
104   - def format_kind(fields)
105   - fields.each do |id, field|
106   - next if field[:kind].blank?
107   - kind = field.delete(:kind)
108   - case kind
109   - when 'radio'
110   - field[:list] = false
111   - field[:multiple] = false
112   - when 'check_box'
113   - field[:list] = false
114   - field[:multiple] = true
115   - when 'select'
116   - field[:list] = true
117   - field[:multiple] = false
118   - when 'multiple_select'
119   - field[:list] = true
120   - field[:multiple] = true
121   - end
122   - end
123   - fields
124   - end
125   -
126   - def format_choices(fields)
127   - fields.each do |id, field|
128   - next if !field.has_key?(:choices)
129   - field[:choices] = field[:choices].map {|key, value| value}.inject({}) do |result, choice|
130   - hash = (choice[:name].blank? || choice[:value].blank?) ? {} : {choice[:name] => choice[:value]}
131   - result.merge!(hash)
132   - end
133   - end
134   - fields
135   - end
136   -
137   - def remove_fields(params, form)
138   - present_fields = params[:fields].map{|id, value| value}.collect {|field| field[:real_id]}.compact
139   - form.fields.each {|field| field.destroy if !present_fields.include?(field.id.to_s) }
140   - end
141   -
142   - def set_form_id(fields, form_id)
143   - fields.each do |id, field|
144   - field[:form_id] = form_id
145   - end
146   - fields
147   - end
148 69 end
... ...
plugins/custom_forms/controllers/custom_forms_plugin_profile_controller.rb
1 1 class CustomFormsPluginProfileController < ProfileController
2   -
3 2 before_filter :has_access, :show
4 3  
5 4 def show
  5 + extend(CustomFormsPlugin::Helper)
  6 +
6 7 @form = CustomFormsPlugin::Form.find(params[:id])
7 8 if user
8 9 @submission ||= CustomFormsPlugin::Submission.find_by_form_id_and_profile_id(@form.id,user.id)
... ... @@ -10,22 +11,33 @@ class CustomFormsPluginProfileController &lt; ProfileController
10 11 else
11 12 @submission ||= CustomFormsPlugin::Submission.new(:form_id => @form.id)
12 13 end
  14 +
  15 + # build the answers
  16 + @submission.answers.push(*(answers = build_answers(params[:submission], @form))) if params[:submission]
  17 +
13 18 if request.post?
14 19 begin
15   - extend(CustomFormsPlugin::Helper)
16   - answers = build_answers(params[:submission], @form)
  20 + raise 'Submission already present!' if CustomFormsPlugin::Submission.find_by_form_id_and_profile_id(@form.id,user.id)
  21 +
  22 + # @submission.answers for some reason has the same answer twice
17 23 failed_answers = answers.select {|answer| !answer.valid? }
  24 +
18 25 if failed_answers.empty?
19   - if !user
20   - @submission.author_name = params[:author_name]
21   - @submission.author_email = params[:author_email]
  26 + # Save the submission
  27 + ActiveRecord::Base.transaction do
  28 + if !user
  29 + @submission.author_name = params[:author_name]
  30 + @submission.author_email = params[:author_email]
  31 + end
  32 + @submission.save!
22 33 end
23   - @submission.save!
24   - answers.map {|answer| answer.submission = @submission; answer.save!}
25 34 else
26   - @submission.valid?
  35 + @submission.errors.clear
27 36 failed_answers.each do |answer|
28   - @submission.errors.add(answer.field.name.to_sym, answer.errors[answer.field.slug.to_sym])
  37 + answer.valid?
  38 + answer.errors.each do |attribute, msg|
  39 + @submission.errors.add(answer.field.id.to_s.to_sym, msg)
  40 + end
29 41 end
30 42 raise 'Submission failed: answers not valid'
31 43 end
... ...
plugins/custom_forms/db/migrate/20130823134700_create_custom_forms_plugin_alternatives.rb 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +class CreateCustomFormsPluginAlternatives < ActiveRecord::Migration
  2 + def self.up
  3 + create_table :custom_forms_plugin_alternatives do |t|
  4 + t.string :label
  5 + t.references :field
  6 + end
  7 + end
  8 +
  9 + def self.down
  10 + drop_table :custom_forms_plugin_alternatives
  11 + end
  12 +end
... ...
plugins/custom_forms/db/migrate/20130823135600_add_select_field_type_to_custom_forms_plugin_fields.rb 0 → 100644
... ... @@ -0,0 +1,29 @@
  1 +class AddSelectFieldTypeToCustomFormsPluginFields < ActiveRecord::Migration
  2 + def self.up
  3 + change_table :custom_forms_plugin_fields do |t|
  4 + t.remove :position
  5 + t.string :select_field_type
  6 + end
  7 +
  8 + CustomFormsPlugin::Field.find_each do |f|
  9 + if !f.list && !f.multiple
  10 + f.select_field_type = :radio
  11 + elsif !f.list && f.multiple
  12 + f.select_field_type = :check_box
  13 + elsif f.list && !f.multiple
  14 + f.select_field_type = :select
  15 + else
  16 + f.select_field_type = :multiple_select
  17 + end
  18 + f.save!
  19 + end
  20 +
  21 + change_table :custom_forms_plugin_fields do |t|
  22 + t.remove :multiple, :list
  23 + end
  24 + end
  25 +
  26 + def self.down
  27 + raise ActiveRecord::IrreversibleMigration
  28 + end
  29 +end
... ...
plugins/custom_forms/db/migrate/20130823151900_associate_fields_to_alternatives.rb 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +class AssociateFieldsToAlternatives < ActiveRecord::Migration
  2 + class CustomFormsPlugin::Field < ActiveRecord::Base
  3 + set_table_name :custom_forms_plugin_fields
  4 + has_many :alternatives, :class_name => 'CustomFormsPlugin::Alternative'
  5 + serialize :choices, Hash
  6 + end
  7 +
  8 + def self.up
  9 + CustomFormsPlugin::Field.reset_column_information
  10 +
  11 + CustomFormsPlugin::Field.find_each do |f|
  12 + f.choices.each do |key, value|
  13 + CustomFormsPlugin::Alternative.create!(:label => key, :field_id => f.id)
  14 + end
  15 + end
  16 +
  17 + change_table :custom_forms_plugin_fields do |t|
  18 + t.remove :choices
  19 + end
  20 + end
  21 +
  22 + def self.down
  23 + raise ActiveRecord::IrreversibleMigration
  24 + end
  25 +end
... ...
plugins/custom_forms/db/migrate/20131002155900_update_select_field_type_in_custom_forms_plugin_fields.rb 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +class UpdateSelectFieldTypeInCustomFormsPluginFields < ActiveRecord::Migration
  2 + def self.up
  3 + change_column :custom_forms_plugin_fields, :select_field_type, :string, :null => false, :default => 'radio'
  4 + end
  5 +
  6 + def self.down
  7 + raise ActiveRecord::IrreversibleMigration
  8 + end
  9 +end
... ...
plugins/custom_forms/db/migrate/20131007120600_add_selected_by_default_to_custom_forms_plugin_alternatives.rb 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +class AddSelectedByDefaultToCustomFormsPluginAlternatives < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :custom_forms_plugin_alternatives, :selected_by_default, :boolean, :null => false, :default => false
  4 + CustomFormsPlugin::Field.find_each do |f|
  5 + f.alternatives.each do |a|
  6 + a.update_attribute(:selected_by_default, true) if a.label == f.default_value
  7 + end
  8 + end
  9 + end
  10 +
  11 + def self.down
  12 + raise ActiveRecord::IrreversibleMigration
  13 + end
  14 +end
... ...
plugins/custom_forms/lib/custom_forms_plugin/alternative.rb 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +class CustomFormsPlugin::Alternative < ActiveRecord::Base
  2 + set_table_name :custom_forms_plugin_alternatives
  3 +
  4 + validates_presence_of :label
  5 +
  6 + belongs_to :field, :class_name => 'CustomFormsPlugin::Field'
  7 +end
  8 +
... ...
plugins/custom_forms/lib/custom_forms_plugin/answer.rb
... ... @@ -7,7 +7,7 @@ class CustomFormsPlugin::Answer &lt; Noosfero::Plugin::ActiveRecord
7 7  
8 8 def value_mandatory
9 9 if field.mandatory && value.blank?
10   - errors.add(field.slug.to_sym, _("is mandatory.").fix_i18n)
  10 + errors.add(:value, _("is mandatory.").fix_i18n)
11 11 end
12 12 end
13 13 end
... ...
plugins/custom_forms/lib/custom_forms_plugin/field.rb
1 1 class CustomFormsPlugin::Field < ActiveRecord::Base
2 2 set_table_name :custom_forms_plugin_fields
3 3  
4   - validates_presence_of :form, :name
5   - validates_uniqueness_of :slug, :scope => :form_id
  4 + validates_presence_of :name
6 5  
7 6 belongs_to :form, :class_name => 'CustomFormsPlugin::Form'
8 7 has_many :answers, :class_name => 'CustomFormsPlugin::Answer'
9 8  
10   - serialize :choices, Hash
  9 + has_many :alternatives, :class_name => 'CustomFormsPlugin::Alternative'
  10 + accepts_nested_attributes_for :alternatives, :allow_destroy => true
11 11  
12 12 before_validation do |field|
13 13 field.slug = field.name.to_slug if field.name.present?
14 14 end
15 15  
16   - before_create do |field|
17   - if field.form.fields.exists?
18   - field.position = field.form.fields.order(:position).last.position + 1
19   - end
20   - end
  16 + private
21 17  
22   - def position
23   - self[:position] || 0
  18 + def attributes_protected_by_default
  19 + super - [self.class.inheritance_column]
24 20 end
  21 +
25 22 end
26 23  
... ...
plugins/custom_forms/lib/custom_forms_plugin/form.rb
1 1 class CustomFormsPlugin::Form < Noosfero::Plugin::ActiveRecord
2 2 belongs_to :profile
3 3  
4   - has_many :fields, :class_name => 'CustomFormsPlugin::Field', :dependent => :destroy, :order => 'position'
  4 + has_many :fields, :class_name => 'CustomFormsPlugin::Field', :dependent => :destroy
  5 + accepts_nested_attributes_for :fields, :allow_destroy => true
  6 +
5 7 has_many :submissions, :class_name => 'CustomFormsPlugin::Submission'
6 8  
7 9 serialize :access
... ...
plugins/custom_forms/lib/custom_forms_plugin/helper.rb
1 1 module CustomFormsPlugin::Helper
  2 + def html_for_field(builder, association, klass)
  3 + new_object = klass.new
  4 + builder.fields_for(association, new_object, :child_index => "new_#{association}") do |f|
  5 + render(partial_for_class(klass), :f => f)
  6 + end
  7 + end
  8 +
2 9 def access_text(form)
3 10 return _('Public') if form.access.nil?
4 11 return _('Logged users') if form.access == 'logged'
... ... @@ -48,8 +55,8 @@ module CustomFormsPlugin::Helper
48 55  
49 56 def type_to_label(type)
50 57 map = {
51   - 'text_field' => _('Text'),
52   - 'select_field' => _('Select')
  58 + 'text_field' => _('Text field'),
  59 + 'select_field' => _('Select field')
53 60 }
54 61 map[type_for_options(type)]
55 62 end
... ... @@ -61,52 +68,53 @@ module CustomFormsPlugin::Helper
61 68 def display_custom_field(field, submission, form)
62 69 answer = submission.answers.select{|answer| answer.field == field}.first
63 70 field_tag = send("display_#{type_for_options(field.class)}",field, answer, form)
64   - if field.mandatory? && !radio_button?(field) && !check_box?(field) && submission.id.nil?
  71 + if field.mandatory? && submission.id.nil?
65 72 required(labelled_form_field(field.name, field_tag))
66   - else
  73 + else
67 74 labelled_form_field(field.name, field_tag)
68 75 end
69 76 end
70 77  
71 78 def display_text_field(field, answer, form)
72 79 value = answer.present? ? answer.value : field.default_value
73   - text_field(form, field.name.to_slug, :value => value, :disabled => answer.present?)
  80 + text_field(form, "#{field.id}", :value => value, :disabled => answer.present? && answer.id.present?)
74 81 end
75 82  
76 83 def display_select_field(field, answer, form)
77   - if field.list && field.multiple
78   - selected = answer.present? ? answer.value.split(',') : []
79   - select_tag "#{form}[#{field.name.to_slug}]", options_for_select(field.choices.to_a, selected), :multiple => true, :size => field.choices.size, :disabled => answer.present?
80   - elsif !field.list && field.multiple
81   - field.choices.map do |name, value|
82   - default = answer.present? ? answer.value.split(',').include?(value) : false
83   - labelled_check_box name, "#{form}[#{field.name.to_slug}][#{value}]", '1', default, :disabled => answer.present?
  84 + case field.select_field_type
  85 + when 'multiple_select'
  86 + selected = answer.present? ? answer.value.split(',') : field.alternatives.select {|a| a.selected_by_default}.map{|a| a.id.to_s}
  87 + select_tag "submission[#{field.id}]", options_for_select(field.alternatives.map{|a| [a.label, a.id.to_s]}, selected), :multiple => true, :size => field.alternatives.size, :disabled => answer.present? && answer.id.present?
  88 + when 'check_box'
  89 + field.alternatives.map do |alternative|
  90 + default = answer.present? ? answer.value.split(',').include?(alternative.id.to_s) : alternative.selected_by_default
  91 + labelled_check_box alternative.label, "submission[#{field.id}][#{alternative.id}]", '1', default, :disabled => answer.present? && answer.id.present?
84 92 end.join("\n")
85   - elsif field.list && !field.multiple
86   - selected = answer.present? ? answer.value.split(',') : []
87   - select_tag "#{form}[#{field.name.to_slug}]", options_for_select([['','']] + field.choices.to_a, selected), :disabled => answer.present?
88   - elsif !field.list && !field.multiple
89   - field.choices.map do |name, value|
90   - default = answer.present? ? answer.value == value : true
91   - labelled_radio_button name, "#{form}[#{field.name.to_slug}]", value, default, :disabled => answer.present?
  93 + when 'select'
  94 + selected = answer.present? ? answer.value.split(',') : field.alternatives.select {|a| a.selected_by_default}.map{|a| a.id.to_s}
  95 + select_tag "submission[#{field.id}]", options_for_select([['','']] + field.alternatives.map {|a| [a.label, a.id.to_s]}, selected), :disabled => answer.present? && answer.id.present?
  96 + when 'radio'
  97 + field.alternatives.map do |alternative|
  98 + default = answer.present? ? answer.value == alternative.id.to_s : alternative.selected_by_default
  99 + labelled_radio_button alternative.label, "submission[#{field.id}]", alternative.id, default, :disabled => answer.present? && answer.id.present?
92 100 end.join("\n")
93 101 end
94 102 end
95 103  
96 104 def radio_button?(field)
97   - type_for_options(field.class) == 'select_field' && !field.list && !field.multiple
  105 + type_for_options(field.class) == 'select_field' && field.select_field_type == 'radio'
98 106 end
99 107  
100 108 def check_box?(field)
101   - type_for_options(field.class) == 'select_field' && !field.list && field.multiple
  109 + type_for_options(field.class) == 'select_field' && field.select_field_type == 'check_box'
102 110 end
103 111  
104 112 def build_answers(submission, form)
105 113 answers = []
106 114 form.fields.each do |field|
107 115 final_value = ''
108   - if submission.has_key?(field.slug)
109   - value = submission[field.slug]
  116 + if submission.has_key?(field.id.to_s)
  117 + value = submission[field.id.to_s]
110 118 if value.kind_of?(String)
111 119 final_value = value
112 120 elsif value.kind_of?(Array)
... ...
plugins/custom_forms/lib/custom_forms_plugin/select_field.rb
1 1 class CustomFormsPlugin::SelectField < CustomFormsPlugin::Field
2 2 set_table_name :custom_forms_plugin_fields
3   - validates_presence_of :choices
  3 +
  4 + validates_length_of :select_field_type, :minimum => 1, :allow_nil => false
  5 + validates_inclusion_of :select_field_type, :in => %w(radio check_box select multiple_select)
4 6 end
... ...
plugins/custom_forms/lib/custom_forms_plugin/submission.rb
... ... @@ -2,11 +2,20 @@ class CustomFormsPlugin::Submission &lt; Noosfero::Plugin::ActiveRecord
2 2 belongs_to :form, :class_name => 'CustomFormsPlugin::Form'
3 3 belongs_to :profile
4 4  
5   - has_many :answers, :class_name => 'CustomFormsPlugin::Answer'
  5 + has_many :answers, :class_name => 'CustomFormsPlugin::Answer', :dependent => :destroy
6 6  
7 7 validates_presence_of :form
8 8 validates_presence_of :author_name, :author_email, :if => lambda {|submission| submission.profile.nil?}
9 9 validates_uniqueness_of :author_email, :scope => :form_id, :allow_nil => true
10 10 validates_format_of :author_email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => (lambda {|submission| !submission.author_email.blank?})
  11 +
  12 + def self.human_attribute_name(attrib)
  13 + if /\d+/ =~ attrib and (f = CustomFormsPlugin::Field.find_by_id(attrib.to_i))
  14 + f.name
  15 + else
  16 + attrib
  17 + end
  18 + end
  19 +
11 20 end
12 21  
... ...
plugins/custom_forms/public/field.js
1   -jQuery('.icon-edit').live('click', function() {
2   - elem = this;
3   - jQuery.fn.colorbox({
4   - overlayClose: false,
5   - escKey: false,
6   - inline: true,
7   - href: function(){
8   - id = jQuery(elem).attr('field_id');
9   - type = jQuery('#fields_'+id+'_type').val().split('_')[0];
10   - selector = '#edit-'+type+'-'+id
11   - return selector
  1 +var customFormsPlugin = {
  2 + removeFieldBox: function (button, confirmMsg) {
  3 + if (confirm(confirmMsg)) {
  4 + fb = jQuery(button).closest('.field-box');
  5 + jQuery('input.destroy-field', fb).val(1);
  6 + jQuery('> div', fb).slideUp({easing:'linear', complete:function(){fb.slideUp({easing:'linear', duration:250})}});
12 7 }
13   - });
14   - return false;
15   -});
16   -
17   -jQuery('.remove-field').live('click', function(){
18   - id = jQuery(this).attr('field_id');
19   - jQuery('#field-'+id).slideDown(function(){
20   - jQuery('#field-'+id).remove();
21   - });
22   - return false
23   -});
24   -
25   -jQuery('.remove-option').live('click', function(){
26   - field_id = jQuery(this).attr('field_id');
27   - option_id = jQuery(this).attr('option_id');
28   - selector = '#field-'+field_id+'-option-'+option_id
29   - jQuery(selector).slideDown(function(){
30   - jQuery(selector).remove();
31   - jQuery.colorbox.resize();
32   - });
33   - return false
34   -});
35   -
36   -function updateEditText(id){
37   - new_id = id+1
38   - jQuery('#edit-text-'+id).attr('id', 'edit-text-'+new_id);
39   - input = jQuery('#edit-text-'+new_id+' input');
40   - jQuery('#edit-text-'+new_id+' .colorbox-ok-button').attr('div_id', 'edit-text-'+new_id);
41   - input.attr('id', input.attr('id').replace(id,new_id));
42   - input.attr('name', input.attr('name').replace(id,new_id));
43   - label = jQuery('#edit-text-'+new_id+' label');
44   - label.attr('for', label.attr('for').replace(id,new_id));
45   -}
46   -
47   -function updateEditSelect(id){
48   - new_id = id+1
49   - jQuery('#edit-select-'+id).attr('id', 'edit-select-'+new_id);
50   - jQuery('#edit-select-'+new_id+' .colorbox-ok-button').attr('div_id', 'edit-select-'+new_id);
51   - jQuery('tr[id^=field-'+id+'-option').each(function(id, element){
52   - jQuery(element).attr('id', jQuery(element).attr('id').replace('field-'+id,'field-'+new_id));
53   - });
54   - jQuery('#edit-select-'+new_id+' label').each(function(index, element){
55   - label = jQuery(element);
56   - label.attr('for', label.attr('for').replace(id,new_id));
57   - });
58   - jQuery('#edit-select-'+new_id+' input').each(function(index, element){
59   - input = jQuery(element);
60   - input.attr('id', input.attr('id').replace(id,new_id));
61   - input.attr('name', input.attr('name').replace(id,new_id));
62   - });
63   - jQuery('#edit-select-'+new_id+' .remove-option').each(function(index, element){
64   - jQuery(element).attr('field_id',new_id);
65   - });
66   - jQuery('#edit-select-'+new_id+' .new-option').attr('field_id',new_id);
67   - jQuery('#edit-select-'+new_id+' #empty-option-'+id).attr('id','empty-option-'+new_id);
68   -}
69   -
70   -function updateEmptyField(id){
71   - id = parseInt(id);
72   - empty_field = jQuery('#empty-field');
73   - empty_field.attr('last_id', (id + 1).toString());
74   - jQuery('#empty-field input').each(function(index, element){
75   - new_id = jQuery(element).attr('id').replace(id,id+1);
76   - jQuery(element).attr('id', new_id);
77   - new_name = jQuery(element).attr('name').replace(id,id+1);
78   - jQuery(element).attr('name', new_name);
79   - });
80   - jQuery('#empty-field select').each(function(index, element){
81   - new_id = jQuery(element).attr('id').replace(id,id+1);
82   - jQuery(element).attr('id', new_id);
83   - new_name = jQuery(element).attr('name').replace(id,id+1);
84   - jQuery(element).attr('name', new_name);
85   - });
86   - jQuery('#empty-field a').each(function(index, element){
87   - jQuery(element).attr('field_id', id+1);
88   - });
89   - updateEditText(id);
90   - updateEditSelect(id);
91   -}
92   -
93   -function updateEmptyOption(field_id, option_id){
94   - field_id = parseInt(field_id);
95   - option_id = parseInt(option_id);
96   - new_option_id = option_id+1;
97   - empty_option = jQuery('#empty-option-'+field_id);
98   - empty_option.attr('option_id',new_option_id);
99   - jQuery('#empty-option-'+field_id+' .remove-option').attr('option_id', new_option_id);
  8 + },
  9 +
  10 + removeAlternative: function (button, confirmMsg) {
  11 + if (confirm(confirmMsg)) {
  12 + alt = jQuery(button).closest('tr.alternative');
  13 + jQuery('input.destroy-field', alt).val(1);
  14 + alt.fadeOut(500, function() {
  15 + customFormsPlugin.checkHeaderDisplay(jQuery(button).closest('table'));
  16 + });
  17 + }
  18 + },
100 19  
101   - name_id = ' #fields_'+field_id+'_choices_'+option_id+'_name';
102   - jQuery('#empty-option-'+field_id+name_id).attr('name', 'fields['+field_id+'][choices]['+new_option_id+'][name]');
103   - jQuery('#empty-option-'+field_id+name_id).attr('id', 'fields_'+field_id+'_choices_'+new_option_id+'_name');
  20 + addFields: function (button, association, content) {
  21 + var new_id = new Date().getTime();
  22 + var regexp = new RegExp("new_" + association, "g");
  23 + jQuery(content.replace(regexp, new_id)).insertBefore(jQuery(button).closest('.addition-buttons')).hide().slideDown();
104 24  
105   - value_id = ' #fields_'+field_id+'_choices_'+option_id+'_value';
106   - jQuery('#empty-option-'+field_id+value_id).attr('name', 'fields['+field_id+'][choices]['+new_option_id+'][value]');
107   - jQuery('#empty-option-'+field_id+value_id).attr('id', 'fields_'+field_id+'_choices_'+new_option_id+'_value');
  25 + if(association == 'alternatives') {
  26 + jQuery(button).closest('table').find('tr:first').show();
  27 + }
  28 + },
  29 +
  30 + checkHeaderDisplay: function(table) {
  31 + trs =jQuery('tr:visible', table);
  32 + if (trs.length <= 2) {
  33 + trs[0].style.display = 'none';
  34 + } else {
  35 + trs[0].style.display = 'table-row';
  36 + }
  37 + }
108 38 }
109   -
110   -jQuery('#new-field').live('click', function(){
111   - empty_field = jQuery('#empty-field');
112   - id = empty_field.attr('last_id');
113   - edit_text = jQuery('#edit-text-'+id);
114   - edit_select = jQuery('#edit-select-'+id);
115   - new_field = empty_field.clone();
116   - new_field.attr('id','field-'+id);
117   - new_field.insertBefore(empty_field).slideDown();
118   - edit_text.clone().insertAfter(edit_text);
119   - edit_select.clone().insertAfter(edit_select);
120   - updateEmptyField(id);
121   - return false
122   -});
123   -
124   -jQuery('.new-option').live('click', function(){
125   - field_id = jQuery(this).attr('field_id');
126   - empty_option = jQuery('#empty-option-'+field_id);
127   - option_id = empty_option.attr('option_id');
128   - new_option = empty_option.clone();
129   - new_option.attr('id','field-'+field_id+'-option-'+option_id);
130   - new_option.insertBefore(empty_option).slideDown();
131   - jQuery.colorbox.resize();
132   - updateEmptyOption(field_id, option_id);
133   - return false
134   -});
135   -
136   -jQuery('.colorbox-ok-button').live('click', function(){
137   - jQuery('#'+jQuery(this).attr('div_id')).hide();
138   - jQuery.colorbox.close();
139   - return false
140   -});
... ...
plugins/custom_forms/public/style.css
... ... @@ -31,3 +31,27 @@
31 31 #colorbox .edit-information {
32 32 display: block;
33 33 }
  34 +
  35 +.field-box {
  36 + margin: 10px 0;
  37 +}
  38 +
  39 +.field-box > div {
  40 + overflow: hide;
  41 +}
  42 +
  43 +.field-box .button {
  44 + margin-left: 15px;
  45 +}
  46 +
  47 +.field-box .addition-buttons .button {
  48 + margin: 0px;
  49 +}
  50 +
  51 +.field-select-type {
  52 + margin: 10px 0;
  53 +}
  54 +
  55 +.field-text-default {
  56 + margin-top: 10px;
  57 +}
... ...
plugins/custom_forms/test/functional/custom_forms_plugin_myprofile_controller_test.rb
... ... @@ -48,21 +48,22 @@ class CustomFormsPluginMyprofileControllerTest &lt; ActionController::TestCase
48 48 :access => 'logged',
49 49 :begining => begining,
50 50 :ending => ending,
51   - :description => 'Cool form'},
52   - :fields => {
53   - 1 => {
54   - :name => 'Name',
55   - :default_value => 'Jack',
56   - :type => 'text_field'
57   - },
58   - 2 => {
59   - :name => 'Color',
60   - :list => '1',
61   - :type => 'select_field',
62   - :choices => {
63   - 1 => {:name => 'Red', :value => 'red'},
64   - 2 => {:name => 'Blue', :value => 'blue'},
65   - 3 => {:name => 'Black', :value => 'black'}
  51 + :description => 'Cool form',
  52 + :fields_attributes => {
  53 + 1 => {
  54 + :name => 'Name',
  55 + :default_value => 'Jack',
  56 + :type => 'CustomFormsPlugin::TextField'
  57 + },
  58 + 2 => {
  59 + :name => 'Color',
  60 + :select_field_type => 'radio',
  61 + :type => 'CustomFormsPlugin::SelectField',
  62 + :alternatives_attributes => {
  63 + 1 => {:label => 'Red'},
  64 + 2 => {:label => 'Blue'},
  65 + 3 => {:label => 'Black'}
  66 + }
66 67 }
67 68 }
68 69 }
... ... @@ -83,10 +84,8 @@ class CustomFormsPluginMyprofileControllerTest &lt; ActionController::TestCase
83 84 assert f1.kind_of?(CustomFormsPlugin::TextField)
84 85  
85 86 assert_equal 'Color', f2.name
86   - assert_equal 'red', f2.choices['Red']
87   - assert_equal 'blue', f2.choices['Blue']
88   - assert_equal 'black', f2.choices['Black']
89   - assert f2.list
  87 + assert_equal f2.alternatives.map(&:label).sort, ['Red', 'Blue', 'Black'].sort
  88 + assert_equal f2.select_field_type, 'radio'
90 89 assert f2.kind_of?(CustomFormsPlugin::SelectField)
91 90 end
92 91  
... ... @@ -100,7 +99,7 @@ class CustomFormsPluginMyprofileControllerTest &lt; ActionController::TestCase
100 99 fields[i.to_s] = {
101 100 :name => i.to_s,
102 101 :default_value => '',
103   - :type => 'text_field'
  102 + :type => 'CustomFormsPlugin::TextField'
104 103 }
105 104 end
106 105 assert_difference CustomFormsPlugin::Form, :count, 1 do
... ... @@ -110,29 +109,35 @@ class CustomFormsPluginMyprofileControllerTest &lt; ActionController::TestCase
110 109 :access => 'logged',
111 110 :begining => begining,
112 111 :ending => ending,
113   - :description => 'Cool form'},
114   - :fields => fields
  112 + :description => 'Cool form',
  113 + :fields_attributes => fields
  114 + }
115 115 end
116 116 form = CustomFormsPlugin::Form.find_by_name('My Form')
117 117 assert_equal num_fields, form.fields.count
  118 + lst = -1
118 119 form.fields.find_each do |f|
119   - assert_equal f.position, f.name.to_i
  120 + assert f.name.to_i > lst
  121 + lst = f.name.to_i
120 122 end
121 123 end
122 124  
123 125 should 'edit a form' do
124 126 form = CustomFormsPlugin::Form.create!(:profile => profile, :name => 'Free Software')
125   - field = CustomFormsPlugin::TextField.create!(:form => form, :name => 'License')
126 127 format = '%Y-%m-%d %H:%M'
127 128 begining = Time.now.strftime(format)
128 129 ending = (Time.now + 1.day).strftime(format)
129 130  
130   - post :edit, :profile => profile.identifier, :id => form.id,
131   - :form => {:name => 'My Form', :access => 'logged', :begining => begining, :ending => ending, :description => 'Cool form'},
132   - :fields => {1 => {:real_id => field.id.to_s, :name => 'Source'}}
  131 + assert_equal form.fields.length, 0
  132 +
  133 + post :update, :profile => profile.identifier, :id => form.id,
  134 + :form => {:name => 'My Form', :access => 'logged', :begining => begining, :ending => ending, :description => 'Cool form',
  135 + :fields_attributes => {1 => {:name => 'Source'}}}
133 136  
134 137 form.reload
135   - field.reload
  138 + assert_equal form.fields.length, 1
  139 +
  140 + field = form.fields.last
136 141  
137 142 assert_equal 'logged', form.access
138 143 assert_equal begining, form.begining.strftime(format)
... ...
plugins/custom_forms/test/functional/custom_forms_plugin_profile_controller_test.rb
... ... @@ -23,7 +23,7 @@ class CustomFormsPluginProfileControllerTest &lt; ActionController::TestCase
23 23 field2 = CustomFormsPlugin::TextField.create(:name => 'License', :form => form)
24 24  
25 25 assert_difference CustomFormsPlugin::Submission, :count, 1 do
26   - post :show, :profile => profile.identifier, :id => form.id, :submission => {field1.name.to_slug => 'Noosfero', field2.name.to_slug => 'GPL'}
  26 + post :show, :profile => profile.identifier, :id => form.id, :submission => {field1.id.to_s => 'Noosfero', field2.id.to_s => 'GPL'}
27 27 end
28 28 assert !session[:notice].include?('not saved')
29 29 assert_redirected_to :action => 'show'
... ...
plugins/custom_forms/test/unit/custom_forms_plugin/answer_test.rb
... ... @@ -27,11 +27,11 @@ class CustomFormsPlugin::AnswerTest &lt; ActiveSupport::TestCase
27 27 field = CustomFormsPlugin::Field.create!(:name => 'License', :form => form, :mandatory => true)
28 28 answer = CustomFormsPlugin::Answer.new(:field => field)
29 29 answer.valid?
30   - assert answer.errors.invalid?(field.slug.to_sym)
  30 + assert answer.errors.invalid?(:value)
31 31  
32 32 answer.value = "GPL"
33 33 answer.valid?
34   - assert !answer.errors.invalid?(field.slug.to_sym)
  34 + assert !answer.errors.invalid?(:value)
35 35 end
36 36  
37 37 end
... ...
plugins/custom_forms/test/unit/custom_forms_plugin/field_test.rb
1 1 require File.dirname(__FILE__) + '/../../../../../test/test_helper'
2 2  
3 3 class CustomFormsPlugin::FieldTest < ActiveSupport::TestCase
4   - should 'validate presence of form' do
5   - field = CustomFormsPlugin::Field.new
6   - field.valid?
7   - assert field.errors.invalid?(:form)
8   - assert field.errors.invalid?(:name)
9   -
10   - form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => fast_create(Profile))
11   - field.form = form
12   - field.name = 'License'
13   - field.valid?
14   - assert !field.errors.invalid?(:form)
15   - assert !field.errors.invalid?(:name)
16   - end
17   -
18 4 should 'set slug before validation based on name' do
19 5 field = CustomFormsPlugin::Field.new(:name => 'Name')
20 6 field.valid?
21 7 assert_equal field.name.to_slug, field.slug
22 8 end
23 9  
24   - should 'validate uniqueness of slug scoped on the form' do
25   - form1 = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => fast_create(Profile))
26   - form2 = CustomFormsPlugin::Form.create!(:name => 'Open Source', :profile => fast_create(Profile))
27   - f1 = CustomFormsPlugin::Field.create!(:name => 'License', :form => form1)
28   - f2 = CustomFormsPlugin::Field.new(:name => 'License', :form => form1)
29   - f3 = CustomFormsPlugin::Field.new(:name => 'License', :form => form2)
30   -
31   - f2.valid?
32   - f3.valid?
33   -
34   - assert f2.errors.invalid?(:slug)
35   - assert !f3.errors.invalid?(:slug)
36   - end
37   -
38 10 should 'set mandatory field as false by default' do
39 11 field = CustomFormsPlugin::Field.new
40 12 assert !field.mandatory
... ... @@ -50,17 +22,6 @@ class CustomFormsPlugin::FieldTest &lt; ActiveSupport::TestCase
50 22 assert_includes field.answers, a2
51 23 end
52 24  
53   - should 'serialize choices into a hash' do
54   - form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => fast_create(Profile))
55   - field = CustomFormsPlugin::Field.create!(:name => 'License', :form => form)
56   - field.choices = {'First' => 1, 'Second' => 2, 'Third' => 3}
57   - field.save!
58   -
59   - assert_equal 1, field.choices['First']
60   - assert_equal 2, field.choices['Second']
61   - assert_equal 3, field.choices['Third']
62   - end
63   -
64 25 should 'not destroy form after removing a field' do
65 26 form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => fast_create(Profile))
66 27 license_field = CustomFormsPlugin::Field.create!(:name => 'License', :form => form)
... ... @@ -71,27 +32,5 @@ class CustomFormsPlugin::FieldTest &lt; ActiveSupport::TestCase
71 32 end
72 33 assert_equal form.fields, [license_field]
73 34 end
74   -
75   - should 'give positions by creation order' do
76   - form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => fast_create(Profile))
77   - field_0 = CustomFormsPlugin::Field.create!(:name => 'License', :form => form)
78   - field_1 = CustomFormsPlugin::Field.create!(:name => 'URL', :form => form)
79   - field_2 = CustomFormsPlugin::Field.create!(:name => 'Wiki', :form => form)
80   - assert_equal 0, field_0.position
81   - assert_equal 1, field_1.position
82   - assert_equal 2, field_2.position
83   - end
84   -
85   - should 'not crash when adding new fields on a form with fields without position' do
86   - form = CustomFormsPlugin::Form.create(:name => 'Free Software', :profile => fast_create(Profile))
87   - field_0 = CustomFormsPlugin::Field.create(:name => 'License', :form => form)
88   - field_0.position = nil
89   - field_0.save
90   -
91   - assert_nothing_raised do
92   - field_1 = CustomFormsPlugin::Field.create!(:name => 'URL', :form => form)
93   - end
94   - end
95   -
96 35 end
97 36  
... ...
plugins/custom_forms/test/unit/custom_forms_plugin/membership_survey_test.rb
... ... @@ -16,7 +16,7 @@ class CustomFormsPlugin::MembershipSurveyTest &lt; ActiveSupport::TestCase
16 16 person = fast_create(Person)
17 17 form = CustomFormsPlugin::Form.create!(:name => 'Simple Form', :profile => profile)
18 18 field = CustomFormsPlugin::Field.create!(:name => 'Name', :form => form)
19   - task = CustomFormsPlugin::MembershipSurvey.create!(:form_id => form.id, :submission => {'name' => 'Jack'}, :target => person, :requestor => profile)
  19 + task = CustomFormsPlugin::MembershipSurvey.create!(:form_id => form.id, :submission => {field.id.to_s => 'Jack'}, :target => person, :requestor => profile)
20 20  
21 21 assert_difference CustomFormsPlugin::Submission, :count, 1 do
22 22 task.finish
... ...
plugins/custom_forms/test/unit/custom_forms_plugin/select_field_test.rb
1 1 require File.dirname(__FILE__) + '/../../../../../test/test_helper'
2 2  
3 3 class CustomFormsPlugin::SelectFieldTest < ActiveSupport::TestCase
4   - should 'validate presence of choices, multiple and list' do
5   - select = CustomFormsPlugin::SelectField.new
6   - select.valid?
7   - assert select.errors.invalid?(:choices)
  4 + should 'validate type' do
  5 + select = CustomFormsPlugin::SelectField.new(:name => 'select_field001' )
8 6  
9   - select.choices = {'label' => 'value'}
10   - select.valid?
11   - assert !select.errors.invalid?(:choices)
  7 + select.update_attribute(:select_field_type, 'random')
  8 + assert select.invalid?
  9 +
  10 + select.update_attribute(:select_field_type, 'radio')
  11 + assert select.valid?
  12 + select.update_attribute(:select_field_type, 'check_box')
  13 + assert select.valid?
  14 + select.update_attribute(:select_field_type, 'select')
  15 + assert select.valid?
  16 + select.update_attribute(:select_field_type, 'multiple_select')
  17 + assert select.valid?
12 18 end
13 19 end
... ...
plugins/custom_forms/views/custom_forms_plugin_myprofile/_edit_select.html.erb
1   -<% elem_id = "edit-select-#{counter}" %>
2   -<div id=<%= elem_id %> class='edit-information'>
  1 +<div class='edit-information edit-select'>
3 2 <h2><%= _('Options') %></h2>
4 3 <table class='action-table' style='width: 420px'>
5 4 <tr>
6 5 <th style='width: 40%'><%= _('Name') %></th>
7 6 <th style='width: 40%'><%= _('Value') %></th>
8   - <th style='width: 20%'><%= _('Actions') %></th>
  7 + <th style='width: 20%'><%= _('Delete') %></th>
9 8 </tr>
10 9 <% option_counter = 1 %>
11 10 <% (field.choices || {}).each do |name, value| %>
... ...
plugins/custom_forms/views/custom_forms_plugin_myprofile/_edit_text.html.erb
... ... @@ -1,10 +0,0 @@
1   -<% elem_id = "edit-text-#{counter}" %>
2   -<div id=<%= elem_id %> class='edit-information'>
3   - <h2><%= _('Default value') %></h2>
4   - <%= labelled_form_field _('Default value'), text_field("fields[#{counter}]", :default_value, :value => field.default_value) %>
5   -
6   - <% button_bar do %>
7   - <%= button :ok, _('Ok'), '#', :class => 'colorbox-ok-button', :div_id => elem_id %>
8   - <% end %>
9   -</div>
10   -
plugins/custom_forms/views/custom_forms_plugin_myprofile/_field.html.erb
1   -<tr id=<%= "field-#{counter}" %>>
2   - <td style="text-align: left"><%= text_field "fields[#{counter}]", :name, :value => field.name, :size => 25 %></td>
3   - <td><%= type_to_label(field.type) %></td>
4   - <%= hidden_field "fields[#{counter}]", :type, :value => type_for_options(field.class) %>
5   - <td><%= check_box "fields[#{counter}]", :mandatory, :checked => field.mandatory %></td>
6   - <%= hidden_field "fields[#{counter}]", :real_id, :value => field.id %>
7   - <%= hidden_field "fields[#{counter}]", :form_id, :value => @form.id %>
8   - <td class='actions'>
9   - <%= button_without_text :edit, _('Edit'), '#', :field_id => counter %>
10   - <%= button_without_text :remove, _('Remove'), '#', :class => 'remove-field', :field_id => counter, :confirm => _('Are you sure you want to remove this field?') %>
11   - </td>
12   -</tr>
  1 +<fieldset class="field-box" <%='style="display:none"' if f.object._destroy %> >
  2 + <legend><%= type_to_label(f.object.type) %></legend>
  3 + <div>
  4 + <%= f.label :name, _('Name:') %>
  5 + <%= f.text_field :name, :size => 25 %>
  6 +
  7 + <%= f.hidden_field :type %>
  8 +
  9 + <%= f.check_box :mandatory %>
  10 + <%= f.label :mandatory, _('Mandatory') %>
  11 +
  12 + <%= f.hidden_field :_destroy, :class => 'destroy-field' %>
  13 + <%= button_to_function :delete, _('Remove field'), "customFormsPlugin.removeFieldBox(this, #{_('Are you sure you want to remove this field?').to_json})" %>
  14 + <%= yield %>
  15 +</div>
  16 +</fieldset>
... ...
plugins/custom_forms/views/custom_forms_plugin_myprofile/_form.html.erb
1 1 <% self.extend(CustomFormsPlugin::Helper) %>
2 2  
3   -<%= error_messages_for :form %>
4   -
5   -<% form_for :form, @form do |f| %>
6   - <%= required labelled_form_field _('Name'), f.text_field(:name) %>
7   - <%= labelled_form_field(_('Period'), (
8   - date_range_field('form[begining]', 'form[ending]', @form.begining, @form.ending,
9   - '%Y-%m-%d %H:%M',
10   - { :time => true, :change_month => true, :change_year => true,
11   - :date_format => 'yy-mm-dd', :time_format => 'hh:mm' },
  3 +<%= f.error_messages %>
  4 +<%= required labelled_form_field _('Name'), f.text_field(:name) %>
  5 +<%= labelled_form_field(_('Period'), (
  6 + date_range_field('form[begining]', 'form[ending]', @form.begining, @form.ending,
  7 + '%Y-%m-%d %H:%M',
  8 + { :time => true, :change_month => true, :change_year => true,
  9 + :date_format => 'yy-mm-dd', :time_format => 'hh:mm' },
12 10 { :size => 14 })
13   - )) %>
14   - <%= labelled_form_field _('Access'), f.select(:access, access_options(profile))%>
15   - <% if profile.organization? %>
16   - <%= labelled_form_field _('Triggered on membership'), f.check_box(:on_membership) %>
17   - <% end %>
18   - <%= labelled_form_field _('Description'), f.text_area(:description, :style => 'width: 100%') %>
  11 +)) %>
  12 +<%= labelled_form_field _('Access'), f.select(:access, access_options(profile))%>
  13 +<% if profile.organization? %>
  14 + <%= labelled_form_field _('Triggered on membership'), f.check_box(:on_membership) %>
  15 +<% end %>
  16 +<%= labelled_form_field _('Description'), f.text_area(:description, :style => 'width: 100%') %>
19 17  
20   - <h2><%= _('Fields') %></h2>
21   - <table class="action-table" id='fields-table'>
22   - <tr>
23   - <th style='width: 40%'><%= _('Name') %></th>
24   - <th style='width: 30%'><%= _('Type') %></th>
25   - <th style='width: 10%'><%= _('Mandatory') %></th>
26   - <th style='width: 20%'><%= _('Actions') %></th>
27   - </tr>
28   - <% counter = 1 %>
29   - <% @fields.each do |field| %>
30   - <%= render :partial => 'field', :locals => {:field => field, :counter => counter} %>
31   - <% counter += 1 %>
32   - <% end %>
33   - <%= render :partial => 'empty_field', :locals => {:field => @empty_field, :counter => counter} %>
34   - <tr class='new-item'>
35   - <td colspan='5'>
36   - <%= button(:add, _('Add a new field'), '#', :id => 'new-field')%>
37   - </td>
38   - </tr>
39   - </table>
  18 +<h2><%= _('Fields') %></h2>
40 19  
41   - <% counter = 1 %>
42   - <% @fields.each do |field| %>
43   - <%= render :partial => 'edit_text', :locals => {:field => field, :counter => counter} %>
44   - <%= render :partial => 'edit_select', :locals => {:field => field, :counter => counter} %>
45   - <% counter += 1 %>
46   - <% end %>
  20 +<% f.fields_for :fields do |builder| %>
  21 + <%= render partial_for_class(builder.object.class), :f => builder %>
  22 +<% end %>
47 23  
48   - <%= render :partial => 'edit_text', :locals => {:field => @empty_field, :counter => counter} %>
49   - <%= render :partial => 'edit_select', :locals => {:field => @empty_field, :counter => counter} %>
  24 +<div class="addition-buttons">
  25 + <%= button(:add, _('Add a new text field'), '#', :onclick => "customFormsPlugin.addFields(this, 'fields', #{html_for_field(f, :fields, CustomFormsPlugin::TextField).to_json}); return false")%>
  26 + <%= button(:add, _('Add a new select field'), '#', :onclick => "customFormsPlugin.addFields(this, 'fields', #{html_for_field(f, :fields, CustomFormsPlugin::SelectField).to_json}); return false")%>
  27 +</div>
50 28  
51   - <% button_bar do %>
52   - <%= submit_button :save, _('Save'), :cancel => {:action => 'index'}%>
53   - <% end %>
  29 +<% button_bar do %>
  30 + <%= submit_button :save, _('Save'), :cancel => {:action => 'index'}%>
54 31 <% end %>
55 32  
56 33 <%= javascript_include_tag '../plugins/custom_forms/field' %>
... ...
plugins/custom_forms/views/custom_forms_plugin_myprofile/_option.html.erb
... ... @@ -1,7 +0,0 @@
1   -<tr id=<%= "field-#{counter}-option-#{option_counter}" %> style="display: auto;">
2   - <td><%= text_field_tag("fields[#{counter}][choices][#{option_counter}][name]", name) %></td>
3   - <td><%= text_field_tag("fields[#{counter}][choices][#{option_counter}][value]", value) %></td>
4   - <td class='actions'>
5   - <%= button_without_text :remove, _('Remove'), '#', :class => 'remove-option', :field_id => counter, :option_id => option_counter, :confirm => _('Are you sure you want to remove this option?') %>
6   - </td>
7   -</tr>
plugins/custom_forms/views/custom_forms_plugin_myprofile/create.html.erb
... ... @@ -1,2 +0,0 @@
1   -<h1><%= _('New form') %></h1>
2   -<%= render :partial => 'form' %>
plugins/custom_forms/views/custom_forms_plugin_myprofile/custom_forms_plugin/_alternative.html.erb 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +<tr class="alternative">
  2 + <td> <%= f.text_field(:label) %> </td>
  3 +
  4 + <td> <%= f.check_box(:selected_by_default) %> </td>
  5 +
  6 + <td>
  7 + <%= f.hidden_field :_destroy, :class => 'destroy-field' %>
  8 + <%= button_to_function_without_text :remove, _('Remove alternative'), "customFormsPlugin.removeAlternative(this, #{_('Are you sure you want to remove this alternative?').to_json})", :class => 'remove-field', :title => _('Remove alternative') %>
  9 + </td>
  10 +</div>
... ...
plugins/custom_forms/views/custom_forms_plugin_myprofile/custom_forms_plugin/_field.html.erb 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +<%-# Small hack necessary for fields_for when validation fails on #new %>
  2 +<% case f.object.type
  3 + when 'CustomFormsPlugin::SelectField' %>
  4 + <%= render partial_for_class(CustomFormsPlugin::SelectField), :f => f %>
  5 +<% when 'CustomFormsPlugin::TextField' %>
  6 + <%= render partial_for_class(CustomFormsPlugin::TextField), :f => f %>
  7 +<% else %>
  8 + <% raise 'This field has no valid type' %>
  9 +<% end %>
... ...
plugins/custom_forms/views/custom_forms_plugin_myprofile/custom_forms_plugin/_select_field.html.erb 0 → 100644
... ... @@ -0,0 +1,31 @@
  1 +<% render :layout => 'field', :locals => { :f => f } do %>
  2 + <div class="field-select-type">
  3 + <%= _('Type:') %>
  4 + <%= f.radio_button(:select_field_type, 'radio') %>
  5 + <%= f.label(:select_field_type, _('Radio'), :value => 'radio') %>
  6 + <%= f.radio_button(:select_field_type, 'check_box') %>
  7 + <%= f.label(:select_field_type, _('Checkbox'), :value => 'check_box') %>
  8 + <%= f.radio_button(:select_field_type, 'select') %>
  9 + <%= f.label(:select_field_type, _('Drop down'), :value => 'select') %>
  10 + <%= f.radio_button(:select_field_type, 'multiple_select') %>
  11 + <%= f.label(:select_field_type, _('Multiple Select'), :value => 'multiple_select') %>
  12 + </div>
  13 +
  14 + <table>
  15 + <tr <%='style="display:none"' if f.object.alternatives.empty? %>>
  16 + <th><%= _('Alternative') %></th>
  17 + <th><%= _('Preselected') %></th>
  18 + <th><%= _('Remove') %></th>
  19 + </tr>
  20 + <% f.fields_for :alternatives do |builder| %>
  21 + <%= render partial_for_class(builder.object.class), :f => builder %>
  22 + <% end %>
  23 + <tr class="addition-buttons">
  24 + <td colspan="3">
  25 + <%= button(:add, _('Add a new alternative'), '#', :onclick => "customFormsPlugin.addFields(this, 'alternatives', #{html_for_field(f, :alternatives, CustomFormsPlugin::Alternative).to_json}); return false") %>
  26 + </td>
  27 + </tr>
  28 + </table>
  29 +
  30 +
  31 +<% end %>
... ...
plugins/custom_forms/views/custom_forms_plugin_myprofile/custom_forms_plugin/_text_field.html.erb 0 → 100644
... ... @@ -0,0 +1,6 @@
  1 +<% render :layout => 'field', :locals => { :f => f } do %>
  2 + <div class="field-text-default">
  3 + <%= f.label(:default_value, _('Default value:')) %>
  4 + <%= f.text_field(:default_value) %>
  5 + </div>
  6 +<% end %>
... ...
plugins/custom_forms/views/custom_forms_plugin_myprofile/edit.html.erb
1 1 <h1><%= _('Edit form') %></h1>
2   -<%= render :partial => 'form' %>
  2 +
  3 +<% form_for :form, @form, :url => { :action => 'update', :id => params[:id] } do |f| %>
  4 + <%= render :partial => 'form', :locals => {:f => f} %>
  5 +<% end %>
... ...
plugins/custom_forms/views/custom_forms_plugin_myprofile/index.html.erb
... ... @@ -22,7 +22,7 @@
22 22 <% end %>
23 23 <tr id="new-item">
24 24 <td colspan='5'>
25   - <%= button(:add, _('Add a new form'), :action => 'create')%>
  25 + <%= button(:add, _('Add a new form'), :action => 'new')%>
26 26 </td>
27 27 </tr>
28 28 </table>
... ...
plugins/custom_forms/views/custom_forms_plugin_myprofile/new.html.erb 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +<h1><%= _('New form') %></h1>
  2 +
  3 +<% form_for :form, @form, :url => { :action => 'create', :id => params[:id] } do |f| %>
  4 + <%= render :partial => 'form', :locals => {:f => f} %>
  5 +<% end %>
... ...
public/stylesheets/application.css
... ... @@ -2471,11 +2471,11 @@ div#activation_enterprise label, div#activation_enterprise input, div#activation
2471 2471 }
2472 2472 /*** REQUIRED FIELDS ***/
2473 2473  
2474   -.required-field label {
  2474 +.required-field label.formlabel {
2475 2475 font-weight: bold;
2476 2476 color: #c00;
2477 2477 }
2478   -.required-field label:after {
  2478 +.required-field label.formlabel:after {
2479 2479 content: ' (*)';
2480 2480 }
2481 2481 .login-box {
... ...