best_in_place 0.1.9 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -31,7 +31,7 @@ BestInPlaceEditor.prototype = {
31
31
  // Public Interface Functions //////////////////////////////////////////////
32
32
 
33
33
  activate : function() {
34
- var elem = this.isNil ? "" : this.element.html();
34
+ var elem = this.isNil ? "" : this.element.html();
35
35
  this.oldValue = elem;
36
36
  $(this.activator).unbind("click", this.clickHandler);
37
37
  this.activateForm();
@@ -69,7 +69,7 @@ BestInPlaceEditor.prototype = {
69
69
  } else if (this.formType == "checkbox") {
70
70
  editor.element.html(this.getValue() ? this.values[1] : this.values[0]);
71
71
  } else {
72
- editor.element.html(this.getValue());
72
+ editor.element.html(this.getValue() != "" ? this.getValue() : this.nil);
73
73
  }
74
74
  },
75
75
 
@@ -89,6 +89,8 @@ BestInPlaceEditor.prototype = {
89
89
  self.objectName = self.objectName || jQuery(this).attr("data-object");
90
90
  self.attributeName = self.attributeName || jQuery(this).attr("data-attribute");
91
91
  self.nil = self.nil || jQuery(this).attr("data-nil");
92
+ self.inner_class = self.inner_class || jQuery(this).attr("data-inner-class");
93
+ self.html_attrs = self.html_attrs || jQuery(this).attr("data-html-attrs");
92
94
  });
93
95
 
94
96
  // Try Rails-id based if parents did not explicitly supply something
@@ -107,6 +109,8 @@ BestInPlaceEditor.prototype = {
107
109
  self.attributeName = self.element.attr("data-attribute") || self.attributeName;
108
110
  self.activator = self.element.attr("data-activator") || self.element;
109
111
  self.nil = self.element.attr("data-nil") || self.nil || "-";
112
+ self.inner_class = self.element.attr("data-inner-class") || self.inner_class || null;
113
+ self.html_attrs = self.element.attr("data-html-attrs") || self.html_attrs;
110
114
 
111
115
  if (!self.element.attr("data-sanitize")) {
112
116
  self.sanitize = true;
@@ -160,7 +164,7 @@ BestInPlaceEditor.prototype = {
160
164
 
161
165
  if (csrf_param !== undefined && csrf_token !== undefined) {
162
166
  data += "&" + csrf_param + "=" + encodeURIComponent(csrf_token);
163
- }
167
+ }
164
168
  return data;
165
169
  },
166
170
 
@@ -174,7 +178,7 @@ BestInPlaceEditor.prototype = {
174
178
 
175
179
  loadSuccessCallback : function(data) {
176
180
  this.element.html(data[this.objectName]);
177
- // Binding back after being clicked
181
+ // Binding back after being clicked
178
182
  $(this.activator).bind('click', {editor: this}, this.clickHandler);
179
183
  },
180
184
 
@@ -183,16 +187,25 @@ BestInPlaceEditor.prototype = {
183
187
 
184
188
  // Display all error messages from server side validation
185
189
  $.each(jQuery.parseJSON(request.responseText), function(index, value) {
190
+ if( typeof(value) == "object") {value = index + " " + value.toString(); }
186
191
  var container = $("<span class='flash-error'></span>").html(value);
187
192
  container.purr();
188
193
  });
189
194
 
190
- // Binding back after being clicked
195
+ // Binding back after being clicked
191
196
  $(this.activator).bind('click', {editor: this}, this.clickHandler);
192
197
  },
193
198
 
194
199
  clickHandler : function(event) {
195
200
  event.data.editor.activate();
201
+ },
202
+
203
+ setHtmlAttributes : function() {
204
+ var formField = this.element.find(this.formType);
205
+ var attrs = jQuery.parseJSON(this.html_attrs);
206
+ for(var key in attrs){
207
+ formField.attr(key, attrs[key]);
208
+ }
196
209
  }
197
210
  };
198
211
 
@@ -201,8 +214,13 @@ BestInPlaceEditor.forms = {
201
214
  "input" : {
202
215
  activateForm : function() {
203
216
  var output = '<form class="form_in_place" action="javascript:void(0)" style="display:inline;">';
204
- output += '<input type="text" value="' + this.sanitizeValue(this.oldValue) + '"></form>';
217
+ output += '<input type="text" name="'+ this.attributeName + '" value="' + this.sanitizeValue(this.oldValue) + '"';
218
+ if (this.inner_class != null) {
219
+ output += ' class="' + this.inner_class + '"';
220
+ }
221
+ output += '></form>'
205
222
  this.element.html(output);
223
+ this.setHtmlAttributes();
206
224
  this.element.find('input')[0].select();
207
225
  this.element.find("form").bind('submit', {editor: this}, BestInPlaceEditor.forms.input.submitHandler);
208
226
  this.element.find("input").bind('blur', {editor: this}, BestInPlaceEditor.forms.input.inputBlurHandler);
@@ -239,6 +257,7 @@ BestInPlaceEditor.forms = {
239
257
  });
240
258
  output += "</select></form>";
241
259
  this.element.html(output);
260
+ this.setHtmlAttributes();
242
261
  this.element.find("select").bind('change', {editor: this}, BestInPlaceEditor.forms.select.blurHandler);
243
262
  this.element.find("select").bind('blur', {editor: this}, BestInPlaceEditor.forms.select.blurHandler);
244
263
  this.element.find("select").bind('keyup', {editor: this}, BestInPlaceEditor.forms.select.keyupHandler);
@@ -263,6 +282,7 @@ BestInPlaceEditor.forms = {
263
282
  var newValue = Boolean(this.oldValue != this.values[1]);
264
283
  var output = newValue ? this.values[1] : this.values[0];
265
284
  this.element.html(output);
285
+ this.setHtmlAttributes();
266
286
  this.update();
267
287
  },
268
288
 
@@ -282,6 +302,7 @@ BestInPlaceEditor.forms = {
282
302
  output += this.sanitizeValue(this.oldValue);
283
303
  output += '</textarea></form>';
284
304
  this.element.html(output);
305
+ this.setHtmlAttributes();
285
306
 
286
307
  // set width and height of textarea
287
308
  jQuery(this.element.find("textarea")[0]).css({ 'min-width': width, 'min-height': height });
@@ -324,132 +345,132 @@ jQuery.fn.best_in_place = function() {
324
345
 
325
346
 
326
347
  /**
327
- * @name Elastic
328
- * @descripton Elastic is Jquery plugin that grow and shrink your textareas automaticliy
329
- * @version 1.6.5
330
- * @requires Jquery 1.2.6+
348
+ * @name Elastic
349
+ * @descripton Elastic is Jquery plugin that grow and shrink your textareas automaticliy
350
+ * @version 1.6.5
351
+ * @requires Jquery 1.2.6+
331
352
  *
332
- * @author Jan Jarfalk
333
- * @author-email jan.jarfalk@unwrongest.com
334
- * @author-website http://www.unwrongest.com
353
+ * @author Jan Jarfalk
354
+ * @author-email jan.jarfalk@unwrongest.com
355
+ * @author-website http://www.unwrongest.com
335
356
  *
336
- * @licens MIT License - http://www.opensource.org/licenses/mit-license.php
357
+ * @licens MIT License - http://www.opensource.org/licenses/mit-license.php
337
358
  */
338
359
 
339
360
  (function(jQuery){
340
- jQuery.fn.extend({
341
- elastic: function() {
342
- // We will create a div clone of the textarea
343
- // by copying these attributes from the textarea to the div.
344
- var mimics = [
345
- 'paddingTop',
346
- 'paddingRight',
347
- 'paddingBottom',
348
- 'paddingLeft',
349
- 'fontSize',
350
- 'lineHeight',
351
- 'fontFamily',
352
- 'width',
353
- 'fontWeight'];
354
-
355
- return this.each( function() {
356
-
357
- // Elastic only works on textareas
358
- if ( this.type != 'textarea' ) {
359
- return false;
360
- }
361
-
362
- var $textarea = jQuery(this),
363
- $twin = jQuery('<div />').css({'position': 'absolute','display':'none','word-wrap':'break-word'}),
364
- lineHeight = parseInt($textarea.css('line-height'),10) || parseInt($textarea.css('font-size'),'10'),
365
- minheight = parseInt($textarea.css('height'),10) || lineHeight*3,
366
- maxheight = parseInt($textarea.css('max-height'),10) || Number.MAX_VALUE,
367
- goalheight = 0,
368
- i = 0;
369
-
370
- // Opera returns max-height of -1 if not set
371
- if (maxheight < 0) { maxheight = Number.MAX_VALUE; }
372
-
373
- // Append the twin to the DOM
374
- // We are going to meassure the height of this, not the textarea.
375
- $twin.appendTo($textarea.parent());
376
-
377
- // Copy the essential styles (mimics) from the textarea to the twin
378
- var i = mimics.length;
379
- while(i--){
380
- $twin.css(mimics[i].toString(),$textarea.css(mimics[i].toString()));
381
- }
382
-
383
-
384
- // Sets a given height and overflow state on the textarea
385
- function setHeightAndOverflow(height, overflow){
386
- curratedHeight = Math.floor(parseInt(height,10));
387
- if($textarea.height() != curratedHeight){
388
- $textarea.css({'height': curratedHeight + 'px','overflow':overflow});
389
-
390
- }
391
- }
392
-
393
-
394
- // This function will update the height of the textarea if necessary
395
- function update() {
396
-
397
- // Get curated content from the textarea.
398
- var textareaContent = $textarea.val().replace(/&/g,'&amp;').replace(/ /g, '&nbsp;').replace(/<|>/g, '&gt;').replace(/\n/g, '<br />');
399
-
400
- // Compare curated content with curated twin.
401
- var twinContent = $twin.html().replace(/<br>/ig,'<br />');
402
-
403
- if(textareaContent+'&nbsp;' != twinContent){
404
-
405
- // Add an extra white space so new rows are added when you are at the end of a row.
406
- $twin.html(textareaContent+'&nbsp;');
407
-
408
- // Change textarea height if twin plus the height of one line differs more than 3 pixel from textarea height
409
- if(Math.abs($twin.height() + lineHeight - $textarea.height()) > 3){
410
-
411
- var goalheight = $twin.height()+lineHeight;
412
- if(goalheight >= maxheight) {
413
- setHeightAndOverflow(maxheight,'auto');
414
- } else if(goalheight <= minheight) {
415
- setHeightAndOverflow(minheight,'hidden');
416
- } else {
417
- setHeightAndOverflow(goalheight,'hidden');
418
- }
419
-
420
- }
421
-
422
- }
423
-
424
- }
425
-
426
- // Hide scrollbars
427
- $textarea.css({'overflow':'hidden'});
428
-
429
- // Update textarea size on keyup, change, cut and paste
430
- $textarea.bind('keyup change cut paste', function(){
431
- update();
432
- });
433
-
434
- // Compact textarea on blur
435
- // Lets animate this....
436
- $textarea.bind('blur',function(){
437
- if($twin.height() < maxheight){
438
- if($twin.height() > minheight) {
439
- $textarea.height($twin.height());
440
- } else {
441
- $textarea.height(minheight);
442
- }
443
- }
444
- });
445
-
446
- // And this line is to catch the browser paste event
447
- $textarea.live('input paste',function(e){ setTimeout( update, 250); });
361
+ jQuery.fn.extend({
362
+ elastic: function() {
363
+ // We will create a div clone of the textarea
364
+ // by copying these attributes from the textarea to the div.
365
+ var mimics = [
366
+ 'paddingTop',
367
+ 'paddingRight',
368
+ 'paddingBottom',
369
+ 'paddingLeft',
370
+ 'fontSize',
371
+ 'lineHeight',
372
+ 'fontFamily',
373
+ 'width',
374
+ 'fontWeight'];
375
+
376
+ return this.each( function() {
377
+
378
+ // Elastic only works on textareas
379
+ if ( this.type != 'textarea' ) {
380
+ return false;
381
+ }
382
+
383
+ var $textarea = jQuery(this),
384
+ $twin = jQuery('<div />').css({'position': 'absolute','display':'none','word-wrap':'break-word'}),
385
+ lineHeight = parseInt($textarea.css('line-height'),10) || parseInt($textarea.css('font-size'),'10'),
386
+ minheight = parseInt($textarea.css('height'),10) || lineHeight*3,
387
+ maxheight = parseInt($textarea.css('max-height'),10) || Number.MAX_VALUE,
388
+ goalheight = 0,
389
+ i = 0;
390
+
391
+ // Opera returns max-height of -1 if not set
392
+ if (maxheight < 0) { maxheight = Number.MAX_VALUE; }
393
+
394
+ // Append the twin to the DOM
395
+ // We are going to meassure the height of this, not the textarea.
396
+ $twin.appendTo($textarea.parent());
397
+
398
+ // Copy the essential styles (mimics) from the textarea to the twin
399
+ var i = mimics.length;
400
+ while(i--){
401
+ $twin.css(mimics[i].toString(),$textarea.css(mimics[i].toString()));
402
+ }
403
+
404
+
405
+ // Sets a given height and overflow state on the textarea
406
+ function setHeightAndOverflow(height, overflow){
407
+ curratedHeight = Math.floor(parseInt(height,10));
408
+ if($textarea.height() != curratedHeight){
409
+ $textarea.css({'height': curratedHeight + 'px','overflow':overflow});
410
+
411
+ }
412
+ }
448
413
 
449
- // Run update once when elastic is initialized
450
- update();
451
414
 
452
- });
415
+ // This function will update the height of the textarea if necessary
416
+ function update() {
417
+
418
+ // Get curated content from the textarea.
419
+ var textareaContent = $textarea.val().replace(/&/g,'&amp;').replace(/ /g, '&nbsp;').replace(/<|>/g, '&gt;').replace(/\n/g, '<br />');
420
+
421
+ // Compare curated content with curated twin.
422
+ var twinContent = $twin.html().replace(/<br>/ig,'<br />');
423
+
424
+ if(textareaContent+'&nbsp;' != twinContent){
425
+
426
+ // Add an extra white space so new rows are added when you are at the end of a row.
427
+ $twin.html(textareaContent+'&nbsp;');
428
+
429
+ // Change textarea height if twin plus the height of one line differs more than 3 pixel from textarea height
430
+ if(Math.abs($twin.height() + lineHeight - $textarea.height()) > 3){
431
+
432
+ var goalheight = $twin.height()+lineHeight;
433
+ if(goalheight >= maxheight) {
434
+ setHeightAndOverflow(maxheight,'auto');
435
+ } else if(goalheight <= minheight) {
436
+ setHeightAndOverflow(minheight,'hidden');
437
+ } else {
438
+ setHeightAndOverflow(goalheight,'hidden');
439
+ }
440
+
441
+ }
442
+
443
+ }
444
+
445
+ }
446
+
447
+ // Hide scrollbars
448
+ $textarea.css({'overflow':'hidden'});
449
+
450
+ // Update textarea size on keyup, change, cut and paste
451
+ $textarea.bind('keyup change cut paste', function(){
452
+ update();
453
+ });
454
+
455
+ // Compact textarea on blur
456
+ // Lets animate this....
457
+ $textarea.bind('blur',function(){
458
+ if($twin.height() < maxheight){
459
+ if($twin.height() > minheight) {
460
+ $textarea.height($twin.height());
461
+ } else {
462
+ $textarea.height(minheight);
463
+ }
464
+ }
465
+ });
466
+
467
+ // And this line is to catch the browser paste event
468
+ $textarea.live('input paste',function(e){ setTimeout( update, 250); });
469
+
470
+ // Run update once when elastic is initialized
471
+ update();
472
+
473
+ });
453
474
 
454
475
  }
455
476
  });
@@ -52,14 +52,14 @@ textarea {
52
52
  /* Missatges Flotants */
53
53
 
54
54
  .purr {
55
- position: fixed;
56
- width: 324px;
57
- top: 20px;
58
- right: 15px;
59
- padding: 20px;
60
- background-color: #000000;
61
- color: #FFFFFF;
62
- border: 2px solid #AAA;
55
+ position: fixed;
56
+ width: 324px;
57
+ top: 20px;
58
+ right: 15px;
59
+ padding: 20px;
60
+ background-color: #000000;
61
+ color: #FFFFFF;
62
+ border: 2px solid #AAA;
63
63
  -moz-border-radius: 10px;
64
64
  -webkit-border-radius: 10px;
65
65
  -o-border-radius: 10px;
@@ -67,13 +67,13 @@ textarea {
67
67
  -khtml-border-radius: 10px;
68
68
  border-radius: 10px;
69
69
  }
70
- .purr:hover .close {
71
- position: absolute;
72
- top: 5px;
73
- right: 3px;
74
- display: block;
75
- width: 25px;
76
- height: 25px;
77
- text-indent: -9999px;
78
- background: url("/images/close-button.gif") no-repeat;
70
+ .purr:hover .close {
71
+ position: absolute;
72
+ top: 5px;
73
+ right: 3px;
74
+ display: block;
75
+ width: 25px;
76
+ height: 25px;
77
+ text-indent: -9999px;
78
+ background: url("/images/close-button.gif") no-repeat;
79
79
  }
metadata CHANGED
@@ -1,62 +1,89 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: best_in_place
3
- version: !ruby/object:Gem::Version
4
- hash: 9
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 1
9
- - 9
10
- version: 0.1.9
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Bernat Farrero
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-02-12 00:00:00 +01:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2011-10-26 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: rails
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &84765280 !ruby/object:Gem::Requirement
25
17
  none: false
26
- requirements:
18
+ requirements:
27
19
  - - ~>
28
- - !ruby/object:Gem::Version
29
- hash: 7
30
- segments:
31
- - 3
32
- - 0
33
- - 0
20
+ - !ruby/object:Gem::Version
34
21
  version: 3.0.0
35
22
  type: :runtime
36
- version_requirements: *id001
37
- description: BestInPlace is a jQuery script and a Rails 3 helper that provide the method best_in_place to display any object field easily editable for the user by just clicking on it. It supports input data, text data, boolean data and custom dropdown data. It works with RESTful controllers.
38
- email:
23
+ prerelease: false
24
+ version_requirements: *84765280
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec-rails
27
+ requirement: &84764870 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 2.7.0
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *84764870
36
+ - !ruby/object:Gem::Dependency
37
+ name: nokogiri
38
+ requirement: &84764560 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 1.5.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *84764560
47
+ - !ruby/object:Gem::Dependency
48
+ name: capybara
49
+ requirement: &84763970 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 1.0.1
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *84763970
58
+ description: BestInPlace is a jQuery script and a Rails 3 helper that provide the
59
+ method best_in_place to display any object field easily editable for the user by
60
+ just clicking on it. It supports input data, text data, boolean data and custom
61
+ dropdown data. It works with RESTful controllers.
62
+ email:
39
63
  - bernat@itnig.net
40
64
  executables: []
41
-
42
65
  extensions: []
43
-
44
66
  extra_rdoc_files: []
45
-
46
- files:
67
+ files:
47
68
  - .gitignore
69
+ - .rspec
70
+ - .travis.yml
48
71
  - Gemfile
49
- - Gemfile.lock
50
72
  - README.md
51
73
  - Rakefile
52
74
  - best_in_place.gemspec
53
75
  - lib/best_in_place.rb
76
+ - lib/best_in_place/helper.rb
77
+ - lib/best_in_place/test_helpers.rb
54
78
  - lib/best_in_place/version.rb
55
79
  - lib/generators/best_in_place/setup_generator.rb
56
80
  - public/javascripts/best_in_place.js
57
81
  - public/javascripts/jquery-1.4.4.js
58
82
  - public/javascripts/jquery.purr.js
59
- - test_app/.gitignore
83
+ - spec/helpers/best_in_place_spec.rb
84
+ - spec/integration/double_init_spec.rb
85
+ - spec/integration/js_spec.rb
86
+ - spec/spec_helper.rb
60
87
  - test_app/Gemfile
61
88
  - test_app/Gemfile.lock
62
89
  - test_app/README
@@ -68,6 +95,7 @@ files:
68
95
  - test_app/app/models/user.rb
69
96
  - test_app/app/views/layouts/application.html.erb
70
97
  - test_app/app/views/users/_form.html.erb
98
+ - test_app/app/views/users/double_init.html.erb
71
99
  - test_app/app/views/users/index.html.erb
72
100
  - test_app/app/views/users/new.html.erb
73
101
  - test_app/app/views/users/show.html.erb
@@ -105,7 +133,6 @@ files:
105
133
  - test_app/public/javascripts/best_in_place.js
106
134
  - test_app/public/javascripts/jquery-1.4.4.min.js
107
135
  - test_app/public/javascripts/jquery.purr.js
108
- - test_app/public/javascripts/jquery.rest_in_place.js
109
136
  - test_app/public/javascripts/rails.js
110
137
  - test_app/public/robots.txt
111
138
  - test_app/public/stylesheets/.gitkeep
@@ -119,39 +146,35 @@ files:
119
146
  - test_app/test/unit/helpers/users_helper_test.rb
120
147
  - test_app/test/unit/user_test.rb
121
148
  - test_app/vendor/plugins/.gitkeep
122
- has_rdoc: true
123
149
  homepage: http://github.com/bernat/best_in_place
124
150
  licenses: []
125
-
126
151
  post_install_message:
127
152
  rdoc_options: []
128
-
129
- require_paths:
153
+ require_paths:
130
154
  - lib
131
- required_ruby_version: !ruby/object:Gem::Requirement
155
+ required_ruby_version: !ruby/object:Gem::Requirement
132
156
  none: false
133
- requirements:
134
- - - ">="
135
- - !ruby/object:Gem::Version
136
- hash: 3
137
- segments:
157
+ requirements:
158
+ - - ! '>='
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ segments:
138
162
  - 0
139
- version: "0"
140
- required_rubygems_version: !ruby/object:Gem::Requirement
163
+ hash: 982211869
164
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
165
  none: false
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- hash: 3
146
- segments:
166
+ requirements:
167
+ - - ! '>='
168
+ - !ruby/object:Gem::Version
169
+ version: '0'
170
+ segments:
147
171
  - 0
148
- version: "0"
172
+ hash: 982211869
149
173
  requirements: []
150
-
151
174
  rubyforge_project: best_in_place
152
- rubygems_version: 1.3.7
175
+ rubygems_version: 1.8.10
153
176
  signing_key:
154
177
  specification_version: 3
155
- summary: It makes any field in place editable by clicking on it, it works for inputs, textareas, select dropdowns and checkboxes
178
+ summary: It makes any field in place editable by clicking on it, it works for inputs,
179
+ textareas, select dropdowns and checkboxes
156
180
  test_files: []
157
-