best_in_place 1.0.6 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +36 -0
- data/README.md +23 -28
- data/lib/assets/javascripts/best_in_place.js +38 -18
- data/lib/best_in_place/controller_extensions.rb +2 -1
- data/lib/best_in_place/helper.rb +28 -9
- data/lib/best_in_place/utils.rb +9 -3
- data/lib/best_in_place/version.rb +1 -1
- data/spec/helpers/best_in_place_spec.rb +23 -0
- data/spec/integration/js_spec.rb +21 -0
- data/spec/integration/live_spec.rb +39 -0
- data/test_app/app/controllers/admin/users_controller.rb +14 -0
- data/test_app/app/controllers/cuca/cars_controller.rb +16 -0
- data/test_app/app/controllers/users_controller.rb +10 -0
- data/test_app/app/models/cuca/car.rb +5 -0
- data/test_app/app/views/admin/users/show.html.erb +20 -0
- data/test_app/app/views/cuca/cars/show.html.erb +13 -0
- data/test_app/app/views/users/email_field.html.erb +1 -0
- data/test_app/app/views/users/show_ajax.html.erb +12 -0
- data/test_app/config/routes.rb +10 -0
- data/test_app/db/migrate/20120513003308_create_cars.rb +11 -0
- data/test_app/db/schema.rb +11 -5
- data/test_app/db/seeds.rb +4 -0
- metadata +58 -16
data/CHANGELOG.md
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#Changelog
|
2
|
+
|
3
|
+
##Master branch (and part of the Rails 3.0 branch)
|
4
|
+
- v.0.1.0 Initial commit
|
5
|
+
- v.0.1.2 Fixing errors in collections (taken value[0] instead of index) and fixing test_app controller responses
|
6
|
+
- v.0.1.3 Bug in Rails Helper. Key wrongly considered an Integer.
|
7
|
+
- v.0.1.4 Adding two new parameters for further customization urlObject and nilValue and making input update on blur.
|
8
|
+
- v.0.1.5 **Attention: this release is not backwards compatible**. Changing params from list to option hash, helper's refactoring,
|
9
|
+
fixing bug with objects inside namespaces, adding feature for passing an external activator handler as param. Adding feature
|
10
|
+
of key ESCAPE for destroying changes before they are made permanent (in inputs and textarea).
|
11
|
+
- v.0.1.6-0.1.7 Avoiding request when the input is not modified and allowing the user to not sanitize input data.
|
12
|
+
- v.0.1.8 jslint compliant, sanitizing tags in the gem, getting right csrf params, controlling size of textarea (elastic script, for autogrowing textarea)
|
13
|
+
- v.0.1.9 Adding elastic autogrowing textareas
|
14
|
+
- v.1.0.0 Setting RSpec and Capybara up, and adding some utilities. Mantaining some HTML attributes. Fix a respond_with bug (thanks, @moabite). Triggering ajax:success when ajax call is complete (thanks, @indrekj). Setting up Travis CI. Updated for Rails 3.1.
|
15
|
+
- v.1.0.1 Fixing a double initialization bug
|
16
|
+
- v.1.0.2 New bip_area text helper to work with text areas.
|
17
|
+
- v.1.0.3 replace apostrophes in collection with corresponding HTML entity,
|
18
|
+
thanks @taavo. Implemented `:display_as` option and adding
|
19
|
+
`respond_with_bip` to be used in the controller.
|
20
|
+
- v.1.0.4 Depend on ActiveModel instead of ActiveRecord (thanks,
|
21
|
+
@skinnyfit). Added date type (thanks @taavo). Added new feature:
|
22
|
+
display_with.
|
23
|
+
- v.1.0.5 Fix a bug involving quotes (thanks @ygoldshtrakh). Minor fixes
|
24
|
+
by @bfalling. Add object name option (thanks @nicholassm). Check
|
25
|
+
version of Rails before booting. Minor fixes.
|
26
|
+
- v.1.0.6 Fix issue with display_with. Update test_app to 3.2.
|
27
|
+
- v.1.1.0 Changed $ by jQuery for compatibility (thanks @tschmitz), new
|
28
|
+
events for 'deactivate' (thanks @glebtv), added new 'data' attribute
|
29
|
+
to BIP's span (thanks @straydogstudio), works with dynamically added
|
30
|
+
elements to the page (thanks @enriclluelles), added object detection to
|
31
|
+
the 'path' parameter and some more bugfixes.
|
32
|
+
|
33
|
+
##Rails 3.0 branch only
|
34
|
+
- v.0.2.0 Added RSpec and Capybara setup, and some tests. Fix countries map syntax, Allowing href and some other HTML attributes. Adding Travis CI too. Added the best_in_place_if option. Added ajax:success trigger, thanks to @indrekj.
|
35
|
+
- v.0.2.1 Fixing double initialization bug.
|
36
|
+
- v.0.2.2 New bip_area text helper.
|
data/README.md
CHANGED
@@ -45,7 +45,7 @@ Params:
|
|
45
45
|
|
46
46
|
Options:
|
47
47
|
|
48
|
-
- **:type** It can be only [:input, :textarea, :select, :checkbox, :date] or if undefined it defaults to :input.
|
48
|
+
- **:type** It can be only [:input, :textarea, :select, :checkbox, :date (>= 1.0.4)] or if undefined it defaults to :input.
|
49
49
|
- **:collection**: In case you are using the :select type then you must specify the collection of values it takes. In case you are
|
50
50
|
using the :checkbox type you can specify the two values it can take, or otherwise they will default to Yes and No.
|
51
51
|
- **:path**: URL to which the updating action will be sent. If not defined it defaults to the :object path.
|
@@ -60,6 +60,7 @@ Options:
|
|
60
60
|
- **:display_as**: A model method which will be called in order to display
|
61
61
|
this field.
|
62
62
|
- **:object_name**: Used for overriding the default params key used for the object (the data-object attribute). Useful for e.g. STI scenarios where best_in_place should post to a common controller for different models.
|
63
|
+
- **:data**: Hash of custom data attributes to be added to span. Can be used to provide data to the ajax:success callback.
|
63
64
|
|
64
65
|
###best_in_place_if
|
65
66
|
**best_in_place_if condition, object, field, OPTIONS**
|
@@ -176,6 +177,27 @@ additional `helper_options` hash:
|
|
176
177
|
|
177
178
|
= best_in_place @user, :money, :display_with => :number_to_currency, :helper_options => {:unit => "€"}
|
178
179
|
|
180
|
+
You can also pass in a proc or lambda like this:
|
181
|
+
|
182
|
+
= best_in_place @post, :body, :display_with => lambda { |v| textilize(v).html_safe }
|
183
|
+
|
184
|
+
## Ajax success callback
|
185
|
+
|
186
|
+
### Binding to ajax:success
|
187
|
+
|
188
|
+
The 'ajax:success' event is triggered upon success. Use bind:
|
189
|
+
|
190
|
+
$('.best_in_place').bind("ajax:success", function(){$(this).closest('tr').effect('highlight'));});
|
191
|
+
|
192
|
+
### Providing data to the callback
|
193
|
+
|
194
|
+
Use the :data option to add HTML5 data attributes to the best_in_place span. For example, in your view:
|
195
|
+
|
196
|
+
<%= best_in_place @user, :name, :data => {:user_name => @user.name} %>
|
197
|
+
|
198
|
+
And in your javascript:
|
199
|
+
|
200
|
+
$('.best_in_place').bind("ajax:success", function(){ alert('Name updated for '+$(this).data('userName')); });
|
179
201
|
|
180
202
|
##Non Active Record environments
|
181
203
|
We are not planning to support other ORMs apart from Active Record, at least for now. So, you can perfectly consider the following workaround as *the right way* until a specific implementation is done for your ORM.
|
@@ -380,33 +402,6 @@ Fork the project on [github](https://github.com/bernat/best_in_place 'bernat / b
|
|
380
402
|
|
381
403
|
---
|
382
404
|
|
383
|
-
##Changelog
|
384
|
-
|
385
|
-
###Master branch (and part of the Rails 3.0 branch)
|
386
|
-
- v.0.1.0 Initial commit
|
387
|
-
- v.0.1.2 Fixing errors in collections (taken value[0] instead of index) and fixing test_app controller responses
|
388
|
-
- v.0.1.3 Bug in Rails Helper. Key wrongly considered an Integer.
|
389
|
-
- v.0.1.4 Adding two new parameters for further customization urlObject and nilValue and making input update on blur.
|
390
|
-
- v.0.1.5 **Attention: this release is not backwards compatible**. Changing params from list to option hash, helper's refactoring,
|
391
|
-
fixing bug with objects inside namespaces, adding feature for passing an external activator handler as param. Adding feature
|
392
|
-
of key ESCAPE for destroying changes before they are made permanent (in inputs and textarea).
|
393
|
-
- v.0.1.6-0.1.7 Avoiding request when the input is not modified and allowing the user to not sanitize input data.
|
394
|
-
- v.0.1.8 jslint compliant, sanitizing tags in the gem, getting right csrf params, controlling size of textarea (elastic script, for autogrowing textarea)
|
395
|
-
- v.0.1.9 Adding elastic autogrowing textareas
|
396
|
-
- v.1.0.0 Setting RSpec and Capybara up, and adding some utilities. Mantaining some HTML attributes. Fix a respond_with bug (thanks, @moabite). Triggering ajax:success when ajax call is complete (thanks, @indrekj). Setting up Travis CI. Updated for Rails 3.1.
|
397
|
-
- v.1.0.1 Fixing a double initialization bug
|
398
|
-
- v.1.0.2 New bip_area text helper to work with text areas.
|
399
|
-
- v.1.0.3 replace apostrophes in collection with corresponding HTML entity,
|
400
|
-
thanks @taavo. Implemented `:display_as` option and adding
|
401
|
-
`respond_with_bip` to be used in the controller.
|
402
|
-
|
403
|
-
###Rails 3.0 branch only
|
404
|
-
- v.0.2.0 Added RSpec and Capybara setup, and some tests. Fix countries map syntax, Allowing href and some other HTML attributes. Adding Travis CI too. Added the best_in_place_if option. Added ajax:success trigger, thanks to @indrekj.
|
405
|
-
- v.0.2.1 Fixing double initialization bug.
|
406
|
-
- v.0.2.2 New bip_area text helper.
|
407
|
-
|
408
|
-
---
|
409
|
-
|
410
405
|
##Authors, License and Stuff
|
411
406
|
|
412
407
|
Code by [Bernat Farrero](http://bernatfarrero.com) from [Itnig Web Services](http://itnig.net) (it was based on the [original project](http://github.com/janv/rest_in_place/) of Jan Varwig) and released under [MIT license](http://www.opensource.org/licenses/mit-license.php).
|
@@ -20,11 +20,11 @@
|
|
20
20
|
*/
|
21
21
|
|
22
22
|
function BestInPlaceEditor(e) {
|
23
|
-
this.element =
|
23
|
+
this.element = e;
|
24
24
|
this.initOptions();
|
25
25
|
this.bindForm();
|
26
26
|
this.initNil();
|
27
|
-
|
27
|
+
jQuery(this.activator).bind('click', {editor: this}, this.clickHandler);
|
28
28
|
}
|
29
29
|
|
30
30
|
BestInPlaceEditor.prototype = {
|
@@ -45,14 +45,17 @@ BestInPlaceEditor.prototype = {
|
|
45
45
|
var elem = this.isNil ? "" : this.element.html();
|
46
46
|
this.oldValue = elem;
|
47
47
|
this.display_value = to_display;
|
48
|
-
|
48
|
+
jQuery(this.activator).unbind("click", this.clickHandler);
|
49
|
+
this.element.trigger(jQuery.Event("best_in_place:activate"));
|
49
50
|
this.activateForm();
|
50
51
|
},
|
51
52
|
|
52
53
|
abort : function() {
|
53
54
|
if (this.isNil) this.element.html(this.nil);
|
54
55
|
else this.element.html(this.oldValue);
|
55
|
-
|
56
|
+
jQuery(this.activator).bind('click', {editor: this}, this.clickHandler);
|
57
|
+
this.element.trigger(jQuery.Event("best_in_place:abort"));
|
58
|
+
this.element.trigger(jQuery.Event("best_in_place:deactivate"));
|
56
59
|
},
|
57
60
|
|
58
61
|
abortIfConfirm : function () {
|
@@ -78,7 +81,7 @@ BestInPlaceEditor.prototype = {
|
|
78
81
|
});
|
79
82
|
if (this.formType == "select") {
|
80
83
|
var value = this.getValue();
|
81
|
-
|
84
|
+
jQuery.each(this.values, function(i, v) {
|
82
85
|
if (value == v[0]) {
|
83
86
|
editor.element.html(v[1]);
|
84
87
|
}
|
@@ -89,7 +92,7 @@ BestInPlaceEditor.prototype = {
|
|
89
92
|
} else {
|
90
93
|
editor.element.html(this.getValue() != "" ? this.getValue() : this.nil);
|
91
94
|
}
|
92
|
-
editor.element.trigger(
|
95
|
+
editor.element.trigger(jQuery.Event("best_in_place:update"));
|
93
96
|
},
|
94
97
|
|
95
98
|
activateForm : function() {
|
@@ -182,8 +185,8 @@ BestInPlaceEditor.prototype = {
|
|
182
185
|
/* Generate the data sent in the POST request */
|
183
186
|
requestData : function() {
|
184
187
|
// To prevent xss attacks, a csrf token must be defined as a meta attribute
|
185
|
-
csrf_token =
|
186
|
-
csrf_param =
|
188
|
+
csrf_token = jQuery('meta[name=csrf-token]').attr('content');
|
189
|
+
csrf_param = jQuery('meta[name=csrf-param]').attr('content');
|
187
190
|
|
188
191
|
var data = "_method=put";
|
189
192
|
data += "&" + this.objectName + '[' + this.attributeName + ']=' + encodeURIComponent(this.getValue());
|
@@ -203,33 +206,37 @@ BestInPlaceEditor.prototype = {
|
|
203
206
|
// Handlers ////////////////////////////////////////////////////////////////
|
204
207
|
|
205
208
|
loadSuccessCallback : function(data) {
|
206
|
-
var response =
|
209
|
+
var response = jQuery.parseJSON(jQuery.trim(data));
|
207
210
|
if (response != null && response.hasOwnProperty("display_as")) {
|
208
211
|
this.element.attr("data-original-content", this.element.html());
|
209
212
|
this.original_content = this.element.html();
|
210
213
|
this.element.html(response["display_as"]);
|
211
214
|
}
|
212
|
-
this.element.trigger(
|
215
|
+
this.element.trigger(jQuery.Event("ajax:success"), data);
|
213
216
|
|
214
217
|
// Binding back after being clicked
|
215
|
-
|
218
|
+
jQuery(this.activator).bind('click', {editor: this}, this.clickHandler);
|
219
|
+
this.element.trigger(jQuery.Event("best_in_place:deactivate"));
|
216
220
|
},
|
217
221
|
|
218
222
|
loadErrorCallback : function(request, error) {
|
219
223
|
this.element.html(this.oldValue);
|
220
224
|
|
221
225
|
// Display all error messages from server side validation
|
222
|
-
|
226
|
+
jQuery.each(jQuery.parseJSON(request.responseText), function(index, value) {
|
223
227
|
if( typeof(value) == "object") {value = index + " " + value.toString(); }
|
224
|
-
var container =
|
228
|
+
var container = jQuery("<span class='flash-error'></span>").html(value);
|
225
229
|
container.purr();
|
226
230
|
});
|
231
|
+
this.element.trigger(jQuery.Event("ajax:error"));
|
227
232
|
|
228
233
|
// Binding back after being clicked
|
229
|
-
|
234
|
+
jQuery(this.activator).bind('click', {editor: this}, this.clickHandler);
|
235
|
+
this.element.trigger(jQuery.Event("best_in_place:deactivate"));
|
230
236
|
},
|
231
237
|
|
232
238
|
clickHandler : function(event) {
|
239
|
+
event.preventDefault();
|
233
240
|
event.data.editor.activate();
|
234
241
|
},
|
235
242
|
|
@@ -366,7 +373,7 @@ BestInPlaceEditor.forms = {
|
|
366
373
|
var output = "<form action='javascript:void(0)' style='display:inline;'><select>";
|
367
374
|
var selected = "";
|
368
375
|
var oldValue = this.oldValue;
|
369
|
-
|
376
|
+
jQuery.each(this.values, function(index, value) {
|
370
377
|
selected = (value[1] == oldValue ? "selected='selected'" : "");
|
371
378
|
output += "<option value='" + value[0] + "' " + selected + ">" + value[1] + "</option>";
|
372
379
|
});
|
@@ -488,11 +495,24 @@ BestInPlaceEditor.forms = {
|
|
488
495
|
};
|
489
496
|
|
490
497
|
jQuery.fn.best_in_place = function() {
|
491
|
-
|
492
|
-
|
493
|
-
|
498
|
+
|
499
|
+
function setBestInPlace(element) {
|
500
|
+
if (!element.data('bestInPlaceEditor')) {
|
501
|
+
element.data('bestInPlaceEditor', new BestInPlaceEditor(element));
|
502
|
+
return true;
|
494
503
|
}
|
504
|
+
}
|
505
|
+
|
506
|
+
jQuery(this.context).delegate(this.selector, 'click', function () {
|
507
|
+
var el = jQuery(this);
|
508
|
+
if (setBestInPlace(el))
|
509
|
+
el.click();
|
495
510
|
});
|
511
|
+
|
512
|
+
this.each(function () {
|
513
|
+
setBestInPlace(jQuery(this));
|
514
|
+
});
|
515
|
+
|
496
516
|
return this;
|
497
517
|
};
|
498
518
|
|
@@ -7,7 +7,8 @@ module BestInPlace
|
|
7
7
|
private
|
8
8
|
def respond_bip_ok(obj)
|
9
9
|
klass = obj.class.to_s
|
10
|
-
|
10
|
+
param_key = BestInPlace::Utils.object_to_key(obj)
|
11
|
+
updating_attr = params[param_key].keys.first
|
11
12
|
|
12
13
|
if renderer = BestInPlace::DisplayMethods.lookup(klass, updating_attr)
|
13
14
|
render :json => renderer.render_json(obj)
|
data/lib/best_in_place/helper.rb
CHANGED
@@ -6,24 +6,25 @@ module BestInPlace
|
|
6
6
|
raise ArgumentError, "Can't use both 'display_as' and 'display_with' options at the same time"
|
7
7
|
end
|
8
8
|
|
9
|
-
if opts[:display_with] && !ViewHelpers.respond_to?(opts[:display_with])
|
9
|
+
if opts[:display_with] && !opts[:display_with].is_a?(Proc) && !ViewHelpers.respond_to?(opts[:display_with])
|
10
10
|
raise ArgumentError, "Can't find helper #{opts[:display_with]}"
|
11
11
|
end
|
12
12
|
|
13
|
+
real_object = (object.is_a?(Array) && object.last.class.respond_to?(:model_name)) ? object.last : object
|
13
14
|
opts[:type] ||= :input
|
14
15
|
opts[:collection] ||= []
|
15
16
|
field = field.to_s
|
16
17
|
|
17
|
-
value = build_value_for(
|
18
|
+
value = build_value_for(real_object, field, opts)
|
18
19
|
|
19
20
|
collection = nil
|
20
21
|
if opts[:type] == :select && !opts[:collection].blank?
|
21
|
-
v =
|
22
|
+
v = real_object.send(field)
|
22
23
|
value = Hash[opts[:collection]][!!(v =~ /^[0-9]+$/) ? v.to_i : v]
|
23
24
|
collection = opts[:collection].to_json
|
24
25
|
end
|
25
26
|
if opts[:type] == :checkbox
|
26
|
-
fieldValue = !!
|
27
|
+
fieldValue = !!real_object.send(field)
|
27
28
|
if opts[:collection].blank? || opts[:collection].size != 2
|
28
29
|
opts[:collection] = ["No", "Yes"]
|
29
30
|
end
|
@@ -31,10 +32,10 @@ module BestInPlace
|
|
31
32
|
collection = opts[:collection].to_json
|
32
33
|
end
|
33
34
|
out = "<span class='best_in_place'"
|
34
|
-
out << " id='#{BestInPlace::Utils.build_best_in_place_id(
|
35
|
+
out << " id='#{BestInPlace::Utils.build_best_in_place_id(real_object, field)}'"
|
35
36
|
out << " data-url='#{opts[:path].blank? ? url_for(object) : url_for(opts[:path])}'"
|
36
|
-
out << " data-object='#{opts[:object_name] ||
|
37
|
-
out << " data-collection='#{collection
|
37
|
+
out << " data-object='#{opts[:object_name] || BestInPlace::Utils.object_to_key(real_object)}'"
|
38
|
+
out << " data-collection='#{attribute_escape(collection)}'" unless collection.blank?
|
38
39
|
out << " data-attribute='#{field}'"
|
39
40
|
out << " data-activator='#{opts[:activator]}'" unless opts[:activator].blank?
|
40
41
|
out << " data-ok-button='#{opts[:ok_button]}'" unless opts[:ok_button].blank?
|
@@ -43,7 +44,15 @@ module BestInPlace
|
|
43
44
|
out << " data-type='#{opts[:type]}'"
|
44
45
|
out << " data-inner-class='#{opts[:inner_class]}'" if opts[:inner_class]
|
45
46
|
out << " data-html-attrs='#{opts[:html_attrs].to_json}'" unless opts[:html_attrs].blank?
|
46
|
-
out << " data-original-content='#{attribute_escape(
|
47
|
+
out << " data-original-content='#{attribute_escape(real_object.send(field))}'" if opts[:display_as] || opts[:display_with]
|
48
|
+
if opts[:data] && opts[:data].is_a?(Hash)
|
49
|
+
opts[:data].each do |k, v|
|
50
|
+
if !v.is_a?(String) && !v.is_a?(Symbol)
|
51
|
+
v = v.to_json
|
52
|
+
end
|
53
|
+
out << %( data-#{k.to_s.dasherize}="#{v}")
|
54
|
+
end
|
55
|
+
end
|
47
56
|
if !opts[:sanitize].nil? && !opts[:sanitize]
|
48
57
|
out << " data-sanitize='false'>"
|
49
58
|
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))
|
@@ -64,10 +73,15 @@ module BestInPlace
|
|
64
73
|
|
65
74
|
private
|
66
75
|
def build_value_for(object, field, opts)
|
76
|
+
return "" if object.send(field).blank?
|
77
|
+
|
67
78
|
if opts[:display_as]
|
68
79
|
BestInPlace::DisplayMethods.add_model_method(object.class.to_s, field, opts[:display_as])
|
69
80
|
object.send(opts[:display_as]).to_s
|
70
81
|
|
82
|
+
elsif opts[:display_with].try(:is_a?, Proc)
|
83
|
+
opts[:display_with].call(object.send(field))
|
84
|
+
|
71
85
|
elsif opts[:display_with]
|
72
86
|
BestInPlace::DisplayMethods.add_helper_method(object.class.to_s, field, opts[:display_with], opts[:helper_options])
|
73
87
|
if opts[:helper_options]
|
@@ -82,7 +96,12 @@ module BestInPlace
|
|
82
96
|
end
|
83
97
|
|
84
98
|
def attribute_escape(data)
|
85
|
-
|
99
|
+
return unless data
|
100
|
+
|
101
|
+
data.to_s.
|
102
|
+
gsub("&", "&").
|
103
|
+
gsub("'", "'").
|
104
|
+
gsub("\n", " ")
|
86
105
|
end
|
87
106
|
end
|
88
107
|
end
|
data/lib/best_in_place/utils.rb
CHANGED
@@ -1,15 +1,21 @@
|
|
1
1
|
module BestInPlace
|
2
|
-
|
2
|
+
module Utils
|
3
|
+
extend self
|
3
4
|
|
4
|
-
def
|
5
|
+
def build_best_in_place_id(object, field)
|
5
6
|
if object.is_a?(Symbol) || object.is_a?(String)
|
6
7
|
return "best_in_place_#{object}_#{field}"
|
7
8
|
end
|
8
9
|
|
9
|
-
id = "best_in_place_#{object
|
10
|
+
id = "best_in_place_#{object_to_key(object)}"
|
10
11
|
id << "_#{object.id}" if object.class.ancestors.include?(ActiveModel::Serializers::JSON)
|
11
12
|
id << "_#{field}"
|
12
13
|
id
|
13
14
|
end
|
15
|
+
|
16
|
+
def object_to_key(object)
|
17
|
+
return object.class.to_s.underscore unless object.class.respond_to?(:model_name)
|
18
|
+
ActiveModel::Naming.param_key(object.class)
|
19
|
+
end
|
14
20
|
end
|
15
21
|
end
|
@@ -16,6 +16,14 @@ describe BestInPlace::BestInPlaceHelpers do
|
|
16
16
|
:money => 150
|
17
17
|
end
|
18
18
|
|
19
|
+
it "should generate a proper id for namespaced models" do
|
20
|
+
@car = Cuca::Car.create :model => "Ford"
|
21
|
+
|
22
|
+
nk = Nokogiri::HTML.parse(helper.best_in_place @car, :model, :path => helper.cuca_cars_path)
|
23
|
+
span = nk.css("span")
|
24
|
+
span.attribute("id").value.should == "best_in_place_cuca_car_#{@car.id}_model"
|
25
|
+
end
|
26
|
+
|
19
27
|
it "should generate a proper span" do
|
20
28
|
nk = Nokogiri::HTML.parse(helper.best_in_place @user, :name)
|
21
29
|
span = nk.css("span")
|
@@ -161,6 +169,14 @@ describe BestInPlace::BestInPlaceHelpers do
|
|
161
169
|
end
|
162
170
|
end
|
163
171
|
|
172
|
+
it "should have html5 data attributes" do
|
173
|
+
out = helper.best_in_place @user, :name, :data => { :foo => "awesome", :bar => "nasty" }
|
174
|
+
nk = Nokogiri::HTML.parse(out)
|
175
|
+
span = nk.css("span")
|
176
|
+
span.attribute("data-foo").value.should == "awesome"
|
177
|
+
span.attribute("data-bar").value.should == "nasty"
|
178
|
+
end
|
179
|
+
|
164
180
|
describe "display_as" do
|
165
181
|
it "should render the address with a custom renderer" do
|
166
182
|
@user.should_receive(:address_format).and_return("the result")
|
@@ -179,6 +195,13 @@ describe BestInPlace::BestInPlaceHelpers do
|
|
179
195
|
span.text.should == "$150.00"
|
180
196
|
end
|
181
197
|
|
198
|
+
it "accepts a proc" do
|
199
|
+
out = helper.best_in_place @user, :name, :display_with => Proc.new { |v| v.upcase }
|
200
|
+
nk = Nokogiri::HTML.parse(out)
|
201
|
+
span = nk.css("span")
|
202
|
+
span.text.should == "LUCIA"
|
203
|
+
end
|
204
|
+
|
182
205
|
it "should raise an error if the given helper can't be found" do
|
183
206
|
lambda { helper.best_in_place @user, :money, :display_with => :fk_number_to_currency }.should raise_error(ArgumentError)
|
184
207
|
end
|
data/spec/integration/js_spec.rb
CHANGED
@@ -18,6 +18,18 @@ describe "JS behaviour", :js => true do
|
|
18
18
|
: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."
|
19
19
|
end
|
20
20
|
|
21
|
+
describe "namespaced controllers" do
|
22
|
+
it "should be able to use array-notation to describe both object and path" do
|
23
|
+
@user.save!
|
24
|
+
visit admin_user_path(@user)
|
25
|
+
|
26
|
+
within("#last_name") { page.should have_content("Napoli") }
|
27
|
+
bip_text @user, :last_name, "Other thing"
|
28
|
+
|
29
|
+
within("#last_name") { page.should have_content("Other thing") }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
21
33
|
describe "nil option" do
|
22
34
|
it "should render the default '-' string when the field is empty" do
|
23
35
|
@user.name = ""
|
@@ -465,6 +477,15 @@ describe "JS behaviour", :js => true do
|
|
465
477
|
end
|
466
478
|
|
467
479
|
describe "display_with" do
|
480
|
+
it "should show nil text when original value is nil" do
|
481
|
+
@user.description = ""
|
482
|
+
@user.save!
|
483
|
+
|
484
|
+
visit user_path(@user)
|
485
|
+
|
486
|
+
within("#dw_description") { page.should have_content("-") }
|
487
|
+
end
|
488
|
+
|
468
489
|
it "should render the money using number_to_currency" do
|
469
490
|
@user.save!
|
470
491
|
visit user_path(@user)
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
describe "Monitor new fields", :js => true do
|
5
|
+
before do
|
6
|
+
@user = User.new :name => "Lucia",
|
7
|
+
:last_name => "Napoli",
|
8
|
+
:email => "lucianapoli@gmail.com",
|
9
|
+
:address => "Via Roma 99",
|
10
|
+
:zip => "25123",
|
11
|
+
:country => "2",
|
12
|
+
:receive_email => false,
|
13
|
+
: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.",
|
14
|
+
:money => 100
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should work when new best_in_place spans are added to the page" do
|
18
|
+
@user.save!
|
19
|
+
visit show_ajax_user_path(@user)
|
20
|
+
|
21
|
+
sleep(1) #give time to the ajax request to work
|
22
|
+
|
23
|
+
within("#email") do
|
24
|
+
page.should have_content("lucianapoli@gmail")
|
25
|
+
end
|
26
|
+
|
27
|
+
bip_text @user, :email, "new@email.com"
|
28
|
+
|
29
|
+
within("#email") do
|
30
|
+
page.should have_content("new@email.com")
|
31
|
+
end
|
32
|
+
|
33
|
+
bip_text @user, :email, "new_two@email.com"
|
34
|
+
|
35
|
+
within("#email") do
|
36
|
+
page.should have_content("new_two@email.com")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class Admin::UsersController < ApplicationController
|
2
|
+
def show
|
3
|
+
@user = User.find params[:id]
|
4
|
+
end
|
5
|
+
|
6
|
+
def update
|
7
|
+
@user = User.find(params[:id])
|
8
|
+
|
9
|
+
respond_to do |format|
|
10
|
+
@user.update_attributes(params[:user])
|
11
|
+
format.json { respond_with_bip(@user) }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Cuca
|
2
|
+
class CarsController < ApplicationController
|
3
|
+
def show
|
4
|
+
@car = Car.find params[:id]
|
5
|
+
end
|
6
|
+
|
7
|
+
def update
|
8
|
+
@car = Car.find params[:id]
|
9
|
+
|
10
|
+
respond_to do |format|
|
11
|
+
@car.update_attributes params[:cuca_car]
|
12
|
+
format.json { respond_with_bip(@car) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -22,6 +22,16 @@ class UsersController < ApplicationController
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
def email_field
|
26
|
+
@user = User.find(params[:id])
|
27
|
+
render :action => :email_field, :layout => false
|
28
|
+
end
|
29
|
+
|
30
|
+
def show_ajax
|
31
|
+
@user = User.find(params[:id])
|
32
|
+
@countries = COUNTRIES.to_a
|
33
|
+
end
|
34
|
+
|
25
35
|
def double_init
|
26
36
|
@user = User.find(params[:id])
|
27
37
|
@countries = COUNTRIES.to_a
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<p id="notice"><%= notice %></p>
|
2
|
+
<div id="user_account">
|
3
|
+
<h1>User details</h1>
|
4
|
+
<%= link_to "Go back to USERS", users_path %>
|
5
|
+
<p style="margin-left:48em">Click to edit</p>
|
6
|
+
<table>
|
7
|
+
<tr>
|
8
|
+
<td id="name">
|
9
|
+
<%= best_in_place [:admin, @user], :name %>
|
10
|
+
</td>
|
11
|
+
</tr>
|
12
|
+
<tr>
|
13
|
+
<td>Last Name</td>
|
14
|
+
<td id="last_name">
|
15
|
+
<%= best_in_place [:admin, @user], :last_name, :nil => "Nothing to show" %>
|
16
|
+
</td>
|
17
|
+
</tr>
|
18
|
+
</table>
|
19
|
+
</div>
|
20
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<p id="notice"><%= notice %></p>
|
2
|
+
<div id="user_account">
|
3
|
+
<h1>Car details</h1>
|
4
|
+
<p style="margin-left:48em">Click to edit</p>
|
5
|
+
<table>
|
6
|
+
<tr>
|
7
|
+
<td>Model</td>
|
8
|
+
<td id="model">
|
9
|
+
<%= best_in_place @car, :model %>
|
10
|
+
</td>
|
11
|
+
</tr>
|
12
|
+
</table>
|
13
|
+
</div>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= best_in_place @user, :email %>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<%= render :template => 'users/show' %>
|
2
|
+
<script>
|
3
|
+
$(document).ready(function () {
|
4
|
+
$('#email').html('');
|
5
|
+
setTimeout( function () { //give time to the other document.ready callbacks to be executed
|
6
|
+
$.get("/users/<%= params[:id]%>/email_field", function(data, status) {
|
7
|
+
$('#email').html(data);
|
8
|
+
});
|
9
|
+
},
|
10
|
+
500);
|
11
|
+
});
|
12
|
+
</script>
|
data/test_app/config/routes.rb
CHANGED
@@ -3,8 +3,18 @@ BipApp::Application.routes.draw do
|
|
3
3
|
member do
|
4
4
|
put :test_respond_with
|
5
5
|
get :double_init
|
6
|
+
get :show_ajax
|
7
|
+
get :email_field
|
6
8
|
end
|
7
9
|
end
|
8
10
|
|
11
|
+
namespace :cuca do
|
12
|
+
resources :cars
|
13
|
+
end
|
14
|
+
|
15
|
+
namespace :admin do
|
16
|
+
resources :users
|
17
|
+
end
|
18
|
+
|
9
19
|
root :to => "users#index"
|
10
20
|
end
|
data/test_app/db/schema.rb
CHANGED
@@ -11,7 +11,12 @@
|
|
11
11
|
#
|
12
12
|
# It's strongly recommended to check this file into your version control system.
|
13
13
|
|
14
|
-
ActiveRecord::Schema.define(:version =>
|
14
|
+
ActiveRecord::Schema.define(:version => 20120513003308) do
|
15
|
+
|
16
|
+
create_table "cars", :force => true do |t|
|
17
|
+
t.string "model"
|
18
|
+
end
|
19
|
+
|
15
20
|
create_table "users", :force => true do |t|
|
16
21
|
t.string "name"
|
17
22
|
t.string "last_name"
|
@@ -19,13 +24,14 @@ ActiveRecord::Schema.define(:version => 20111224181356) do
|
|
19
24
|
t.string "email", :null => false
|
20
25
|
t.string "zip"
|
21
26
|
t.string "country"
|
22
|
-
t.datetime "created_at"
|
23
|
-
t.datetime "updated_at"
|
27
|
+
t.datetime "created_at", :null => false
|
28
|
+
t.datetime "updated_at", :null => false
|
24
29
|
t.boolean "receive_email"
|
25
30
|
t.text "description"
|
26
|
-
t.datetime "birth_date"
|
27
|
-
t.float "money"
|
28
31
|
t.string "favorite_color"
|
29
32
|
t.text "favorite_books"
|
33
|
+
t.datetime "birth_date"
|
34
|
+
t.float "money"
|
30
35
|
end
|
36
|
+
|
31
37
|
end
|
data/test_app/db/seeds.rb
CHANGED
@@ -13,3 +13,7 @@ User.create!(:name => "Lucia", :last_name => "Napoli", :email => "lucianapoli@gm
|
|
13
13
|
User.create!(:name => "Carmen", :last_name => "Luciago", :email => "carmen@luciago.com", :address => "c/Ambrosio 10", :zip => "21333", :country => "2", :receive_email => true, :birth_date => Date.today - 18.years, :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.")
|
14
14
|
User.create!(:name => "Angels", :last_name => "Domènech", :email => "angels@gmail.com", :address => "Avinguda Sant Andreu 1", :zip => "08033", :country => "3", :receive_email => false, :birth_date => Date.today - 65.years, :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.")
|
15
15
|
User.create!(:name => "Dominic", :last_name => "Lepoin", :email => "dominiclepoin@gmail.com", :address => "Rue Tour Eiffel 4993", :zip => "11192", :country => "4", :receive_email => true, :birth_date => Date.today - 40.years, :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
|
+
|
17
|
+
|
18
|
+
Cuca::Car.delete_all
|
19
|
+
Cuca::Car.create! :model => "Ford"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: best_in_place
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-05-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: '3.1'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.1'
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: jquery-rails
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,10 +37,15 @@ dependencies:
|
|
32
37
|
version: '0'
|
33
38
|
type: :runtime
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: rspec-rails
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ~>
|
@@ -43,10 +53,15 @@ dependencies:
|
|
43
53
|
version: 2.8.0
|
44
54
|
type: :development
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.8.0
|
47
62
|
- !ruby/object:Gem::Dependency
|
48
63
|
name: nokogiri
|
49
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
50
65
|
none: false
|
51
66
|
requirements:
|
52
67
|
- - ! '>='
|
@@ -54,10 +69,15 @@ dependencies:
|
|
54
69
|
version: 1.5.0
|
55
70
|
type: :development
|
56
71
|
prerelease: false
|
57
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.5.0
|
58
78
|
- !ruby/object:Gem::Dependency
|
59
79
|
name: capybara
|
60
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
61
81
|
none: false
|
62
82
|
requirements:
|
63
83
|
- - ! '>='
|
@@ -65,7 +85,12 @@ dependencies:
|
|
65
85
|
version: 1.0.1
|
66
86
|
type: :development
|
67
87
|
prerelease: false
|
68
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 1.0.1
|
69
94
|
description: BestInPlace is a jQuery script and a Rails 3 helper that provide the
|
70
95
|
method best_in_place to display any object field easily editable for the user by
|
71
96
|
just clicking on it. It supports input data, text data, boolean data and custom
|
@@ -79,6 +104,7 @@ files:
|
|
79
104
|
- .gitignore
|
80
105
|
- .rspec
|
81
106
|
- .travis.yml
|
107
|
+
- CHANGELOG.md
|
82
108
|
- Gemfile
|
83
109
|
- README.md
|
84
110
|
- Rakefile
|
@@ -98,6 +124,7 @@ files:
|
|
98
124
|
- spec/helpers/best_in_place_spec.rb
|
99
125
|
- spec/integration/double_init_spec.rb
|
100
126
|
- spec/integration/js_spec.rb
|
127
|
+
- spec/integration/live_spec.rb
|
101
128
|
- spec/integration/text_area_spec.rb
|
102
129
|
- spec/spec_helper.rb
|
103
130
|
- spec/support/retry_on_timeout.rb
|
@@ -124,17 +151,24 @@ files:
|
|
124
151
|
- test_app/app/assets/stylesheets/jquery-ui-1.8.16.custom.css.erb
|
125
152
|
- test_app/app/assets/stylesheets/scaffold.css
|
126
153
|
- test_app/app/assets/stylesheets/style.css.erb
|
154
|
+
- test_app/app/controllers/admin/users_controller.rb
|
127
155
|
- test_app/app/controllers/application_controller.rb
|
156
|
+
- test_app/app/controllers/cuca/cars_controller.rb
|
128
157
|
- test_app/app/controllers/users_controller.rb
|
129
158
|
- test_app/app/helpers/application_helper.rb
|
130
159
|
- test_app/app/helpers/users_helper.rb
|
160
|
+
- test_app/app/models/cuca/car.rb
|
131
161
|
- test_app/app/models/user.rb
|
162
|
+
- test_app/app/views/admin/users/show.html.erb
|
163
|
+
- test_app/app/views/cuca/cars/show.html.erb
|
132
164
|
- test_app/app/views/layouts/application.html.erb
|
133
165
|
- test_app/app/views/users/_form.html.erb
|
134
166
|
- test_app/app/views/users/double_init.html.erb
|
167
|
+
- test_app/app/views/users/email_field.html.erb
|
135
168
|
- test_app/app/views/users/index.html.erb
|
136
169
|
- test_app/app/views/users/new.html.erb
|
137
170
|
- test_app/app/views/users/show.html.erb
|
171
|
+
- test_app/app/views/users/show_ajax.html.erb
|
138
172
|
- test_app/config.ru
|
139
173
|
- test_app/config/application.rb
|
140
174
|
- test_app/config/boot.rb
|
@@ -159,6 +193,7 @@ files:
|
|
159
193
|
- test_app/db/migrate/20111210084251_add_favorite_books_to_users.rb
|
160
194
|
- test_app/db/migrate/20111217215935_add_birth_date_to_users.rb
|
161
195
|
- test_app/db/migrate/20111224181356_add_money_to_user.rb
|
196
|
+
- test_app/db/migrate/20120513003308_create_cars.rb
|
162
197
|
- test_app/db/schema.rb
|
163
198
|
- test_app/db/seeds.rb
|
164
199
|
- test_app/doc/README_FOR_APP
|
@@ -191,7 +226,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
191
226
|
version: '0'
|
192
227
|
segments:
|
193
228
|
- 0
|
194
|
-
hash: -
|
229
|
+
hash: -3850247748831605605
|
195
230
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
196
231
|
none: false
|
197
232
|
requirements:
|
@@ -200,12 +235,19 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
200
235
|
version: '0'
|
201
236
|
segments:
|
202
237
|
- 0
|
203
|
-
hash: -
|
238
|
+
hash: -3850247748831605605
|
204
239
|
requirements: []
|
205
240
|
rubyforge_project: best_in_place
|
206
|
-
rubygems_version: 1.8.
|
241
|
+
rubygems_version: 1.8.19
|
207
242
|
signing_key:
|
208
243
|
specification_version: 3
|
209
244
|
summary: It makes any field in place editable by clicking on it, it works for inputs,
|
210
245
|
textareas, select dropdowns and checkboxes
|
211
|
-
test_files:
|
246
|
+
test_files:
|
247
|
+
- spec/helpers/best_in_place_spec.rb
|
248
|
+
- spec/integration/double_init_spec.rb
|
249
|
+
- spec/integration/js_spec.rb
|
250
|
+
- spec/integration/live_spec.rb
|
251
|
+
- spec/integration/text_area_spec.rb
|
252
|
+
- spec/spec_helper.rb
|
253
|
+
- spec/support/retry_on_timeout.rb
|