best_in_place 2.0.3 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: []