Commit c224f8a93b63bb7c02398390218daba4303a41d1
1 parent
103b7ebe
Exists in
master
and in
29 other branches
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 < 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 < 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
plugins/custom_forms/lib/custom_forms_plugin/answer.rb
... | ... | @@ -7,7 +7,7 @@ class CustomFormsPlugin::Answer < 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 < 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 < 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 < 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 < 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 < 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 < 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 < 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 < 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 < 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 < 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
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
plugins/custom_forms/views/custom_forms_plugin_myprofile/edit.html.erb
plugins/custom_forms/views/custom_forms_plugin_myprofile/index.html.erb
plugins/custom_forms/views/custom_forms_plugin_myprofile/new.html.erb
0 → 100644
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 { | ... | ... |