erp_forms 2.1.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -2,90 +2,15 @@
2
2
 
3
3
  ERP Forms adds dynamic forms to Compass using ExtJS.
4
4
 
5
+ == For a quick HOWTO, read this document in the wiki
5
6
 
6
- == Models
7
-
8
- DynamicFormModel - Used for keeping track of what models have forms. Every model that uses the has_dynamic_forms "mixin", extends DynamicFormDocument or simply wants to use DynamicForm, needs to be given a record in the dynamic_form_models table.
9
-
10
- DynamicDatum - This is where dynamic attributes are stored. Any model that uses has_dynamic_data will store its data in the dynamic_data table.
11
-
12
- DynamicForm - Handles dynamic forms. Each model can have many forms which are looked up by model_name. Every model must have a default form but any form can be retrieved using an internal_identifier. Form definition is a JSON string which is equivalent to an ExtJS form definition which is an array of hashes.
13
-
14
- DynamicFormDocument - This model enables the creation of dynamic records using has_dynamic_forms and has_dynamic_data. DynamicFormDocument can explicitly be subclassed or a subclass can be declared on the fly using the "declare" class method.
15
-
16
-
17
- == Mixins
18
-
19
- has_dynamic_forms - Adds dynamic forms to any model.
20
-
21
- has_dynamic_data - Adds dynamic data to any model
22
-
23
-
24
- == Libraries
25
-
26
- DynamicGridColumn - Builds ExtJS dynamic grid columns.
27
-
28
- DynamicFormField - Builds ExtJS dynamic form fields. This is done in text in order to support validation. Outputs JSON strings which can be parsed into JSON Ruby objects. See the instance method "definition_object" on DynamicForm.
29
-
30
-
31
- == Examples
32
-
33
- Creating a DynamicFormModel
34
- DynamicFormModel.create({ :model_name => "MyDynamicModel" })
35
-
36
- Creating a DynamicForm
37
- fields = []
38
- fields << DynamicFormField.textfield({:fieldLabel => 'First Name', :name => 'first_name', :width => '200' })
39
- fields << DynamicFormField.textfield({:fieldLabel => 'Last Name', :name => 'last_name', :width => '200' })
40
- fields << DynamicFormField.email({:fieldLabel => 'Email', :name => 'email', :width => '200' })
41
- fields << DynamicFormField.textarea({:fieldLabel => 'Message', :name => 'message', :width => '200' })
42
-
43
- d = DynamicForm.new
44
- d.description = 'My Dynamic Form'
45
- d.definition = DynamicForm.concat_fields_to_build_definition(fields)
46
- d.model_name = 'MyDynamicModel'
47
- d.internal_identifier = 'my_dyn_model'
48
- d.default = true
49
- d.dynamic_form_model_id = DynamicFormModel.find_by_model_name('MyDynamicModel').id
50
- d.save
51
-
52
- Declaring a DynamicFormDocument on the fly
53
- DynamicFormDocument.declare("MyDynamicModel")
54
- @dyn_model = "MyDynamicModel".constantize.new
55
- @dyn_model.data.created_with_form = @dyn_model.default_form
56
-
57
- # create as many dynamic attributes as you need by prefixing them with "dyn_"
58
- @dyn_model.data.dyn_my_dynamic_field = "hello world"
59
-
60
- @dyn_model.data.created_by = current_user.id
61
- @dyn_model.save
62
-
63
- Subclassing DynamicFormDocument
64
- class MyDynamicModel < DynamicFormDocument
65
- # no need to declare mixins since they will be inherited from DynamicFormDocument
66
- # so only reason to subclass is if you need custom methods
67
- end
68
-
69
- Adding dynamic forms and data to an existing model
70
- class Party
71
- has_dynamic_forms
72
- has_dynamic_data
73
- end
74
-
75
- Using the Knitkit DynamicForms widget
76
- Edit Section Layout, click Dynamic Forms widget icon and the following will be added to the layout:
77
- <%=raw render_widget :dynamic_forms, :params => {:model_name => 'MyDynamicModel', :width => '350'} %>
78
-
7
+ https://github.com/portablemind/compass_agile_enterprise/wiki/Dynamic-Forms
79
8
 
80
9
  == TODO
81
-
82
- Dynamic Form Builder
83
- Search Dynamic Attributes via SOLR
84
10
  Code Mirror form field
85
- file attachments w/ has_file_assets and plupload
86
11
  concatenated field
87
12
  calculated field
88
- related field with search ahead for relations with huge datasets
89
13
 
90
14
  ============================================================
91
- Copyright (c) 2011 Adam Hull
15
+ Developed by Adam Hull
16
+ Copyright (c) 2011-2013 True North Technology Solutions
@@ -55,7 +55,7 @@ module ErpForms::ErpApp::Desktop::DynamicForms
55
55
 
56
56
  myDynamicObject = DynamicFormModel.get_constant(params[:model_name])
57
57
 
58
- if $USE_SOLR_FOR_DYNAMIC_FORM_MODELS and myDynamicObject.is_searchable?
58
+ if ErpForms.use_solr? and myDynamicObject.is_searchable?
59
59
  solr_search_results = myDynamicObject.search do
60
60
  keywords query_filter unless params[:query_filter].blank?
61
61
  paginate(:page => page, :per_page => per_page)
@@ -141,10 +141,10 @@ class ErpForms::ErpApp::Desktop::DynamicForms::FormsController < ErpForms::ErpAp
141
141
  dform = assign_form_attributes(dform)
142
142
  dform.updated_by_id = current_user.id
143
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
144
  if dform.save
145
+ # update solr config for model
146
+ DynamicFormModel.get_constant(dform.model_name).sunspot_setup if ErpForms.use_solr?
147
+
148
148
  render :json => {:success => true}
149
149
  else
150
150
  render :json => {:success => false}
@@ -159,7 +159,11 @@ class ErpForms::ErpApp::Desktop::DynamicForms::FormsController < ErpForms::ErpAp
159
159
  dform.dynamic_form_model_id = DynamicFormModel.find_by_model_name(params[:model_name]).id
160
160
  dform.default = false
161
161
  dform.created_by_id = current_user.id
162
+
162
163
  if dform.save
164
+ # update solr config for model
165
+ DynamicFormModel.get_constant(dform.model_name).sunspot_setup if ErpForms.use_solr?
166
+
163
167
  render :json => {:success => true, :id => dform.id}
164
168
  else
165
169
  render :json => {:success => false}
@@ -24,6 +24,9 @@ class ErpForms::ErpApp::Desktop::DynamicForms::ModelsController < ErpForms::ErpA
24
24
  myDynamicObject = DynamicFormModel.get_constant(params[:model_name])
25
25
  myDynamicObject.set_default(params[:id])
26
26
 
27
+ # update solr config for model
28
+ DynamicFormModel.get_constant(params[:model_name]).sunspot_setup if ErpForms.use_solr?
29
+
27
30
  render :json => {:success => true}
28
31
  end
29
32
 
@@ -5,6 +5,8 @@ class DynamicForm < ActiveRecord::Base
5
5
  belongs_to :created_by, :class_name => "User"
6
6
  belongs_to :updated_by, :class_name => "User"
7
7
 
8
+ after_create :default_form_check
9
+
8
10
  extend FriendlyId
9
11
  friendly_id :description, :use => [:slugged], :slug_column => :internal_identifier
10
12
  def should_generate_new_friendly_id?
@@ -12,7 +14,14 @@ class DynamicForm < ActiveRecord::Base
12
14
  end
13
15
 
14
16
  validates_uniqueness_of :internal_identifier, :scope => :model_name, :case_sensitive => false
15
-
17
+
18
+ def default_form_check
19
+ # count how many forms this model has, if one, set as default
20
+ if dynamic_form_model.dynamic_forms.count == 1
21
+ DynamicFormModel.get_constant(self.model_name).set_default(self.id)
22
+ end
23
+ end
24
+
16
25
  def self.class_exists?(class_name)
17
26
  result = nil
18
27
  begin
@@ -175,9 +184,9 @@ class DynamicForm < ActiveRecord::Base
175
184
  :text => self.cancel_button_label,
176
185
  :listeners => NonEscapeJsonString.new("{
177
186
  \"click\":function(button){
178
- var form = button.findParentByType('form');
179
- if (form.close_selector){
180
- form.up(form.close_selector).close();
187
+ var form = button.findParentByType('dynamic_form_panel');
188
+ if (form.up('tabpanel')){
189
+ form.up('tabpanel').remove(form.up('panel'));
181
190
  }else{
182
191
  form.up('window').close();
183
192
  }
@@ -1,8 +1,5 @@
1
1
  class DynamicFormField
2
- =begin
3
- Field Options TODO
4
- searchable
5
-
2
+ =begin
6
3
  Field Types TODO
7
4
  special:
8
5
  codemirror
@@ -11,7 +8,6 @@ class DynamicFormField
11
8
  complex (for future implementation):
12
9
  concatenated
13
10
  calculated
14
- related with search ahead for relations with huge datasets
15
11
  =end
16
12
 
17
13
  # options = {
@@ -16,14 +16,10 @@ module ErpForms
16
16
  end
17
17
 
18
18
  ErpBaseErpSvcs.register_as_compass_ae_engine(config, self)
19
- ::ErpApp::Widgets::Loader.load_compass_ae_widgets(config, self)
20
19
 
21
20
  config.to_prepare do
22
21
  #dynamic_attributes patch
23
22
  require "erp_forms/dynamic_attributes_patch"
24
-
25
- # setup sunspot for all dynamic form models if we're using solr
26
- DynamicFormModel.sunspot_setup_all if ($USE_SOLR_FOR_DYNAMIC_FORM_MODELS && ActiveRecord::Base.connection.table_exists?('dynamic_form_models'))
27
23
  end
28
24
 
29
25
  end
@@ -58,10 +58,10 @@ module ErpForms
58
58
  DynamicForm.find_all_by_model_name(self.class_name)
59
59
  end
60
60
 
61
- def set_default(internal_identifier)
62
- DynamicForm.update_all({:default => false}, "model_name=#{self.class.to_s}")
63
- DynamicForm.update_all({:default => true}, "model_name=#{self.class.to_s} AND internal_identifier=#{internal_identifier}")
64
- end
61
+ # def set_default(internal_identifier)
62
+ # DynamicForm.update_all({:default => false}, "model_name=#{self.class.to_s}")
63
+ # DynamicForm.update_all({:default => true}, "model_name=#{self.class.to_s} AND internal_identifier=#{internal_identifier}")
64
+ # end
65
65
 
66
66
  end
67
67
  end
@@ -1,7 +1,7 @@
1
1
  module ErpForms
2
2
  module VERSION #:nodoc:
3
- MAJOR = 2
4
- MINOR = 1
3
+ MAJOR = 3
4
+ MINOR = 0
5
5
  TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].compact.join('.')
data/lib/erp_forms.rb CHANGED
@@ -13,4 +13,8 @@ require 'erp_forms/extensions/extensions'
13
13
  require "erp_forms/engine"
14
14
 
15
15
  module ErpForms
16
+
17
+ def self.use_solr?
18
+ Object.const_defined?('ErpSearch') and ErpSearch::Config.use_solr_for_dynamic_form_models
19
+ end
16
20
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: erp_forms
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 3.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-11 00:00:00.000000000 Z
12
+ date: 2013-02-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: dynamic_attributes
@@ -109,11 +109,6 @@ files:
109
109
  - app/views/dynamic_form_mailer/widget_email_with_attachments.text.erb
110
110
  - app/views/layouts/application.html.erb
111
111
  - app/views/layouts/erp_forms/application.html.erb
112
- - app/widgets/dynamic_forms/base.rb
113
- - app/widgets/dynamic_forms/javascript/dynamic_forms.js
114
- - app/widgets/dynamic_forms/views/error.html.erb
115
- - app/widgets/dynamic_forms/views/index.html.erb
116
- - app/widgets/dynamic_forms/views/success.html.erb
117
112
  - config/routes.rb
118
113
  - db/data_migrations/20110608185830_create_default_dynamic_models_and_forms.rb
119
114
  - db/data_migrations/20110828190913_create_desktop_app_dynamic_forms.rb
@@ -220,18 +215,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
220
215
  - - ! '>='
221
216
  - !ruby/object:Gem::Version
222
217
  version: '0'
223
- segments:
224
- - 0
225
- hash: -1443867374414206625
226
218
  required_rubygems_version: !ruby/object:Gem::Requirement
227
219
  none: false
228
220
  requirements:
229
221
  - - ! '>='
230
222
  - !ruby/object:Gem::Version
231
223
  version: '0'
232
- segments:
233
- - 0
234
- hash: -1443867374414206625
235
224
  requirements: []
236
225
  rubyforge_project:
237
226
  rubygems_version: 1.8.24
@@ -1,139 +0,0 @@
1
- module Widgets
2
- module DynamicForms
3
- class Base < ErpApp::Widgets::Base
4
- def index
5
- render
6
- end
7
-
8
- def new
9
- begin
10
- unless params[:file].nil?
11
- # size check
12
- if params[:file].tempfile.size > ErpTechSvcs::Config.max_file_size_in_mb.megabytes
13
- raise "File cannot be larger than #{ErpTechSvcs::Config.max_file_size_in_mb}MB"
14
- end
15
- end
16
- form_data = JSON.parse(params[:form_data_json])
17
- form_data[:dynamic_form_id] = params[:dynamic_form_id]
18
- form_data[:model_name] = params[:model_name]
19
- form_data.symbolize_keys!
20
- @website = Website.find_by_host(request.host_with_port)
21
-
22
- if form_data[:email_subject].blank?
23
- subject = "#{form_data[:model_name]} Submission from #{@website.title}"
24
- else
25
- subject = strip_tags(form_data[:email_subject])
26
- form_data.delete(:email_subject)
27
- end
28
-
29
- @myDynamicObject = DynamicFormModel.get_instance(form_data[:model_name])
30
-
31
- form_data[:created_by] = current_user unless current_user.nil?
32
- form_data[:created_with_form_id] = form_data[:dynamic_form_id] if form_data[:dynamic_form_id] and params[:is_html_form].blank?
33
- form_data[:website] = @website.title
34
-
35
- @myDynamicObject = @myDynamicObject.assign_all_attributes(form_data, ErpApp::Widgets::Base::IGNORED_PARAMS)
36
-
37
- # get dynamic for from form_data[:created_with_form_id]
38
- form = DynamicForm.find(form_data[:created_with_form_id])
39
-
40
- # check widget_action from dynamic form
41
- if !form.nil? and ['email', 'both'].include?(form.widget_action)
42
- # email data
43
- attachments = (params[:file].nil? ? [] : [params[:file]])
44
- send_email(form, @myDynamicObject, subject, attachments)
45
- end
46
-
47
- if form.nil? or (!form.nil? and ['save', 'both'].include?(form.widget_action))
48
- #save data
49
- @myDynamicObject.save
50
- save_file_asset(form_data) unless params[:file].nil?
51
- end
52
-
53
- output = render_to_string(:template => "success", :layout => false)
54
- render :inline => {
55
- :success => true,
56
- :response => (file_upload_request? ? ERB::Util.html_escape(output) : output)
57
- }.to_json
58
- rescue Exception => e
59
- Rails.logger.error e.message
60
- Rails.logger.error e.backtrace.join("\n")
61
- output = render_to_string(:template => "error", :layout => false, :locals => {:message => e.message})
62
- render :inline => {
63
- :success => false,
64
- :response => (file_upload_request? ? ERB::Util.html_escape(output) : output)
65
- }.to_json
66
- end
67
- end
68
-
69
- protected
70
- def file_upload_request?
71
- request.env['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest'
72
- end
73
-
74
- def save_file_asset(form_data)
75
- result = {}
76
- name = params[:file].original_filename
77
- data = params[:file].tempfile
78
- set_file_support
79
-
80
- begin
81
- @root_node = File.join(ErpTechSvcs::Config.file_assets_location, form_data[:model_name], @myDynamicObject.id.to_s)
82
- file = @myDynamicObject.add_file(data, File.join(@file_support.root, base_path, name))
83
-
84
- roles = ['admin', @myDynamicObject.role_iid]
85
- (@myDynamicObject.file_security_default == 'private') ? file.add_capability(:download, 'FileAsset', roles) : file.remove_all_capabilities
86
-
87
- return {:success => true}
88
- rescue Exception => e
89
- Rails.logger.error e.message
90
- Rails.logger.error e.backtrace
91
- raise "Error uploading file. #{e.message}"
92
- end
93
- end
94
-
95
- def base_path
96
- @base_path = (@root_node.nil? ? nil : File.join(@file_support.root, @root_node))
97
- end
98
-
99
- def set_file_support
100
- @file_support = ErpTechSvcs::FileSupport::Base.new(:storage => ErpTechSvcs::Config.file_storage)
101
- end
102
-
103
- def send_email(form, dynamicObject, subject='', attachments=[])
104
- begin
105
- DynamicFormMailer.widget_email_with_attachments(form, dynamicObject, subject, attachments).deliver
106
- rescue Exception => e
107
- Rails.logger.error e.message
108
- Rails.logger.error e.backtrace
109
- raise "Error sending email. #{e.message}"
110
- end
111
- end
112
-
113
- #should not be modified
114
- #modify at your own risk
115
- def locate
116
- File.dirname(__FILE__)
117
- end
118
-
119
- class << self
120
- def title
121
- "Dynamic Forms"
122
- end
123
-
124
- def widget_name
125
- File.basename(File.dirname(__FILE__))
126
- end
127
-
128
- def base_layout
129
- begin
130
- file = File.join(File.dirname(__FILE__),"/views/layouts/base.html.erb")
131
- IO.read(file)
132
- rescue
133
- return nil
134
- end
135
- end
136
- end
137
- end
138
- end
139
- end
@@ -1,111 +0,0 @@
1
- Compass.ErpApp.Widgets.DynamicForms = {
2
- addDynamicForm:function(){
3
- var addDynamicFormWidgetWindow = Ext.create("Ext.window.Window",{
4
- layout:'fit',
5
- width:375,
6
- title:'Add DynamicForm Widget',
7
- plain: true,
8
- buttonAlign:'center',
9
- items: Ext.create("Ext.form.Panel",{
10
- labelWidth: 100,
11
- frame:false,
12
- bodyStyle:'padding:5px 5px 0',
13
- defaults: {
14
- width: 325
15
- },
16
- items: [
17
- {
18
- xtype:'combo',
19
- value:'',
20
- loadingText:'Retrieving Dynamic Form Models ...',
21
- store:Ext.create('Ext.data.Store',{
22
- proxy:{
23
- type:'ajax',
24
- reader:{
25
- type:'json',
26
- root: 'dynamic_form_model'
27
- },
28
- url:'/erp_forms/erp_app/desktop/dynamic_forms/models/index'
29
- },
30
- fields:[
31
- {
32
- name:'id'
33
- },
34
- {
35
- name:'model_name'
36
- }
37
- ]
38
- }),
39
- forceSelection:true,
40
- editable:true,
41
- fieldLabel:'Model Name',
42
- autoSelect:true,
43
- mode: 'remote',
44
- name: 'model_name',
45
- displayField:'model_name',
46
- valueField:'model_name',
47
- triggerAction: 'all',
48
- allowBlank:false,
49
- plugins: [new helpQtip("Dynamic Form Model Name (Class)")]
50
- },
51
- {
52
- xtype:'textfield',
53
- fieldLabel:'Form Width',
54
- name: 'form_width',
55
- allowBlank:true,
56
- plugins: [new helpQtip("Form Width in Pixels. Leave blank for auto width.")]
57
- }
58
- ]
59
- }),
60
- buttons: [{
61
- text:'Submit',
62
- listeners:{
63
- 'click':function(button){
64
- var tpl = null;
65
- var content = null;
66
- var formPanel = button.findParentByType('window').query('form').first();
67
- var basicForm = formPanel.getForm();
68
- var WidgetDynamicFormModelName = basicForm.findField('model_name');
69
- var WidgetDynamicFormWidth = basicForm.findField('form_width');
70
- if (basicForm.isValid()){
71
- var data = {
72
- WidgetDynamicFormModelName: WidgetDynamicFormModelName.getValue(),
73
- WidgetDynamicFormWidth: WidgetDynamicFormWidth.getValue()
74
- };
75
-
76
- tpl = new Ext.XTemplate(
77
- "<% # Optional Parameters:\n",
78
- " # internal_identifier: Models can have multiple forms\n",
79
- " # Leave blank if you want to use the default form\n",
80
- " # Specify internal_identifier to choose a specific form %>\n",
81
- "<%= render_widget :dynamic_forms,\n",
82
- " :params => {:model_name => '{WidgetDynamicFormModelName}',\n",
83
- " :internal_identifier => ''",
84
- '<tpl if="WidgetDynamicFormWidth">',
85
- ",\n :width => {WidgetDynamicFormWidth} ",
86
- '</tpl>',
87
- "} %>");
88
- content = tpl.apply(data);
89
-
90
- //add rendered template to center region editor
91
- Ext.getCmp('knitkitCenterRegion').addContentToActiveCodeMirror(content);
92
- addDynamicFormWidgetWindow.close();
93
- }
94
- }
95
- }
96
- },{
97
- text: 'Close',
98
- handler: function(){
99
- addDynamicFormWidgetWindow.close();
100
- }
101
- }]
102
- });
103
- addDynamicFormWidgetWindow.show();
104
- }
105
- };
106
-
107
- Compass.ErpApp.Widgets.AvailableWidgets.push({
108
- name:'Dynamic Forms',
109
- iconUrl:'/images/icons/document_text/document_text_48x48.png',
110
- onClick:Compass.ErpApp.Widgets.DynamicForms.addDynamicForm
111
- });
@@ -1,5 +0,0 @@
1
- <div>
2
- <h1>An Error Occurred</h1>
3
- <%= message unless message.nil? %>
4
-
5
- </div>
@@ -1,8 +0,0 @@
1
- <div id="<%=widget_result_id %>"></div>
2
-
3
- <%=raw render_dynamic_form(params[:model_name], {
4
- :internal_identifier => params[:internal_identifier],
5
- :width => (params[:width] ? params[:width].to_i : nil)
6
- }) %>
7
-
8
- <div id="dynamic_form_target"></div>
@@ -1,4 +0,0 @@
1
- <div>
2
- <h1>Thank you.</h1>
3
- <p>Your form has been processed successfully.</p>
4
- </div>