erp_forms 2.0.6 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/app/controllers/erp_forms/erp_app/desktop/dynamic_forms/base_controller.rb +4 -37
- data/app/controllers/erp_forms/erp_app/desktop/dynamic_forms/data_controller.rb +348 -82
- data/app/controllers/erp_forms/erp_app/desktop/dynamic_forms/forms_controller.rb +110 -15
- data/app/controllers/erp_forms/erp_app/desktop/dynamic_forms/models_controller.rb +19 -3
- data/app/mailers/dynamic_form_mailer.rb +35 -0
- data/app/models/dynamic_datum.rb +97 -22
- data/app/models/dynamic_form.rb +172 -98
- data/app/models/dynamic_form_document.rb +4 -11
- data/app/models/dynamic_form_model.rb +46 -22
- data/app/models/ticket.rb +4 -0
- data/app/views/dynamic_form_mailer/widget_email_with_attachments.html.erb +3 -0
- data/app/views/dynamic_form_mailer/widget_email_with_attachments.text.erb +3 -0
- data/app/widgets/dynamic_forms/base.rb +101 -19
- data/app/widgets/dynamic_forms/javascript/dynamic_forms.js +40 -38
- data/app/widgets/dynamic_forms/views/error.html.erb +1 -0
- data/db/data_migrations/20110608185830_create_default_dynamic_models_and_forms.rb +2 -0
- data/db/data_migrations/20120824013449_create_ticket_form.rb +1 -0
- data/db/data_migrations/20121026013449_update_ticket_form.rb +64 -0
- data/db/data_migrations/{20120904191738_update_contact_form.rb → 20121026191738_update_contact_form.rb} +4 -0
- data/db/migrate/20110530193446_dynamic_forms.rb +12 -0
- data/db/migrate/20121007022323_upgrade_dynamic_forms_table.rb +31 -0
- data/lib/erp_forms.rb +4 -0
- data/lib/erp_forms/dynamic_form_field.rb +31 -28
- data/lib/erp_forms/dynamic_grid_column.rb +2 -2
- data/lib/erp_forms/engine.rb +5 -0
- data/lib/erp_forms/extensions/active_record/acts_as_commentable.rb +33 -0
- data/lib/erp_forms/extensions/active_record/acts_as_dynamic_form_model.rb +80 -0
- data/lib/erp_forms/extensions/active_record/has_dynamic_forms.rb +4 -4
- data/lib/erp_forms/extensions/extensions.rb +2 -0
- data/lib/erp_forms/extensions/railties/action_view.rb +2 -2
- data/lib/erp_forms/version.rb +2 -2
- data/public/javascripts/erp_app/desktop/applications/dynamic_forms/center_region.js +2 -1
- data/public/javascripts/erp_app/desktop/applications/dynamic_forms/dynamic_data_grid.js +264 -82
- data/public/javascripts/erp_app/desktop/applications/dynamic_forms/form_builder.js +1476 -58
- data/public/javascripts/erp_app/desktop/applications/dynamic_forms/module.js +24 -1
- data/public/javascripts/erp_app/desktop/applications/dynamic_forms/west_region.js +493 -210
- data/public/javascripts/erp_app/shared/dynamic_forms/dynamic_form_fields.js +82 -20
- data/public/javascripts/erp_app/shared/dynamic_forms/dynamic_forms_validation.js +23 -3
- data/spec/dummy/config/application.rb +6 -2
- data/spec/dummy/config/environments/spec.rb +3 -0
- data/spec/dummy/db/data_migrations/20110109173616_create_capability_scope_types.erp_tech_svcs.rb +15 -0
- data/spec/dummy/db/data_migrations/20110525001935_add_usd_currency.erp_base_erp_svcs.rb +12 -0
- data/spec/dummy/db/data_migrations/20110608185830_create_default_dynamic_models_and_forms.erp_forms.rb +33 -0
- data/spec/dummy/db/data_migrations/20110609150135_add_iso_codes.erp_base_erp_svcs.rb +19 -0
- data/spec/dummy/db/data_migrations/20110728201729_erp_app_setup.erp_app.rb +252 -0
- data/spec/dummy/db/data_migrations/20110728201733_update_preferences.erp_app.rb +53 -0
- data/spec/dummy/db/data_migrations/20110802200222_schedule_delete_expired_sessions_job.erp_tech_svcs.rb +16 -0
- data/spec/dummy/db/data_migrations/20110816161238_create_desktop_app_audit_log_viewer.erp_app.rb +21 -0
- data/spec/dummy/db/data_migrations/20110817160743_add_file_manager_application.erp_app.rb +32 -0
- data/spec/dummy/db/data_migrations/20110828190913_create_desktop_app_dynamic_forms.erp_forms.rb +19 -0
- data/spec/dummy/db/data_migrations/20110913145838_setup_compass_ae_instance.erp_base_erp_svcs.rb +12 -0
- data/spec/dummy/db/data_migrations/20111108183739_add_default_capabilities.erp_app.rb +23 -0
- data/spec/dummy/db/data_migrations/20111108183740_add_new_contact_widgets.erp_app.rb +42 -0
- data/spec/dummy/db/data_migrations/20111111144706_setup_audit_log_types.erp_tech_svcs.rb +22 -0
- data/spec/dummy/db/data_migrations/20120109173616_create_download_capability_type.erp_tech_svcs.rb +14 -0
- data/spec/dummy/db/data_migrations/20120229160222_add_userinfo_widget.erp_app.rb +29 -0
- data/spec/dummy/db/data_migrations/20120405193721_create_party_and_role_type_for_communication_events.erp_app.rb +11 -0
- data/spec/dummy/db/data_migrations/20120411180756_create_user_management_mobile_application.erp_app.rb +19 -0
- data/spec/dummy/db/data_migrations/20120418164215_create_configuration_management_desktop_application.erp_app.rb +23 -0
- data/spec/dummy/db/data_migrations/20120824013449_create_ticket_form.erp_forms.rb +67 -0
- data/spec/dummy/db/data_migrations/20121026013449_update_ticket_form.erp_forms.rb +65 -0
- data/spec/dummy/db/data_migrations/20121026191738_update_contact_form.erp_forms.rb +27 -0
- data/spec/dummy/db/data_migrations/20121116155018_create_group_relationship_and_role_types.erp_tech_svcs.rb +20 -0
- data/spec/dummy/db/data_migrations/20121130201859_upgrade_remove_system_mgmt_app.erp_app.rb +16 -0
- data/spec/dummy/db/data_migrations/20121130212146_note_capabilities.erp_tech_svcs.rb +24 -0
- data/spec/dummy/db/data_migrations/20121218175028_create_security_management_desktop_application.erp_app.rb +23 -0
- data/spec/dummy/db/migrate/20121213234847_base_erp_services.erp_base_erp_svcs.rb +461 -0
- data/spec/dummy/db/migrate/20121213234848_base_tech_services.erp_tech_svcs.rb +255 -0
- data/spec/dummy/db/migrate/20121213234849_create_has_attribute_tables.erp_tech_svcs.rb +39 -0
- data/spec/dummy/db/migrate/20121213234850_base_app_framework.erp_app.rb +276 -0
- data/spec/dummy/db/migrate/20121213234851_dynamic_forms.erp_forms.rb +95 -0
- data/spec/dummy/db/migrate/20121213234852_create_tickets.erp_forms.rb +19 -0
- data/spec/dummy/db/migrate/20121213234853_upgrade_dynamic_forms_table.erp_forms.rb +32 -0
- data/spec/dummy/db/migrate/20130107181041_create_groups.erp_tech_svcs.rb +19 -0
- data/spec/dummy/db/migrate/20130107181042_upgrade_security.erp_tech_svcs.rb +54 -0
- data/spec/dummy/db/migrate/20130107181043_upgrade_security2.erp_tech_svcs.rb +270 -0
- data/spec/dummy/db/schema.rb +879 -0
- data/spec/dummy/db/spec.sqlite3 +0 -0
- data/spec/dummy/log/spec.log +13580 -0
- data/spec/models/dynamic_form_model_spec.rb +1 -1
- data/spec/spec_helper.rb +11 -3
- metadata +136 -14
@@ -2,7 +2,7 @@ class ErpForms::ErpApp::Desktop::DynamicForms::FormsController < ErpForms::ErpAp
|
|
2
2
|
|
3
3
|
# get tree of dynamic models and forms
|
4
4
|
def get_tree
|
5
|
-
models = params[:node] == "root" ? DynamicFormModel.all(:order => :model_name) : DynamicFormModel.find_all_by_id(id)
|
5
|
+
models = params[:node] == "root" ? DynamicFormModel.all(:order => :model_name) : DynamicFormModel.find_all_by_id(params[:id])
|
6
6
|
tree = []
|
7
7
|
|
8
8
|
models.each do |form_model|
|
@@ -13,10 +13,15 @@ class ErpForms::ErpApp::Desktop::DynamicForms::FormsController < ErpForms::ErpAp
|
|
13
13
|
:text => form_model.model_name,
|
14
14
|
:iconCls => 'icon-data',
|
15
15
|
:id => "form_model_#{form_model.id}",
|
16
|
-
:
|
17
|
-
:
|
16
|
+
:formModelId => form_model.id,
|
17
|
+
:isFormModel => true,
|
18
|
+
:allow_comments => form_model.allow_comments,
|
19
|
+
:allow_files => form_model.allow_files,
|
20
|
+
:file_security_default => form_model.file_security_default,
|
21
|
+
:show_in_multitask => form_model.show_in_multitask,
|
18
22
|
:isForm => false,
|
19
23
|
:leaf => false,
|
24
|
+
:expanded => true,
|
20
25
|
:children => []
|
21
26
|
}
|
22
27
|
|
@@ -27,9 +32,9 @@ class ErpForms::ErpApp::Desktop::DynamicForms::FormsController < ErpForms::ErpAp
|
|
27
32
|
:iconCls => (form.default ? 'icon-document_ok' : 'icon-document'),
|
28
33
|
:id => "form_#{form.id}",
|
29
34
|
:formId => form.id,
|
30
|
-
:
|
31
|
-
:
|
32
|
-
:
|
35
|
+
:isFormModel => false,
|
36
|
+
:isDefaultForm => form.default,
|
37
|
+
:formModelName => form_model.model_name,
|
33
38
|
:isForm => true,
|
34
39
|
:leaf => true
|
35
40
|
}
|
@@ -46,15 +51,34 @@ class ErpForms::ErpApp::Desktop::DynamicForms::FormsController < ErpForms::ErpAp
|
|
46
51
|
|
47
52
|
# get a single form definition
|
48
53
|
def get_definition
|
49
|
-
|
54
|
+
dform = DynamicForm.find_by_id(params[:id]) if params[:id]
|
55
|
+
dform = DynamicForm.get_form(params[:model_name], params[:internal_identifier]) if dform.nil? and params[:model_name]
|
56
|
+
|
57
|
+
if dform.nil?
|
58
|
+
render :json => {:success => false}
|
59
|
+
else
|
60
|
+
render :json => dform.definition
|
61
|
+
end
|
62
|
+
end
|
50
63
|
|
51
|
-
|
64
|
+
# get a single form record
|
65
|
+
def get_record
|
66
|
+
dform = DynamicForm.find(params[:id]) rescue nil
|
67
|
+
|
68
|
+
unless dform.nil?
|
69
|
+
dform_hash = dform.to_hash
|
70
|
+
dform_hash[:created_by] = dform.created_by.username rescue 'Unknown'
|
71
|
+
dform_hash[:updated_by] = dform.updated_by.username rescue 'Unknown'
|
72
|
+
dform_hash[:created_at] = dform.created_at.getlocal.strftime(@@datetime_format)
|
73
|
+
dform_hash[:updated_at] = dform.updated_at.getlocal.strftime(@@datetime_format)
|
74
|
+
end
|
75
|
+
render :json => [dform_hash]
|
52
76
|
end
|
53
77
|
|
54
78
|
# get a single form
|
55
79
|
def get
|
56
80
|
dform = DynamicForm.find_by_id(params[:id]) if params[:id]
|
57
|
-
dform = DynamicForm.get_form(params[:model_name]) if dform.nil? and params[:model_name]
|
81
|
+
dform = DynamicForm.get_form(params[:model_name], params[:internal_identifier]) if dform.nil? and params[:model_name]
|
58
82
|
|
59
83
|
if dform.nil?
|
60
84
|
render :json => {:success => false, :error => "Don't know how to find form"} and return
|
@@ -70,25 +94,96 @@ class ErpForms::ErpApp::Desktop::DynamicForms::FormsController < ErpForms::ErpAp
|
|
70
94
|
|
71
95
|
# get related data for a related field
|
72
96
|
def related_field
|
73
|
-
|
74
|
-
|
97
|
+
if params[:model].blank? or (params[:displayField].blank? and params[:search_fields].blank?)
|
98
|
+
render :inline => '[]'
|
99
|
+
else
|
100
|
+
related_model = params[:model].camelize.constantize
|
101
|
+
query = related_model
|
102
|
+
|
103
|
+
unless params[:search_fields].blank?
|
104
|
+
#related_searchbox
|
105
|
+
search_fields = params[:search_fields].split(',')
|
106
|
+
unless params[:query].blank?
|
107
|
+
sql = ''
|
108
|
+
search_fields.each_with_index do |f,i|
|
109
|
+
sql += " OR " if i > 0
|
110
|
+
sql += "UPPER(#{f}) LIKE UPPER('%#{params[:query]}%')"
|
111
|
+
end
|
112
|
+
query = query.where(sql)
|
113
|
+
end
|
114
|
+
query = query.paginate(:page => page, :per_page => per_page)
|
115
|
+
end
|
75
116
|
|
76
|
-
|
117
|
+
total = query.count
|
118
|
+
data = query.all
|
119
|
+
render :inline => { :data => data, :total => total}.to_json
|
120
|
+
end
|
77
121
|
end
|
78
122
|
|
79
123
|
# delete dynamic form
|
80
124
|
def delete
|
81
|
-
|
125
|
+
dform = DynamicForm.find_by_id(params[:id])
|
126
|
+
unless dform.nil?
|
127
|
+
begin
|
128
|
+
dform.destroy
|
129
|
+
render :json => {:success => true}
|
130
|
+
rescue Exception => e
|
131
|
+
render :json => {:success => false, :error => e.message}
|
132
|
+
end
|
133
|
+
else
|
134
|
+
render :json => {:success => false, :error => 'Could not find form.'}
|
135
|
+
end
|
82
136
|
end
|
83
137
|
|
84
138
|
# update dynamic form
|
85
139
|
def update
|
86
|
-
|
140
|
+
dform = DynamicForm.find_by_id(params[:id])
|
141
|
+
dform = assign_form_attributes(dform)
|
142
|
+
dform.updated_by_id = current_user.id
|
143
|
+
|
144
|
+
# update solr config for model (doesn't work yet)
|
145
|
+
# DynamicFormModel.get_constant(dform.model_name).sunspot_setup if $USE_SOLR_FOR_DYNAMIC_FORM_MODELS
|
146
|
+
|
147
|
+
if dform.save
|
148
|
+
render :json => {:success => true}
|
149
|
+
else
|
150
|
+
render :json => {:success => false}
|
151
|
+
end
|
87
152
|
end
|
88
153
|
|
89
154
|
# create dynamic form
|
90
155
|
def create
|
91
|
-
|
156
|
+
if params[:form_definition] and params[:description] and params[:model_name]
|
157
|
+
dform = DynamicForm.new
|
158
|
+
dform = assign_form_attributes(dform)
|
159
|
+
dform.dynamic_form_model_id = DynamicFormModel.find_by_model_name(params[:model_name]).id
|
160
|
+
dform.default = false
|
161
|
+
dform.created_by_id = current_user.id
|
162
|
+
if dform.save
|
163
|
+
render :json => {:success => true, :id => dform.id}
|
164
|
+
else
|
165
|
+
render :json => {:success => false}
|
166
|
+
end
|
167
|
+
else
|
168
|
+
render :json => {:success => false, :error => 'Insufficient info to create form.'}
|
169
|
+
end
|
92
170
|
end
|
93
171
|
|
172
|
+
protected
|
173
|
+
def assign_form_attributes(dform)
|
174
|
+
dform.description = params[:description] unless params[:description].nil?
|
175
|
+
dform.definition = params[:form_definition] unless params[:form_definition].nil?
|
176
|
+
dform.model_name = params[:model_name] unless params[:model_name].nil?
|
177
|
+
dform.widget_action = params[:widget_action] unless params[:widget_action].nil?
|
178
|
+
dform.widget_email_recipients = params[:widget_email_recipients] unless params[:widget_email_recipients].nil?
|
179
|
+
dform.focus_first_field = params[:focus_first_field] unless params[:focus_first_field].nil?
|
180
|
+
dform.show_in_multitask = params[:show_in_multitask] unless params[:show_in_multitask].nil?
|
181
|
+
dform.msg_target = params[:msg_target] unless params[:msg_target].nil?
|
182
|
+
dform.submit_empty_text = params[:submit_empty_text] unless params[:submit_empty_text].nil?
|
183
|
+
dform.submit_button_label = params[:submit_button_label] unless params[:submit_button_label].nil?
|
184
|
+
dform.cancel_button_label = params[:cancel_button_label] unless params[:cancel_button_label].nil?
|
185
|
+
dform.comment = params[:comment] unless params[:comment].nil?
|
186
|
+
dform
|
187
|
+
end
|
188
|
+
|
94
189
|
end
|
@@ -8,7 +8,9 @@ class ErpForms::ErpApp::Desktop::DynamicForms::ModelsController < ErpForms::ErpA
|
|
8
8
|
dynamic_form_models.each do |m|
|
9
9
|
model_hash = {
|
10
10
|
:id => m.id,
|
11
|
-
:model_name => m.model_name
|
11
|
+
:model_name => m.model_name,
|
12
|
+
:file_security_default => m.file_security_default,
|
13
|
+
:show_in_multitask => m.show_in_multitask
|
12
14
|
}
|
13
15
|
|
14
16
|
models << model_hash
|
@@ -34,12 +36,26 @@ class ErpForms::ErpApp::Desktop::DynamicForms::ModelsController < ErpForms::ErpA
|
|
34
36
|
|
35
37
|
# create a dynamic form model
|
36
38
|
def create
|
37
|
-
model_name = params[:model_name]
|
38
39
|
DynamicFormModel.create({
|
39
|
-
:model_name => model_name
|
40
|
+
:model_name => params[:model_name],
|
41
|
+
:allow_comments => params[:allow_comments],
|
42
|
+
:allow_files => params[:allow_files],
|
43
|
+
:file_security_default => params[:file_security_default]
|
40
44
|
})
|
41
45
|
|
42
46
|
render :json => {:success => true}
|
43
47
|
end
|
48
|
+
|
49
|
+
# update a dynamic form model
|
50
|
+
def update
|
51
|
+
m = DynamicFormModel.find(params[:id])
|
52
|
+
m.allow_comments = params[:allow_comments] unless params[:allow_comments].nil?
|
53
|
+
m.allow_files = params[:allow_files] unless params[:allow_files].nil?
|
54
|
+
m.file_security_default = params[:file_security_default] unless params[:file_security_default].blank?
|
55
|
+
m.show_in_multitask = params[:show_in_multitask] unless params[:show_in_multitask].nil?
|
56
|
+
m.save
|
57
|
+
|
58
|
+
render :json => {:success => true}
|
59
|
+
end
|
44
60
|
|
45
61
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class DynamicFormMailer < ActionMailer::Base
|
2
|
+
|
3
|
+
# def widget_email(form, dynamicObject, subject='')
|
4
|
+
# subject = "#{model_name} Submission" if subject.blank?
|
5
|
+
# @dynamicObject = dynamicObject
|
6
|
+
|
7
|
+
# mail( :to => form.widget_email_recipients,
|
8
|
+
# :from => ErpTechSvcs::Config.email_notifications_from,
|
9
|
+
# :subject => subject,
|
10
|
+
# :content_type => 'text/plain'
|
11
|
+
# )
|
12
|
+
# end
|
13
|
+
|
14
|
+
# uses mail_alternatives_with_attachments gem
|
15
|
+
# ActionMailer doesn't handle attachments well without this gem
|
16
|
+
def widget_email_with_attachments(form, dynamicObject, subject='', files=[])
|
17
|
+
related_fields = dynamicObject.form.related_fields rescue []
|
18
|
+
@dynamicData = dynamicObject.data.dynamic_attributes_with_related_data(related_fields, true)
|
19
|
+
subject = "#{model_name} Submission" if subject.blank?
|
20
|
+
message = prepare_message to: form.widget_email_recipients, from: ErpTechSvcs::Config.email_notifications_from, subject: subject, :content_type => "multipart/mixed"
|
21
|
+
|
22
|
+
message.alternative_content_types_with_attachment(
|
23
|
+
:text => render_to_string(:template => "dynamic_form_mailer/widget_email_with_attachments.text"),
|
24
|
+
:html => render_to_string(:template => "dynamic_form_mailer/widget_email_with_attachments.html")
|
25
|
+
) do |inline_attachments|
|
26
|
+
files.each do |f|
|
27
|
+
attachments.inline[f.original_filename] = f.tempfile.read
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
message
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
data/app/models/dynamic_datum.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
class DynamicDatum < ActiveRecord::Base
|
2
|
+
attr_protected :created_at, :updated_at
|
3
|
+
|
2
4
|
DYNAMIC_ATTRIBUTE_PREFIX = 'dyn_'
|
3
5
|
|
4
6
|
has_dynamic_attributes :dynamic_attribute_prefix => DYNAMIC_ATTRIBUTE_PREFIX, :destroy_dynamic_attribute_for_nil => false
|
@@ -20,11 +22,19 @@ class DynamicDatum < ActiveRecord::Base
|
|
20
22
|
|
21
23
|
def dynamic_attributes_with_related_data(related_fields=[], use_label=false)
|
22
24
|
key = (use_label ? :fieldLabel : :name)
|
23
|
-
data = sorted_dynamic_attributes(
|
25
|
+
data = sorted_dynamic_attributes(:use_label => use_label)
|
24
26
|
related_fields.each do |r|
|
25
27
|
data.each do |k,v|
|
26
28
|
if k == r[key]
|
27
|
-
|
29
|
+
if r[:xtype] == 'related_combobox'
|
30
|
+
d = r[:displayField]
|
31
|
+
t = nil
|
32
|
+
else
|
33
|
+
#related_searchbox
|
34
|
+
d = r[:display_fields].split(',')
|
35
|
+
t = r[:display_template]
|
36
|
+
end
|
37
|
+
data[k] = DynamicDatum.related_data_value(r[:extraParams]['model'], v, d, t)
|
28
38
|
end
|
29
39
|
end
|
30
40
|
end
|
@@ -32,44 +42,109 @@ class DynamicDatum < ActiveRecord::Base
|
|
32
42
|
data
|
33
43
|
end
|
34
44
|
|
45
|
+
#column can be a string or array of strings
|
46
|
+
def self.related_data_value(model, id, column, template=nil)
|
47
|
+
if column.is_a?(String)
|
48
|
+
return model.camelize.constantize.find(id).send(column) rescue nil
|
49
|
+
else
|
50
|
+
final_display = template
|
51
|
+
column.each do |c|
|
52
|
+
value = model.camelize.constantize.find(id).send(c) rescue nil
|
53
|
+
final_display = final_display.gsub(c, value)
|
54
|
+
end
|
55
|
+
return final_display.gsub('{','').gsub('}','')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
35
59
|
# we cannot assume that dynamic attributes are stored in order in the database as this is often not the case
|
36
60
|
# this method will sort them according to the order of the fields in the form definition
|
37
61
|
# method returns an ordered hash
|
38
|
-
#
|
39
|
-
|
40
|
-
|
62
|
+
# options = {:with_prefix => false, :use_label => false, :all => false}
|
63
|
+
# :with_prefix = false will remove the dyn_ from the attribute key
|
64
|
+
# if :with_prefix is false, you may choose to use the fieldLabel as the hash key by setting :use_label = true
|
65
|
+
# :use_label is useful displaying data on a view screen or formatting an email
|
66
|
+
# :all = false will only return attributes that are in the form definition
|
67
|
+
# :all = true will return all attributes with those not in the form definition last
|
68
|
+
# you can set :all = true and :use_label = true, but attributes not in definition will use key.titleize
|
69
|
+
# if for some reason a form cannot be found, sorting will not be attempted
|
70
|
+
def sorted_dynamic_attributes(options={})
|
71
|
+
options[:with_prefix] = false if options[:with_prefix].nil?
|
72
|
+
options[:use_label] = false if options[:use_label].nil?
|
73
|
+
options[:all] = true if options[:all].nil?
|
74
|
+
|
75
|
+
form = self.updated_with_form !self.updated_with_form.nil?
|
41
76
|
form = self.created_with_form if form.nil? and !self.created_with_form.nil?
|
42
77
|
form = DynamicForm.get_form(self.reference_type) if form.nil?
|
43
78
|
|
44
79
|
unless form.nil?
|
45
|
-
|
46
|
-
|
80
|
+
fields = form.definition_object
|
81
|
+
|
82
|
+
fields_and_values = {}
|
83
|
+
if options[:with_prefix]
|
84
|
+
fields.each do |f|
|
85
|
+
k = DYNAMIC_ATTRIBUTE_PREFIX + f[:name]
|
86
|
+
next if k == DYNAMIC_ATTRIBUTE_PREFIX + 'file' # we dont want to show file upload fields
|
87
|
+
fields_and_values[k] = {}
|
88
|
+
fields_and_values[k][:value] = self.dynamic_attributes[k]
|
89
|
+
fields_and_values[k][:xtype] = f[:xtype]
|
90
|
+
end
|
47
91
|
else
|
48
|
-
|
49
|
-
|
92
|
+
fields.each do |f|
|
93
|
+
k = f[:name]
|
94
|
+
next if k == 'file' # we dont want to show file upload fields
|
95
|
+
fields_and_values[k] = {}
|
96
|
+
fields_and_values[k][:value] = self.dynamic_attributes_without_prefix[k]
|
97
|
+
fields_and_values[k][:xtype] = f[:xtype]
|
98
|
+
fields_and_values[k][:fieldLabel] = f[:fieldLabel] if options[:use_label]
|
99
|
+
end
|
50
100
|
end
|
51
101
|
|
102
|
+
# although we try and save integers as integers, we ensure here they are integers so that combobox value is selected
|
103
|
+
related_fields = form.related_fields
|
104
|
+
if related_fields.length > 0
|
105
|
+
related_fields.collect{|f| f[:name]}.each do |k|
|
106
|
+
k = DYNAMIC_ATTRIBUTE_PREFIX+k if options[:with_prefix]
|
107
|
+
fields_and_values[k][:value] = fields_and_values[k][:value].to_i
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
52
111
|
sorted = {}
|
53
112
|
i=0
|
54
|
-
|
55
|
-
if with_prefix
|
56
|
-
sorted[key] =
|
113
|
+
fields_and_values.each do |key, field|
|
114
|
+
if options[:with_prefix]
|
115
|
+
sorted[key] = field[:value]
|
57
116
|
else
|
58
|
-
index = (use_label ?
|
59
|
-
sorted[index] =
|
60
|
-
end
|
61
|
-
|
117
|
+
index = (options[:use_label] ? field[:fieldLabel] : key)
|
118
|
+
sorted[index] = field[:value]
|
119
|
+
end
|
62
120
|
i += 1
|
63
121
|
end
|
64
122
|
|
123
|
+
if options[:all]
|
124
|
+
# append attributes not in definition
|
125
|
+
attrs = (options[:with_prefix] ? self.dynamic_attributes : self.dynamic_attributes_without_prefix)
|
126
|
+
keys = fields_and_values.collect{|k,v| k}
|
127
|
+
|
128
|
+
i=0
|
129
|
+
sorted.each do |k,v|
|
130
|
+
index = (options[:use_label] ? keys[i] : k)
|
131
|
+
attrs.delete(index)
|
132
|
+
i += 1
|
133
|
+
end
|
134
|
+
|
135
|
+
attrs.each do |k,v|
|
136
|
+
if options[:with_prefix]
|
137
|
+
sorted[k] = self.dynamic_attributes[k]
|
138
|
+
else
|
139
|
+
index = (options[:use_label] ? k.titleize : k)
|
140
|
+
sorted[index] = self.dynamic_attributes_without_prefix[k]
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
65
145
|
return sorted
|
66
146
|
else
|
67
|
-
|
68
|
-
return self.dynamic_attributes
|
69
|
-
else
|
70
|
-
return self.dynamic_attributes_without_prefix
|
71
|
-
end
|
147
|
+
return (options[:with_prefix] ? self.dynamic_attributes : self.dynamic_attributes_without_prefix)
|
72
148
|
end
|
73
149
|
end
|
74
|
-
|
75
150
|
end
|
data/app/models/dynamic_form.rb
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
class DynamicForm < ActiveRecord::Base
|
2
|
+
attr_protected :created_at, :updated_at
|
3
|
+
|
2
4
|
belongs_to :dynamic_form_model
|
5
|
+
belongs_to :created_by, :class_name => "User"
|
6
|
+
belongs_to :updated_by, :class_name => "User"
|
7
|
+
|
8
|
+
extend FriendlyId
|
9
|
+
friendly_id :description, :use => [:slugged], :slug_column => :internal_identifier
|
10
|
+
def should_generate_new_friendly_id?
|
11
|
+
new_record?
|
12
|
+
end
|
3
13
|
|
4
14
|
validates_uniqueness_of :internal_identifier, :scope => :model_name, :case_sensitive => false
|
5
15
|
|
@@ -7,7 +17,7 @@ class DynamicForm < ActiveRecord::Base
|
|
7
17
|
result = nil
|
8
18
|
begin
|
9
19
|
klass = Module.const_get(class_name)
|
10
|
-
|
20
|
+
result = (klass.is_a?(Class) ? ((klass.superclass == ActiveRecord::Base or klass.superclass == DynamicModel) ? true : nil) : nil)
|
11
21
|
rescue NameError
|
12
22
|
result = nil
|
13
23
|
end
|
@@ -15,12 +25,9 @@ class DynamicForm < ActiveRecord::Base
|
|
15
25
|
end
|
16
26
|
|
17
27
|
def self.get_form(klass_name, internal_identifier='')
|
18
|
-
result = nil
|
19
|
-
|
20
|
-
|
21
|
-
else
|
22
|
-
result = DynamicForm.find_by_model_name_and_default(klass_name, true)
|
23
|
-
end
|
28
|
+
result = nil
|
29
|
+
result = DynamicForm.find_by_model_name_and_internal_identifier(klass_name, internal_identifier) unless internal_identifier.blank?
|
30
|
+
result = DynamicForm.find_by_model_name_and_default(klass_name, true) if result.nil?
|
24
31
|
result
|
25
32
|
end
|
26
33
|
|
@@ -38,22 +45,30 @@ class DynamicForm < ActiveRecord::Base
|
|
38
45
|
end
|
39
46
|
|
40
47
|
def add_validation(def_object)
|
41
|
-
def_object.each do |item|
|
42
|
-
if item[:
|
43
|
-
item[:
|
44
|
-
elsif item[:
|
45
|
-
item[:validator] = NonEscapeJsonString.new("function(v){ return
|
48
|
+
def_object.each do |item|
|
49
|
+
if !item[:validation_regex].blank?
|
50
|
+
item[:regex] = NonEscapeJsonString.new(item[:validation_regex].match('^\/') ? item[:validation_regex] : '/'+item[:validation_regex]+'/')
|
51
|
+
elsif !item[:validator_function].blank?
|
52
|
+
item[:validator] = NonEscapeJsonString.new("function(v){ return #{item[:validator_function]}; }")
|
46
53
|
end
|
47
54
|
end
|
48
55
|
|
49
56
|
def_object
|
50
57
|
end
|
58
|
+
|
59
|
+
def add_help_qtip(def_object)
|
60
|
+
def_object.each do |item|
|
61
|
+
item[:plugins] = NonEscapeJsonString.new('[new helpQtip("'+item[:help_qtip].gsub(/\"/,'\"')+'")]') unless item[:help_qtip].blank?
|
62
|
+
end
|
63
|
+
|
64
|
+
def_object
|
65
|
+
end
|
51
66
|
|
52
67
|
# will return an array of field names that are of xtype 'related_combobox'
|
53
68
|
def related_fields
|
54
69
|
related_fields = []
|
55
70
|
definition_object.each do |f|
|
56
|
-
related_fields << f if f[:xtype]
|
71
|
+
related_fields << f if ['related_combobox','related_searchbox'].include?(f[:xtype])
|
57
72
|
end
|
58
73
|
|
59
74
|
related_fields
|
@@ -74,53 +89,98 @@ class DynamicForm < ActiveRecord::Base
|
|
74
89
|
array_of_fields.to_json
|
75
90
|
end
|
76
91
|
|
77
|
-
def
|
92
|
+
def focus_first_field_js
|
93
|
+
if self.focus_first_field
|
94
|
+
return "form.getComponent(0).focus(true, 200);"
|
95
|
+
else
|
96
|
+
return ''
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def submit_empty_text_js
|
101
|
+
if self.submit_empty_text
|
102
|
+
return "submitEmptyText: true,"
|
103
|
+
else
|
104
|
+
return ''
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def to_extjs_formpanel(options={})
|
78
109
|
form_hash = {
|
79
|
-
:xtype => '
|
80
|
-
:id => "dynamic_form_panel_#{model_name}",
|
110
|
+
:xtype => 'dynamic_form_panel',
|
81
111
|
:url => options[:url],
|
82
112
|
:title => self.description,
|
83
113
|
:frame => true,
|
84
|
-
:bodyStyle => 'padding: 5px 5px 0;'
|
114
|
+
:bodyStyle => 'padding: 5px 5px 0;',
|
115
|
+
:baseParams => {
|
116
|
+
:dynamic_form_id => self.id,
|
117
|
+
:dynamic_form_model_id => self.dynamic_form_model_id,
|
118
|
+
:model_name => self.model_name
|
119
|
+
},
|
120
|
+
:defaults => {},
|
121
|
+
:items => add_help_qtip(definition_with_validation)
|
85
122
|
}
|
86
|
-
|
123
|
+
form_hash[:defaults][:msgTarget] = self.msg_target unless self.msg_target.blank?
|
87
124
|
form_hash[:width] = options[:width] if options[:width]
|
88
|
-
form_hash[:baseParams] = {}
|
89
125
|
form_hash[:baseParams][:id] = options[:record_id] if options[:record_id]
|
90
|
-
form_hash[:baseParams][:dynamic_form_id] = self.id
|
91
|
-
form_hash[:baseParams][:dynamic_form_model_id] = self.dynamic_form_model_id
|
92
|
-
form_hash[:baseParams][:model_name] = self.model_name
|
93
126
|
form_hash[:listeners] = {
|
94
|
-
:afterrender => NonEscapeJsonString.new("function(form) {
|
127
|
+
:afterrender => NonEscapeJsonString.new("function(form) { #{focus_first_field_js} }")
|
95
128
|
}
|
96
|
-
form_hash[:items] = definition_with_validation
|
97
129
|
form_hash[:buttons] = []
|
98
|
-
form_hash[:buttons]
|
99
|
-
:text =>
|
130
|
+
form_hash[:buttons] << {
|
131
|
+
:text => self.submit_button_label,
|
100
132
|
:listeners => NonEscapeJsonString.new("{
|
101
|
-
|
102
|
-
var
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
}
|
111
|
-
},
|
112
|
-
failure:function(form, action){
|
113
|
-
Ext.Msg.alert(action.response.responseText);
|
114
|
-
}
|
133
|
+
click:function(button){
|
134
|
+
var form = button.findParentByType('form').getForm();
|
135
|
+
//jsonSubmit option only works when there is no filefield so we have to do it ourselves
|
136
|
+
//JSON is important to preserve data types (ie. we want integers to save as integers not strings)
|
137
|
+
var form_data = {};
|
138
|
+
Ext.each(form.getFields().items, function(field) {
|
139
|
+
if (Ext.Array.indexOf(['filefield','fileuploadfield'], field.xtype) < 0){
|
140
|
+
form_data[field.name] = field.getValue();
|
141
|
+
}
|
115
142
|
});
|
143
|
+
if (form.isValid()){
|
144
|
+
form.submit({
|
145
|
+
#{submit_empty_text_js}
|
146
|
+
reset:false,
|
147
|
+
params:{
|
148
|
+
form_data_json: Ext.encode(form_data)
|
149
|
+
},
|
150
|
+
success:function(form, action){
|
151
|
+
var obj = Ext.decode(action.response.responseText);
|
152
|
+
if(obj.success){
|
153
|
+
if (form.getRecord()){
|
154
|
+
form.owner.fireEvent('afterupdate');
|
155
|
+
}else{
|
156
|
+
form.owner.fireEvent('aftercreate', {
|
157
|
+
record: obj
|
158
|
+
});
|
159
|
+
}
|
160
|
+
}else{
|
161
|
+
Ext.Msg.alert('Error', obj.message);
|
162
|
+
}
|
163
|
+
},
|
164
|
+
failure:function(form, action){
|
165
|
+
Ext.Msg.alert('Error', action.response.responseText);
|
166
|
+
}
|
167
|
+
});
|
168
|
+
}else{
|
169
|
+
Ext.Msg.alert('Error','Please complete form.');
|
170
|
+
}
|
116
171
|
}
|
117
172
|
}")
|
118
173
|
}
|
119
|
-
form_hash[:buttons]
|
120
|
-
:text =>
|
174
|
+
form_hash[:buttons] << {
|
175
|
+
:text => self.cancel_button_label,
|
121
176
|
:listeners => NonEscapeJsonString.new("{
|
122
177
|
\"click\":function(button){
|
123
|
-
|
178
|
+
var form = button.findParentByType('form');
|
179
|
+
if (form.close_selector){
|
180
|
+
form.up(form.close_selector).close();
|
181
|
+
}else{
|
182
|
+
form.up('window').close();
|
183
|
+
}
|
124
184
|
}
|
125
185
|
}")
|
126
186
|
}
|
@@ -136,62 +196,76 @@ class DynamicForm < ActiveRecord::Base
|
|
136
196
|
# :widget_result_id =>
|
137
197
|
# :width =>
|
138
198
|
def to_extjs_widget(options={})
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
199
|
+
javascript = "Ext.QuickTips.init(); Ext.create('Ext.form.Panel',"
|
200
|
+
|
201
|
+
config_hash = {
|
202
|
+
:url => "#{options[:url]}",
|
203
|
+
:title => "#{self.description}",
|
204
|
+
:frame => true,
|
205
|
+
:bodyStyle => 'padding: 5px 5px 0;',
|
206
|
+
:renderTo => 'dynamic_form_target',
|
207
|
+
:baseParams => {
|
208
|
+
:dynamic_form_id => self.id,
|
209
|
+
:dynamic_form_model_id => self.dynamic_form_model_id,
|
210
|
+
:model_name => self.model_name
|
211
|
+
},
|
212
|
+
:items => add_help_qtip(definition_with_validation),
|
213
|
+
:defaults => {},
|
214
|
+
:listeners => {
|
215
|
+
:afterrender => NonEscapeJsonString.new("function(form) { #{focus_first_field_js} }")
|
216
|
+
}
|
217
|
+
}
|
218
|
+
config_hash[:defaults][:msgTarget] = self.msg_target unless self.msg_target.blank?
|
219
|
+
config_hash[:width] = options[:width] if options[:width]
|
220
|
+
config_hash[:buttons] = []
|
221
|
+
config_hash[:buttons] << {
|
222
|
+
:text => self.submit_button_label,
|
223
|
+
:listeners => NonEscapeJsonString.new("{
|
224
|
+
\"click\":function(button){
|
225
|
+
var form = button.findParentByType('form').getForm();
|
226
|
+
//jsonSubmit option only works when there is no filefield so we have to do it ourselves
|
227
|
+
//JSON is important to preserve data types (ie. we want integers to save as integers not strings)
|
228
|
+
var form_data = {};
|
229
|
+
Ext.each(form.getFields().items, function(field) {
|
230
|
+
if (Ext.Array.indexOf(['filefield','fileuploadfield'], field.xtype) < 0){
|
231
|
+
form_data[field.name] = field.getValue();
|
232
|
+
}
|
233
|
+
});
|
234
|
+
form.submit({
|
235
|
+
#{submit_empty_text_js}
|
236
|
+
reset:true,
|
237
|
+
params:{
|
238
|
+
form_data_json: Ext.encode(form_data)
|
239
|
+
},
|
240
|
+
success:function(form, action){
|
241
|
+
json_hash = Ext.decode(action.response.responseText);
|
242
|
+
Ext.get('#{options[:widget_result_id]}').dom.innerHTML = json_hash.response;
|
243
|
+
var scriptTags = Ext.get('#{options[:widget_result_id]}').dom.getElementsByTagName('script');
|
244
|
+
Ext.each(scriptTags, function(scriptTag){
|
245
|
+
eval(scriptTag.text);
|
246
|
+
});
|
247
|
+
},
|
248
|
+
failure:function(form, action){
|
249
|
+
if (action.response){
|
250
|
+
json_hash = Ext.decode(action.response.responseText);
|
251
|
+
Ext.get('#{options[:widget_result_id]}').dom.innerHTML = json_hash.response;
|
252
|
+
}
|
188
253
|
}
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
254
|
+
});
|
255
|
+
}
|
256
|
+
}")
|
257
|
+
}
|
258
|
+
config_hash[:buttons] << {
|
259
|
+
:text => 'Reset',
|
260
|
+
:listeners => NonEscapeJsonString.new("{
|
261
|
+
\"click\":function(button){
|
262
|
+
button.findParentByType('form').getForm().reset();
|
263
|
+
}
|
264
|
+
}")
|
265
|
+
}
|
266
|
+
|
267
|
+
javascript += "#{config_hash.to_json});"
|
268
|
+
#logger.info javascript
|
195
269
|
javascript
|
196
270
|
end
|
197
271
|
|