best_in_place 2.0.3 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,4 @@
1
1
  rvm:
2
- - 1.9.2
3
2
  - 1.9.3
4
3
 
5
4
  env: "RAILS_ENV=test DISPLAY=:99.0"
data/README.md CHANGED
@@ -53,7 +53,9 @@ Options:
53
53
  If not defined it will show *"-"*.
54
54
  - **:activator**: Is the DOM object that can activate the field. If not defined the user will making editable by clicking on it.
55
55
  - **:ok_button**: (Inputs and textareas only) If set to a string, then an OK button will be shown with the string as its label, replacing save on blur.
56
+ - **:ok_button_class**: (Inputs and textareas only) Specifies any extra classes to set on the OK button.
56
57
  - **:cancel_button**: (Inputs and textareas only) If set to a string, then a Cancel button will be shown with the string as its label.
58
+ - **:cancel_button_class**: (Inputs and textareas only) Specifies any extra classes to set on the Cancel button.
57
59
  - **:sanitize**: True by default. If set to false the input/textarea will accept html tags.
58
60
  - **:html_attrs**: Hash of html arguments, such as maxlength, default-value etc.
59
61
  - **:inner_class**: Class that is set to the rendered form.
@@ -188,7 +190,7 @@ You can also pass in a proc or lambda like this:
188
190
 
189
191
  The 'ajax:success' event is triggered upon success. Use bind:
190
192
 
191
- $('.best_in_place').bind("ajax:success", function(){$(this).closest('tr').effect('highlight'));});
193
+ $('.best_in_place').bind("ajax:success", function () {$(this).closest('tr').effect('highlight'); });
192
194
 
193
195
  To bind a callback that is specific to a particular field, use the 'classes' option in the helper method and
194
196
  then bind to that class.
@@ -32,7 +32,7 @@ BestInPlaceEditor.prototype = {
32
32
 
33
33
  activate : function() {
34
34
  var to_display = "";
35
- if (this.isNil) {
35
+ if (this.isNil()) {
36
36
  to_display = "";
37
37
  }
38
38
  else if (this.original_content) {
@@ -46,8 +46,7 @@ BestInPlaceEditor.prototype = {
46
46
  }
47
47
  }
48
48
 
49
- var elem = this.isNil ? "-" : this.element.html();
50
- this.oldValue = elem;
49
+ this.oldValue = this.isNil() ? "" : this.element.html();
51
50
  this.display_value = to_display;
52
51
  jQuery(this.activator).unbind("click", this.clickHandler);
53
52
  this.activateForm();
@@ -55,8 +54,7 @@ BestInPlaceEditor.prototype = {
55
54
  },
56
55
 
57
56
  abort : function() {
58
- if (this.isNil) this.element.html(this.nil);
59
- else this.element.html(this.oldValue);
57
+ this.activateText(this.oldValue);
60
58
  jQuery(this.activator).bind('click', {editor: this}, this.clickHandler);
61
59
  this.element.trigger(jQuery.Event("best_in_place:abort"));
62
60
  this.element.trigger(jQuery.Event("best_in_place:deactivate"));
@@ -80,7 +78,6 @@ BestInPlaceEditor.prototype = {
80
78
  this.abort();
81
79
  return true;
82
80
  }
83
- this.isNil = false;
84
81
  editor.ajax({
85
82
  "type" : "post",
86
83
  "dataType" : "text",
@@ -114,6 +111,11 @@ BestInPlaceEditor.prototype = {
114
111
  alert("The form was not properly initialized. activateForm is unbound");
115
112
  },
116
113
 
114
+ activateText : function(value){
115
+ this.element.html(value);
116
+ if(this.isNil()) this.element.html(this.nil);
117
+ },
118
+
117
119
  // Helper Functions ////////////////////////////////////////////////////////
118
120
 
119
121
  initOptions : function() {
@@ -121,19 +123,21 @@ BestInPlaceEditor.prototype = {
121
123
  var self = this;
122
124
  self.element.parents().each(function(){
123
125
  $parent = jQuery(this);
124
- self.url = self.url || $parent.attr("data-url");
125
- self.collection = self.collection || $parent.attr("data-collection");
126
- self.formType = self.formType || $parent.attr("data-type");
127
- self.objectName = self.objectName || $parent.attr("data-object");
128
- self.attributeName = self.attributeName || $parent.attr("data-attribute");
129
- self.activator = self.activator || $parent.attr("data-activator");
130
- self.okButton = self.okButton || $parent.attr("data-ok-button");
131
- self.cancelButton = self.cancelButton || $parent.attr("data-cancel-button");
132
- self.nil = self.nil || $parent.attr("data-nil");
133
- self.inner_class = self.inner_class || $parent.attr("data-inner-class");
134
- self.html_attrs = self.html_attrs || $parent.attr("data-html-attrs");
135
- self.original_content = self.original_content || $parent.attr("data-original-content");
136
- self.collectionValue = self.collectionValue || $parent.attr("data-value");
126
+ self.url = self.url || $parent.attr("data-url");
127
+ self.collection = self.collection || $parent.attr("data-collection");
128
+ self.formType = self.formType || $parent.attr("data-type");
129
+ self.objectName = self.objectName || $parent.attr("data-object");
130
+ self.attributeName = self.attributeName || $parent.attr("data-attribute");
131
+ self.activator = self.activator || $parent.attr("data-activator");
132
+ self.okButton = self.okButton || $parent.attr("data-ok-button");
133
+ self.okButtonClass = self.okButtonClass || $parent.attr("data-ok-button-class");
134
+ self.cancelButton = self.cancelButton || $parent.attr("data-cancel-button");
135
+ self.cancelButtonClass = self.cancelButtonClass || $parent.attr("data-cancel-button-class");
136
+ self.nil = self.nil || $parent.attr("data-nil");
137
+ self.inner_class = self.inner_class || $parent.attr("data-inner-class");
138
+ self.html_attrs = self.html_attrs || $parent.attr("data-html-attrs");
139
+ self.original_content = self.original_content || $parent.attr("data-original-content");
140
+ self.collectionValue = self.collectionValue || $parent.attr("data-value");
137
141
  });
138
142
 
139
143
  // Try Rails-id based if parents did not explicitly supply something
@@ -145,19 +149,21 @@ BestInPlaceEditor.prototype = {
145
149
  });
146
150
 
147
151
  // Load own attributes (overrides all others)
148
- self.url = self.element.attr("data-url") || self.url || document.location.pathname;
149
- self.collection = self.element.attr("data-collection") || self.collection;
150
- self.formType = self.element.attr("data-type") || self.formtype || "input";
151
- self.objectName = self.element.attr("data-object") || self.objectName;
152
- self.attributeName = self.element.attr("data-attribute") || self.attributeName;
153
- self.activator = self.element.attr("data-activator") || self.element;
154
- self.okButton = self.element.attr("data-ok-button") || self.okButton;
155
- self.cancelButton = self.element.attr("data-cancel-button") || self.cancelButton;
156
- self.nil = self.element.attr("data-nil") || self.nil || "-";
157
- self.inner_class = self.element.attr("data-inner-class") || self.inner_class || null;
158
- self.html_attrs = self.element.attr("data-html-attrs") || self.html_attrs;
159
- self.original_content = self.element.attr("data-original-content") || self.original_content;
160
- self.collectionValue = self.element.attr("data-value") || self.collectionValue;
152
+ self.url = self.element.attr("data-url") || self.url || document.location.pathname;
153
+ self.collection = self.element.attr("data-collection") || self.collection;
154
+ self.formType = self.element.attr("data-type") || self.formtype || "input";
155
+ self.objectName = self.element.attr("data-object") || self.objectName;
156
+ self.attributeName = self.element.attr("data-attribute") || self.attributeName;
157
+ self.activator = self.element.attr("data-activator") || self.element;
158
+ self.okButton = self.element.attr("data-ok-button") || self.okButton;
159
+ self.okButtonClass = self.element.attr("data-ok-button-class") || self.okButtonClass || "";
160
+ self.cancelButton = self.element.attr("data-cancel-button") || self.cancelButton;
161
+ self.cancelButtonClass = self.element.attr("data-cancel-button-class") || self.cancelButtonClass || "";
162
+ self.nil = self.element.attr("data-nil") || self.nil || "—";
163
+ self.inner_class = self.element.attr("data-inner-class") || self.inner_class || null;
164
+ self.html_attrs = self.element.attr("data-html-attrs") || self.html_attrs;
165
+ self.original_content = self.element.attr("data-original-content") || self.original_content;
166
+ self.collectionValue = self.element.attr("data-value") || self.collectionValue;
161
167
 
162
168
  if (!self.element.attr("data-sanitize")) {
163
169
  self.sanitize = true;
@@ -187,11 +193,16 @@ BestInPlaceEditor.prototype = {
187
193
  initNil: function() {
188
194
  if (this.element.html() === "")
189
195
  {
190
- this.isNil = true;
191
196
  this.element.html(this.nil);
192
197
  }
193
198
  },
194
199
 
200
+ isNil: function() {
201
+ // TODO: It only work when form is deactivated.
202
+ // Condition will fail when form is activated
203
+ return this.element.html() === "" || this.element.html() === this.nil;
204
+ },
205
+
195
206
  getValue : function() {
196
207
  alert("The form was not properly initialized. getValue is unbound");
197
208
  },
@@ -225,7 +236,7 @@ BestInPlaceEditor.prototype = {
225
236
  // Handlers ////////////////////////////////////////////////////////////////
226
237
 
227
238
  loadSuccessCallback : function(data) {
228
- data = $.trim(data);
239
+ data = jQuery.trim(data);
229
240
 
230
241
  if(data && data!=""){
231
242
  var response = jQuery.parseJSON(jQuery.trim(data));
@@ -234,8 +245,12 @@ BestInPlaceEditor.prototype = {
234
245
  this.original_content = this.element.text();
235
246
  this.element.html(response["display_as"]);
236
247
  }
248
+
237
249
  this.element.trigger(jQuery.Event("best_in_place:success"), data);
238
250
  this.element.trigger(jQuery.Event("ajax:success"), data);
251
+ } else {
252
+ this.element.trigger(jQuery.Event("best_in_place:success"));
253
+ this.element.trigger(jQuery.Event("ajax:success"));
239
254
  }
240
255
 
241
256
  // Binding back after being clicked
@@ -249,7 +264,7 @@ BestInPlaceEditor.prototype = {
249
264
  },
250
265
 
251
266
  loadErrorCallback : function(request, error) {
252
- this.element.html(this.oldValue);
267
+ this.activateText(this.oldValue);
253
268
 
254
269
  this.element.trigger(jQuery.Event("best_in_place:error"), [request, error]);
255
270
  this.element.trigger(jQuery.Event("ajax:error"), request, error);
@@ -301,6 +316,7 @@ BestInPlaceEditor.forms = {
301
316
  output.append(
302
317
  jQuery(document.createElement('input'))
303
318
  .attr('type', 'submit')
319
+ .attr('class', this.okButtonClass)
304
320
  .attr('value', this.okButton)
305
321
  )
306
322
  }
@@ -308,6 +324,7 @@ BestInPlaceEditor.forms = {
308
324
  output.append(
309
325
  jQuery(document.createElement('input'))
310
326
  .attr('type', 'button')
327
+ .attr('class', this.cancelButtonClass)
311
328
  .attr('value', this.cancelButton)
312
329
  )
313
330
  }
@@ -423,7 +440,8 @@ BestInPlaceEditor.forms = {
423
440
  .attr('style', 'display:inline');
424
441
  selected = '',
425
442
  oldValue = this.oldValue,
426
- select_elt = jQuery(document.createElement('select')),
443
+ select_elt = jQuery(document.createElement('select'))
444
+ .attr('class', this.inned_class !== null ? this.inner_class : '' ),
427
445
  currentCollectionValue = this.collectionValue;
428
446
 
429
447
  jQuery.each(this.values, function (index, value) {
@@ -62,7 +62,7 @@
62
62
 
63
63
  // If ESC is pressed remove notice
64
64
  jQuery(document).keyup(function(e) {
65
- if (e.keyCode == 27) {
65
+ if (e.keyCode === 27) {
66
66
  removeNotice();
67
67
  }
68
68
  });
@@ -70,24 +70,15 @@
70
70
  // Add the notice to the page and keep it hidden initially
71
71
  notice.appendTo(cont).hide();
72
72
 
73
- if (jQuery.browser.msie && options.usingTransparentPNG)
74
- {
75
- // IE7 and earlier can't handle the combination of opacity and transparent pngs, so if we're using transparent pngs in our
76
- // notice style, we'll just skip the fading in.
77
- notice.show();
78
- }
79
- else
80
- {
81
- //Fade in the notice we just added
82
- notice.fadeIn(options.fadeInSpeed);
83
- }
73
+ //Fade in the notice we just added
74
+ notice.fadeIn(options.fadeInSpeed);
84
75
 
85
76
  // Set up the removal interval for the added notice if that notice is not a sticky
86
77
  if (!options.isSticky)
87
78
  {
88
79
  var topSpotInt = setInterval(function() {
89
80
  // Check to see if our notice is the first non-sticky notice in the list
90
- if (notice.prevAll('.purr').length == 0)
81
+ if (notice.prevAll('.purr').length === 0)
91
82
  {
92
83
  // Stop checking once the condition is met
93
84
  clearInterval(topSpotInt);
@@ -103,41 +94,24 @@
103
94
 
104
95
  function removeNotice()
105
96
  {
106
- // IE7 and earlier can't handle the combination of opacity and transparent pngs, so if we're using transparent pngs in our
107
- // notice style, we'll just skip the fading out.
108
- if (jQuery.browser.msie && options.usingTransparentPNG)
109
- {
110
- notice.css({ opacity: 0 }).animate({ height: '0px'},
97
+ // Fade the object out before reducing its height to produce the sliding effect
98
+ notice.animate({ opacity: '0' },
99
+ {
100
+ duration: options.fadeOutSpeed,
101
+ complete: function ()
111
102
  {
112
- duration: options.fadeOutSpeed,
113
- complete: function ()
114
- {
115
- notice.remove();
116
- }
103
+ notice.animate({ height: '0px' },
104
+ {
105
+ duration: options.fadeOutSpeed,
106
+ complete: function()
107
+ {
108
+ notice.remove();
109
+ }
110
+ }
111
+ );
117
112
  }
118
- );
119
- }
120
- else
121
- {
122
- // Fade the object out before reducing its height to produce the sliding effect
123
- notice.animate({ opacity: '0' },
124
- {
125
- duration: options.fadeOutSpeed,
126
- complete: function ()
127
- {
128
- notice.animate({ height: '0px' },
129
- {
130
- duration: options.fadeOutSpeed,
131
- complete: function()
132
- {
133
- notice.remove();
134
- }
135
- }
136
- );
137
- }
138
- }
139
- );
140
- }
113
+ }
114
+ );
141
115
  };
142
116
  };
143
117
 
@@ -17,7 +17,7 @@ module BestInPlace
17
17
  if renderer = BestInPlace::DisplayMethods.lookup(klass, updating_attr)
18
18
  render :json => renderer.render_json(obj)
19
19
  else
20
- head :ok
20
+ head :no_content
21
21
  end
22
22
  end
23
23
 
@@ -47,7 +47,9 @@ module BestInPlace
47
47
  out << " data-attribute='#{field}'"
48
48
  out << " data-activator='#{opts[:activator]}'" unless opts[:activator].blank?
49
49
  out << " data-ok-button='#{opts[:ok_button]}'" unless opts[:ok_button].blank?
50
+ out << " data-ok-button-class='#{opts[:ok_button_class]}'" unless opts[:ok_button_class].blank?
50
51
  out << " data-cancel-button='#{opts[:cancel_button]}'" unless opts[:cancel_button].blank?
52
+ out << " data-cancel-button-class='#{opts[:cancel_button_class]}'" unless opts[:cancel_button_class].blank?
51
53
  out << " data-nil='#{attribute_escape(opts[:nil])}'" unless opts[:nil].blank?
52
54
  out << " data-use-confirm='#{opts[:use_confirm]}'" unless opts[:use_confirm].nil?
53
55
  out << " data-type='#{opts[:type]}'"
@@ -86,11 +88,12 @@ module BestInPlace
86
88
  def build_value_for(object, field, opts)
87
89
  return "" if object.send(field).blank?
88
90
 
89
- if (object.respond_to?(:id))
90
- klass = "#{object.class}_#{object.id}"
91
+ klass = if object.respond_to?(:id)
92
+ "#{object.class}_#{object.id}"
91
93
  else
92
- klass = object.class.to_s
94
+ object.class.to_s
93
95
  end
96
+
94
97
  if opts[:display_as]
95
98
  BestInPlace::DisplayMethods.add_model_method(klass, field, opts[:display_as])
96
99
  object.send(opts[:display_as]).to_s
@@ -98,6 +101,7 @@ module BestInPlace
98
101
  elsif opts[:display_with].try(:is_a?, Proc)
99
102
  BestInPlace::DisplayMethods.add_helper_proc(klass, field, opts[:display_with])
100
103
  opts[:display_with].call(object.send(field))
104
+
101
105
  elsif opts[:display_with]
102
106
  BestInPlace::DisplayMethods.add_helper_method(klass, field, opts[:display_with], opts[:helper_options])
103
107
  if opts[:helper_options]
@@ -107,7 +111,7 @@ module BestInPlace
107
111
  end
108
112
 
109
113
  else
110
- object.send(field).to_s.presence || ""
114
+ object.send(field).to_s
111
115
  end
112
116
  end
113
117
 
@@ -9,6 +9,7 @@ module BestInPlace
9
9
  jQuery("##{id}").click();
10
10
  jQuery("##{id} form textarea").val('#{escape_javascript new_value.to_s}');
11
11
  jQuery("##{id} form textarea").blur();
12
+ jQuery("##{id} form textarea").blur();
12
13
  JS
13
14
  end
14
15
 
@@ -1,3 +1,3 @@
1
1
  module BestInPlace
2
- VERSION = "2.0.3"
2
+ VERSION = "2.1.0"
3
3
  end
@@ -75,10 +75,18 @@ describe BestInPlace::BestInPlaceHelpers do
75
75
  @span.attribute("data-ok-button").should be_nil
76
76
  end
77
77
 
78
+ it "should have no OK button class by default" do
79
+ @span.attribute("data-ok-button-class").should be_nil
80
+ end
81
+
78
82
  it "should have no Cancel button text by default" do
79
83
  @span.attribute("data-cancel-button").should be_nil
80
84
  end
81
85
 
86
+ it "should have no Cancel button class by default" do
87
+ @span.attribute("data-cancel-button-class").should be_nil
88
+ end
89
+
82
90
  it "should have no Use-Confirmation dialog option by default" do
83
91
  @span.attribute("data-use-confirm").should be_nil
84
92
  end
@@ -158,6 +166,13 @@ describe BestInPlace::BestInPlaceHelpers do
158
166
  span.attribute("data-ok-button").value.should == "okay"
159
167
  end
160
168
 
169
+ it "should have the given OK button class" do
170
+ out = helper.best_in_place @user, :name, :ok_button => "okay", :ok_button_class => "okay-class"
171
+ nk = Nokogiri::HTML.parse(out)
172
+ span = nk.css("span")
173
+ span.attribute("data-ok-button-class").value.should == "okay-class"
174
+ end
175
+
161
176
  it "should have the given Cancel button text" do
162
177
  out = helper.best_in_place @user, :name, :cancel_button => "nasty"
163
178
  nk = Nokogiri::HTML.parse(out)
@@ -165,6 +180,13 @@ describe BestInPlace::BestInPlaceHelpers do
165
180
  span.attribute("data-cancel-button").value.should == "nasty"
166
181
  end
167
182
 
183
+ it "should have the given Cancel button class" do
184
+ out = helper.best_in_place @user, :name, :cancel_button => "nasty", :cancel_button_class => "nasty-class"
185
+ nk = Nokogiri::HTML.parse(out)
186
+ span = nk.css("span")
187
+ span.attribute("data-cancel-button-class").value.should == "nasty-class"
188
+ end
189
+
168
190
  it "should have the given Use-Confirmation dialog option" do
169
191
  out = helper.best_in_place @user, :name, :use_confirm => "false"
170
192
  nk = Nokogiri::HTML.parse(out)
@@ -34,17 +34,17 @@ describe "JS behaviour", :js => true do
34
34
  end
35
35
 
36
36
  describe "nil option" do
37
- it "should render the default '-' string when the field is empty" do
37
+ it "should render an em-dash when the field is empty" do
38
38
  @user.name = ""
39
39
  @user.save :validate => false
40
40
  visit user_path(@user)
41
41
 
42
42
  within("#name") do
43
- page.should have_content("-")
43
+ page.should have_content("\u2014")
44
44
  end
45
45
  end
46
46
 
47
- it "should render the default '-' string when there is an error and if the intial string is '-'" do
47
+ it "should render the default em-dash string when there is an error and if the intial string is em-dash" do
48
48
  @user.money = nil
49
49
  @user.save!
50
50
  visit user_path(@user)
@@ -52,7 +52,7 @@ describe "JS behaviour", :js => true do
52
52
  bip_text @user, :money, "abcd"
53
53
 
54
54
  within("#money") do
55
- page.should have_content("-")
55
+ page.should have_content("\u2014")
56
56
  end
57
57
  end
58
58
 
@@ -87,6 +87,36 @@ describe "JS behaviour", :js => true do
87
87
  end
88
88
  end
89
89
 
90
+ it "should display an empty input field the second time I open it" do
91
+ @user.favorite_locale = nil
92
+ @user.save!
93
+ visit user_path(@user)
94
+
95
+ within("#favorite_locale") do
96
+ page.should have_content("N/A")
97
+ end
98
+
99
+ id = BestInPlace::Utils.build_best_in_place_id @user, :favorite_locale
100
+ page.execute_script <<-JS
101
+ $("##{id}").click();
102
+ JS
103
+
104
+ text = page.find("##{id} input").value
105
+ text.should == ""
106
+
107
+ page.execute_script <<-JS
108
+ $("##{id} input[name='favorite_locale']").blur();
109
+ $("##{id} input[name='favorite_locale']").blur();
110
+ JS
111
+ sleep 1
112
+
113
+ page.execute_script <<-JS
114
+ $("##{id}").click();
115
+ JS
116
+
117
+ text = page.find("##{id} input").value
118
+ text.should == ""
119
+ end
90
120
  end
91
121
 
92
122
  it "should be able to update last but one item in list" do
@@ -196,6 +226,14 @@ describe "JS behaviour", :js => true do
196
226
  end
197
227
  end
198
228
 
229
+ it "should apply the inner_class option to a select field" do
230
+ @user.save!
231
+ visit user_path(@user)
232
+
233
+ find('#country span').click
234
+ find('#country').should have_css('select.some_class')
235
+ end
236
+
199
237
  it "should be able to use bip_text to change a date field" do
200
238
  @user.save!
201
239
  today = Time.now.utc.to_date
@@ -295,6 +333,12 @@ describe "JS behaviour", :js => true do
295
333
  page.execute_script <<-JS
296
334
  $("##{id}").click();
297
335
  $("##{id} input[name='favorite_color']").val('Blue');
336
+ JS
337
+
338
+ page.find("##{id} input[type='submit']").value.should == 'Do it!'
339
+ page.should have_css("##{id} input[type='submit'].custom-submit.other-custom-submit")
340
+
341
+ page.execute_script <<-JS
298
342
  $("##{id} input[type='submit']").click();
299
343
  JS
300
344
 
@@ -316,6 +360,12 @@ describe "JS behaviour", :js => true do
316
360
  page.execute_script <<-JS
317
361
  $("##{id}").click();
318
362
  $("##{id} input[name='favorite_color']").val('Blue');
363
+ JS
364
+
365
+ page.find("##{id} input[type='button']").value.should == 'Nope'
366
+ page.should have_css("##{id} input[type='button'].custom-cancel.other-custom-cancel")
367
+
368
+ page.execute_script <<-JS
319
369
  $("##{id} input[type='button']").click();
320
370
  JS
321
371
 
@@ -378,6 +428,7 @@ describe "JS behaviour", :js => true do
378
428
  page.execute_script <<-JS
379
429
  $("##{id} input[name='favorite_color']").val('Blue');
380
430
  $("##{id} input[name='favorite_color']").blur();
431
+ $("##{id} input[name='favorite_color']").blur();
381
432
  JS
382
433
  sleep 1 # Increase if browser is slow
383
434
 
@@ -443,6 +494,7 @@ describe "JS behaviour", :js => true do
443
494
  $("##{id}").click();
444
495
  $("##{id} textarea").val('1Q84');
445
496
  $("##{id} textarea").blur();
497
+ $("##{id} textarea").blur();
446
498
  JS
447
499
  sleep 1 # Increase if browser is slow
448
500
  page.driver.browser.switch_to.alert.accept
@@ -467,6 +519,7 @@ describe "JS behaviour", :js => true do
467
519
  page.execute_script <<-JS
468
520
  $("##{id} textarea").val('1Q84');
469
521
  $("##{id} textarea").blur();
522
+ $("##{id} textarea").blur();
470
523
  JS
471
524
  sleep 1 # Increase if browser is slow
472
525
 
@@ -501,6 +554,20 @@ describe "JS behaviour", :js => true do
501
554
  page.should have_content('Last name was updated!')
502
555
  end
503
556
 
557
+ it "should fire off a callback when retrieve success with empty data" do
558
+ @user.save!
559
+ visit user_path(@user)
560
+
561
+ id = BestInPlace::Utils.build_best_in_place_id @user, :last_name
562
+ page.execute_script <<-JS
563
+ $("##{id}").bind('best_in_place:success', function() { $('body').append('Updated successfully!') });
564
+ JS
565
+
566
+ page.should have_no_content('Updated successfully!')
567
+ bip_text @user, :last_name, 'Empty'
568
+ page.should have_content('Updated successfully!')
569
+ end
570
+
504
571
  describe "display_as" do
505
572
  it "should render the address with a custom format" do
506
573
  @user.save!
@@ -590,7 +657,7 @@ describe "JS behaviour", :js => true do
590
657
 
591
658
  visit user_path(@user)
592
659
 
593
- within("#dw_description") { page.should have_content("-") }
660
+ within("#dw_description") { page.should have_content("\u2014") }
594
661
  end
595
662
 
596
663
  it "should render the money using number_to_currency" do
@@ -716,6 +783,7 @@ describe "JS behaviour", :js => true do
716
783
  page.execute_script <<-JS
717
784
  jQuery("#edit_#{@user.id}").click();
718
785
  jQuery("##{id} input[name='name']").blur();
786
+ jQuery("##{id} input[name='name']").blur();
719
787
  JS
720
788
  within("tr#user_#{@user.id} > .name > span") do
721
789
  page.should have_content("Lucia")
@@ -867,6 +935,7 @@ describe "JS behaviour", :js => true do
867
935
  $("##{id}").click();
868
936
  $("##{id} select").val("5' 7\\\"");
869
937
  $("##{id} select").blur();
938
+ $("##{id} select").blur();
870
939
  JS
871
940
 
872
941
  sleep 1
@@ -23,6 +23,14 @@ input[type=submit], input[type=button] {
23
23
  input[type=checkbox] {
24
24
  width: 1em;
25
25
  }
26
+ .custom-submit {
27
+ color: white;
28
+ background-color: black;
29
+ }
30
+ .custom-cancel {
31
+ border: 2px solid red;
32
+ font-style: italic;
33
+ }
26
34
  textarea {
27
35
  max-height:15em;
28
36
  min-width: 40em;
@@ -49,7 +49,7 @@
49
49
  <tr>
50
50
  <td>Country</td>
51
51
  <td id="country">
52
- <%= best_in_place @user, :country, :type => :select, :collection => @countries %>
52
+ <%= best_in_place @user, :country, :type => :select, :collection => @countries, :inner_class => :some_class %>
53
53
  </td>
54
54
  </tr>
55
55
  <tr>
@@ -67,12 +67,18 @@
67
67
  <tr>
68
68
  <td>Favorite color</td>
69
69
  <td id="favorite_color">
70
- <%- opts = { :ok_button => 'Do it!', :cancel_button => 'Nope' } %>
70
+ <%- opts = { :ok_button => 'Do it!', :cancel_button => 'Nope', :ok_button_class => 'custom-submit other-custom-submit', :cancel_button_class => 'custom-cancel other-custom-cancel' } %>
71
71
  <%- opts.delete(:ok_button) if params[:suppress_ok_button] %>
72
72
  <%- opts[:nil] = "<span class='nil'>Click to add your favorite color</span>" %>
73
73
  <%= best_in_place @user, :favorite_color, opts %>
74
74
  </td>
75
75
  </tr>
76
+ <tr>
77
+ <td>Favorite locale</td>
78
+ <td id="favorite_locale">
79
+ <%= best_in_place @user, :favorite_locale, :nil => "N/A" %>
80
+ </td>
81
+ </tr>
76
82
  <tr>
77
83
  <td>Favorite books</td>
78
84
  <td id="favorite_books">
@@ -102,7 +108,7 @@
102
108
  <tr>
103
109
  <td>Money with proc</td>
104
110
  <td id="money_proc">
105
- <%= best_in_place @user, :money_proc, :display_with => lambda{ |v| number_to_currency(v) } %>
111
+ <%= best_in_place @user, :money_proc, :display_with => lambda{ |v| v.blank? ? "No money" : number_to_currency(v) } %>
106
112
  </td>
107
113
  </tr>
108
114
  <tr>
@@ -0,0 +1,5 @@
1
+ class AddFavoriteLocaleToUsers < ActiveRecord::Migration
2
+ def change
3
+ add_column :users, :favorite_locale, :string
4
+ end
5
+ end
@@ -11,7 +11,7 @@
11
11
  #
12
12
  # It's strongly recommended to check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(:version => 20120620165212) do
14
+ ActiveRecord::Schema.define(:version => 20130213224102) do
15
15
 
16
16
  create_table "cars", :force => true do |t|
17
17
  t.string "model"
@@ -21,20 +21,21 @@ ActiveRecord::Schema.define(:version => 20120620165212) do
21
21
  t.string "name"
22
22
  t.string "last_name"
23
23
  t.string "address"
24
- t.string "email", :null => false
24
+ t.string "email", :null => false
25
25
  t.string "zip"
26
26
  t.string "country"
27
- t.datetime "created_at", :null => false
28
- t.datetime "updated_at", :null => false
27
+ t.datetime "created_at", :null => false
28
+ t.datetime "updated_at", :null => false
29
29
  t.boolean "receive_email"
30
30
  t.text "description"
31
31
  t.string "favorite_color"
32
32
  t.text "favorite_books"
33
33
  t.datetime "birth_date"
34
34
  t.float "money"
35
+ t.string "favorite_movie"
35
36
  t.float "money_proc"
36
37
  t.string "height"
37
- t.string "favorite_movie"
38
+ t.string "favorite_locale"
38
39
  end
39
40
 
40
41
  end
metadata CHANGED
@@ -1,91 +1,91 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: best_in_place
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
5
4
  prerelease:
5
+ version: 2.1.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Bernat Farrero
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-22 00:00:00.000000000 Z
12
+ date: 2013-02-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
+ prerelease: false
16
+ type: :runtime
15
17
  name: rails
16
- requirement: !ruby/object:Gem::Requirement
18
+ version_requirements: !ruby/object:Gem::Requirement
17
19
  none: false
18
20
  requirements:
19
21
  - - ~>
20
22
  - !ruby/object:Gem::Version
21
23
  version: '3.1'
22
- type: :runtime
23
- prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
24
+ requirement: !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
29
  version: '3.1'
30
30
  - !ruby/object:Gem::Dependency
31
+ prerelease: false
32
+ type: :runtime
31
33
  name: jquery-rails
32
- requirement: !ruby/object:Gem::Requirement
34
+ version_requirements: !ruby/object:Gem::Requirement
33
35
  none: false
34
36
  requirements:
35
37
  - - ! '>='
36
38
  - !ruby/object:Gem::Version
37
39
  version: '0'
38
- type: :runtime
39
- prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
40
+ requirement: !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
46
  - !ruby/object:Gem::Dependency
47
+ prerelease: false
48
+ type: :development
47
49
  name: rspec-rails
48
- requirement: !ruby/object:Gem::Requirement
50
+ version_requirements: !ruby/object:Gem::Requirement
49
51
  none: false
50
52
  requirements:
51
53
  - - ~>
52
54
  - !ruby/object:Gem::Version
53
55
  version: 2.8.0
54
- type: :development
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
56
+ requirement: !ruby/object:Gem::Requirement
57
57
  none: false
58
58
  requirements:
59
59
  - - ~>
60
60
  - !ruby/object:Gem::Version
61
61
  version: 2.8.0
62
62
  - !ruby/object:Gem::Dependency
63
+ prerelease: false
64
+ type: :development
63
65
  name: nokogiri
64
- requirement: !ruby/object:Gem::Requirement
66
+ version_requirements: !ruby/object:Gem::Requirement
65
67
  none: false
66
68
  requirements:
67
69
  - - ! '>='
68
70
  - !ruby/object:Gem::Version
69
71
  version: '0'
70
- type: :development
71
- prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
72
+ requirement: !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ! '>='
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
78
  - !ruby/object:Gem::Dependency
79
+ prerelease: false
80
+ type: :development
79
81
  name: capybara
80
- requirement: !ruby/object:Gem::Requirement
82
+ version_requirements: !ruby/object:Gem::Requirement
81
83
  none: false
82
84
  requirements:
83
85
  - - ~>
84
86
  - !ruby/object:Gem::Version
85
87
  version: 1.1.2
86
- type: :development
87
- prerelease: false
88
- version_requirements: !ruby/object:Gem::Requirement
88
+ requirement: !ruby/object:Gem::Requirement
89
89
  none: false
90
90
  requirements:
91
91
  - - ~>
@@ -200,6 +200,7 @@ files:
200
200
  - test_app/db/migrate/20120607172609_add_favorite_movie_to_users.rb
201
201
  - test_app/db/migrate/20120616170454_add_money_proc_to_users.rb
202
202
  - test_app/db/migrate/20120620165212_add_height_to_user.rb
203
+ - test_app/db/migrate/20130213224102_add_favorite_locale_to_users.rb
203
204
  - test_app/db/schema.rb
204
205
  - test_app/db/seeds.rb
205
206
  - test_app/doc/README_FOR_APP
@@ -230,30 +231,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
230
231
  - - ! '>='
231
232
  - !ruby/object:Gem::Version
232
233
  version: '0'
233
- segments:
234
- - 0
235
- hash: -1762438104594404996
236
234
  required_rubygems_version: !ruby/object:Gem::Requirement
237
235
  none: false
238
236
  requirements:
239
237
  - - ! '>='
240
238
  - !ruby/object:Gem::Version
241
239
  version: '0'
242
- segments:
243
- - 0
244
- hash: -1762438104594404996
245
240
  requirements: []
246
241
  rubyforge_project: best_in_place
247
- rubygems_version: 1.8.24
242
+ rubygems_version: 1.8.25
248
243
  signing_key:
249
244
  specification_version: 3
250
245
  summary: It makes any field in place editable by clicking on it, it works for inputs,
251
246
  textareas, select dropdowns and checkboxes
252
- test_files:
253
- - spec/helpers/best_in_place_spec.rb
254
- - spec/integration/double_init_spec.rb
255
- - spec/integration/js_spec.rb
256
- - spec/integration/live_spec.rb
257
- - spec/integration/text_area_spec.rb
258
- - spec/spec_helper.rb
259
- - spec/support/retry_on_timeout.rb
247
+ test_files: []