Commit 9e954d8c60e672519a5b4e93fec0520b6e0e3b79
Exists in
master
and in
29 other branches
Merge branch 'master' into custom-forms
Conflicts: plugins/custom_forms/test/functional/custom_forms_plugin_myprofile_controller_test.rb plugins/custom_forms/views/custom_forms_plugin_myprofile/_form.html.erb plugins/custom_forms/views/custom_forms_plugin_profile/show.html.erb po/pt/noosfero.po
Showing
49 changed files
with
1212 additions
and
480 deletions
Show diff stats
plugins/custom_forms/controllers/custom_forms_plugin_myprofile_controller.rb
1 | -class CustomFormsPluginMyprofileController < MyProfileController | 1 | +require 'csv' |
2 | 2 | ||
3 | +class CustomFormsPluginMyprofileController < MyProfileController | ||
3 | protect 'post_content', :profile | 4 | protect 'post_content', :profile |
5 | + | ||
4 | def index | 6 | def index |
5 | @forms = CustomFormsPlugin::Form.from(profile) | 7 | @forms = CustomFormsPlugin::Form.from(profile) |
6 | end | 8 | end |
7 | 9 | ||
10 | + def new | ||
11 | + @form = CustomFormsPlugin::Form.new | ||
12 | + | ||
13 | + respond_to do |format| | ||
14 | + format.html | ||
15 | + end | ||
16 | + end | ||
17 | + | ||
8 | def create | 18 | 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') | 19 | + params[:form][:profile_id] = profile.id |
20 | + @form = CustomFormsPlugin::Form.new(params[:form]) | ||
21 | + | ||
22 | + normalize_positions(@form) | ||
23 | + | ||
24 | + respond_to do |format| | ||
25 | + if @form.save | ||
26 | + flash[:notice] = _("Custom form #{@form.name} was successfully created.") | ||
27 | + format.html { redirect_to(:action=>'index') } | ||
28 | + else | ||
29 | + format.html { render :action => 'new' } | ||
24 | end | 30 | end |
25 | end | 31 | end |
26 | end | 32 | end |
27 | 33 | ||
28 | def edit | 34 | def edit |
29 | @form = CustomFormsPlugin::Form.find(params[:id]) | 35 | @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) | 36 | + end |
37 | + | ||
38 | + def update | ||
39 | + @form = CustomFormsPlugin::Form.find(params[:id]) | ||
40 | + @form.attributes = params[:form] | ||
41 | + | ||
42 | + normalize_positions(@form) | ||
43 | + | ||
44 | + respond_to do |format| | ||
45 | + if @form.save | ||
46 | + flash[:notice] = _("Custom form #{@form.name} was successfully updated.") | ||
47 | + format.html { redirect_to(:action=>'index') } | ||
48 | + else | ||
44 | session['notice'] = _('Form could not be updated') | 49 | session['notice'] = _('Form could not be updated') |
50 | + format.html { render :action => 'edit' } | ||
45 | end | 51 | end |
46 | end | 52 | end |
47 | end | 53 | end |
@@ -60,6 +66,26 @@ class CustomFormsPluginMyprofileController < MyProfileController | @@ -60,6 +66,26 @@ class CustomFormsPluginMyprofileController < MyProfileController | ||
60 | def submissions | 66 | def submissions |
61 | @form = CustomFormsPlugin::Form.find(params[:id]) | 67 | @form = CustomFormsPlugin::Form.find(params[:id]) |
62 | @submissions = @form.submissions | 68 | @submissions = @form.submissions |
69 | + | ||
70 | + @sort_by = params[:sort_by] | ||
71 | + @submissions = @submissions.sort_by { |s| s.profile.present? ? s.profile.name : s.author_name } if @sort_by == 'author' | ||
72 | + | ||
73 | + respond_to do |format| | ||
74 | + format.html | ||
75 | + format.csv do | ||
76 | + # CSV contains form fields, timestamp, user name and user email | ||
77 | + columns = @form.fields.count + 3 | ||
78 | + csv_content = CSV.generate_line(['Timestamp', 'Name', 'Email'] + @form.fields.map(&:name)) + "\n" | ||
79 | + @submissions.each do |s| | ||
80 | + fields = [s.updated_at.strftime('%Y/%m/%d %T %Z'), s.profile.present? ? s.profile.name : s.author_name, s.profile.present? ? s.profile.email : s.author_email] | ||
81 | + @form.fields.each do |f| | ||
82 | + fields << s.answers.select{|a| a.field == f}.map{|answer| answer.to_s} | ||
83 | + end | ||
84 | + CSV.generate_row(fields, columns, csv_content) | ||
85 | + end | ||
86 | + send_data csv_content, :type => 'text/csv', :filename => "#{@form.name}.csv" | ||
87 | + end | ||
88 | + end | ||
63 | end | 89 | end |
64 | 90 | ||
65 | def show_submission | 91 | def show_submission |
@@ -67,82 +93,29 @@ class CustomFormsPluginMyprofileController < MyProfileController | @@ -67,82 +93,29 @@ class CustomFormsPluginMyprofileController < MyProfileController | ||
67 | @form = @submission.form | 93 | @form = @submission.form |
68 | end | 94 | end |
69 | 95 | ||
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 | 96 | + def pending |
97 | + @form = CustomFormsPlugin::Form.find(params[:id]) | ||
98 | + @pendings = CustomFormsPlugin::AdmissionSurvey.from(@form.profile).pending.select {|task| task.form_id == @form.id}.map {|a| {:profile => a.target, :time => a.created_at} } | ||
82 | 99 | ||
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 | 100 | + @sort_by = params[:sort_by] |
101 | + @pendings = @pendings.sort_by { |s| s[:profile].name } if @sort_by == 'user' | ||
94 | end | 102 | end |
95 | 103 | ||
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 | 104 | + private |
103 | 105 | ||
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 | 106 | + def normalize_positions(form) |
107 | + counter = 0 | ||
108 | + form.fields.sort_by{ |f| f.position.to_i }.each do |field| | ||
109 | + field.position = counter | ||
110 | + counter += 1 | ||
122 | end | 111 | 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) | 112 | + form.fields.each do |field| |
113 | + counter = 0 | ||
114 | + field.alternatives.sort_by{ |alt| alt.position.to_i }.each do |alt| | ||
115 | + alt.position = counter | ||
116 | + counter += 1 | ||
132 | end | 117 | end |
133 | end | 118 | end |
134 | - fields | ||
135 | end | 119 | end |
136 | 120 | ||
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 | end | 121 | end |
plugins/custom_forms/controllers/custom_forms_plugin_profile_controller.rb
1 | class CustomFormsPluginProfileController < ProfileController | 1 | class CustomFormsPluginProfileController < ProfileController |
2 | - | ||
3 | before_filter :has_access, :show | 2 | before_filter :has_access, :show |
4 | 3 | ||
5 | def show | 4 | def show |
5 | + extend(CustomFormsPlugin::Helper) | ||
6 | + | ||
6 | @form = CustomFormsPlugin::Form.find(params[:id]) | 7 | @form = CustomFormsPlugin::Form.find(params[:id]) |
7 | if user | 8 | if user |
8 | @submission ||= CustomFormsPlugin::Submission.find_by_form_id_and_profile_id(@form.id,user.id) | 9 | @submission ||= CustomFormsPlugin::Submission.find_by_form_id_and_profile_id(@form.id,user.id) |
@@ -10,22 +11,34 @@ class CustomFormsPluginProfileController < ProfileController | @@ -10,22 +11,34 @@ class CustomFormsPluginProfileController < ProfileController | ||
10 | else | 11 | else |
11 | @submission ||= CustomFormsPlugin::Submission.new(:form_id => @form.id) | 12 | @submission ||= CustomFormsPlugin::Submission.new(:form_id => @form.id) |
12 | end | 13 | end |
14 | + | ||
15 | + # build the answers | ||
16 | + @submission.answers.push(*(answers = build_answers(params[:submission], @form))) if params[:submission] | ||
17 | + | ||
13 | if request.post? | 18 | if request.post? |
14 | begin | 19 | begin |
15 | - extend(CustomFormsPlugin::Helper) | ||
16 | - answers = build_answers(params[:submission], @form) | 20 | + raise 'Submission already present!' if user.present? && CustomFormsPlugin::Submission.find_by_form_id_and_profile_id(@form.id,user.id) |
21 | + raise 'Form expired!' if @form.expired? | ||
22 | + | ||
23 | + # @submission.answers for some reason has the same answer twice | ||
17 | failed_answers = answers.select {|answer| !answer.valid? } | 24 | failed_answers = answers.select {|answer| !answer.valid? } |
25 | + | ||
18 | if failed_answers.empty? | 26 | if failed_answers.empty? |
19 | - if !user | ||
20 | - @submission.author_name = params[:author_name] | ||
21 | - @submission.author_email = params[:author_email] | 27 | + # Save the submission |
28 | + ActiveRecord::Base.transaction do | ||
29 | + if !user | ||
30 | + @submission.author_name = params[:author_name] | ||
31 | + @submission.author_email = params[:author_email] | ||
32 | + end | ||
33 | + @submission.save! | ||
22 | end | 34 | end |
23 | - @submission.save! | ||
24 | - answers.map {|answer| answer.submission = @submission; answer.save!} | ||
25 | else | 35 | else |
26 | - @submission.valid? | 36 | + @submission.errors.clear |
27 | failed_answers.each do |answer| | 37 | failed_answers.each do |answer| |
28 | - @submission.errors.add(answer.field.name.to_sym, answer.errors[answer.field.slug.to_sym]) | 38 | + answer.valid? |
39 | + answer.errors.each do |attribute, msg| | ||
40 | + @submission.errors.add(answer.field.id.to_s.to_sym, msg) | ||
41 | + end | ||
29 | end | 42 | end |
30 | raise 'Submission failed: answers not valid' | 43 | raise 'Submission failed: answers not valid' |
31 | end | 44 | end |
plugins/custom_forms/db/migrate/20130823134700_create_custom_forms_plugin_alternatives.rb
0 → 100644
@@ -0,0 +1,12 @@ | @@ -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,32 @@ | @@ -0,0 +1,32 @@ | ||
1 | +class AddSelectFieldTypeToCustomFormsPluginFields < ActiveRecord::Migration | ||
2 | + def self.up | ||
3 | + change_table :custom_forms_plugin_fields do |t| | ||
4 | + t.string :select_field_type | ||
5 | + end | ||
6 | + | ||
7 | + update("UPDATE custom_forms_plugin_fields SET select_field_type='radio' WHERE list IS FALSE AND multiple IS FALSE") | ||
8 | + update("UPDATE custom_forms_plugin_fields SET select_field_type='check_box' WHERE list IS FALSE AND multiple IS TRUE") | ||
9 | + update("UPDATE custom_forms_plugin_fields SET select_field_type='select' WHERE list IS TRUE AND multiple IS FALSE") | ||
10 | + update("UPDATE custom_forms_plugin_fields SET select_field_type='multiple_select' WHERE list IS TRUE AND multiple IS TRUE") | ||
11 | + | ||
12 | + change_table :custom_forms_plugin_fields do |t| | ||
13 | + t.remove :multiple, :list | ||
14 | + end | ||
15 | + end | ||
16 | + | ||
17 | + def self.down | ||
18 | + change_table :custom_forms_plugin_fields do |t| | ||
19 | + t.boolean :multiple | ||
20 | + t.boolean :list | ||
21 | + end | ||
22 | + | ||
23 | + update("UPDATE custom_forms_plugin_fields SET list=TRUE, multiple=FALSE WHERE select_field_type='radio'") | ||
24 | + update("UPDATE custom_forms_plugin_fields SET list=FALSE, multiople=TRUE WHERE select_field_type='check_box'") | ||
25 | + update("UPDATE custom_forms_plugin_fields SET list=TRUE, multiple=FALSE WHERE select_field_type='select'") | ||
26 | + update("UPDATE custom_forms_plugin_fields SET list=TRUE, multiple=TRUE WHERE select_field_type='multiple_select'") | ||
27 | + | ||
28 | + change_table :custom_forms_plugin_fields do |t| | ||
29 | + t.remove :select_fields_type | ||
30 | + end | ||
31 | + end | ||
32 | +end |
plugins/custom_forms/db/migrate/20130823151900_associate_fields_to_alternatives.rb
0 → 100644
@@ -0,0 +1,37 @@ | @@ -0,0 +1,37 @@ | ||
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 | + CustomFormsPlugin::Answer.find_each do |answer| | ||
18 | + labels = [] | ||
19 | + answer.value.split(',').each do |value| | ||
20 | + labels << answer.field.choices.invert[value] | ||
21 | + end | ||
22 | + labels.compact! | ||
23 | + if labels.present? | ||
24 | + answer.value = answer.field.alternatives.where('label IN (?)', labels).map(&:id).join(',') | ||
25 | + answer.save! | ||
26 | + end | ||
27 | + end | ||
28 | + | ||
29 | + change_table :custom_forms_plugin_fields do |t| | ||
30 | + t.remove :choices | ||
31 | + end | ||
32 | + end | ||
33 | + | ||
34 | + def self.down | ||
35 | + raise ActiveRecord::IrreversibleMigration | ||
36 | + end | ||
37 | +end |
plugins/custom_forms/db/migrate/20131002155900_update_select_field_type_in_custom_forms_plugin_fields.rb
0 → 100644
@@ -0,0 +1,9 @@ | @@ -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 @@ | @@ -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/db/migrate/20131107050913_add_position_to_field_and_alternatives.rb
0 → 100644
@@ -0,0 +1,17 @@ | @@ -0,0 +1,17 @@ | ||
1 | +class AddPositionToFieldAndAlternatives < ActiveRecord::Migration | ||
2 | + def self.up | ||
3 | + change_table :custom_forms_plugin_alternatives do |t| | ||
4 | + t.integer :position, :default => 0 | ||
5 | + end | ||
6 | + | ||
7 | + update("UPDATE custom_forms_plugin_fields SET position=id") | ||
8 | + update("UPDATE custom_forms_plugin_alternatives SET position=id") | ||
9 | + | ||
10 | + end | ||
11 | + | ||
12 | + def self.down | ||
13 | + change_table :custom_forms_plugin_alternatives do |t| | ||
14 | + t.remove :position | ||
15 | + end | ||
16 | + end | ||
17 | +end |
plugins/custom_forms/db/migrate/20131107125327_add_admission_to_form.rb
0 → 100644
@@ -0,0 +1,18 @@ | @@ -0,0 +1,18 @@ | ||
1 | +class AddAdmissionToForm < ActiveRecord::Migration | ||
2 | + def self.up | ||
3 | + change_table :custom_forms_plugin_forms do |t| | ||
4 | + t.boolean :for_admission, :default => false | ||
5 | + end | ||
6 | + | ||
7 | + CustomFormsPlugin::Form.find_each do |f| | ||
8 | + f.for_admission = false | ||
9 | + f.save! | ||
10 | + end | ||
11 | + end | ||
12 | + | ||
13 | + def self.down | ||
14 | + change_table :custom_forms_plugin_forms do |t| | ||
15 | + t.remove :for_admission | ||
16 | + end | ||
17 | + end | ||
18 | +end |
plugins/custom_forms/lib/custom_forms_plugin/admission_survey.rb
0 → 100644
@@ -0,0 +1,24 @@ | @@ -0,0 +1,24 @@ | ||
1 | +class CustomFormsPlugin::AdmissionSurvey < CustomFormsPlugin::MembershipSurvey | ||
2 | + | ||
3 | + def perform | ||
4 | + super | ||
5 | + requestor.add_member(target) | ||
6 | + end | ||
7 | + | ||
8 | + def title | ||
9 | + _("Admission survey") | ||
10 | + end | ||
11 | + | ||
12 | + def information | ||
13 | + {:message => _('%{requestor} wants you to fill in some information before joining.')} | ||
14 | + end | ||
15 | + | ||
16 | + def target_notification_message | ||
17 | + _('Before joining %{requestor}, the administrators of this organization | ||
18 | + wants you to fill in some further information.') % {:requestor => requestor.name} | ||
19 | + end | ||
20 | + | ||
21 | + def target_notification_description | ||
22 | + _('%{requestor} wants you to fill in some further information.') % {:requestor => requestor.name} | ||
23 | + end | ||
24 | +end |
plugins/custom_forms/lib/custom_forms_plugin/alternative.rb
0 → 100644
plugins/custom_forms/lib/custom_forms_plugin/answer.rb
@@ -7,8 +7,14 @@ class CustomFormsPlugin::Answer < Noosfero::Plugin::ActiveRecord | @@ -7,8 +7,14 @@ class CustomFormsPlugin::Answer < Noosfero::Plugin::ActiveRecord | ||
7 | 7 | ||
8 | def value_mandatory | 8 | def value_mandatory |
9 | if field.mandatory && value.blank? | 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 | end | 11 | end |
12 | end | 12 | end |
13 | + | ||
14 | + def to_s | ||
15 | + return value if value.blank? || field.alternatives.blank? | ||
16 | + selected = value.split(',') | ||
17 | + field.alternatives.select {|alt| selected.include? alt.id.to_s }.map(&:label).join(';') | ||
18 | + end | ||
13 | end | 19 | end |
14 | 20 |
plugins/custom_forms/lib/custom_forms_plugin/field.rb
1 | class CustomFormsPlugin::Field < ActiveRecord::Base | 1 | class CustomFormsPlugin::Field < ActiveRecord::Base |
2 | set_table_name :custom_forms_plugin_fields | 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 | belongs_to :form, :class_name => 'CustomFormsPlugin::Form' | 6 | belongs_to :form, :class_name => 'CustomFormsPlugin::Form' |
8 | has_many :answers, :class_name => 'CustomFormsPlugin::Answer' | 7 | has_many :answers, :class_name => 'CustomFormsPlugin::Answer' |
9 | 8 | ||
10 | - serialize :choices, Hash | 9 | + has_many :alternatives, :order => 'position', :class_name => 'CustomFormsPlugin::Alternative' |
10 | + accepts_nested_attributes_for :alternatives, :allow_destroy => true | ||
11 | + #FIXME This validation should be in the subclass, but since we are using Single Table | ||
12 | + # Inheritance we are instantiating a Field object with the type as a param. So the validation | ||
13 | + # had to go here or rails would skip it. | ||
14 | + validates_length_of :alternatives, :minimum => 1, :message => 'can\'t be empty', :if => Proc.new { |f| f.type == 'CustomFormsPlugin::SelectField' } | ||
11 | 15 | ||
12 | before_validation do |field| | 16 | before_validation do |field| |
13 | field.slug = field.name.to_slug if field.name.present? | 17 | field.slug = field.name.to_slug if field.name.present? |
14 | end | 18 | end |
15 | 19 | ||
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 | 20 | + private |
21 | 21 | ||
22 | - def position | ||
23 | - self[:position] || 0 | 22 | + def attributes_protected_by_default |
23 | + super - [self.class.inheritance_column] | ||
24 | end | 24 | end |
25 | + | ||
25 | end | 26 | end |
26 | 27 |
plugins/custom_forms/lib/custom_forms_plugin/form.rb
1 | class CustomFormsPlugin::Form < Noosfero::Plugin::ActiveRecord | 1 | class CustomFormsPlugin::Form < Noosfero::Plugin::ActiveRecord |
2 | belongs_to :profile | 2 | belongs_to :profile |
3 | 3 | ||
4 | - has_many :fields, :class_name => 'CustomFormsPlugin::Field', :dependent => :destroy, :order => 'position' | 4 | + has_many :fields, :order => 'position', :class_name => 'CustomFormsPlugin::Field', :dependent => :destroy |
5 | + accepts_nested_attributes_for :fields, :allow_destroy => true | ||
6 | + | ||
5 | has_many :submissions, :class_name => 'CustomFormsPlugin::Submission' | 7 | has_many :submissions, :class_name => 'CustomFormsPlugin::Submission' |
6 | 8 | ||
7 | serialize :access | 9 | serialize :access |
8 | 10 | ||
9 | validates_presence_of :profile, :name | 11 | validates_presence_of :profile, :name |
10 | validates_uniqueness_of :slug, :scope => :profile_id | 12 | validates_uniqueness_of :slug, :scope => :profile_id |
13 | + validate :period_range, :if => Proc.new { |f| f.begining.present? && f.ending.present? } | ||
11 | validate :access_format | 14 | validate :access_format |
12 | 15 | ||
13 | before_validation do |form| | 16 | before_validation do |form| |
@@ -15,10 +18,16 @@ class CustomFormsPlugin::Form < Noosfero::Plugin::ActiveRecord | @@ -15,10 +18,16 @@ class CustomFormsPlugin::Form < Noosfero::Plugin::ActiveRecord | ||
15 | form.access = nil if form.access.blank? | 18 | form.access = nil if form.access.blank? |
16 | end | 19 | end |
17 | 20 | ||
21 | + after_destroy do |form| | ||
22 | + tasks = CustomFormsPlugin::MembershipSurvey.from(form.profile).opened.select { |t| t.form_id == form.id } | ||
23 | + tasks.each {|task| task.cancel} | ||
24 | + end | ||
25 | + | ||
18 | named_scope :from, lambda {|profile| {:conditions => {:profile_id => profile.id}}} | 26 | named_scope :from, lambda {|profile| {:conditions => {:profile_id => profile.id}}} |
19 | - named_scope :on_memberships, {:conditions => {:on_membership => true}} | 27 | + named_scope :on_memberships, {:conditions => {:on_membership => true, :for_admission => false}} |
28 | + named_scope :for_admissions, {:conditions => {:for_admission => true}} | ||
20 | =begin | 29 | =begin |
21 | - named_scope :accessible_to lambda do |profile| | 30 | + named_scope :accessible_to lambda do |profile| |
22 | #TODO should verify is profile is associated with the form owner | 31 | #TODO should verify is profile is associated with the form owner |
23 | profile_associated = ??? | 32 | profile_associated = ??? |
24 | {:conditions => [" | 33 | {:conditions => [" |
@@ -34,6 +43,10 @@ class CustomFormsPlugin::Form < Noosfero::Plugin::ActiveRecord | @@ -34,6 +43,10 @@ class CustomFormsPlugin::Form < Noosfero::Plugin::ActiveRecord | ||
34 | (begining.present? && Time.now < begining) || (ending.present? && Time.now > ending) | 43 | (begining.present? && Time.now < begining) || (ending.present? && Time.now > ending) |
35 | end | 44 | end |
36 | 45 | ||
46 | + def will_open? | ||
47 | + begining.present? && Time.now < begining | ||
48 | + end | ||
49 | + | ||
37 | def accessible_to(target) | 50 | def accessible_to(target) |
38 | return true if access.nil? || target == profile | 51 | return true if access.nil? || target == profile |
39 | return false if target.nil? | 52 | return false if target.nil? |
@@ -58,7 +71,7 @@ class CustomFormsPlugin::Form < Noosfero::Plugin::ActiveRecord | @@ -58,7 +71,7 @@ class CustomFormsPlugin::Form < Noosfero::Plugin::ActiveRecord | ||
58 | elsif access.kind_of?(Array) | 71 | elsif access.kind_of?(Array) |
59 | access.each do |value| | 72 | access.each do |value| |
60 | if !value.kind_of?(Integer) || !Profile.exists?(value) | 73 | if !value.kind_of?(Integer) || !Profile.exists?(value) |
61 | - errors.add(:access, _('There is no profile with the provided id.')) | 74 | + errors.add(:access, _('There is no profile with the provided id.')) |
62 | break | 75 | break |
63 | end | 76 | end |
64 | end | 77 | end |
@@ -67,4 +80,8 @@ class CustomFormsPlugin::Form < Noosfero::Plugin::ActiveRecord | @@ -67,4 +80,8 @@ class CustomFormsPlugin::Form < Noosfero::Plugin::ActiveRecord | ||
67 | end | 80 | end |
68 | end | 81 | end |
69 | end | 82 | end |
83 | + | ||
84 | + def period_range | ||
85 | + errors.add(:base, _('The time range selected is invalid.')) if ending < begining | ||
86 | + end | ||
70 | end | 87 | end |
plugins/custom_forms/lib/custom_forms_plugin/helper.rb
1 | module CustomFormsPlugin::Helper | 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 | def access_text(form) | 9 | def access_text(form) |
3 | return _('Public') if form.access.nil? | 10 | return _('Public') if form.access.nil? |
4 | return _('Logged users') if form.access == 'logged' | 11 | return _('Logged users') if form.access == 'logged' |
5 | if form.access == 'associated' | 12 | if form.access == 'associated' |
6 | - return _('Members') if form.profile.organization? | 13 | + return _('Members') if form.profile.organization? |
7 | return _('Friends') if form.profile.person? | 14 | return _('Friends') if form.profile.person? |
8 | end | 15 | end |
9 | return _('Custom') | 16 | return _('Custom') |
@@ -48,8 +55,8 @@ module CustomFormsPlugin::Helper | @@ -48,8 +55,8 @@ module CustomFormsPlugin::Helper | ||
48 | 55 | ||
49 | def type_to_label(type) | 56 | def type_to_label(type) |
50 | map = { | 57 | map = { |
51 | - 'text_field' => _('Text'), | ||
52 | - 'select_field' => _('Select') | 58 | + 'text_field' => _('Text field'), |
59 | + 'select_field' => _('Select field') | ||
53 | } | 60 | } |
54 | map[type_for_options(type)] | 61 | map[type_for_options(type)] |
55 | end | 62 | end |
@@ -61,52 +68,61 @@ module CustomFormsPlugin::Helper | @@ -61,52 +68,61 @@ module CustomFormsPlugin::Helper | ||
61 | def display_custom_field(field, submission, form) | 68 | def display_custom_field(field, submission, form) |
62 | answer = submission.answers.select{|answer| answer.field == field}.first | 69 | answer = submission.answers.select{|answer| answer.field == field}.first |
63 | field_tag = send("display_#{type_for_options(field.class)}",field, answer, form) | 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 | required(labelled_form_field(field.name, field_tag)) | 72 | required(labelled_form_field(field.name, field_tag)) |
66 | - else | 73 | + else |
67 | labelled_form_field(field.name, field_tag) | 74 | labelled_form_field(field.name, field_tag) |
68 | end | 75 | end |
69 | end | 76 | end |
70 | 77 | ||
78 | + def display_disabled?(field, answer) | ||
79 | + (answer.present? && answer.id.present?) || field.form.expired? | ||
80 | + end | ||
81 | + | ||
71 | def display_text_field(field, answer, form) | 82 | def display_text_field(field, answer, form) |
72 | value = answer.present? ? answer.value : field.default_value | 83 | value = answer.present? ? answer.value : field.default_value |
73 | - text_field(form, field.name.to_slug, :value => value, :disabled => answer.present?) | 84 | + text_field(form, "#{field.id}", :value => value, :disabled => display_disabled?(field, answer)) |
85 | + end | ||
86 | + | ||
87 | + def default_selected(field, answer) | ||
88 | + answer.present? ? answer.value.split(',') : field.alternatives.select {|a| a.selected_by_default}.map{|a| a.id.to_s} | ||
74 | end | 89 | end |
75 | 90 | ||
76 | def display_select_field(field, answer, form) | 91 | 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? | 92 | + case field.select_field_type |
93 | + when 'select' | ||
94 | + selected = default_selected(field, answer) | ||
95 | + select_tag form.to_s + "[#{field.id}]", options_for_select([['','']] + field.alternatives.map {|a| [a.label, a.id.to_s]}, selected), :disabled => display_disabled?(field, answer) | ||
96 | + when 'multiple_select' | ||
97 | + selected = default_selected(field, answer) | ||
98 | + select_tag form.to_s + "[#{field.id}]", options_for_select(field.alternatives.map{|a| [a.label, a.id.to_s]}, selected), :multiple => true, :title => _('Hold down Ctrl to select options'), :size => field.alternatives.size, :disabled => display_disabled?(field, answer) | ||
99 | + when 'check_box' | ||
100 | + field.alternatives.map do |alternative| | ||
101 | + default = answer.present? ? answer.value.split(',').include?(alternative.id.to_s) : alternative.selected_by_default | ||
102 | + labelled_check_box alternative.label, form.to_s + "[#{field.id}][#{alternative.id}]", '1', default, :disabled => display_disabled?(field, answer) | ||
84 | end.join("\n") | 103 | 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? | 104 | + when 'radio' |
105 | + field.alternatives.map do |alternative| | ||
106 | + default = answer.present? ? answer.value == alternative.id.to_s : alternative.selected_by_default | ||
107 | + labelled_radio_button alternative.label, form.to_s + "[#{field.id}]", alternative.id, default, :disabled => display_disabled?(field, answer) | ||
92 | end.join("\n") | 108 | end.join("\n") |
93 | end | 109 | end |
94 | end | 110 | end |
95 | 111 | ||
96 | def radio_button?(field) | 112 | def radio_button?(field) |
97 | - type_for_options(field.class) == 'select_field' && !field.list && !field.multiple | 113 | + type_for_options(field.class) == 'select_field' && field.select_field_type == 'radio' |
98 | end | 114 | end |
99 | 115 | ||
100 | def check_box?(field) | 116 | def check_box?(field) |
101 | - type_for_options(field.class) == 'select_field' && !field.list && field.multiple | 117 | + type_for_options(field.class) == 'select_field' && field.select_field_type == 'check_box' |
102 | end | 118 | end |
103 | 119 | ||
104 | def build_answers(submission, form) | 120 | def build_answers(submission, form) |
105 | answers = [] | 121 | answers = [] |
106 | form.fields.each do |field| | 122 | form.fields.each do |field| |
107 | final_value = '' | 123 | final_value = '' |
108 | - if submission.has_key?(field.slug) | ||
109 | - value = submission[field.slug] | 124 | + if submission.has_key?(field.id.to_s) |
125 | + value = submission[field.id.to_s] | ||
110 | if value.kind_of?(String) | 126 | if value.kind_of?(String) |
111 | final_value = value | 127 | final_value = value |
112 | elsif value.kind_of?(Array) | 128 | elsif value.kind_of?(Array) |
plugins/custom_forms/lib/custom_forms_plugin/membership_survey.rb
@@ -5,11 +5,29 @@ class CustomFormsPlugin::MembershipSurvey < Task | @@ -5,11 +5,29 @@ class CustomFormsPlugin::MembershipSurvey < Task | ||
5 | 5 | ||
6 | include CustomFormsPlugin::Helper | 6 | include CustomFormsPlugin::Helper |
7 | 7 | ||
8 | + named_scope :from, lambda {|profile| {:conditions => {:requestor_id => profile.id}}} | ||
9 | + | ||
8 | def perform | 10 | def perform |
9 | form = CustomFormsPlugin::Form.find(form_id) | 11 | form = CustomFormsPlugin::Form.find(form_id) |
12 | + raise 'Form expired' if form.expired? | ||
13 | + | ||
10 | answers = build_answers(submission, form) | 14 | answers = build_answers(submission, form) |
11 | s = CustomFormsPlugin::Submission.create!(:form => form, :profile => target) | 15 | s = CustomFormsPlugin::Submission.create!(:form => form, :profile => target) |
12 | - answers.map {|answer| answer.submission = s; answer.save!} | 16 | + s.answers.push(*answers) |
17 | + | ||
18 | + failed_answers = answers.select {|answer| !answer.valid? } | ||
19 | + if failed_answers.empty? | ||
20 | + s.save! | ||
21 | + else | ||
22 | + s.errors.clear | ||
23 | + answers.each do |answer| | ||
24 | + answer.valid? | ||
25 | + answer.errors.each do |attribute, msg| | ||
26 | + s.errors.add(answer.field.id.to_s.to_sym, msg) | ||
27 | + end | ||
28 | + end | ||
29 | + raise ActiveRecord::RecordInvalid, s | ||
30 | + end | ||
13 | end | 31 | end |
14 | 32 | ||
15 | def title | 33 | def title |
plugins/custom_forms/lib/custom_forms_plugin/select_field.rb
1 | class CustomFormsPlugin::SelectField < CustomFormsPlugin::Field | 1 | class CustomFormsPlugin::SelectField < CustomFormsPlugin::Field |
2 | set_table_name :custom_forms_plugin_fields | 2 | set_table_name :custom_forms_plugin_fields |
3 | - validates_presence_of :choices | 3 | + validates_inclusion_of :select_field_type, :in => %w(radio check_box select multiple_select) |
4 | + validates_length_of :alternatives, :minimum => 1, :message => 'can\'t be empty' | ||
4 | end | 5 | end |
plugins/custom_forms/lib/custom_forms_plugin/submission.rb
@@ -2,11 +2,20 @@ class CustomFormsPlugin::Submission < Noosfero::Plugin::ActiveRecord | @@ -2,11 +2,20 @@ class CustomFormsPlugin::Submission < Noosfero::Plugin::ActiveRecord | ||
2 | belongs_to :form, :class_name => 'CustomFormsPlugin::Form' | 2 | belongs_to :form, :class_name => 'CustomFormsPlugin::Form' |
3 | belongs_to :profile | 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 | validates_presence_of :form | 7 | validates_presence_of :form |
8 | validates_presence_of :author_name, :author_email, :if => lambda {|submission| submission.profile.nil?} | 8 | validates_presence_of :author_name, :author_email, :if => lambda {|submission| submission.profile.nil?} |
9 | validates_uniqueness_of :author_email, :scope => :form_id, :allow_nil => true | 9 | validates_uniqueness_of :author_email, :scope => :form_id, :allow_nil => true |
10 | validates_format_of :author_email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => (lambda {|submission| !submission.author_email.blank?}) | 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 | end | 20 | end |
12 | 21 |
plugins/custom_forms/lib/ext/role_assignment_trigger.rb
@@ -13,7 +13,26 @@ module RoleAssignmentTrigger | @@ -13,7 +13,26 @@ module RoleAssignmentTrigger | ||
13 | end | 13 | end |
14 | end | 14 | end |
15 | end | 15 | end |
16 | - | 16 | + |
17 | + before_validation_on_create do |ra| | ||
18 | + proceed_creation = true | ||
19 | + if ra.resource.kind_of?(Profile) | ||
20 | + profile = ra.resource | ||
21 | + person = ra.accessor | ||
22 | + ok = !profile.nil? && !person.nil? && profile.environment.present? | ||
23 | + if ok && profile.environment.plugin_enabled?(CustomFormsPlugin) && !person.is_member_of?(profile) | ||
24 | + CustomFormsPlugin::Form.from(profile).for_admissions.each do |form| | ||
25 | + admission_task_pending = person.tasks.pending.select {|task| task.kind_of?(CustomFormsPlugin::AdmissionSurvey) && task.form_id == form.id }.present? | ||
26 | + admission_task_finished = person.tasks.finished.select {|task| task.kind_of?(CustomFormsPlugin::AdmissionSurvey) && task.form_id == form.id }.present? | ||
27 | + | ||
28 | + CustomFormsPlugin::AdmissionSurvey.create!(:requestor => profile, :target => person, :form_id => form.id) unless admission_task_finished || admission_task_pending | ||
29 | + proceed_creation = false unless admission_task_finished | ||
30 | + end | ||
31 | + end | ||
32 | + end | ||
33 | + proceed_creation | ||
34 | + end | ||
35 | + | ||
17 | after_destroy do |ra| | 36 | after_destroy do |ra| |
18 | if ra.resource.kind_of?(Profile) | 37 | if ra.resource.kind_of?(Profile) |
19 | profile = ra.resource | 38 | profile = ra.resource |
@@ -24,6 +43,10 @@ module RoleAssignmentTrigger | @@ -24,6 +43,10 @@ module RoleAssignmentTrigger | ||
24 | task = person.tasks.pending.select {|task| task.kind_of?(CustomFormsPlugin::MembershipSurvey) && task.form_id == form.id}.first | 43 | task = person.tasks.pending.select {|task| task.kind_of?(CustomFormsPlugin::MembershipSurvey) && task.form_id == form.id}.first |
25 | task.cancel if task | 44 | task.cancel if task |
26 | end | 45 | end |
46 | + CustomFormsPlugin::Form.from(profile).for_admissions.each do |form| | ||
47 | + task = person.tasks.pending.select {|task| task.kind_of?(CustomFormsPlugin::MembershipSurvey) && task.form_id == form.id}.first | ||
48 | + task.cancel if task | ||
49 | + end | ||
27 | end | 50 | end |
28 | end | 51 | end |
29 | end | 52 | end |
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 | ||
12 | - } | 1 | +var fixHelperSortable = function(e, tr) { |
2 | + tr.children().each(function() { | ||
3 | + jQuery(this).width(jQuery(this).width()); | ||
13 | }); | 4 | }); |
14 | - return false; | ||
15 | -}); | 5 | + return tr; |
6 | +}; | ||
16 | 7 | ||
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 | -}); | 8 | +var updatePosition = function(e, ui) { |
9 | + var tag = ui.item[0].tagName.toLowerCase(); | ||
10 | + var count = ui.item.prevAll(tag).eq(0).find('input').filter(function() {return /_position/.test(this.id); }).val(); | ||
11 | + count = count ? ++count : 0; | ||
24 | 12 | ||
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 | -}); | 13 | + ui.item.find('input').filter(function() {return /_position/.test(this.id); }).eq(0).val(count); |
35 | 14 | ||
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)); | 15 | + for (i = 0; i < ui.item.nextAll(tag).length; i++) { |
16 | + count++; | ||
17 | + ui.item.nextAll(tag).eq(i).find('input').filter(function() {return /_position/.test(this.id); }).val(count); | ||
18 | + } | ||
45 | } | 19 | } |
46 | 20 | ||
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 | -} | 21 | +jQuery('tbody.field-list').sortable({ |
22 | + helper: fixHelperSortable, | ||
23 | + update: updatePosition | ||
24 | +}); | ||
69 | 25 | ||
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 | -} | 26 | +jQuery("ul.field-list").sortable({ |
27 | + placeholder: 'ui-state-highlight', | ||
28 | + axis: 'y', | ||
29 | + opacity: 0.8, | ||
30 | + cursor: 'move', | ||
31 | + tolerance: 'pointer', | ||
32 | + forcePlaceholderSize: true, | ||
33 | + update: updatePosition | ||
34 | +}); | ||
92 | 35 | ||
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); | 36 | +jQuery("ul.field-list li").disableSelection(); |
100 | 37 | ||
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'); | 38 | +var customFormsPlugin = { |
39 | + removeFieldBox: function (button, confirmMsg) { | ||
40 | + if (confirm(confirmMsg)) { | ||
41 | + fb = jQuery(button).closest('.field-box'); | ||
42 | + jQuery('input.destroy-field', fb).val(1); | ||
43 | + jQuery('> div', fb).slideUp({easing:'linear', complete:function(){fb.slideUp({easing:'linear', duration:250})}}); | ||
44 | + } | ||
45 | + }, | ||
104 | 46 | ||
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'); | ||
108 | -} | 47 | + removeAlternative: function (button, confirmMsg) { |
48 | + if (confirm(confirmMsg)) { | ||
49 | + alt = jQuery(button).closest('tr.alternative'); | ||
50 | + jQuery('input.destroy-field', alt).val(1); | ||
51 | + alt.fadeOut(500, function() { | ||
52 | + customFormsPlugin.checkHeaderDisplay(jQuery(button).closest('table')); | ||
53 | + }); | ||
54 | + } | ||
55 | + }, | ||
109 | 56 | ||
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 | -}); | 57 | + addFields: function (button, association, content) { |
58 | + var new_id = new Date().getTime(); | ||
59 | + var regexp = new RegExp("new_" + association, "g"); | ||
60 | + content = content.replace(regexp, new_id); | ||
123 | 61 | ||
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 | -}); | 62 | + if(association == 'alternatives') { |
63 | + jQuery(content).appendTo(jQuery(button).closest('tfoot').next('tbody.field-list')).hide().slideDown(); | ||
64 | + jQuery(button).closest('table').find('tr:first').show(); | ||
65 | + jQuery(button).closest('tfoot').next('tbody.field-list').sortable({ helper: fixHelperSortable, update: updatePosition}); | ||
66 | + } else { | ||
67 | + jQuery('<li>').append(jQuery(content)).appendTo(jQuery(button).parent().prev('ul.field-list')).hide().slideDown(); | ||
68 | + } | ||
135 | 69 | ||
136 | -jQuery('.colorbox-ok-button').live('click', function(){ | ||
137 | - jQuery('#'+jQuery(this).attr('div_id')).hide(); | ||
138 | - jQuery.colorbox.close(); | ||
139 | - return false | ||
140 | -}); | 70 | + jQuery('input').filter(function () { return new RegExp(new_id + "_position", "g").test(this.id); }).val(new_id); |
71 | + }, | ||
72 | + | ||
73 | + checkHeaderDisplay: function(table) { | ||
74 | + trs =jQuery('tr:visible', table); | ||
75 | + if (trs.length <= 2) { | ||
76 | + trs[0].style.display = 'none'; | ||
77 | + } else { | ||
78 | + trs[0].style.display = 'table-row'; | ||
79 | + } | ||
80 | + } | ||
81 | +} |
plugins/custom_forms/public/style.css
@@ -4,7 +4,7 @@ | @@ -4,7 +4,7 @@ | ||
4 | } | 4 | } |
5 | 5 | ||
6 | .action-table { | 6 | .action-table { |
7 | - width: 100%; | 7 | + width: 100%; |
8 | overflow: hidden; | 8 | overflow: hidden; |
9 | } | 9 | } |
10 | 10 | ||
@@ -13,12 +13,9 @@ | @@ -13,12 +13,9 @@ | ||
13 | text-align: center; | 13 | text-align: center; |
14 | } | 14 | } |
15 | 15 | ||
16 | -.action-table td{ | ||
17 | - cursor: move; | ||
18 | -} | ||
19 | - | ||
20 | .action-table .actions{ | 16 | .action-table .actions{ |
21 | white-space: nowrap; | 17 | white-space: nowrap; |
18 | + text-align: left; | ||
22 | } | 19 | } |
23 | 20 | ||
24 | .action-table .new-item{ | 21 | .action-table .new-item{ |
@@ -31,3 +28,62 @@ | @@ -31,3 +28,62 @@ | ||
31 | #colorbox .edit-information { | 28 | #colorbox .edit-information { |
32 | display: block; | 29 | display: block; |
33 | } | 30 | } |
31 | + | ||
32 | +.field-box { | ||
33 | + margin: 10px 0; | ||
34 | +} | ||
35 | + | ||
36 | +.field-box > div { | ||
37 | + overflow: hide; | ||
38 | +} | ||
39 | + | ||
40 | +.field-box .button { | ||
41 | + margin-left: 15px; | ||
42 | +} | ||
43 | + | ||
44 | +.field-box .addition-buttons .button { | ||
45 | + margin: 0px; | ||
46 | +} | ||
47 | + | ||
48 | +.field-box .required-field label{ | ||
49 | + font-weight: bold; | ||
50 | + color: #c00; | ||
51 | +} | ||
52 | +.field-box .required-field label:after { | ||
53 | + content: ' (*)'; | ||
54 | +} | ||
55 | + | ||
56 | +.field-select-type { | ||
57 | + margin: 10px 0; | ||
58 | +} | ||
59 | + | ||
60 | +.field-text-default { | ||
61 | + margin-top: 10px; | ||
62 | +} | ||
63 | + | ||
64 | +.field-list { | ||
65 | + list-style-type: none; | ||
66 | + margin: 0px; | ||
67 | + padding: 0px; | ||
68 | + cursor: move; | ||
69 | +} | ||
70 | + | ||
71 | +.field-list label, .field-list legend { | ||
72 | + cursor: move; | ||
73 | +} | ||
74 | + | ||
75 | +ul.field-list > li > fieldset:hover { | ||
76 | + border: 2px dotted #BBB; | ||
77 | +} | ||
78 | + | ||
79 | +tr.addition-buttons { | ||
80 | + cursor: auto; | ||
81 | +} | ||
82 | + | ||
83 | +#ui-datepicker-div { | ||
84 | + border: 1px solid #CCC; | ||
85 | +} | ||
86 | +.ui-slider-horizontal { | ||
87 | + border: 1px solid #BBB; | ||
88 | + border-radius: 4px; | ||
89 | +} |
plugins/custom_forms/test/functional/custom_forms_plugin_myprofile_controller_test.rb
@@ -48,21 +48,22 @@ class CustomFormsPluginMyprofileControllerTest < ActionController::TestCase | @@ -48,21 +48,22 @@ class CustomFormsPluginMyprofileControllerTest < ActionController::TestCase | ||
48 | :access => 'logged', | 48 | :access => 'logged', |
49 | :begining => begining, | 49 | :begining => begining, |
50 | :ending => ending, | 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 | } |
@@ -75,32 +76,30 @@ class CustomFormsPluginMyprofileControllerTest < ActionController::TestCase | @@ -75,32 +76,30 @@ class CustomFormsPluginMyprofileControllerTest < ActionController::TestCase | ||
75 | assert_equal 'Cool form', form.description | 76 | assert_equal 'Cool form', form.description |
76 | assert_equal 2, form.fields.count | 77 | assert_equal 2, form.fields.count |
77 | 78 | ||
78 | - f1 = form.fields.first | ||
79 | - f2 = form.fields.last | 79 | + f1 = form.fields[0] |
80 | + f2 = form.fields[1] | ||
80 | 81 | ||
81 | assert_equal 'Name', f1.name | 82 | assert_equal 'Name', f1.name |
82 | assert_equal 'Jack', f1.default_value | 83 | assert_equal 'Jack', f1.default_value |
83 | assert f1.kind_of?(CustomFormsPlugin::TextField) | 84 | assert f1.kind_of?(CustomFormsPlugin::TextField) |
84 | 85 | ||
85 | assert_equal 'Color', f2.name | 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 | assert f2.kind_of?(CustomFormsPlugin::SelectField) | 89 | assert f2.kind_of?(CustomFormsPlugin::SelectField) |
91 | end | 90 | end |
92 | 91 | ||
93 | - should 'create fields in the order they are sent' do | 92 | + should 'create fields in the order they are sent when no position defined' do |
94 | format = '%Y-%m-%d %H:%M' | 93 | format = '%Y-%m-%d %H:%M' |
95 | num_fields = 10 | 94 | num_fields = 10 |
96 | begining = Time.now.strftime(format) | 95 | begining = Time.now.strftime(format) |
97 | ending = (Time.now + 1.day).strftime(format) | 96 | ending = (Time.now + 1.day).strftime(format) |
98 | fields = {} | 97 | fields = {} |
99 | num_fields.times do |i| | 98 | num_fields.times do |i| |
100 | - fields[i.to_s] = { | ||
101 | - :name => i.to_s, | 99 | + fields[i] = { |
100 | + :name => (10-i).to_s, | ||
102 | :default_value => '', | 101 | :default_value => '', |
103 | - :type => 'text_field' | 102 | + :type => 'CustomFormsPlugin::TextField' |
104 | } | 103 | } |
105 | end | 104 | end |
106 | assert_difference CustomFormsPlugin::Form, :count, 1 do | 105 | assert_difference CustomFormsPlugin::Form, :count, 1 do |
@@ -110,29 +109,69 @@ class CustomFormsPluginMyprofileControllerTest < ActionController::TestCase | @@ -110,29 +109,69 @@ class CustomFormsPluginMyprofileControllerTest < ActionController::TestCase | ||
110 | :access => 'logged', | 109 | :access => 'logged', |
111 | :begining => begining, | 110 | :begining => begining, |
112 | :ending => ending, | 111 | :ending => ending, |
113 | - :description => 'Cool form'}, | ||
114 | - :fields => fields | 112 | + :description => 'Cool form', |
113 | + :fields_attributes => fields | ||
114 | + } | ||
115 | end | 115 | end |
116 | form = CustomFormsPlugin::Form.find_by_name('My Form') | 116 | form = CustomFormsPlugin::Form.find_by_name('My Form') |
117 | assert_equal num_fields, form.fields.count | 117 | assert_equal num_fields, form.fields.count |
118 | - form.fields.find_each do |f| | ||
119 | - assert_equal f.position, f.name.to_i | 118 | + lst = 10 |
119 | + form.fields.each do |f| | ||
120 | + assert f.name.to_i == lst | ||
121 | + lst = lst - 1 | ||
120 | end | 122 | end |
121 | end | 123 | end |
122 | 124 | ||
125 | + should 'create fields in any position size' do | ||
126 | + format = '%Y-%m-%d %H:%M' | ||
127 | + begining = Time.now.strftime(format) | ||
128 | + ending = (Time.now + 1.day).strftime(format) | ||
129 | + fields = {} | ||
130 | + fields['0'] = { | ||
131 | + :name => '0', | ||
132 | + :default_value => '', | ||
133 | + :type => 'CustomFormsPlugin::TextField', | ||
134 | + :position => '999999999999' | ||
135 | + } | ||
136 | + fields['1'] = { | ||
137 | + :name => '1', | ||
138 | + :default_value => '', | ||
139 | + :type => 'CustomFormsPlugin::TextField', | ||
140 | + :position => '1' | ||
141 | + } | ||
142 | + assert_difference CustomFormsPlugin::Form, :count, 1 do | ||
143 | + post :create, :profile => profile.identifier, | ||
144 | + :form => { | ||
145 | + :name => 'My Form', | ||
146 | + :access => 'logged', | ||
147 | + :begining => begining, | ||
148 | + :ending => ending, | ||
149 | + :description => 'Cool form', | ||
150 | + :fields_attributes => fields | ||
151 | + } | ||
152 | + end | ||
153 | + form = CustomFormsPlugin::Form.find_by_name('My Form') | ||
154 | + assert_equal 2, form.fields.count | ||
155 | + assert form.fields.first.name == "1" | ||
156 | + assert form.fields.last.name == "0" | ||
157 | + end | ||
158 | + | ||
123 | should 'edit a form' do | 159 | should 'edit a form' do |
124 | form = CustomFormsPlugin::Form.create!(:profile => profile, :name => 'Free Software') | 160 | form = CustomFormsPlugin::Form.create!(:profile => profile, :name => 'Free Software') |
125 | - field = CustomFormsPlugin::TextField.create!(:form => form, :name => 'License') | ||
126 | format = '%Y-%m-%d %H:%M' | 161 | format = '%Y-%m-%d %H:%M' |
127 | begining = Time.now.strftime(format) | 162 | begining = Time.now.strftime(format) |
128 | ending = (Time.now + 1.day).strftime(format) | 163 | ending = (Time.now + 1.day).strftime(format) |
129 | 164 | ||
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'}} | 165 | + assert_equal form.fields.length, 0 |
166 | + | ||
167 | + post :update, :profile => profile.identifier, :id => form.id, | ||
168 | + :form => {:name => 'My Form', :access => 'logged', :begining => begining, :ending => ending, :description => 'Cool form', | ||
169 | + :fields_attributes => {1 => {:name => 'Source'}}} | ||
133 | 170 | ||
134 | form.reload | 171 | form.reload |
135 | - field.reload | 172 | + assert_equal form.fields.length, 1 |
173 | + | ||
174 | + field = form.fields.last | ||
136 | 175 | ||
137 | assert_equal 'logged', form.access | 176 | assert_equal 'logged', form.access |
138 | assert_equal begining, form.begining.strftime(format) | 177 | assert_equal begining, form.begining.strftime(format) |
@@ -149,5 +188,50 @@ class CustomFormsPluginMyprofileControllerTest < ActionController::TestCase | @@ -149,5 +188,50 @@ class CustomFormsPluginMyprofileControllerTest < ActionController::TestCase | ||
149 | assert_tag :tag => 'textarea', :attributes => { :id => 'form_description', :class => 'mceEditor' } | 188 | assert_tag :tag => 'textarea', :attributes => { :id => 'form_description', :class => 'mceEditor' } |
150 | end | 189 | end |
151 | 190 | ||
152 | -end | 191 | + should 'export submissions as csv' do |
192 | + form = CustomFormsPlugin::Form.create!(:profile => profile, :name => 'Free Software') | ||
193 | + field = CustomFormsPlugin::TextField.create!(:name => "Title") | ||
194 | + form.fields << field | ||
153 | 195 | ||
196 | + answer = CustomFormsPlugin::Answer.create!(:value => 'example', :field => field) | ||
197 | + | ||
198 | + sub1 = CustomFormsPlugin::Submission.create!(:author_name => "john", :author_email => 'john@example.com', :form => form) | ||
199 | + sub1.answers << answer | ||
200 | + | ||
201 | + bob = create_user('bob').person | ||
202 | + sub2 = CustomFormsPlugin::Submission.create!(:profile => bob, :form => form) | ||
203 | + | ||
204 | + get :submissions, :profile => profile.identifier, :id => form.id, :format => 'csv' | ||
205 | + assert_equal @response.content_type, 'text/csv' | ||
206 | + assert_equal @response.body.split("\n")[0], 'Timestamp,Name,Email,Title' | ||
207 | + assert_equal @response.body.split("\n")[1], "#{sub1.updated_at.strftime('%Y/%m/%d %T %Z')},john,john@example.com,example" | ||
208 | + assert_equal @response.body.split("\n")[2], "#{sub2.updated_at.strftime('%Y/%m/%d %T %Z')},bob,#{bob.email},\"\"" | ||
209 | + end | ||
210 | + | ||
211 | + should 'order submissions by name or time' do | ||
212 | + form = CustomFormsPlugin::Form.create!(:profile => profile, :name => 'Free Software') | ||
213 | + field = CustomFormsPlugin::TextField.create!(:name => "Title") | ||
214 | + form.fields << field | ||
215 | + sub1 = CustomFormsPlugin::Submission.create!(:author_name => "john", :author_email => 'john@example.com', :form => form) | ||
216 | + bob = create_user('bob').person | ||
217 | + sub2 = CustomFormsPlugin::Submission.create!(:profile => bob, :form => form) | ||
218 | + | ||
219 | + get :submissions, :profile => profile.identifier, :id => form.id, :sort_by => 'time' | ||
220 | + assert_not_nil assigns(:sort_by) | ||
221 | + assert_select 'table.action-table', /Author\W*Time\W*john[\W\dh]*bob[\W\dh]*/ | ||
222 | + | ||
223 | + get :submissions, :profile => profile.identifier, :id => form.id, :sort_by => 'author' | ||
224 | + assert_not_nil assigns(:sort_by) | ||
225 | + assert_select 'table.action-table', /Author\W*Time\W*bob[\W\dh]*john[\W\dh]*/ | ||
226 | + end | ||
227 | + | ||
228 | + should 'list pending submissions for a form' do | ||
229 | + person = fast_create(Person) | ||
230 | + form = CustomFormsPlugin::Form.create!(:profile => profile, :name => 'Free Software', :for_admission => true) | ||
231 | + task = CustomFormsPlugin::AdmissionSurvey.create!(:form_id => form.id, :target => person, :requestor => profile) | ||
232 | + | ||
233 | + get :pending, :profile => profile.identifier, :id => form.id | ||
234 | + | ||
235 | + assert_tag :td, :content => person.name | ||
236 | + end | ||
237 | +end |
plugins/custom_forms/test/functional/custom_forms_plugin_profile_controller_test.rb
@@ -23,9 +23,35 @@ class CustomFormsPluginProfileControllerTest < ActionController::TestCase | @@ -23,9 +23,35 @@ class CustomFormsPluginProfileControllerTest < ActionController::TestCase | ||
23 | field2 = CustomFormsPlugin::TextField.create(:name => 'License', :form => form) | 23 | field2 = CustomFormsPlugin::TextField.create(:name => 'License', :form => form) |
24 | 24 | ||
25 | assert_difference CustomFormsPlugin::Submission, :count, 1 do | 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 | end | 27 | end |
28 | assert !session[:notice].include?('not saved') | 28 | assert !session[:notice].include?('not saved') |
29 | assert_redirected_to :action => 'show' | 29 | assert_redirected_to :action => 'show' |
30 | end | 30 | end |
31 | + | ||
32 | + should 'disable fields if form expired' do | ||
33 | + form = CustomFormsPlugin::Form.create!(:profile => profile, :name => 'Free Software', :begining => Time.now + 1.day) | ||
34 | + form.fields << CustomFormsPlugin::TextField.create(:name => 'Field Name', :form => form, :default_value => "First Field") | ||
35 | + | ||
36 | + get :show, :profile => profile.identifier, :id => form.id | ||
37 | + | ||
38 | + assert_tag :tag => 'input', :attributes => {:disabled => 'disabled'} | ||
39 | + end | ||
40 | + | ||
41 | + should 'show expired message' do | ||
42 | + form = CustomFormsPlugin::Form.create!(:profile => profile, :name => 'Free Software', :begining => Time.now + 1.day) | ||
43 | + form.fields << CustomFormsPlugin::TextField.create(:name => 'Field Name', :form => form, :default_value => "First Field") | ||
44 | + | ||
45 | + get :show, :profile => profile.identifier, :id => form.id | ||
46 | + | ||
47 | + assert_tag :tag => 'h2', :content => 'Sorry, you can\'t fill this form yet' | ||
48 | + | ||
49 | + form.begining = Time.now - 2.days | ||
50 | + form.ending = Time.now - 1.days | ||
51 | + form.save | ||
52 | + | ||
53 | + get :show, :profile => profile.identifier, :id => form.id | ||
54 | + | ||
55 | + assert_tag :tag => 'h2', :content => 'Sorry, you can\'t fill this form anymore' | ||
56 | + end | ||
31 | end | 57 | end |
plugins/custom_forms/test/unit/custom_forms_plugin/admission_survey_test.rb
0 → 100644
@@ -0,0 +1,14 @@ | @@ -0,0 +1,14 @@ | ||
1 | +require File.dirname(__FILE__) + '/../../../../../test/test_helper' | ||
2 | + | ||
3 | +class CustomFormsPlugin::AdmissionSurveyTest < ActiveSupport::TestCase | ||
4 | + should 'add member to community on perform' do | ||
5 | + profile = fast_create(Community) | ||
6 | + person = fast_create(Person) | ||
7 | + form = CustomFormsPlugin::Form.create!(:name => 'Simple Form', :profile => profile) | ||
8 | + task = CustomFormsPlugin::AdmissionSurvey.create!(:form_id => form.id, :target => person, :requestor => profile) | ||
9 | + | ||
10 | + assert_difference person.memberships, :count, 1 do | ||
11 | + task.finish | ||
12 | + end | ||
13 | + end | ||
14 | +end |
plugins/custom_forms/test/unit/custom_forms_plugin/answer_test.rb
@@ -27,11 +27,24 @@ class CustomFormsPlugin::AnswerTest < ActiveSupport::TestCase | @@ -27,11 +27,24 @@ class CustomFormsPlugin::AnswerTest < ActiveSupport::TestCase | ||
27 | field = CustomFormsPlugin::Field.create!(:name => 'License', :form => form, :mandatory => true) | 27 | field = CustomFormsPlugin::Field.create!(:name => 'License', :form => form, :mandatory => true) |
28 | answer = CustomFormsPlugin::Answer.new(:field => field) | 28 | answer = CustomFormsPlugin::Answer.new(:field => field) |
29 | answer.valid? | 29 | answer.valid? |
30 | - assert answer.errors.invalid?(field.slug.to_sym) | 30 | + assert answer.errors.invalid?(:value) |
31 | 31 | ||
32 | answer.value = "GPL" | 32 | answer.value = "GPL" |
33 | answer.valid? | 33 | answer.valid? |
34 | - assert !answer.errors.invalid?(field.slug.to_sym) | 34 | + assert !answer.errors.invalid?(:value) |
35 | + end | ||
36 | + | ||
37 | + should 'make string representation show answers' do | ||
38 | + form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => fast_create(Profile)) | ||
39 | + field = CustomFormsPlugin::Field.create!(:name => 'ProjectName', :form => form) | ||
40 | + answer = CustomFormsPlugin::Answer.new(:field => field, :value => 'MyProject') | ||
41 | + | ||
42 | + field_select = CustomFormsPlugin::Field.create!(:name => 'License', :form => form) | ||
43 | + alt = CustomFormsPlugin::Alternative.create!(:id => 1, :field => field_select, :label => 'GPL') | ||
44 | + answer2 = CustomFormsPlugin::Answer.new(:field => field_select, :value => alt.id.to_s) | ||
45 | + | ||
46 | + assert_equal 'MyProject', answer.to_s | ||
47 | + assert_equal 'GPL', answer2.to_s | ||
35 | end | 48 | end |
36 | 49 | ||
37 | end | 50 | end |
plugins/custom_forms/test/unit/custom_forms_plugin/field_test.rb
1 | require File.dirname(__FILE__) + '/../../../../../test/test_helper' | 1 | require File.dirname(__FILE__) + '/../../../../../test/test_helper' |
2 | 2 | ||
3 | class CustomFormsPlugin::FieldTest < ActiveSupport::TestCase | 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 | should 'set slug before validation based on name' do | 4 | should 'set slug before validation based on name' do |
19 | field = CustomFormsPlugin::Field.new(:name => 'Name') | 5 | field = CustomFormsPlugin::Field.new(:name => 'Name') |
20 | field.valid? | 6 | field.valid? |
21 | assert_equal field.name.to_slug, field.slug | 7 | assert_equal field.name.to_slug, field.slug |
22 | end | 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 | should 'set mandatory field as false by default' do | 10 | should 'set mandatory field as false by default' do |
39 | field = CustomFormsPlugin::Field.new | 11 | field = CustomFormsPlugin::Field.new |
40 | assert !field.mandatory | 12 | assert !field.mandatory |
@@ -50,17 +22,6 @@ class CustomFormsPlugin::FieldTest < ActiveSupport::TestCase | @@ -50,17 +22,6 @@ class CustomFormsPlugin::FieldTest < ActiveSupport::TestCase | ||
50 | assert_includes field.answers, a2 | 22 | assert_includes field.answers, a2 |
51 | end | 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 | should 'not destroy form after removing a field' do | 25 | should 'not destroy form after removing a field' do |
65 | form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => fast_create(Profile)) | 26 | form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => fast_create(Profile)) |
66 | license_field = CustomFormsPlugin::Field.create!(:name => 'License', :form => form) | 27 | license_field = CustomFormsPlugin::Field.create!(:name => 'License', :form => form) |
@@ -72,26 +33,20 @@ class CustomFormsPlugin::FieldTest < ActiveSupport::TestCase | @@ -72,26 +33,20 @@ class CustomFormsPlugin::FieldTest < ActiveSupport::TestCase | ||
72 | assert_equal form.fields, [license_field] | 33 | assert_equal form.fields, [license_field] |
73 | end | 34 | end |
74 | 35 | ||
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 | 36 | + should 'have alternative if type is SelectField' do |
37 | + select = CustomFormsPlugin::Field.new(:name => 'select_field001', :type => 'CustomFormsPlugin::SelectField') | ||
38 | + assert !select.save | ||
39 | + | ||
40 | + select.alternatives << CustomFormsPlugin::Alternative.new(:label => 'option') | ||
41 | + assert select.save | ||
83 | end | 42 | end |
84 | 43 | ||
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 | 44 | + should 'sort alternatives by position' do |
45 | + field = CustomFormsPlugin::Field.create!(:name => 'field001') | ||
46 | + second = CustomFormsPlugin::Alternative.create!(:label => 'second', :field => field, :position => 2) | ||
47 | + first = CustomFormsPlugin::Alternative.create!(:label => 'first', :field => field, :position => 1) | ||
90 | 48 | ||
91 | - assert_nothing_raised do | ||
92 | - field_1 = CustomFormsPlugin::Field.create!(:name => 'URL', :form => form) | ||
93 | - end | 49 | + assert_equal field.alternatives, [first, second] |
94 | end | 50 | end |
95 | - | ||
96 | end | 51 | end |
97 | 52 |
plugins/custom_forms/test/unit/custom_forms_plugin/form_test.rb
@@ -53,6 +53,20 @@ class CustomFormsPlugin::FormTest < ActiveSupport::TestCase | @@ -53,6 +53,20 @@ class CustomFormsPlugin::FormTest < ActiveSupport::TestCase | ||
53 | assert !form.errors.invalid?(:slug) | 53 | assert !form.errors.invalid?(:slug) |
54 | end | 54 | end |
55 | 55 | ||
56 | + should 'validate the difference between ending and beginning is positive' do | ||
57 | + profile = fast_create(Profile) | ||
58 | + form = CustomFormsPlugin::Form.new(:profile => profile, :name => 'Free Software') | ||
59 | + | ||
60 | + form.begining = Time.now | ||
61 | + form.ending = Time.now + 1.day | ||
62 | + assert form.valid? | ||
63 | + assert !form.errors.invalid?(:base) | ||
64 | + | ||
65 | + form.ending = Time.now - 2.day | ||
66 | + assert !form.valid? | ||
67 | + assert form.errors.invalid?(:base) | ||
68 | + end | ||
69 | + | ||
56 | should 'define form expiration' do | 70 | should 'define form expiration' do |
57 | form = CustomFormsPlugin::Form.new | 71 | form = CustomFormsPlugin::Form.new |
58 | assert !form.expired? | 72 | assert !form.expired? |
@@ -75,6 +89,22 @@ class CustomFormsPlugin::FormTest < ActiveSupport::TestCase | @@ -75,6 +89,22 @@ class CustomFormsPlugin::FormTest < ActiveSupport::TestCase | ||
75 | assert !form.expired? | 89 | assert !form.expired? |
76 | end | 90 | end |
77 | 91 | ||
92 | + should 'define if form will still open' do | ||
93 | + form = CustomFormsPlugin::Form.new | ||
94 | + assert !form.will_open? | ||
95 | + | ||
96 | + form.begining = Time.now + 1.day | ||
97 | + assert form.will_open? | ||
98 | + | ||
99 | + form.begining = Time.now - 1.day | ||
100 | + assert !form.will_open? | ||
101 | + | ||
102 | + form.begining = Time.now - 2.day | ||
103 | + form.ending = Time.now - 1.day | ||
104 | + assert form.expired? | ||
105 | + assert !form.will_open? | ||
106 | + end | ||
107 | + | ||
78 | should 'validates format of access' do | 108 | should 'validates format of access' do |
79 | form = CustomFormsPlugin::Form.new | 109 | form = CustomFormsPlugin::Form.new |
80 | form.valid? | 110 | form.valid? |
@@ -180,4 +210,54 @@ class CustomFormsPlugin::FormTest < ActiveSupport::TestCase | @@ -180,4 +210,54 @@ class CustomFormsPlugin::FormTest < ActiveSupport::TestCase | ||
180 | end | 210 | end |
181 | end | 211 | end |
182 | 212 | ||
213 | + should 'sort fields by position' do | ||
214 | + form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => fast_create(Profile)) | ||
215 | + license_field = CustomFormsPlugin::Field.create!(:name => 'License', :form => form, :position => 2) | ||
216 | + url_field = CustomFormsPlugin::Field.create!(:name => 'URL', :form => form, :position => 0) | ||
217 | + | ||
218 | + assert_equal form.fields, [url_field, license_field] | ||
219 | + end | ||
220 | + | ||
221 | + should 'have a named_scope that retrieves all forms required for membership' do | ||
222 | + profile = fast_create(Profile) | ||
223 | + f1 = CustomFormsPlugin::Form.create!(:name => 'For admission 1', :profile => profile, :for_admission => true) | ||
224 | + f2 = CustomFormsPlugin::Form.create!(:name => 'For admission 2', :profile => profile, :for_admission => true) | ||
225 | + f3 = CustomFormsPlugin::Form.create!(:name => 'Not for admission', :profile => profile, :for_admission => false) | ||
226 | + scope = CustomFormsPlugin::Form.from(profile).for_admissions | ||
227 | + | ||
228 | + assert_equal ActiveRecord::NamedScope::Scope, scope.class | ||
229 | + assert_includes scope, f1 | ||
230 | + assert_includes scope, f2 | ||
231 | + assert_not_includes scope, f3 | ||
232 | + end | ||
233 | + | ||
234 | + should 'not include admission membership in on membership named scope' do | ||
235 | + profile = fast_create(Profile) | ||
236 | + f1 = CustomFormsPlugin::Form.create!(:name => 'On membership', :profile => profile, :on_membership => true) | ||
237 | + f2 = CustomFormsPlugin::Form.create!(:name => 'For admission', :profile => profile, :on_membership => true, :for_admission => true) | ||
238 | + scope = CustomFormsPlugin::Form.from(profile).on_memberships | ||
239 | + | ||
240 | + assert_equal ActiveRecord::NamedScope::Scope, scope.class | ||
241 | + assert_includes scope, f1 | ||
242 | + assert_not_includes scope, f2 | ||
243 | + end | ||
244 | + | ||
245 | + should 'cancel survey tasks after removing a form' do | ||
246 | + profile = fast_create(Profile) | ||
247 | + person = fast_create(Person) | ||
248 | + | ||
249 | + form1 = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => profile) | ||
250 | + form2 = CustomFormsPlugin::Form.create!(:name => 'Operation System', :profile => profile) | ||
251 | + | ||
252 | + task1 = CustomFormsPlugin::MembershipSurvey.create!(:form_id => form1.id, :target => person, :requestor => profile) | ||
253 | + task2 = CustomFormsPlugin::MembershipSurvey.create!(:form_id => form2.id, :target => person, :requestor => profile) | ||
254 | + | ||
255 | + assert_includes Task.opened, task1 | ||
256 | + assert_includes Task.opened, task2 | ||
257 | + form1.destroy | ||
258 | + assert_includes Task.canceled, task1 | ||
259 | + assert_includes Task.opened, task2 | ||
260 | + form2.destroy | ||
261 | + assert_includes Task.canceled, task2 | ||
262 | + end | ||
183 | end | 263 | end |
plugins/custom_forms/test/unit/custom_forms_plugin/membership_survey_test.rb
@@ -16,16 +16,29 @@ class CustomFormsPlugin::MembershipSurveyTest < ActiveSupport::TestCase | @@ -16,16 +16,29 @@ class CustomFormsPlugin::MembershipSurveyTest < ActiveSupport::TestCase | ||
16 | person = fast_create(Person) | 16 | person = fast_create(Person) |
17 | form = CustomFormsPlugin::Form.create!(:name => 'Simple Form', :profile => profile) | 17 | form = CustomFormsPlugin::Form.create!(:name => 'Simple Form', :profile => profile) |
18 | field = CustomFormsPlugin::Field.create!(:name => 'Name', :form => form) | 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 | assert_difference CustomFormsPlugin::Submission, :count, 1 do | 21 | assert_difference CustomFormsPlugin::Submission, :count, 1 do |
22 | task.finish | 22 | task.finish |
23 | end | 23 | end |
24 | 24 | ||
25 | submission = CustomFormsPlugin::Submission.last | 25 | submission = CustomFormsPlugin::Submission.last |
26 | - assert_equal submission.answers.count, 1 | 26 | + assert_equal submission.answers.count, 1 |
27 | 27 | ||
28 | answer = submission.answers.first | 28 | answer = submission.answers.first |
29 | assert_equal answer.value, 'Jack' | 29 | assert_equal answer.value, 'Jack' |
30 | end | 30 | end |
31 | + | ||
32 | + should 'have a named_scope that retrieves all tasks requested by profile' do | ||
33 | + profile = fast_create(Profile) | ||
34 | + person = fast_create(Person) | ||
35 | + form = CustomFormsPlugin::Form.create!(:name => 'Simple Form', :profile => profile) | ||
36 | + task1 = CustomFormsPlugin::MembershipSurvey.create!(:form_id => form.id, :target => person, :requestor => profile) | ||
37 | + task2 = CustomFormsPlugin::MembershipSurvey.create!(:form_id => form.id, :target => person, :requestor => fast_create(Profile)) | ||
38 | + scope = CustomFormsPlugin::MembershipSurvey.from(profile) | ||
39 | + | ||
40 | + assert_equal ActiveRecord::NamedScope::Scope, scope.class | ||
41 | + assert_includes scope, task1 | ||
42 | + assert_not_includes scope, task2 | ||
43 | + end | ||
31 | end | 44 | end |
plugins/custom_forms/test/unit/custom_forms_plugin/select_field_test.rb
1 | require File.dirname(__FILE__) + '/../../../../../test/test_helper' | 1 | require File.dirname(__FILE__) + '/../../../../../test/test_helper' |
2 | 2 | ||
3 | class CustomFormsPlugin::SelectFieldTest < ActiveSupport::TestCase | 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) | ||
8 | - | ||
9 | - select.choices = {'label' => 'value'} | ||
10 | - select.valid? | ||
11 | - assert !select.errors.invalid?(:choices) | 4 | + should 'have alternative' do |
5 | + select = CustomFormsPlugin::SelectField.new(:name => 'select_field001' ) | ||
6 | + assert !select.save | ||
7 | + | ||
8 | + select.alternatives << CustomFormsPlugin::Alternative.new(:label => 'option') | ||
9 | + assert select.save | ||
10 | + end | ||
11 | + | ||
12 | + should 'validate type' do | ||
13 | + select = CustomFormsPlugin::SelectField.new(:name => 'select_field001' ) | ||
14 | + select.alternatives << CustomFormsPlugin::Alternative.new(:label => 'option') | ||
15 | + | ||
16 | + select.update_attribute(:select_field_type, 'random') | ||
17 | + assert select.invalid? | ||
18 | + | ||
19 | + select.update_attribute(:select_field_type, 'radio') | ||
20 | + assert select.valid? | ||
21 | + select.update_attribute(:select_field_type, 'check_box') | ||
22 | + assert select.valid? | ||
23 | + select.update_attribute(:select_field_type, 'select') | ||
24 | + assert select.valid? | ||
25 | + select.update_attribute(:select_field_type, 'multiple_select') | ||
26 | + assert select.valid? | ||
12 | end | 27 | end |
13 | end | 28 | end |
plugins/custom_forms/test/unit/ext/role_assingment_test.rb
@@ -27,25 +27,46 @@ class RoleAssignmentsTest < ActiveSupport::TestCase | @@ -27,25 +27,46 @@ class RoleAssignmentsTest < ActiveSupport::TestCase | ||
27 | end | 27 | end |
28 | end | 28 | end |
29 | 29 | ||
30 | - should 'cancel membership_surveys if membership is undone and task is active' do | 30 | + should 'cancel surveys if membership is undone and task is active' do |
31 | environment = Environment.default | 31 | environment = Environment.default |
32 | environment.enable_plugin(CustomFormsPlugin) | 32 | environment.enable_plugin(CustomFormsPlugin) |
33 | organization = fast_create(Organization) | 33 | organization = fast_create(Organization) |
34 | person = fast_create(Person) | 34 | person = fast_create(Person) |
35 | - form = CustomFormsPlugin::Form.create!(:profile => organization, :name => 'Form', :on_membership => true) | 35 | + form1 = CustomFormsPlugin::Form.create!(:profile => organization, :name => 'Form 1', :on_membership => true) |
36 | organization.add_member(person) | 36 | organization.add_member(person) |
37 | 37 | ||
38 | assert_difference CustomFormsPlugin::MembershipSurvey.pending, :count, -1 do | 38 | assert_difference CustomFormsPlugin::MembershipSurvey.pending, :count, -1 do |
39 | organization.remove_member(person) | 39 | organization.remove_member(person) |
40 | end | 40 | end |
41 | 41 | ||
42 | + form2 = CustomFormsPlugin::Form.create!(:profile => organization, :name => 'Form 2', :for_admission => true) | ||
42 | organization.add_member(person) | 43 | organization.add_member(person) |
43 | - task = CustomFormsPlugin::MembershipSurvey.last | ||
44 | - task.status = Task::Status::FINISHED | ||
45 | - task.save! | 44 | + |
45 | + assert_difference CustomFormsPlugin::AdmissionSurvey.pending, :count, -1 do | ||
46 | + organization.remove_member(person) | ||
47 | + end | ||
48 | + | ||
49 | + organization.add_member(person) | ||
50 | + tasks = CustomFormsPlugin::MembershipSurvey.all.last(2) | ||
51 | + tasks.each {|t| t.status = Task::Status::FINISHED } | ||
52 | + tasks.each {|t| t.save! } | ||
46 | assert_no_difference CustomFormsPlugin::MembershipSurvey.finished, :count do | 53 | assert_no_difference CustomFormsPlugin::MembershipSurvey.finished, :count do |
47 | organization.remove_member(person) | 54 | organization.remove_member(person) |
48 | end | 55 | end |
49 | end | 56 | end |
50 | -end | ||
51 | 57 | ||
58 | + should 'create admission survey when atempted membership' do | ||
59 | + environment = Environment.default | ||
60 | + environment.enable_plugin(CustomFormsPlugin) | ||
61 | + organization = fast_create(Organization) | ||
62 | + person = fast_create(Person) | ||
63 | + f1 = CustomFormsPlugin::Form.create!(:profile => organization, :name => 'Form 1', :for_admission => true) | ||
64 | + f2 = CustomFormsPlugin::Form.create!(:profile => organization, :name => 'Form 2', :for_admission => true) | ||
65 | + f3 = CustomFormsPlugin::Form.create!(:profile => organization, :name => 'Form 3', :for_admission => false) | ||
66 | + | ||
67 | + assert_difference CustomFormsPlugin::AdmissionSurvey, :count, 2 do | ||
68 | + organization.add_member(person) | ||
69 | + end | ||
70 | + assert !organization.members.include?(person) | ||
71 | + end | ||
72 | +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 | <h2><%= _('Options') %></h2> | 2 | <h2><%= _('Options') %></h2> |
4 | <table class='action-table' style='width: 420px'> | 3 | <table class='action-table' style='width: 420px'> |
5 | <tr> | 4 | <tr> |
6 | <th style='width: 40%'><%= _('Name') %></th> | 5 | <th style='width: 40%'><%= _('Name') %></th> |
7 | <th style='width: 40%'><%= _('Value') %></th> | 6 | <th style='width: 40%'><%= _('Value') %></th> |
8 | - <th style='width: 20%'><%= _('Actions') %></th> | 7 | + <th style='width: 20%'><%= _('Delete') %></th> |
9 | </tr> | 8 | </tr> |
10 | <% option_counter = 1 %> | 9 | <% option_counter = 1 %> |
11 | <% (field.choices || {}).each do |name, value| %> | 10 | <% (field.choices || {}).each do |name, value| %> |
plugins/custom_forms/views/custom_forms_plugin_myprofile/_edit_text.html.erb
@@ -1,10 +0,0 @@ | @@ -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 | + <%= required f.label :name, _('Name:') %> | ||
5 | + <%= f.text_field :name, :style => 'width: 14em' %> | ||
6 | + | ||
7 | + <%= f.hidden_field :type %> | ||
8 | + | ||
9 | + <%= f.check_box :mandatory %> | ||
10 | + <%= f.label :mandatory, _('Mandatory') %> | ||
11 | + | ||
12 | + <%= f.hidden_field(:position) %> | ||
13 | + | ||
14 | + <%= f.hidden_field :_destroy, :class => 'destroy-field' %> | ||
15 | + <%= button_to_function :delete, _('Remove field'), "customFormsPlugin.removeFieldBox(this, #{_('Are you sure you want to remove this field?').to_json})" %> | ||
16 | + <%= yield %> | ||
17 | +</div> | ||
18 | +</fieldset> |
plugins/custom_forms/views/custom_forms_plugin_myprofile/_form.html.erb
1 | <% self.extend(CustomFormsPlugin::Helper) %> | 1 | <% self.extend(CustomFormsPlugin::Helper) %> |
2 | <%= render :file => 'shared/tiny_mce', :locals => {:mode => 'simple'} %> | 2 | <%= render :file => 'shared/tiny_mce', :locals => {:mode => 'simple'} %> |
3 | 3 | ||
4 | -<%= error_messages_for :form %> | ||
5 | - | ||
6 | -<% form_for :form, @form do |f| %> | ||
7 | - <%= required labelled_form_field _('Name'), f.text_field(:name) %> | ||
8 | - <%= labelled_form_field(_('Period'), ( | ||
9 | - date_range_field('form[begining]', 'form[ending]', @form.begining, @form.ending, | ||
10 | - '%Y-%m-%d %H:%M', | ||
11 | - { :time => true, :change_month => true, :change_year => true, | ||
12 | - :date_format => 'yy-mm-dd', :time_format => 'hh:mm' }, | 4 | +<%= f.error_messages %> |
5 | +<%= required labelled_form_field _('Name'), f.text_field(:name) %> | ||
6 | +<%= labelled_form_field(_('What is the time limit for this form to be filled?'), ( | ||
7 | + date_range_field('form[begining]', 'form[ending]', @form.begining, @form.ending, | ||
8 | + '%Y-%m-%d %H:%M', | ||
9 | + { :time => true, :change_month => true, :change_year => true, | ||
10 | + :date_format => 'yy-mm-dd', :time_format => 'hh:mm' }, | ||
13 | { :size => 14 }) | 11 | { :size => 14 }) |
14 | - )) %> | ||
15 | - <%= labelled_form_field _('Access'), f.select(:access, access_options(profile))%> | ||
16 | - <% if profile.organization? %> | ||
17 | - <%= labelled_form_field _('Triggered on membership'), f.check_box(:on_membership) %> | ||
18 | - <% end %> | ||
19 | - <%= labelled_form_field _('Description'), f.text_area(:description, :style => 'width: 100%', :class => 'mceEditor') %> | 12 | +)) %> |
13 | +<%= labelled_form_field _('Access'), f.select(:access, access_options(profile))%> | ||
14 | +<% if profile.organization? %> | ||
15 | + <p> | ||
16 | + <%= labelled_check_box _('Triggered on membership request as requirement for approval'), 'form[for_admission]', '1', @form.for_admission %> | ||
17 | + <br/> | ||
18 | + <%= labelled_check_box _('Triggered after membership'), 'form[on_membership]', '1', @form.on_membership %> | ||
19 | + </p> | ||
20 | +<% end %> | ||
21 | +<%= labelled_form_field _('Description'), f.text_area(:description, :style => 'width: 100%', :class => 'mceEditor') %> | ||
20 | 22 | ||
21 | - <h2><%= _('Fields') %></h2> | ||
22 | - <table class="action-table" id='fields-table'> | ||
23 | - <tr> | ||
24 | - <th style='width: 40%'><%= _('Name') %></th> | ||
25 | - <th style='width: 30%'><%= _('Type') %></th> | ||
26 | - <th style='width: 10%'><%= _('Mandatory') %></th> | ||
27 | - <th style='width: 20%'><%= _('Actions') %></th> | ||
28 | - </tr> | ||
29 | - <% counter = 1 %> | ||
30 | - <% @fields.each do |field| %> | ||
31 | - <%= render :partial => 'field', :locals => {:field => field, :counter => counter} %> | ||
32 | - <% counter += 1 %> | ||
33 | - <% end %> | ||
34 | - <%= render :partial => 'empty_field', :locals => {:field => @empty_field, :counter => counter} %> | ||
35 | - <tr class='new-item'> | ||
36 | - <td colspan='5'> | ||
37 | - <%= button(:add, _('Add a new field'), '#', :id => 'new-field')%> | ||
38 | - </td> | ||
39 | - </tr> | ||
40 | - </table> | 23 | +<h2><%= _('Fields') %></h2> |
41 | 24 | ||
42 | - <% counter = 1 %> | ||
43 | - <% @fields.each do |field| %> | ||
44 | - <%= render :partial => 'edit_text', :locals => {:field => field, :counter => counter} %> | ||
45 | - <%= render :partial => 'edit_select', :locals => {:field => field, :counter => counter} %> | ||
46 | - <% counter += 1 %> | 25 | +<ul class='field-list'> |
26 | + <% f.fields_for :fields do |builder| %> | ||
27 | + <li> | ||
28 | + <%= render partial_for_class(builder.object.class), :f => builder %> | ||
29 | + </li> | ||
47 | <% end %> | 30 | <% end %> |
31 | +</ul> | ||
48 | 32 | ||
49 | - <%= render :partial => 'edit_text', :locals => {:field => @empty_field, :counter => counter} %> | ||
50 | - <%= render :partial => 'edit_select', :locals => {:field => @empty_field, :counter => counter} %> | 33 | +<div class="addition-buttons"> |
34 | + <%= button(:add, _('Add a new text field'), '#', :onclick => "customFormsPlugin.addFields(this, 'fields', #{html_for_field(f, :fields, CustomFormsPlugin::TextField).to_json}); return false")%> | ||
35 | + <%= button(:add, _('Add a new select field'), '#', :onclick => "customFormsPlugin.addFields(this, 'fields', #{html_for_field(f, :fields, CustomFormsPlugin::SelectField).to_json}); return false")%> | ||
36 | +</div> | ||
51 | 37 | ||
52 | - <% button_bar do %> | ||
53 | - <%= submit_button :save, _('Save'), :cancel => {:action => 'index'}%> | ||
54 | - <% end %> | 38 | +<% button_bar do %> |
39 | + <%= submit_button :save, _('Save'), :cancel => {:action => 'index'}%> | ||
55 | <% end %> | 40 | <% end %> |
56 | 41 | ||
57 | <%= javascript_include_tag '../plugins/custom_forms/field' %> | 42 | <%= javascript_include_tag '../plugins/custom_forms/field' %> |
plugins/custom_forms/views/custom_forms_plugin_myprofile/_option.html.erb
@@ -1,7 +0,0 @@ | @@ -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,12 @@ | @@ -0,0 +1,12 @@ | ||
1 | +<tr class="alternative"> | ||
2 | + <td> <%= f.text_field(:label) %> </td> | ||
3 | + | ||
4 | + <td> <%= f.check_box(:selected_by_default) %> </td> | ||
5 | + | ||
6 | + <%= f.hidden_field(:position) %> | ||
7 | + | ||
8 | + <td> | ||
9 | + <%= f.hidden_field :_destroy, :class => 'destroy-field' %> | ||
10 | + <%= 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') %> | ||
11 | + </td> | ||
12 | +</tr> |
plugins/custom_forms/views/custom_forms_plugin_myprofile/custom_forms_plugin/_field.html.erb
0 → 100644
@@ -0,0 +1,9 @@ | @@ -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,36 @@ | @@ -0,0 +1,36 @@ | ||
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 | + <thead> | ||
16 | + <tr <%='style="display:none"' if f.object.alternatives.empty? %>> | ||
17 | + <th><%= _('Alternative') %></th> | ||
18 | + <th><%= _('Preselected') %></th> | ||
19 | + <th><%= _('Remove') %></th> | ||
20 | + </tr> | ||
21 | + </thead> | ||
22 | + <tfoot> | ||
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 | + </tfoot> | ||
29 | + <tbody class='field-list'> | ||
30 | + <% f.fields_for :alternatives do |builder| %> | ||
31 | + <%= render partial_for_class(builder.object.class), :f => builder %> | ||
32 | + <% end %> | ||
33 | + </tbody> | ||
34 | + </table> | ||
35 | + | ||
36 | +<% 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
@@ -17,12 +17,14 @@ | @@ -17,12 +17,14 @@ | ||
17 | <td><%= access_text(form) %></td> | 17 | <td><%= access_text(form) %></td> |
18 | <td class="actions"> | 18 | <td class="actions"> |
19 | <%= button_without_text :edit, _('Edit'), :action => 'edit', :id => form.id %> | 19 | <%= button_without_text :edit, _('Edit'), :action => 'edit', :id => form.id %> |
20 | - <%= button_without_text :remove, _('Remove'), {:action => 'remove', :id => form.id}, :confirm => _('Are you sure you want to remove this form?') %></td> | 20 | + <%= button_without_text :search, _('Pending'), :action => 'pending', :id => form.id if form.for_admission %> |
21 | + <%= button_without_text :remove, _('Remove'), {:action => 'remove', :id => form.id}, :confirm => _('Are you sure you want to remove this form?') %> | ||
22 | + </td> | ||
21 | </tr> | 23 | </tr> |
22 | <% end %> | 24 | <% end %> |
23 | <tr id="new-item"> | 25 | <tr id="new-item"> |
24 | <td colspan='5'> | 26 | <td colspan='5'> |
25 | - <%= button(:add, _('Add a new form'), :action => 'create')%> | 27 | + <%= button(:add, _('Add a new form'), :action => 'new')%> |
26 | </td> | 28 | </td> |
27 | </tr> | 29 | </tr> |
28 | </table> | 30 | </table> |
plugins/custom_forms/views/custom_forms_plugin_myprofile/new.html.erb
0 → 100644
plugins/custom_forms/views/custom_forms_plugin_myprofile/pending.html.erb
0 → 100644
@@ -0,0 +1,27 @@ | @@ -0,0 +1,27 @@ | ||
1 | +<% self.extend CustomFormsPlugin::Helper %> | ||
2 | + | ||
3 | +<h1><%= _('Pending submissions for %s') % @form.name %></h1> | ||
4 | + | ||
5 | +<% if @pendings.empty? %> | ||
6 | + <%= _('There are no pending submissions for this form.') %> | ||
7 | +<% else %> | ||
8 | + <p> | ||
9 | + <%= labelled_select(_('Sort by')+': ', :sort_by, :first, :last, @sort_by, [['time', _('Time')], ['user', _('User')]], :onchange => 'document.location.href = "?sort_by="+this.value') %> | ||
10 | + </p> | ||
11 | + <table class="action-table"> | ||
12 | + <tr> | ||
13 | + <th style='width: 50%'><%= _('User') %></th> | ||
14 | + <th style='width: 50%'><%= _('Time') %></th> | ||
15 | + </tr> | ||
16 | + <% @pendings.each do |pending| %> | ||
17 | + <tr> | ||
18 | + <td><%= link_to(pending[:profile].name, {:controller => :profile, :profile => pending[:profile].identifier}) %></td> | ||
19 | + <td><%= time_format(pending[:time]) %></td> | ||
20 | + </tr> | ||
21 | + <% end %> | ||
22 | + </table> | ||
23 | +<% end %> | ||
24 | + | ||
25 | +<% button_bar do %> | ||
26 | + <%= button :back, _('Back to forms'), :action => 'index' %> | ||
27 | +<% end %> |
plugins/custom_forms/views/custom_forms_plugin_myprofile/submissions.html.erb
@@ -5,6 +5,13 @@ | @@ -5,6 +5,13 @@ | ||
5 | <% if @form.submissions.empty? %> | 5 | <% if @form.submissions.empty? %> |
6 | <%= _('There are no submissions for this form.') %> | 6 | <%= _('There are no submissions for this form.') %> |
7 | <% else %> | 7 | <% else %> |
8 | + <p> | ||
9 | + <%= _('Download all form responses as') %>: | ||
10 | + <%= link_to '[CSV]', :format => 'csv' %> | ||
11 | + </p> | ||
12 | + <p> | ||
13 | + <%= labelled_select(_('Sort by')+': ', :sort_by, :first, :last, @sort_by, [['time', _('Time')], ['author', _('Author')]], :onchange => 'document.location.href = "?sort_by="+this.value') %> | ||
14 | + </p> | ||
8 | <table class="action-table"> | 15 | <table class="action-table"> |
9 | <tr> | 16 | <tr> |
10 | <th style='width: 50%'><%= _('Author') %></th> | 17 | <th style='width: 50%'><%= _('Author') %></th> |
plugins/custom_forms/views/custom_forms_plugin_profile/show.html.erb
@@ -2,6 +2,14 @@ | @@ -2,6 +2,14 @@ | ||
2 | <p><%= @form.description %></p> | 2 | <p><%= @form.description %></p> |
3 | 3 | ||
4 | <% if @submission.id.nil? %> | 4 | <% if @submission.id.nil? %> |
5 | + <% if @form.expired? %> | ||
6 | + <% if @form.will_open? %> | ||
7 | + <h2><%= _('Sorry, you can\'t fill this form yet') %></h2> | ||
8 | + <% else %> | ||
9 | + <h2><%= _('Sorry, you can\'t fill this form anymore') %></h2> | ||
10 | + <% end %> | ||
11 | + <% end %> | ||
12 | + | ||
5 | <%= error_messages_for :submission %> | 13 | <%= error_messages_for :submission %> |
6 | 14 | ||
7 | <% form_for :submission, @submission do |f| %> | 15 | <% form_for :submission, @submission do |f| %> |
@@ -13,8 +21,13 @@ | @@ -13,8 +21,13 @@ | ||
13 | <%= render :partial => 'shared/form_submission', :locals => {:f => f} %> | 21 | <%= render :partial => 'shared/form_submission', :locals => {:f => f} %> |
14 | 22 | ||
15 | <% button_bar do %> | 23 | <% button_bar do %> |
16 | - <%= submit_button :save, _('Save'), :cancel => {:controller=>:profile, :profile => profile.identifier} %> | 24 | + <% if @form.expired? %> |
25 | + <%= submit_button :save, _('Save'), :disabled => '', :class => 'disabled', :cancel => {:controller => :profile, :profile => profile.identifier} %> | ||
26 | + <% else %> | ||
27 | + <%= submit_button :save, _('Save'), :cancel => {:controller => :profile, :profile => profile.identifier} %> | ||
28 | + <% end %> | ||
17 | <% end %> | 29 | <% end %> |
30 | + | ||
18 | <% end %> | 31 | <% end %> |
19 | <% else %> | 32 | <% else %> |
20 | <% fields_for :submission, @submission do |f| %> | 33 | <% fields_for :submission, @submission do |f| %> |
plugins/custom_forms/views/tasks/custom_forms_plugin/_membership_survey_accept_details.html.erb
@@ -3,8 +3,14 @@ | @@ -3,8 +3,14 @@ | ||
3 | 3 | ||
4 | <h2><%= @form.name %></h2> | 4 | <h2><%= @form.name %></h2> |
5 | <p><%= @form.description %></p> | 5 | <p><%= @form.description %></p> |
6 | +<% if @form.expired? %> | ||
7 | + <% if @form.will_open? %> | ||
8 | + <h3><%= _('Sorry, you can\'t fill this form yet') %></h3> | ||
9 | + <% else %> | ||
10 | + <h3><%= _('Sorry, you can\'t fill this form anymore') %></h3> | ||
11 | + <% end %> | ||
12 | +<% end %> | ||
6 | 13 | ||
7 | <% f.fields_for :submission do |fi| %> | 14 | <% f.fields_for :submission do |fi| %> |
8 | - <%#= fi.error_messages_for :submission %> | ||
9 | <%= render :partial => 'shared/form_submission', :locals => {:f => fi} %> | 15 | <%= render :partial => 'shared/form_submission', :locals => {:f => fi} %> |
10 | <% end %> | 16 | <% end %> |
po/pt/noosfero.po
@@ -10441,6 +10441,18 @@ msgstr "Bloco salvo com sucesso." | @@ -10441,6 +10441,18 @@ msgstr "Bloco salvo com sucesso." | ||
10441 | msgid "Sub-organizations updated" | 10441 | msgid "Sub-organizations updated" |
10442 | msgstr "Sub-organizações atualizadas" | 10442 | msgstr "Sub-organizações atualizadas" |
10443 | 10443 | ||
10444 | +#: plugins/custom_forms/controllers/custom_forms_plugin_myprofile_controller.rb:26 | ||
10445 | +msgid "Custom form #{@form.name} was successfully created." | ||
10446 | +msgstr "O formulário #{@form.name} foi criado com sucesso." | ||
10447 | + | ||
10448 | +#: plugins/custom_forms/controllers/custom_forms_plugin_myprofile_controller.rb:46 | ||
10449 | +msgid "Custom form #{@form.name} was successfully updated." | ||
10450 | +msgstr "O formulário #{@form.name} foi atualizado com sucesso." | ||
10451 | + | ||
10452 | +#: plugins/tolerance_time/controllers/tolerance_time_plugin_myprofile_controller.rb:10 | ||
10453 | +msgid "Tolerance updated" | ||
10454 | +msgstr "A tolerância foi atualizada" | ||
10455 | + | ||
10444 | #: plugins/sub_organizations/controllers/sub_organizations_plugin_myprofile_controller.rb:28 | 10456 | #: plugins/sub_organizations/controllers/sub_organizations_plugin_myprofile_controller.rb:28 |
10445 | msgid "Sub-organizations could not be updated" | 10457 | msgid "Sub-organizations could not be updated" |
10446 | msgstr "As sub-organizações não puderam ser salvas" | 10458 | msgstr "As sub-organizações não puderam ser salvas" |
@@ -11087,6 +11099,15 @@ msgstr "%s artigos encontrados" | @@ -11087,6 +11099,15 @@ msgstr "%s artigos encontrados" | ||
11087 | msgid "%s events found" | 11099 | msgid "%s events found" |
11088 | msgstr "%s eventos encontrados" | 11100 | msgstr "%s eventos encontrados" |
11089 | 11101 | ||
11102 | +#: plugins/custom_forms/lib/custom_forms_plugin/helper.rb:87 | ||
11103 | +msgid "Hold down Ctrl to select options" | ||
11104 | +msgstr "Segure Ctrl para selecionar as opções" | ||
11105 | + | ||
11106 | +#: plugins/custom_forms/lib/custom_forms_plugin/helper.rb:4 | ||
11107 | +#: plugins/custom_forms/lib/custom_forms_plugin/helper.rb:37 | ||
11108 | +msgid "Logged users" | ||
11109 | +msgstr "Usuários logados" | ||
11110 | + | ||
11090 | #: plugins/solr/lib/solr_plugin/search_helper.rb:138 | 11111 | #: plugins/solr/lib/solr_plugin/search_helper.rb:138 |
11091 | msgid "%s people found" | 11112 | msgid "%s people found" |
11092 | msgstr "%s pessoas encontradas" | 11113 | msgstr "%s pessoas encontradas" |
@@ -11119,6 +11140,47 @@ msgstr "Um plugin que mostra grupos de comentários." | @@ -11119,6 +11140,47 @@ msgstr "Um plugin que mostra grupos de comentários." | ||
11119 | msgid "A plugin that add a container block." | 11140 | msgid "A plugin that add a container block." |
11120 | msgstr "Um plugin que adiciona um bloco container." | 11141 | msgstr "Um plugin que adiciona um bloco container." |
11121 | 11142 | ||
11143 | +#: plugins/custom_forms/lib/custom_forms_plugin/helper.rb:58 | ||
11144 | +msgid "Text field" | ||
11145 | +msgstr "Campo de texto" | ||
11146 | + | ||
11147 | +#: plugins/custom_forms/lib/custom_forms_plugin/helper.rb:59 | ||
11148 | +msgid "Select field" | ||
11149 | +msgstr "Campo de seleção" | ||
11150 | + | ||
11151 | +#: plugins/custom_forms/lib/custom_forms_plugin/membership_survey.rb:16 | ||
11152 | +msgid "Membership survey" | ||
11153 | +msgstr "Pesquisa na associação de novos integrantes" | ||
11154 | + | ||
11155 | +#: plugins/custom_forms/lib/custom_forms_plugin/admission_survey.rb:9 | ||
11156 | +msgid "Admission survey" | ||
11157 | +msgstr "Questionário para associação" | ||
11158 | + | ||
11159 | +#: plugins/custom_forms/lib/custom_forms_plugin/admission_survey.rb:13 | ||
11160 | +msgid "%{requestor} wants you to fill in some information before joining." | ||
11161 | +msgstr "%{requestor} quer que você preencha algumas informações antes de se associar." | ||
11162 | + | ||
11163 | +#: plugins/custom_forms/lib/custom_forms_plugin/membership_survey.rb:28 | ||
11164 | +msgid "%{requestor} wants you to fill in some information." | ||
11165 | +msgstr "%{requestor} quer que você preencha algumas informações." | ||
11166 | + | ||
11167 | +#: plugins/custom_forms/lib/custom_forms_plugin/admission_survey.rb:17 | ||
11168 | +msgid "" | ||
11169 | +"Before joining %{requestor}, the administrators of this organization\n" | ||
11170 | +" wants you to fill in some further information." | ||
11171 | +msgstr "" | ||
11172 | +"Antes de entrar em %{requestor}, os administradores dessa organização\n" | ||
11173 | +" querem que você preencha algumas informações adicionais." | ||
11174 | + | ||
11175 | +#: plugins/custom_forms/lib/custom_forms_plugin/membership_survey.rb:40 | ||
11176 | +msgid "" | ||
11177 | +"After joining %{requestor}, the administrators of this organization\n" | ||
11178 | +" wants you to fill in some further information." | ||
11179 | +msgstr "" | ||
11180 | +"Após entrar em %{requestor}, os administradores dessa organização\n" | ||
11181 | +" querem que você preencha algumas informações adicionais." | ||
11182 | +>>>>>>> custom_forms | ||
11183 | + | ||
11122 | #: plugins/container_block/lib/container_block_plugin/container_block.rb:11 | 11184 | #: plugins/container_block/lib/container_block_plugin/container_block.rb:11 |
11123 | msgid "Container" | 11185 | msgid "Container" |
11124 | msgstr "Container" | 11186 | msgstr "Container" |
@@ -12106,6 +12168,39 @@ msgstr "Horas" | @@ -12106,6 +12168,39 @@ msgstr "Horas" | ||
12106 | msgid "Content edition tolerance time" | 12168 | msgid "Content edition tolerance time" |
12107 | msgstr "Tempo de tolerância para edição de conteúdo" | 12169 | msgstr "Tempo de tolerância para edição de conteúdo" |
12108 | 12170 | ||
12171 | +#: plugins/custom_forms/views/custom_forms_plugin_profile/show.html.erb:7 | ||
12172 | +msgid "Sorry, you can't fill this form yet" | ||
12173 | +msgstr "Desculpe, você não pode preencher esse formulário ainda" | ||
12174 | + | ||
12175 | +#: plugins/custom_forms/views/custom_forms_plugin_profile/show.html.erb:9 | ||
12176 | +msgid "Sorry, you can't fill this form anymore" | ||
12177 | +msgstr "Desculpe, você não pode mais preencher esse formulário" | ||
12178 | + | ||
12179 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/_empty_field.html.erb:8 | ||
12180 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/_field.html.erb:10 | ||
12181 | +msgid "Are you sure you want to remove this field?" | ||
12182 | +msgstr "Tem certeza de que deseja remover este campo?" | ||
12183 | + | ||
12184 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/_field.html.erb:3 | ||
12185 | +msgid "Remove field" | ||
12186 | +msgstr "Remover campo" | ||
12187 | + | ||
12188 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/index.html.erb:3 | ||
12189 | +msgid "Manage forms" | ||
12190 | +msgstr "Gerenciar formulários" | ||
12191 | + | ||
12192 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/index.html.erb:7 | ||
12193 | +msgid "Period" | ||
12194 | +msgstr "Período" | ||
12195 | + | ||
12196 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/_form.html.erb:7 | ||
12197 | +msgid "What is the time limit for this form to be filled?" | ||
12198 | +msgstr "Qual o período limite em que esse formulário pode ser preenchido?" | ||
12199 | + | ||
12200 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/index.html.erb:8 | ||
12201 | +msgid "Submissions" | ||
12202 | +msgstr "Submissões" | ||
12203 | + | ||
12109 | #: plugins/tolerance_time/views/tolerance_time_plugin_myprofile/index.html.erb:14 | 12204 | #: plugins/tolerance_time/views/tolerance_time_plugin_myprofile/index.html.erb:14 |
12110 | msgid "Comment edition tolerance time" | 12205 | msgid "Comment edition tolerance time" |
12111 | msgstr "Tempo de tolerância para edição de comentários" | 12206 | msgstr "Tempo de tolerância para edição de comentários" |
@@ -12122,6 +12217,14 @@ msgstr "Mostrando página %d de %d" | @@ -12122,6 +12217,14 @@ msgstr "Mostrando página %d de %d" | ||
12122 | msgid "No filter available" | 12217 | msgid "No filter available" |
12123 | msgstr "Nenhum filtro disponível" | 12218 | msgstr "Nenhum filtro disponível" |
12124 | 12219 | ||
12220 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/_form.html.erb:14 | ||
12221 | +msgid "Triggered on membership request as requirement for approval" | ||
12222 | +msgstr "Disparado para novos integrantes como requisito de aprovação" | ||
12223 | + | ||
12224 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/_form.html.erb:15 | ||
12225 | +msgid "Triggered after membership" | ||
12226 | +msgstr "Disparado depois da aprovação de um novo integrante" | ||
12227 | + | ||
12125 | #: plugins/sub_organizations/views/sub_organizations_plugin_myprofile/index.html.erb:4 | 12228 | #: plugins/sub_organizations/views/sub_organizations_plugin_myprofile/index.html.erb:4 |
12126 | msgid "Sub-groups awaiting approval:" | 12229 | msgid "Sub-groups awaiting approval:" |
12127 | msgstr "Sub-grupos aguardando aprovação:" | 12230 | msgstr "Sub-grupos aguardando aprovação:" |
@@ -12134,6 +12237,36 @@ msgstr "Criar nova sub-comunidade" | @@ -12134,6 +12237,36 @@ msgstr "Criar nova sub-comunidade" | ||
12134 | msgid "Register a new sub-enterprise" | 12237 | msgid "Register a new sub-enterprise" |
12135 | msgstr "Registrar um novo sub-empreendimento" | 12238 | msgstr "Registrar um novo sub-empreendimento" |
12136 | 12239 | ||
12240 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/_form.html.erb:30 | ||
12241 | +msgid "Add a new text field" | ||
12242 | +msgstr "Adicionar novo campo de texto" | ||
12243 | + | ||
12244 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/_form.html.erb:31 | ||
12245 | +msgid "Add a new select field" | ||
12246 | +msgstr "Adicionar novo campo de seleção" | ||
12247 | + | ||
12248 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/_option.html.erb:5 | ||
12249 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/_empty_option.html.erb:5 | ||
12250 | +msgid "Are you sure you want to remove this option?" | ||
12251 | +msgstr "Tem certeza de que deseja remover esta opção?" | ||
12252 | + | ||
12253 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/pending.html.erb:3 | ||
12254 | +msgid "Pending submissions for %s" | ||
12255 | +msgstr "Submissões pendentes para %s" | ||
12256 | + | ||
12257 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/pending.html.erb:6 | ||
12258 | +msgid "There are no pending submissions for this form." | ||
12259 | +msgstr "Não há submissões pendentes para esse formulário" | ||
12260 | + | ||
12261 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/pending.html.erb:13 | ||
12262 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/pending.html.erb:9 | ||
12263 | +msgid "User" | ||
12264 | +msgstr "Usuário" | ||
12265 | + | ||
12266 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/show_submission.html.erb:9 | ||
12267 | +msgid "Back to submissions" | ||
12268 | +msgstr "Voltar para submissões" | ||
12269 | + | ||
12137 | #: plugins/sub_organizations/views/sub_organizations_plugin_myprofile/index.html.erb:18 | 12270 | #: plugins/sub_organizations/views/sub_organizations_plugin_myprofile/index.html.erb:18 |
12138 | msgid "" | 12271 | msgid "" |
12139 | "Fill in the search field to find the groups that should be added as sub-" | 12272 | "Fill in the search field to find the groups that should be added as sub-" |
@@ -12158,6 +12291,14 @@ msgstr "" | @@ -12158,6 +12291,14 @@ msgstr "" | ||
12158 | "O fornecedor já recebeu o seu pedido de compra e deve te contactar para " | 12291 | "O fornecedor já recebeu o seu pedido de compra e deve te contactar para " |
12159 | "confirmação." | 12292 | "confirmação." |
12160 | 12293 | ||
12294 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/submissions.html.erb:9 | ||
12295 | +msgid "Download all form responses as" | ||
12296 | +msgstr "Baixar todas as respostas como" | ||
12297 | + | ||
12298 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/submissions.html.erb:11 | ||
12299 | +msgid "Time" | ||
12300 | +msgstr "Tempo" | ||
12301 | + | ||
12161 | #: plugins/shopping_cart/views/shopping_cart_plugin/mailer/customer_notification.html.erb:12 | 12302 | #: plugins/shopping_cart/views/shopping_cart_plugin/mailer/customer_notification.html.erb:12 |
12162 | msgid "If you have any doubts, contact us at: %s" | 12303 | msgid "If you have any doubts, contact us at: %s" |
12163 | msgstr "Se você tem alguma dúvida, nos contacte em: %s" | 12304 | msgstr "Se você tem alguma dúvida, nos contacte em: %s" |
@@ -12218,6 +12359,34 @@ msgstr "Esse é um pedido de compra feito por %s." | @@ -12218,6 +12359,34 @@ msgstr "Esse é um pedido de compra feito por %s." | ||
12218 | msgid "Below follows the customer informations:" | 12359 | msgid "Below follows the customer informations:" |
12219 | msgstr "Abaixo seguem as informações do consumidor:" | 12360 | msgstr "Abaixo seguem as informações do consumidor:" |
12220 | 12361 | ||
12362 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/custom_forms_plugin/_text_field.html.erb:25 | ||
12363 | +msgid "Default text:" | ||
12364 | +msgstr "Texto padrão:" | ||
12365 | + | ||
12366 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/custom_forms_plugin/_select_field.html.erb:17 | ||
12367 | +msgid "Alternative" | ||
12368 | +msgstr "Alternativa" | ||
12369 | + | ||
12370 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/custom_forms_plugin/_select_field.html.erb:18 | ||
12371 | +msgid "Preselected" | ||
12372 | +msgstr "Pré-selecionado" | ||
12373 | + | ||
12374 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/custom_forms_plugin/_select_field.html.erb:25 | ||
12375 | +msgid "Add a new alternative" | ||
12376 | +msgstr "Adicionar nova alternativa" | ||
12377 | + | ||
12378 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/custom_forms_plugin/_alternative.html.erb:10 | ||
12379 | +msgid "Remove alternative" | ||
12380 | +msgstr "Remover alternativa" | ||
12381 | + | ||
12382 | +#: plugins/custom_forms/views/custom_forms_plugin_myprofile/custom_forms_plugin/_alternative.html.erb:10 | ||
12383 | +msgid "Are you sure you want to remove this alternative?" | ||
12384 | +msgstr "Tem certeza que quer remover essa alternativa?" | ||
12385 | + | ||
12386 | +#: plugins/tolerance_time/views/tolerance_time_plugin_myprofile/index.html.erb:1 | ||
12387 | +msgid "Tolerance Adjustments" | ||
12388 | +msgstr "Configurações de Tolerância" | ||
12389 | + | ||
12221 | #: plugins/shopping_cart/views/shopping_cart_plugin/mailer/supplier_notification.html.erb:45 | 12390 | #: plugins/shopping_cart/views/shopping_cart_plugin/mailer/supplier_notification.html.erb:45 |
12222 | msgid "And here are the items bought by this customer:" | 12391 | msgid "And here are the items bought by this customer:" |
12223 | msgstr "E aqui estão os itens pedidos por esse consumidor:" | 12392 | msgstr "E aqui estão os itens pedidos por esse consumidor:" |
public/stylesheets/application.css
@@ -2533,11 +2533,11 @@ div#activation_enterprise label, div#activation_enterprise input, div#activation | @@ -2533,11 +2533,11 @@ div#activation_enterprise label, div#activation_enterprise input, div#activation | ||
2533 | } | 2533 | } |
2534 | /*** REQUIRED FIELDS ***/ | 2534 | /*** REQUIRED FIELDS ***/ |
2535 | 2535 | ||
2536 | -.required-field label { | 2536 | +.required-field label.formlabel { |
2537 | font-weight: bold; | 2537 | font-weight: bold; |
2538 | color: #c00; | 2538 | color: #c00; |
2539 | } | 2539 | } |
2540 | -.required-field label:after { | 2540 | +.required-field label.formlabel:after { |
2541 | content: ' (*)'; | 2541 | content: ' (*)'; |
2542 | } | 2542 | } |
2543 | .login-box { | 2543 | .login-box { |