best_in_place 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +0 -1
- data/README.md +54 -46
- data/lib/assets/javascripts/best_in_place.js +42 -0
- data/lib/best_in_place.rb +4 -0
- data/lib/best_in_place/controller_extensions.rb +1 -1
- data/lib/best_in_place/display_methods.rb +24 -2
- data/lib/best_in_place/helper.rb +26 -9
- data/lib/best_in_place/utils.rb +1 -1
- data/lib/best_in_place/version.rb +1 -1
- data/spec/helpers/best_in_place_spec.rb +46 -1
- data/spec/integration/double_init_spec.rb +2 -1
- data/spec/integration/js_spec.rb +178 -8
- data/spec/support/retry_on_timeout.rb +10 -0
- data/test_app/app/assets/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- data/test_app/app/assets/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- data/test_app/app/assets/images/ui-bg_flat_10_000000_40x100.png +0 -0
- data/test_app/app/assets/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- data/test_app/app/assets/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- data/test_app/app/assets/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/test_app/app/assets/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- data/test_app/app/assets/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- data/test_app/app/assets/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- data/test_app/app/assets/images/ui-icons_222222_256x240.png +0 -0
- data/test_app/app/assets/images/ui-icons_228ef1_256x240.png +0 -0
- data/test_app/app/assets/images/ui-icons_ef8c08_256x240.png +0 -0
- data/test_app/app/assets/images/ui-icons_ffd27a_256x240.png +0 -0
- data/test_app/app/assets/images/ui-icons_ffffff_256x240.png +0 -0
- data/test_app/app/assets/javascripts/application.js +25 -55
- data/test_app/app/assets/stylesheets/jquery-ui-1.8.16.custom.css.erb +357 -0
- data/test_app/app/assets/stylesheets/{style.css → style.css.erb} +1 -1
- data/test_app/app/models/user.rb +1 -0
- data/test_app/app/views/layouts/application.html.erb +1 -1
- data/test_app/app/views/users/double_init.html.erb +7 -0
- data/test_app/app/views/users/show.html.erb +13 -0
- data/test_app/config/initializers/default_date_format.rb +2 -0
- data/test_app/db/migrate/20111217215935_add_birth_date_to_users.rb +5 -0
- data/test_app/db/migrate/20111224181356_add_money_to_user.rb +5 -0
- data/test_app/db/schema.rb +3 -1
- data/test_app/db/seeds.rb +4 -4
- metadata +34 -15
data/README.md
CHANGED
@@ -21,6 +21,7 @@ The editor works by PUTting the updated value to the server and GETting the upda
|
|
21
21
|
- Compatible with **textarea**
|
22
22
|
- Compatible with **select** dropdown with custom collections
|
23
23
|
- Compatible with custom boolean values (same usage of **checkboxes**)
|
24
|
+
- Compatible with **jQuery UI Datepickers**
|
24
25
|
- Sanitize HTML and trim spaces of user's input on user's choice
|
25
26
|
- Displays server-side **validation** errors
|
26
27
|
- Allows external activator
|
@@ -28,7 +29,8 @@ The editor works by PUTting the updated value to the server and GETting the upda
|
|
28
29
|
- Autogrowing textarea
|
29
30
|
- Helper for generating the best_in_place field only if a condition is satisfied
|
30
31
|
- Provided test helpers to be used in your integration specs
|
31
|
-
- Custom display methods
|
32
|
+
- Custom display methods using a method from your model or an existing rails
|
33
|
+
view helper
|
32
34
|
|
33
35
|
##Usage of Rails 3 Gem
|
34
36
|
|
@@ -42,7 +44,7 @@ Params:
|
|
42
44
|
|
43
45
|
Options:
|
44
46
|
|
45
|
-
- **:type** It can be only [:input, :textarea, :select, :checkbox] or if undefined it defaults to :input.
|
47
|
+
- **:type** It can be only [:input, :textarea, :select, :checkbox, :date] or if undefined it defaults to :input.
|
46
48
|
- **:collection**: In case you are using the :select type then you must specify the collection of values it takes. In case you are
|
47
49
|
using the :checkbox type you can specify the two values it can take, or otherwise they will default to Yes and No.
|
48
50
|
- **:path**: URL to which the updating action will be sent. If not defined it defaults to the :object path.
|
@@ -66,7 +68,7 @@ condition, is satisfied. Specifically:
|
|
66
68
|
|
67
69
|
Say we have something like
|
68
70
|
|
69
|
-
<%=
|
71
|
+
<%= best_in_place_if condition, @user, :name, :type => :input %>
|
70
72
|
|
71
73
|
In case *condition* is satisfied, the outcome will be just the same as:
|
72
74
|
|
@@ -109,48 +111,41 @@ The key can be a string or an integer.
|
|
109
111
|
The first value is always the negative boolean value and the second the positive. Structure: `["false value", "true value"]`.
|
110
112
|
If not defined, it will default to *Yes* and *No* options.
|
111
113
|
|
112
|
-
|
114
|
+
### Date
|
113
115
|
|
114
|
-
|
115
|
-
place javascript. A simple example would be:
|
116
|
+
<%= best_in_place @user, :birth_date, :type => :date %>
|
116
117
|
|
117
|
-
|
118
|
-
|
119
|
-
|
118
|
+
With the :date type the input field will be initialized as a datepicker input.
|
119
|
+
In order to provide custom options to the datepicker initialization you must
|
120
|
+
prepare a `$.datepicker.setDefaults` call with the preferences of your choice.
|
120
121
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
122
|
+
More information about datepicker and setting defaults can be found
|
123
|
+
[here](http://docs.jquery.com/UI/Datepicker/$.datepicker.setDefaults)
|
124
|
+
|
125
|
+
## Controller response with respond_with_bip
|
126
|
+
|
127
|
+
Best in place provides a utility method you should use in your controller in
|
128
|
+
order to provide the response that is expected by the javascript side, using
|
129
|
+
the :json format. This is a simple example showing an update action using it:
|
130
|
+
|
131
|
+
def update
|
132
|
+
@user = User.find params[:id]
|
133
|
+
|
134
|
+
respond_to do |format|
|
135
|
+
if @user.update_attributes(params[:user])
|
136
|
+
format.html { redirect_to(@user, :notice => 'User was successfully updated.') }
|
137
|
+
format.json { respond_with_bip(@user) }
|
138
|
+
else
|
139
|
+
format.html { render :action => "edit" }
|
140
|
+
format.json { respond_with_bip(@user) }
|
129
141
|
end
|
130
142
|
end
|
131
143
|
end
|
132
144
|
|
133
|
-
If you respond with a json like `{:display_as => "New value to show"}` with
|
134
|
-
status 200 (ok), then the updated field will show *New value to show* after
|
135
|
-
being updated. This is needed in order to support the custom display methods,
|
136
|
-
and it's automatically handled if you use the new method to encapsulate
|
137
|
-
the responses:
|
138
|
-
|
139
|
-
|
140
|
-
respond_to do |format|
|
141
|
-
if @user.update_attributes(params[:user])
|
142
|
-
format.html { redirect_to(@user, :notice => 'User was successfully updated.') }
|
143
|
-
format.json { respond_with_bip(@user) }
|
144
|
-
else
|
145
|
-
format.html { render :action => "edit" }
|
146
|
-
format.json { respond_with_bip(@user) }
|
147
|
-
end
|
148
|
-
end
|
149
145
|
|
150
|
-
|
151
|
-
handle custom display methods.
|
146
|
+
## Custom display methods
|
152
147
|
|
153
|
-
|
148
|
+
### Using `display_as`
|
154
149
|
|
155
150
|
As of best in place 1.0.3 you can use custom methods in your model in order to
|
156
151
|
decide how a certain field has to be displayed. You can write something like:
|
@@ -159,17 +154,21 @@ decide how a certain field has to be displayed. You can write something like:
|
|
159
154
|
|
160
155
|
Then instead of using `@user.description` to show the actual value, best in
|
161
156
|
place will call `@user.mk_description`. This can be used for any kind of
|
162
|
-
custom formatting, text with markdown,
|
157
|
+
custom formatting, text with markdown, etc...
|
163
158
|
|
164
|
-
|
165
|
-
javascript after a successful update, the only way to display the new correct
|
166
|
-
value after an edition is to use the provided methods to respond in your
|
167
|
-
controllers, or implement the same in your own way.
|
159
|
+
### Using `display_with`
|
168
160
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
161
|
+
In practice the most common situation is when you want to use an existing
|
162
|
+
helper to render the attribute, like `number_to_currency` or `simple_format`.
|
163
|
+
As of version 1.0.4 best in place provides this feature using the
|
164
|
+
`display_with` option. You can use it like this:
|
165
|
+
|
166
|
+
= best_in_place @user, :money, :display_with => :number_to_currency
|
167
|
+
|
168
|
+
If you want to pass further arguments to the helper you can do it providing an
|
169
|
+
additional `helper_options` hash:
|
170
|
+
|
171
|
+
= best_in_place @user, :money, :display_with => :number_to_currency, :helper_options => {:unit => "€"}
|
173
172
|
|
174
173
|
|
175
174
|
##Non Active Record environments
|
@@ -277,12 +276,17 @@ thanks to Rails 3.1. Just begin including the gem in your Gemfile:
|
|
277
276
|
gem "best_in_place"
|
278
277
|
|
279
278
|
After that, specify the use of the jquery, jquery.purr and best in place
|
280
|
-
javascripts in your application.js
|
279
|
+
javascripts in your application.js, and optionally specify jquery-ui if
|
280
|
+
you want to use jQuery UI datepickers:
|
281
281
|
|
282
282
|
//= require jquery
|
283
|
+
//= require jquery-ui
|
283
284
|
//= require jquery.purr
|
284
285
|
//= require best_in_place
|
285
286
|
|
287
|
+
If you want to use jQuery UI datepickers, you should also install and
|
288
|
+
load your preferred jquery-ui CSS file and associated assets.
|
289
|
+
|
286
290
|
Then, just add a binding to prepare all best in place fields when the document is ready:
|
287
291
|
|
288
292
|
$(document).ready(function() {
|
@@ -315,6 +319,10 @@ You can automatize this installation by doing
|
|
315
319
|
|
316
320
|
rails g best_in_place:setup
|
317
321
|
|
322
|
+
If you want to use jQuery UI datepickers, you should also install and
|
323
|
+
load jquery-ui.js as well as your preferred jquery-ui CSS file and
|
324
|
+
associated assets.
|
325
|
+
|
318
326
|
Finally, as for Rails 3.1, just add a binding to prepare all best in place fields when the document is ready:
|
319
327
|
|
320
328
|
$(document).ready(function() {
|
@@ -83,6 +83,7 @@ BestInPlaceEditor.prototype = {
|
|
83
83
|
} else {
|
84
84
|
editor.element.html(this.getValue() != "" ? this.getValue() : this.nil);
|
85
85
|
}
|
86
|
+
editor.element.trigger($.Event("best_in_place:update"));
|
86
87
|
},
|
87
88
|
|
88
89
|
activateForm : function() {
|
@@ -193,6 +194,8 @@ BestInPlaceEditor.prototype = {
|
|
193
194
|
loadSuccessCallback : function(data) {
|
194
195
|
var response = $.parseJSON($.trim(data));
|
195
196
|
if (response != null && response.hasOwnProperty("display_as")) {
|
197
|
+
this.element.attr("data-original-content", this.element.html());
|
198
|
+
this.original_content = this.element.html();
|
196
199
|
this.element.html(response["display_as"]);
|
197
200
|
}
|
198
201
|
this.element.trigger($.Event("ajax:success"), data);
|
@@ -265,6 +268,45 @@ BestInPlaceEditor.forms = {
|
|
265
268
|
}
|
266
269
|
},
|
267
270
|
|
271
|
+
"date" : {
|
272
|
+
activateForm : function() {
|
273
|
+
var that = this,
|
274
|
+
output = '<form class="form_in_place" action="javascript:void(0)" style="display:inline;">';
|
275
|
+
output += '<input type="text" name="'+ this.attributeName + '" value="' + this.sanitizeValue(this.display_value) + '"';
|
276
|
+
if (this.inner_class != null) {
|
277
|
+
output += ' class="' + this.inner_class + '"';
|
278
|
+
}
|
279
|
+
output += '></form>'
|
280
|
+
this.element.html(output);
|
281
|
+
this.setHtmlAttributes();
|
282
|
+
this.element.find('input')[0].select();
|
283
|
+
this.element.find("form").bind('submit', {editor: this}, BestInPlaceEditor.forms.input.submitHandler);
|
284
|
+
this.element.find("input").bind('keyup', {editor: this}, BestInPlaceEditor.forms.input.keyupHandler);
|
285
|
+
|
286
|
+
this.element.find('input')
|
287
|
+
.datepicker({
|
288
|
+
onClose: function() {
|
289
|
+
that.update();
|
290
|
+
}
|
291
|
+
})
|
292
|
+
.datepicker('show');
|
293
|
+
},
|
294
|
+
|
295
|
+
getValue : function() {
|
296
|
+
return this.sanitizeValue(this.element.find("input").val());
|
297
|
+
},
|
298
|
+
|
299
|
+
submitHandler : function(event) {
|
300
|
+
event.data.editor.update();
|
301
|
+
},
|
302
|
+
|
303
|
+
keyupHandler : function(event) {
|
304
|
+
if (event.keyCode == 27) {
|
305
|
+
event.data.editor.abort();
|
306
|
+
}
|
307
|
+
}
|
308
|
+
},
|
309
|
+
|
268
310
|
"select" : {
|
269
311
|
activateForm : function() {
|
270
312
|
var output = "<form action='javascript:void(0)' style='display:inline;'><select>";
|
data/lib/best_in_place.rb
CHANGED
@@ -10,7 +10,7 @@ module BestInPlace
|
|
10
10
|
updating_attr = params[klass.underscore].keys.first
|
11
11
|
|
12
12
|
if renderer = BestInPlace::DisplayMethods.lookup(klass, updating_attr)
|
13
|
-
render :json =>
|
13
|
+
render :json => renderer.render_json(obj)
|
14
14
|
else
|
15
15
|
head :ok
|
16
16
|
end
|
@@ -2,6 +2,24 @@ module BestInPlace
|
|
2
2
|
module DisplayMethods
|
3
3
|
extend self
|
4
4
|
|
5
|
+
class Renderer < Struct.new(:opts)
|
6
|
+
def render_json(object)
|
7
|
+
case opts[:type]
|
8
|
+
when :model
|
9
|
+
{:display_as => object.send(opts[:method])}.to_json
|
10
|
+
when :helper
|
11
|
+
value = if opts[:helper_options]
|
12
|
+
BestInPlace::ViewHelpers.send(opts[:method], object.send(opts[:attr]), opts[:helper_options])
|
13
|
+
else
|
14
|
+
BestInPlace::ViewHelpers.send(opts[:method], object.send(opts[:attr]))
|
15
|
+
end
|
16
|
+
{:display_as => value}.to_json
|
17
|
+
else
|
18
|
+
{}.to_json
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
5
23
|
@@table = Hash.new { |h,k| h[k] = Hash.new(&h.default_proc) }
|
6
24
|
|
7
25
|
def lookup(klass, attr)
|
@@ -9,8 +27,12 @@ module BestInPlace
|
|
9
27
|
foo == {} ? nil : foo
|
10
28
|
end
|
11
29
|
|
12
|
-
def
|
13
|
-
@@table[klass.to_s][attr.to_s] = display_as.to_sym
|
30
|
+
def add_model_method(klass, attr, display_as)
|
31
|
+
@@table[klass.to_s][attr.to_s] = Renderer.new :method => display_as.to_sym, :type => :model
|
32
|
+
end
|
33
|
+
|
34
|
+
def add_helper_method(klass, attr, helper_method, helper_options = nil)
|
35
|
+
@@table[klass.to_s][attr.to_s] = Renderer.new :method => helper_method.to_sym, :type => :helper, :attr => attr, :helper_options => helper_options
|
14
36
|
end
|
15
37
|
end
|
16
38
|
end
|
data/lib/best_in_place/helper.rb
CHANGED
@@ -2,6 +2,14 @@ module BestInPlace
|
|
2
2
|
module BestInPlaceHelpers
|
3
3
|
|
4
4
|
def best_in_place(object, field, opts = {})
|
5
|
+
if opts[:display_as] && opts[:display_with]
|
6
|
+
raise ArgumentError, "Can't use both 'display_as' and 'display_with' options at the same time"
|
7
|
+
end
|
8
|
+
|
9
|
+
if opts[:display_with] && !ViewHelpers.respond_to?(opts[:display_with])
|
10
|
+
raise ArgumentError, "Can't find helper #{opts[:display_with]}"
|
11
|
+
end
|
12
|
+
|
5
13
|
opts[:type] ||= :input
|
6
14
|
opts[:collection] ||= []
|
7
15
|
field = field.to_s
|
@@ -24,21 +32,21 @@ module BestInPlace
|
|
24
32
|
end
|
25
33
|
out = "<span class='best_in_place'"
|
26
34
|
out << " id='#{BestInPlace::Utils.build_best_in_place_id(object, field)}'"
|
27
|
-
out << " data-url='#{opts[:path].blank? ? url_for(object)
|
35
|
+
out << " data-url='#{opts[:path].blank? ? url_for(object) : url_for(opts[:path])}'"
|
28
36
|
out << " data-object='#{object.class.to_s.gsub("::", "_").underscore}'"
|
29
37
|
out << " data-collection='#{collection.gsub(/'/, "'")}'" unless collection.blank?
|
30
38
|
out << " data-attribute='#{field}'"
|
31
39
|
out << " data-activator='#{opts[:activator]}'" unless opts[:activator].blank?
|
32
|
-
out << " data-nil='#{opts[:nil]
|
33
|
-
out << " data-type='#{opts[:type]
|
34
|
-
out << " data-inner-class='#{opts[:inner_class]
|
40
|
+
out << " data-nil='#{opts[:nil]}'" unless opts[:nil].blank?
|
41
|
+
out << " data-type='#{opts[:type]}'"
|
42
|
+
out << " data-inner-class='#{opts[:inner_class]}'" if opts[:inner_class]
|
35
43
|
out << " data-html-attrs='#{opts[:html_attrs].to_json}'" unless opts[:html_attrs].blank?
|
36
|
-
out << " data-original-content='#{object.send(field)}'" if opts[:display_as]
|
44
|
+
out << " data-original-content='#{object.send(field)}'" if opts[:display_as] || opts[:display_with]
|
37
45
|
if !opts[:sanitize].nil? && !opts[:sanitize]
|
38
46
|
out << " data-sanitize='false'>"
|
39
|
-
out << sanitize(value
|
47
|
+
out << sanitize(value, :tags => %w(b i u s a strong em p h1 h2 h3 h4 h5 ul li ol hr pre span img br), :attributes => %w(id class href))
|
40
48
|
else
|
41
|
-
out << ">#{sanitize(value
|
49
|
+
out << ">#{sanitize(value, :tags => nil, :attributes => nil)}"
|
42
50
|
end
|
43
51
|
out << "</span>"
|
44
52
|
raw out
|
@@ -55,10 +63,19 @@ module BestInPlace
|
|
55
63
|
private
|
56
64
|
def build_value_for(object, field, opts)
|
57
65
|
if opts[:display_as]
|
58
|
-
BestInPlace::DisplayMethods.
|
66
|
+
BestInPlace::DisplayMethods.add_model_method(object.class.to_s, field, opts[:display_as])
|
59
67
|
object.send(opts[:display_as]).to_s
|
68
|
+
|
69
|
+
elsif opts[:display_with]
|
70
|
+
BestInPlace::DisplayMethods.add_helper_method(object.class.to_s, field, opts[:display_with], opts[:helper_options])
|
71
|
+
if opts[:helper_options]
|
72
|
+
BestInPlace::ViewHelpers.send(opts[:display_with], object.send(field), opts[:helper_options])
|
73
|
+
else
|
74
|
+
BestInPlace::ViewHelpers.send(opts[:display_with], object.send(field))
|
75
|
+
end
|
76
|
+
|
60
77
|
else
|
61
|
-
object.send(field).
|
78
|
+
object.send(field).to_s.presence || ""
|
62
79
|
end
|
63
80
|
end
|
64
81
|
end
|
data/lib/best_in_place/utils.rb
CHANGED
@@ -7,7 +7,7 @@ module BestInPlace
|
|
7
7
|
end
|
8
8
|
|
9
9
|
id = "best_in_place_#{object.class.to_s.demodulize.underscore}"
|
10
|
-
id << "_#{object.id}" if object.class.ancestors.include?(
|
10
|
+
id << "_#{object.id}" if object.class.ancestors.include?(ActiveModel::Serializers::JSON)
|
11
11
|
id << "_#{field}"
|
12
12
|
id
|
13
13
|
end
|
@@ -11,7 +11,9 @@ describe BestInPlace::BestInPlaceHelpers do
|
|
11
11
|
:zip => "25123",
|
12
12
|
:country => "2",
|
13
13
|
:receive_email => false,
|
14
|
-
:
|
14
|
+
:birth_date => Time.now.utc.to_date,
|
15
|
+
:description => "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus a lectus et lacus ultrices auctor. Morbi aliquet convallis tincidunt. Praesent enim libero, iaculis at commodo nec, fermentum a dolor. Quisque eget eros id felis lacinia faucibus feugiat et ante. Aenean justo nisi, aliquam vel egestas vel, porta in ligula. Etiam molestie, lacus eget tincidunt accumsan, elit justo rhoncus urna, nec pretium neque mi et lorem. Aliquam posuere, dolor quis pulvinar luctus, felis dolor tincidunt leo, eget pretium orci purus ac nibh. Ut enim sem, suscipit ac elementum vitae, sodales vel sem.",
|
16
|
+
:money => 150
|
15
17
|
end
|
16
18
|
|
17
19
|
it "should generate a proper span" do
|
@@ -20,6 +22,10 @@ describe BestInPlace::BestInPlaceHelpers do
|
|
20
22
|
span.should_not be_empty
|
21
23
|
end
|
22
24
|
|
25
|
+
it "should not allow both display_as and display_with option" do
|
26
|
+
lambda { helper.best_in_place(@user, :money, :display_with => :number_to_currency, :display_as => :custom) }.should raise_error(ArgumentError)
|
27
|
+
end
|
28
|
+
|
23
29
|
describe "general properties" do
|
24
30
|
before do
|
25
31
|
nk = Nokogiri::HTML.parse(helper.best_in_place @user, :name)
|
@@ -133,6 +139,26 @@ describe BestInPlace::BestInPlaceHelpers do
|
|
133
139
|
span.text.should == "the result"
|
134
140
|
end
|
135
141
|
end
|
142
|
+
|
143
|
+
describe "display_with" do
|
144
|
+
it "should render the money with the given view helper" do
|
145
|
+
out = helper.best_in_place @user, :money, :display_with => :number_to_currency
|
146
|
+
nk = Nokogiri::HTML.parse(out)
|
147
|
+
span = nk.css("span")
|
148
|
+
span.text.should == "$150.00"
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should raise an error if the given helper can't be found" do
|
152
|
+
lambda { helper.best_in_place @user, :money, :display_with => :fk_number_to_currency }.should raise_error(ArgumentError)
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should call the helper method with the given arguments" do
|
156
|
+
out = helper.best_in_place @user, :money, :display_with => :number_to_currency, :helper_options => {:unit => "º"}
|
157
|
+
nk = Nokogiri::HTML.parse(out)
|
158
|
+
span = nk.css("span")
|
159
|
+
span.text.should == "º150.00"
|
160
|
+
end
|
161
|
+
end
|
136
162
|
end
|
137
163
|
|
138
164
|
|
@@ -155,6 +181,25 @@ describe BestInPlace::BestInPlaceHelpers do
|
|
155
181
|
end
|
156
182
|
end
|
157
183
|
|
184
|
+
context "with a date attribute" do
|
185
|
+
before do
|
186
|
+
nk = Nokogiri::HTML.parse(helper.best_in_place @user, :birth_date, :type => :date)
|
187
|
+
@span = nk.css("span")
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should render the date as text" do
|
191
|
+
@span.text.should == @user.birth_date.to_date.to_s
|
192
|
+
end
|
193
|
+
|
194
|
+
it "should have a date data-type" do
|
195
|
+
@span.attribute("data-type").value.should == "date"
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should have no data-collection" do
|
199
|
+
@span.attribute("data-collection").should be_nil
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
158
203
|
context "with a boolean attribute" do
|
159
204
|
before do
|
160
205
|
nk = Nokogiri::HTML.parse(helper.best_in_place @user, :receive_email, :type => :checkbox)
|