inline_forms 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +20 -0
- data/VERSION +1 -1
- data/app/controllers/inline_forms_controller.rb +132 -0
- data/app/helpers/inline_form_helper.rb +330 -0
- data/app/models/geo_code_curacao.rb +51 -0
- data/app/models/inline_form.rb +2 -0
- data/app/views/inline_forms/_subform.html.erb +16 -0
- data/app/views/inline_forms/edit.html.erb +17 -0
- data/app/views/inline_forms/index.html.erb +4 -0
- data/app/views/inline_forms/new.html.erb +17 -0
- data/app/views/layouts/inline_forms.rhtml +7 -0
- data/inline_forms.gemspec +73 -0
- metadata +14 -3
data/Gemfile.lock
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
git (1.2.5)
|
5
|
+
jeweler (1.5.2)
|
6
|
+
bundler (~> 1.0.0)
|
7
|
+
git (>= 1.2.5)
|
8
|
+
rake
|
9
|
+
rake (0.8.7)
|
10
|
+
rcov (0.9.9)
|
11
|
+
shoulda (2.11.3)
|
12
|
+
|
13
|
+
PLATFORMS
|
14
|
+
ruby
|
15
|
+
|
16
|
+
DEPENDENCIES
|
17
|
+
bundler (~> 1.0.0)
|
18
|
+
jeweler (~> 1.5.2)
|
19
|
+
rcov
|
20
|
+
shoulda
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.1
|
@@ -0,0 +1,132 @@
|
|
1
|
+
class InlineFormsController < ApplicationController
|
2
|
+
unloadable # see http://dev.rubyonrails.org/ticket/6001
|
3
|
+
# == Generic controller for the inline_forms plugin.
|
4
|
+
# === Usage
|
5
|
+
# If you have an Example class, then you can add a route like this:
|
6
|
+
# <tt>map.resources :examples, :controller => :inline_forms</tt>
|
7
|
+
# this will give you REST stuff without creating a sepearte examples_controller.rb
|
8
|
+
# === How it works
|
9
|
+
# The getKlass before_filter extracts the classname from the request. So, '/examples/1' and
|
10
|
+
# '/examples?name=value' will result in @Klass being set to 'Example', which is the class.
|
11
|
+
# === Limited Access
|
12
|
+
# the must_be_xhr_request before_filter is supposed to only perform the specific actions
|
13
|
+
# if the request is an XhttpRequest. There is not much use perming the actions outside of
|
14
|
+
# the XhttpRequest context (except action => :index). Of course, this is not a security measure.
|
15
|
+
before_filter :getKlass
|
16
|
+
before_filter :must_be_xhr_request, :except => :index
|
17
|
+
helper :inline_form
|
18
|
+
include InlineFormHelper
|
19
|
+
layout false
|
20
|
+
|
21
|
+
# :index shows a list of all objects from class Klass, with all attribute values linked to the 'edit' action.
|
22
|
+
# Each field (attribute) is edited seperately (so you don't edit an entire object!)
|
23
|
+
# The link to 'new' allows you to create a new record.
|
24
|
+
#
|
25
|
+
# GET /examples
|
26
|
+
#
|
27
|
+
def index
|
28
|
+
nolayout = params[:layout] == 'false' || false
|
29
|
+
@objects = @Klass.constantize.all
|
30
|
+
render( :layout => nolayout || 'inline_forms' )
|
31
|
+
end
|
32
|
+
|
33
|
+
# :show shows one field (attribute) from a record (object). It inludes the link to 'edit'
|
34
|
+
#
|
35
|
+
# GET /examples/1?field=name&form_element=text
|
36
|
+
#
|
37
|
+
def show
|
38
|
+
@object = @Klass.constantize.find(params[:id])
|
39
|
+
@field = params[:field]
|
40
|
+
@form_element = params[:form_element]
|
41
|
+
if @form_element == "associated"
|
42
|
+
@sub_id = params[:sub_id]
|
43
|
+
if @sub_id.to_i > 0
|
44
|
+
@associated_record_id = @object.send(@field.singularize + "_ids").index(@sub_id.to_i)
|
45
|
+
@associated_record = @object.send(@field)[@associated_record_id]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
render :inline => '<%= send("#{@form_element}_show", @object, @field, @values) %>'
|
49
|
+
end
|
50
|
+
|
51
|
+
# :new prepares a new object, updates the entire list of objects and replaces it with a new
|
52
|
+
# empty form. After pressing OK or Cancel, the list of objects is retrieved in the same way as :index
|
53
|
+
#
|
54
|
+
# GET /examples/new
|
55
|
+
def new
|
56
|
+
@object = @Klass.constantize.new
|
57
|
+
end
|
58
|
+
|
59
|
+
# :edit presents a form to edit one specific field from an object
|
60
|
+
#
|
61
|
+
# GET /examples/1/edit
|
62
|
+
#
|
63
|
+
def edit
|
64
|
+
@object = @Klass.constantize.find(params[:id])
|
65
|
+
@field = params[:field]
|
66
|
+
@form_element = params[:form_element]
|
67
|
+
@values = params[:values]
|
68
|
+
@sub_id = params[:sub_id]
|
69
|
+
end
|
70
|
+
|
71
|
+
# :create creates the object made with :new. It then presents the list of objects.
|
72
|
+
#
|
73
|
+
# POST /examples
|
74
|
+
#
|
75
|
+
def create
|
76
|
+
object = @Klass.constantize.new
|
77
|
+
attributes = object.respond_to?(:field_list) ? object.field_list : [ '', :name, :text ] # sensible default
|
78
|
+
attributes = [ attributes ] if not attributes[0].is_a?(Array) # make sure we have an array of arrays
|
79
|
+
attributes.each do | name, attribute, form_element, values |
|
80
|
+
send("#{form_element.to_s}_update", object, attribute, values)
|
81
|
+
end
|
82
|
+
object.save
|
83
|
+
@objects = @Klass.constantize.all
|
84
|
+
render( :action => :index )
|
85
|
+
end
|
86
|
+
|
87
|
+
# :update updates a specific field from an object.
|
88
|
+
#
|
89
|
+
# PUT /examples/1
|
90
|
+
#
|
91
|
+
def update
|
92
|
+
@object = @Klass.constantize.find(params[:id])
|
93
|
+
@field = params[:field]
|
94
|
+
@form_element = params[:form_element]
|
95
|
+
@values = params[:values]
|
96
|
+
@sub_id = params[:sub_id]
|
97
|
+
send("#{@form_element.to_s}_update", @object, @field, @values)
|
98
|
+
@object.save
|
99
|
+
render :inline => '<%= send("#{@form_element.to_s}_show", @object, @field, @values) %>'
|
100
|
+
end
|
101
|
+
|
102
|
+
# :destroy is not implemented
|
103
|
+
# TODO implement a destroy method
|
104
|
+
#
|
105
|
+
# DELETE /examples/1
|
106
|
+
#
|
107
|
+
def destroy
|
108
|
+
# @@Klass.constantize = @Klass.constantize.find(params[:id])
|
109
|
+
# @@Klass.constantize.destroy
|
110
|
+
redirect_to(@Klass.constantizes_url)
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
# If it's not an XhttpRequest, redirect to the index page for this controller.
|
115
|
+
#
|
116
|
+
# Used in before_filter as a way to limit access to all actions (except :index)
|
117
|
+
def must_be_xhr_request #:doc:
|
118
|
+
redirect_to "/#{@Klass_pluralized}" if not request.xhr?
|
119
|
+
end
|
120
|
+
|
121
|
+
# Get the classname from the request uri.
|
122
|
+
# /examples/1 => Example
|
123
|
+
# /examples?field=name => Example
|
124
|
+
#
|
125
|
+
# Used in before_filter
|
126
|
+
def getKlass #:doc:
|
127
|
+
@Klass = request.request_uri.split(/[\/?]/)[1].classify
|
128
|
+
@Klass_constantized = @Klass.constantize
|
129
|
+
@Klass_underscored = @Klass.underscore
|
130
|
+
@Klass_pluralized = @Klass_underscored.pluralize
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,330 @@
|
|
1
|
+
module InlineFormHelper
|
2
|
+
# display the forms from an array of attributes
|
3
|
+
def inline_form_display(object, attributes, action=:show)
|
4
|
+
attributes = [ attributes ] if not attributes[0].is_a?(Array) # make sure we have an array of arrays
|
5
|
+
out = String.new #ugly as hell but that's how content_tag works...
|
6
|
+
case action
|
7
|
+
when :show
|
8
|
+
attributes.each do | name, attribute, form_element, values |
|
9
|
+
#css_class_id = form_element == :associated ? "subform_#{attribute.to_s}_#{object.id}" : "field_#{attribute.to_s}_#{object.id}"
|
10
|
+
css_class_id = "field_#{attribute.to_s}_#{object.id}"
|
11
|
+
name_cell = content_tag :td, :valign=>'top' do
|
12
|
+
content_tag :div, :class=> "field_name field_#{attribute.to_s} form_element_#{form_element.to_s}" do
|
13
|
+
h(name)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
value_cell = content_tag :td, :valign=>'top' do
|
17
|
+
content_tag :div, :class=> "field_value field_#{attribute.to_s} form_element_#{form_element.to_s}" do
|
18
|
+
content_tag :span, :id => css_class_id do
|
19
|
+
send("#{form_element.to_s}_#{action}", object, attribute, values)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
out += content_tag :tr, name_cell + value_cell
|
24
|
+
end
|
25
|
+
return content_tag :table, out, :cellspacing => 0, :cellpadding => 0
|
26
|
+
when :new
|
27
|
+
attributes.each do | name, attribute, form_element, values |
|
28
|
+
#css_class_id = form_element == :associated ? "subform_#{attribute.to_s}_#{object.id}" : "field_#{attribute.to_s}_#{object.id}"
|
29
|
+
css_class_id = "field_#{attribute.to_s}_#{object.id}"
|
30
|
+
name_cell = content_tag :td, :valign=>'top' do
|
31
|
+
content_tag :div, :class=> "field_name field_#{attribute.to_s} form_element_#{form_element.to_s}" do
|
32
|
+
h(name)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
value_cell = content_tag :td, :valign=>'top' do
|
36
|
+
content_tag :div, :class=> "field_value field_#{attribute.to_s} form_element_#{form_element.to_s}" do
|
37
|
+
content_tag :span, :id => css_class_id do
|
38
|
+
if not form_element == :associated
|
39
|
+
send("#{form_element.to_s}_edit", object, attribute, values)
|
40
|
+
else
|
41
|
+
#send("#{form_element.to_s}_show", object, attribute, values)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
out += content_tag :tr, name_cell + value_cell
|
47
|
+
end
|
48
|
+
return content_tag :table, out, :cellspacing => 0, :cellpadding => 0
|
49
|
+
end
|
50
|
+
end
|
51
|
+
# display a list of objects
|
52
|
+
def inline_form_display_list(objects, tag=:li)
|
53
|
+
t = ''
|
54
|
+
objects.each do |object|
|
55
|
+
t += content_tag tag do
|
56
|
+
inline_form_display object, object.respond_to?(:field_list) ? object.field_list : [ '', :name, :text ]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
return t
|
60
|
+
end
|
61
|
+
# link for new item
|
62
|
+
def inline_form_new_record(attribute, form_element, text='new', update_span='inline_form_list')
|
63
|
+
link_to_remote( text,
|
64
|
+
:url => {
|
65
|
+
:action => :new,
|
66
|
+
:controller => @Klass_pluralized,
|
67
|
+
:field => attribute,
|
68
|
+
:form_element => form_element,
|
69
|
+
:update_span => update_span },
|
70
|
+
:method => :get,
|
71
|
+
:update => update_span )
|
72
|
+
end
|
73
|
+
|
74
|
+
# dropdown
|
75
|
+
def dropdown_show(object, attribute, values)
|
76
|
+
attribute_value = object.send(attribute).presentation rescue nil
|
77
|
+
link_to_inline_edit object, attribute, attribute_value, nil
|
78
|
+
end
|
79
|
+
def dropdown_edit(object, attribute, values)
|
80
|
+
object.send('build_' + attribute.to_s) unless object.send(attribute)
|
81
|
+
values = object.send(attribute).class.name.constantize.find(:all, :order => 'name ASC')
|
82
|
+
# the leading underscore is to avoid name conflicts, like 'email' and 'email_type' will result in 'email' and 'email[email_type_id]' in the form!
|
83
|
+
collection_select( ('_' + object.class.to_s.downcase).to_sym, attribute.to_s.foreign_key.to_sym, values, 'id', 'presentation', :selected => object.send(attribute).id)
|
84
|
+
end
|
85
|
+
def dropdown_update(object, attribute, values)
|
86
|
+
object[attribute.to_s.foreign_key.to_sym] = params[('_' + object.class.to_s.downcase).to_sym][attribute.to_s.foreign_key.to_sym]
|
87
|
+
end
|
88
|
+
|
89
|
+
# dropdown_with_values
|
90
|
+
def dropdown_with_values_show(object, attribute, values)
|
91
|
+
link_to_inline_edit object, attribute, values[object.send(attribute)], values
|
92
|
+
end
|
93
|
+
def dropdown_with_values_edit(object, attribute, values)
|
94
|
+
# the leading underscore is to avoid name conflicts, like 'email' and 'email_type' will result in 'email' and 'email[email_type_id]' in the form!
|
95
|
+
collection_select( ('_' + object.class.to_s.downcase).to_sym, attribute.to_sym, values, 'first', 'last', :selected => object.send(attribute))
|
96
|
+
end
|
97
|
+
def dropdown_with_values_update(object, attribute, values)
|
98
|
+
object[attribute.to_sym] = params[('_' + object.class.to_s.downcase).to_sym][attribute.to_sym]
|
99
|
+
end
|
100
|
+
|
101
|
+
# range
|
102
|
+
def range_show(object, attribute, values)
|
103
|
+
link_to_inline_edit object, attribute, object.send(attribute), nil
|
104
|
+
end
|
105
|
+
def range_edit(object, attribute, values)
|
106
|
+
# the leading underscore is to avoid name conflicts, like 'email' and 'email_type' will result in 'email' and 'email[email_type_id]' in the form!
|
107
|
+
collection_select( ('_' + object.class.to_s.downcase).to_sym, attribute.to_sym, values, 'to_i', 'to_s', :selected => object.send(attribute))
|
108
|
+
end
|
109
|
+
def range_update(object, attribute, values)
|
110
|
+
object[attribute.to_sym] = params[('_' + object.class.to_s.downcase).to_sym][attribute.to_sym]
|
111
|
+
end
|
112
|
+
|
113
|
+
# date
|
114
|
+
def date_show(object, attribute, values)
|
115
|
+
link_to_inline_edit object, attribute, object.send(attribute), nil
|
116
|
+
end
|
117
|
+
def date_edit(object, attribute, values)
|
118
|
+
calendar_date_select_tag attribute, object[attribute], :year_range => 30.years.ago..5.years.from_now, :popup => :force
|
119
|
+
end
|
120
|
+
def date_update(object, attribute, values)
|
121
|
+
object[attribute.to_sym] = params[attribute.to_sym]
|
122
|
+
end
|
123
|
+
|
124
|
+
# textarea
|
125
|
+
def textarea_show(object, attribute, values)
|
126
|
+
link_to_inline_edit object, attribute, object.send(attribute), nil
|
127
|
+
end
|
128
|
+
def textarea_edit(object, attribute, values)
|
129
|
+
text_area_tag attribute, object[attribute], :class => 'field_textarea'
|
130
|
+
end
|
131
|
+
def textarea_update(object, attribute, values)
|
132
|
+
object[attribute.to_sym] = params[attribute.to_sym]
|
133
|
+
end
|
134
|
+
|
135
|
+
# text
|
136
|
+
def text_show(object, attribute, values)
|
137
|
+
link_to_inline_edit object, attribute, object.send(attribute), nil
|
138
|
+
end
|
139
|
+
def text_edit(object, attribute, values)
|
140
|
+
text_field_tag attribute, object[attribute], :class => 'input_text'
|
141
|
+
end
|
142
|
+
def text_update(object, attribute, values)
|
143
|
+
object[attribute.to_sym] = params[attribute.to_sym]
|
144
|
+
end
|
145
|
+
|
146
|
+
# bool
|
147
|
+
def bool_show(object, attribute, values)
|
148
|
+
link_to_inline_edit object, attribute, values[object.send(attribute).to_s], values
|
149
|
+
end
|
150
|
+
def bool_edit(object, attribute, values)
|
151
|
+
collection_select( object.class.to_s.downcase, attribute, values, 'first', 'last', :selected => object.send(attribute).to_s)
|
152
|
+
end
|
153
|
+
def bool_update(object, attribute, values)
|
154
|
+
object[attribute.to_s.to_sym] = params[object.class.to_s.downcase.to_sym][attribute.to_s.to_sym]
|
155
|
+
end
|
156
|
+
|
157
|
+
# checklist
|
158
|
+
def checklist_show(object, attribute, values)
|
159
|
+
out = '<ul class="checklist">'
|
160
|
+
out << link_to_inline_edit(object, attribute, nil, nil) if object.send(attribute).empty?
|
161
|
+
object.send(attribute).sort.each do | item |
|
162
|
+
out << '<li>'
|
163
|
+
out << link_to_inline_edit(object, attribute, item.title, nil)
|
164
|
+
out << '</li>'
|
165
|
+
end
|
166
|
+
out << '</ul>'
|
167
|
+
end
|
168
|
+
def checklist_edit(object, attribute, values)
|
169
|
+
object.send(attribute).build if object.send(attribute).empty?
|
170
|
+
values = object.send(attribute).first.class.name.constantize.find(:all, :order => "name ASC")
|
171
|
+
out = '<div class="edit_form_checklist">'
|
172
|
+
out << '<ul>'
|
173
|
+
values.each do | item |
|
174
|
+
out << '<li>'
|
175
|
+
out << check_box_tag( attribute + '[' + item.id.to_s + ']', 'yes', object.send(attribute.singularize + "_ids").include?(item.id) )
|
176
|
+
out << '<div class="edit_form_checklist_text">'
|
177
|
+
out << h(item.title)
|
178
|
+
out << '</div>'
|
179
|
+
out << '<div style="clear: both;"></div>'
|
180
|
+
out << '</li>'
|
181
|
+
end
|
182
|
+
out << '</ul>'
|
183
|
+
out << '</div>'
|
184
|
+
end
|
185
|
+
def checklist_update(object, attribute, values)
|
186
|
+
params[attribute] ||= {}
|
187
|
+
object.send(attribute.singularize + '_ids=', params[attribute].keys)
|
188
|
+
end
|
189
|
+
|
190
|
+
# associated
|
191
|
+
def associated_show(object, attribute, values)
|
192
|
+
#show a list of records
|
193
|
+
out = ""
|
194
|
+
if @sub_id && @sub_id.to_i > 0
|
195
|
+
# if it's not a new record (sub_id > 0) then just update the list-element
|
196
|
+
out << '<li>'
|
197
|
+
out << link_to_remote( @associated_record.title,
|
198
|
+
:url => { :action => 'edit',
|
199
|
+
:id => object.id,
|
200
|
+
:field => attribute,
|
201
|
+
:sub_id => @sub_id,
|
202
|
+
:form_element => this_method.reverse.sub(/.*_/,'').reverse,
|
203
|
+
:values => values },
|
204
|
+
:method => :get,
|
205
|
+
:update => "field_#{attribute.singularize}_#{@sub_id.to_s}" )
|
206
|
+
out << '</li>'
|
207
|
+
else
|
208
|
+
# if it's a new record (sub_id == 0) then update the whole <ul> and redraw all list-elements
|
209
|
+
out << "<ul class='associated #{attribute}' id='list_#{attribute}_#{object.id.to_s}'>" if @sub_id.nil?
|
210
|
+
if not object.send(attribute.pluralize).empty?
|
211
|
+
# if there are things to show, show them
|
212
|
+
object.send(attribute.pluralize).each do |m|
|
213
|
+
out << "<span id='field_#{attribute.singularize}_#{m.id.to_s}'>"
|
214
|
+
out << '<li>'
|
215
|
+
out << link_to_remote( m.title,
|
216
|
+
:url => { :action => 'edit',
|
217
|
+
:id => object.id,
|
218
|
+
:field => attribute,
|
219
|
+
:sub_id => m.id,
|
220
|
+
:form_element => this_method.sub(/_[a-z]+$/,''),
|
221
|
+
:values => values },
|
222
|
+
:method => :get,
|
223
|
+
:update => "field_#{attribute.singularize}_#{m.id.to_s}" )
|
224
|
+
out << '</li>'
|
225
|
+
out << '</span>'
|
226
|
+
end
|
227
|
+
end
|
228
|
+
# add a 'new' link for creating a new record
|
229
|
+
out << '<li>'
|
230
|
+
out << link_to_remote( 'new',
|
231
|
+
:url => { :action => 'edit',
|
232
|
+
:id => object.id,
|
233
|
+
:field => attribute,
|
234
|
+
:sub_id => 0,
|
235
|
+
:form_element => this_method.sub(/_[a-z]+$/,''),
|
236
|
+
:values => values },
|
237
|
+
:method => :get,
|
238
|
+
:update => "list_#{attribute}_#{object.id.to_s}" )
|
239
|
+
out << '</li>'
|
240
|
+
out << '</ul>' if @sub_id.nil?
|
241
|
+
end
|
242
|
+
out
|
243
|
+
end
|
244
|
+
def associated_edit(object, attribute, values)
|
245
|
+
# @sub_id is the id of the assoicated record
|
246
|
+
if @sub_id.to_i > 0
|
247
|
+
# only if @sub_id > 0, means we have a associated record
|
248
|
+
@associated_record_id = object.send(attribute.singularize + "_ids").index(@sub_id.to_i)
|
249
|
+
@associated_record = object.send(attribute)[@associated_record_id]
|
250
|
+
@update_span = "field_#{attribute.singularize}_#{@sub_id.to_s}"
|
251
|
+
else
|
252
|
+
# but if @sub_id = 0, then we are dealing with a new associated record
|
253
|
+
# in that case, we .new a record, and the update_span is the whole <ul>
|
254
|
+
@associated_record = attribute.singularize.capitalize.constantize.new
|
255
|
+
@update_span = "list_#{attribute}_#{object.id.to_s}"
|
256
|
+
end
|
257
|
+
render :partial => "subform"
|
258
|
+
end
|
259
|
+
def associated_update(object, attribute, values)
|
260
|
+
return if object.id.nil?
|
261
|
+
if @sub_id.to_i > 0
|
262
|
+
# get the existing associated record
|
263
|
+
@associated_record_id = object.send(attribute.singularize + "_ids").index(@sub_id.to_i)
|
264
|
+
@associated_record = object.send(attribute)[@associated_record_id]
|
265
|
+
@update_span = "field_" + attribute.singularize + '_' + @sub_id.to_s
|
266
|
+
else
|
267
|
+
# create a new associated record
|
268
|
+
@associated_record = object.send(attribute.to_sym).new
|
269
|
+
@update_span = 'list_#{attribute}_#{object.id.to_s}'
|
270
|
+
end
|
271
|
+
# process the sub_form fields (attributes). These are declared in the model!
|
272
|
+
@associated_record.field_list.each do | @subform_description, @subform_field, @subform_element |
|
273
|
+
# have no fear
|
274
|
+
send("#{@subform_element}_update", @associated_record, @subform_field, nil)
|
275
|
+
end
|
276
|
+
@associated_record.save
|
277
|
+
end
|
278
|
+
|
279
|
+
# geo_code_curacao
|
280
|
+
def geo_code_curacao_show(object, attribute, values)
|
281
|
+
attribute_value = object.send(attribute).presentation rescue nil
|
282
|
+
link_to_inline_edit object, attribute, attribute_value, nil
|
283
|
+
end
|
284
|
+
def geo_code_curacao_edit(object, attribute, values)
|
285
|
+
text_field_with_auto_complete :geo_code_curacao, :street, :skip_style => true
|
286
|
+
end
|
287
|
+
def geo_code_curacao_update(object, attribute, values)
|
288
|
+
# extract the geocode
|
289
|
+
geo_code = params[attribute.to_sym][:street].scan(/\d\d\d\d\d\d/).to_s || nil
|
290
|
+
object[attribute.to_sym] = GeoCodeCuracao.new(geo_code).valid? ? geo_code : nil
|
291
|
+
end
|
292
|
+
|
293
|
+
private
|
294
|
+
|
295
|
+
# link_to_inline_edit
|
296
|
+
# Directly call Erb::Util.h because we sometimes call this from the controller!
|
297
|
+
# same with link_to_remote. We are using the @template stuff.
|
298
|
+
def link_to_inline_edit(object, attribute, attribute_value, values)
|
299
|
+
#needed for h() and link_to_remote()
|
300
|
+
attribute_value = h(attribute_value)
|
301
|
+
spaces = attribute_value.length > 40 ? 0 : 40 - attribute_value.length
|
302
|
+
attribute_value << " " * spaces
|
303
|
+
if @Klass == 'Index'
|
304
|
+
link_to_remote attribute_value,
|
305
|
+
:url => "/#{@Klass_pluralized}/edit/#{object.id}?field=#{attribute.to_s}&form_element=#{calling_method.sub(/_[a-z]+$/,'')}&values=#{values}",
|
306
|
+
:update => 'field_' + attribute.to_s + '_' + object.id.to_s,
|
307
|
+
:method => :get
|
308
|
+
else
|
309
|
+
link_to_remote attribute_value,
|
310
|
+
:url => "/#{@Klass_pluralized}/#{object.id}/edit?field=#{attribute.to_s}&form_element=#{calling_method.sub(/_[a-z]+$/,'')}&values=#{values}",
|
311
|
+
:update => 'field_' + attribute.to_s + '_' + object.id.to_s,
|
312
|
+
:method => :get
|
313
|
+
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
# make the current method and the calling method available
|
319
|
+
# http://www.ruby-forum.com/topic/75258
|
320
|
+
# supposedly, this is fixed in 1.9
|
321
|
+
module Kernel
|
322
|
+
private
|
323
|
+
def this_method
|
324
|
+
caller[0] =~ /`([^']*)'/ and $1
|
325
|
+
end
|
326
|
+
def calling_method
|
327
|
+
caller[1] =~ /`([^']*)'/ and $1
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class GeoCodeCuracao
|
2
|
+
attr_accessor :street, :neighbourhood, :zone
|
3
|
+
|
4
|
+
class Zone < ActiveRecord::Base
|
5
|
+
set_table_name "Zones"
|
6
|
+
alias_attribute :name, :NAME
|
7
|
+
end
|
8
|
+
class Neighbourhood < ActiveRecord::Base
|
9
|
+
set_table_name "Buurten"
|
10
|
+
alias_attribute :name, :NAME
|
11
|
+
end
|
12
|
+
class Street < ActiveRecord::Base
|
13
|
+
set_table_name "Straatcode"
|
14
|
+
alias_attribute :name, :NAME
|
15
|
+
end
|
16
|
+
def initialize(geo_code_curacao)
|
17
|
+
return nil if geo_code_curacao.nil?
|
18
|
+
decoded = geo_code_curacao.to_s.scan(/\d\d/)
|
19
|
+
zone_code = decoded[0]
|
20
|
+
neighbourhood_code = decoded[1]
|
21
|
+
street_code = decoded[2]
|
22
|
+
#Hash[*['zone','neighbourhood','street'].zip(gecode.to_s.scan(/\d\d/).map(&:to_i)).flatten]
|
23
|
+
self.street = Street.find_by_ZONECODE_and_NBRHCODE_and_STREETCODE(zone_code,neighbourhood_code,street_code)
|
24
|
+
self.neighbourhood = Neighbourhood.find_by_ZONECODE_and_NBRHCODE(zone_code,neighbourhood_code) if self.street
|
25
|
+
self.zone = Zone.find_by_ZONECODE(zone_code) if self.street
|
26
|
+
end
|
27
|
+
def valid?
|
28
|
+
not self.street.nil?
|
29
|
+
end
|
30
|
+
def presentation
|
31
|
+
"#{street.name}, #{zone.name}"
|
32
|
+
end
|
33
|
+
def self.find(*args)
|
34
|
+
find_options = args.extract_options!
|
35
|
+
if args.first.to_s == "all"
|
36
|
+
# ActiveRecord::Base.sanitize_sql_for_conditions can not be called from here. Why?
|
37
|
+
street = find_options[:conditions][1].gsub(/\\/, '\&\&').gsub(/'/, "''") # http://www.ruby-forum.com/topic/80357, active_record/connection_adapter/Quoting.rb
|
38
|
+
sql = "select CONCAT( CONCAT_WS( ', ', S.NAME, B.NAME, Z.NAME), ' (', LPAD( S.ZONECODE, 2, '0' ), LPAD( S.NBRHCODE, 2, '0' ), LPAD( S.STREETCODE, 2, '0' ), ')' ) AS street
|
39
|
+
FROM Straatcode S, Buurten B, Zones Z
|
40
|
+
WHERE
|
41
|
+
B.RECORDTYPE='NBRHOOD'
|
42
|
+
AND S.ZONECODE=Z.ZONECODE
|
43
|
+
AND B.ZONECODE=Z.ZONECODE
|
44
|
+
AND S.ZONECODE=B.ZONECODE
|
45
|
+
AND S.NBRHCODE = B.NBRHCODE
|
46
|
+
AND S.NAME LIKE '#{street}'
|
47
|
+
ORDER BY S.NAME"
|
48
|
+
ids = ActiveRecord::Base.connection.execute(sql)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<table cellpadding="0" cellspacing="0" class="subform">
|
2
|
+
<% @associated_record.field_list.each do | @subform_description, @subform_field, @subform_element, @values | %>
|
3
|
+
<tr>
|
4
|
+
<td valign="top">
|
5
|
+
<div class="subform_field-name">
|
6
|
+
<%= h(@subform_description) %>
|
7
|
+
</div>
|
8
|
+
</td>
|
9
|
+
<td valign="top">
|
10
|
+
<div class="subform_field-value">
|
11
|
+
<%= send("#{@subform_element}_edit", @associated_record, @subform_field.to_s, @values) %>
|
12
|
+
</div>
|
13
|
+
</td>
|
14
|
+
</tr>
|
15
|
+
<% end %>
|
16
|
+
</table>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<% form_remote_tag :update => @update_span || @form_element == "associated" ? @sub_id && @sub_id.to_i > 0 ? "field_#{@field.singularize}_#{@sub_id}" : "list_#{@field}_#{@object.id.to_s}" : "field_#{@field}_#{@object.id.to_s}",
|
2
|
+
:url => "/#{@Klass_pluralized}/#{params[:id]}?field=#{@field}&form_element=#{@form_element}&values=#{@values}&sub_id=#{@sub_id}",
|
3
|
+
:method => :put,
|
4
|
+
:multipart => true,
|
5
|
+
:html => { :class => "edit_form" } do -%>
|
6
|
+
<div class="edit_form_field">
|
7
|
+
<%= send("#{@form_element.to_s}_edit", @object, @field, @values) %>
|
8
|
+
</div>
|
9
|
+
<%= link_to_remote "nee",
|
10
|
+
:url => "/#{@Klass_pluralized}/#{params[:id]}?field=#{@field}&form_element=#{@form_element}&values=#{@values}&sub_id=#{@sub_id}",
|
11
|
+
:method => :get,
|
12
|
+
:html => { :class => "edit_form_cancel" },
|
13
|
+
:update => @update_span || "field_#{@field}_#{@object.id.to_s}" -%>
|
14
|
+
<%= submit_tag "ok", :class => "edit_form_submit"-%>
|
15
|
+
<div style="clear: both;"></div>
|
16
|
+
<% end -%>
|
17
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<% form_remote_tag :multipart => true,
|
2
|
+
:url => "/#{@Klass_pluralized}?field=#{@attribute.to_s}&form_element=#{@form_element}&values=#{@values}&sub_id=#{@sub_id}",
|
3
|
+
:update => @update_span || 'inline_form_list',
|
4
|
+
:html => { :class => "edit_form" } do -%>
|
5
|
+
<div class="edit_form_field">
|
6
|
+
<%= inline_form_display(@object, @object.respond_to?(:field_list) ? @object.field_list : [ '', :name, :text ], :new) %>
|
7
|
+
</div>
|
8
|
+
<%= link_to_remote "nee",
|
9
|
+
# :url => "/#{@Klass_pluralized}/index?field=#{@attribute.to_s}&form_element=#{@form_element}&values=#{@values}&sub_id=#{@sub_id}",
|
10
|
+
:url => "/#{@Klass_pluralized}?layout=false",
|
11
|
+
:html => { :class => "edit_form_cancel" },
|
12
|
+
:update => 'inline_form_list',
|
13
|
+
:method => :get -%>
|
14
|
+
<%= submit_tag "ok", :class => "edit_form_submit"-%>
|
15
|
+
<div style="clear: both;"></div>
|
16
|
+
<% end -%>
|
17
|
+
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{inline_forms}
|
8
|
+
s.version = "0.1.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Ace Suares"]
|
12
|
+
s.date = %q{2011-01-27}
|
13
|
+
s.description = %q{Inline Forms aims to ease the setup of forms that provide inline editing. The field list can be specified in the model.}
|
14
|
+
s.email = %q{ace@suares.an}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"LICENSE.txt",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"app/controllers/inline_forms_controller.rb",
|
28
|
+
"app/helpers/inline_form_helper.rb",
|
29
|
+
"app/models/geo_code_curacao.rb",
|
30
|
+
"app/models/inline_form.rb",
|
31
|
+
"app/views/inline_forms/_subform.html.erb",
|
32
|
+
"app/views/inline_forms/edit.html.erb",
|
33
|
+
"app/views/inline_forms/index.html.erb",
|
34
|
+
"app/views/inline_forms/new.html.erb",
|
35
|
+
"app/views/layouts/inline_forms.rhtml",
|
36
|
+
"inline_forms.gemspec",
|
37
|
+
"lib/inline_forms.rb",
|
38
|
+
"test/helper.rb",
|
39
|
+
"test/test_inline_forms.rb"
|
40
|
+
]
|
41
|
+
s.homepage = %q{http://github.com/acesuares/inline_forms}
|
42
|
+
s.licenses = ["MIT"]
|
43
|
+
s.require_paths = ["lib"]
|
44
|
+
s.rubygems_version = %q{1.3.7}
|
45
|
+
s.summary = %q{Inline editing of forms.}
|
46
|
+
s.test_files = [
|
47
|
+
"test/helper.rb",
|
48
|
+
"test/test_inline_forms.rb"
|
49
|
+
]
|
50
|
+
|
51
|
+
if s.respond_to? :specification_version then
|
52
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
53
|
+
s.specification_version = 3
|
54
|
+
|
55
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
56
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
57
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
58
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
59
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
60
|
+
else
|
61
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
62
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
63
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
64
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
65
|
+
end
|
66
|
+
else
|
67
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
68
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
69
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
70
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inline_forms
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ace Suares
|
@@ -90,10 +90,21 @@ extra_rdoc_files:
|
|
90
90
|
files:
|
91
91
|
- .document
|
92
92
|
- Gemfile
|
93
|
+
- Gemfile.lock
|
93
94
|
- LICENSE.txt
|
94
95
|
- README.rdoc
|
95
96
|
- Rakefile
|
96
97
|
- VERSION
|
98
|
+
- app/controllers/inline_forms_controller.rb
|
99
|
+
- app/helpers/inline_form_helper.rb
|
100
|
+
- app/models/geo_code_curacao.rb
|
101
|
+
- app/models/inline_form.rb
|
102
|
+
- app/views/inline_forms/_subform.html.erb
|
103
|
+
- app/views/inline_forms/edit.html.erb
|
104
|
+
- app/views/inline_forms/index.html.erb
|
105
|
+
- app/views/inline_forms/new.html.erb
|
106
|
+
- app/views/layouts/inline_forms.rhtml
|
107
|
+
- inline_forms.gemspec
|
97
108
|
- lib/inline_forms.rb
|
98
109
|
- test/helper.rb
|
99
110
|
- test/test_inline_forms.rb
|