bradleypriest-on_the_spot 0.0.7

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.
@@ -0,0 +1,5 @@
1
+ README.markdown
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem "rake"
4
+ gem "jeweler"
5
+ gem "json_pure"
6
+
7
+ group :test do
8
+ gem "rspec", ">= 2.0.0.rc"
9
+ gem "actionpack", ">=3.0.0"
10
+ #gem "rcov"
11
+ gem "simplecov", :require => false
12
+ end
@@ -0,0 +1,64 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ abstract (1.0.0)
5
+ actionpack (3.0.0)
6
+ activemodel (= 3.0.0)
7
+ activesupport (= 3.0.0)
8
+ builder (~> 2.1.2)
9
+ erubis (~> 2.6.6)
10
+ i18n (~> 0.4.1)
11
+ rack (~> 1.2.1)
12
+ rack-mount (~> 0.6.12)
13
+ rack-test (~> 0.5.4)
14
+ tzinfo (~> 0.3.23)
15
+ activemodel (3.0.0)
16
+ activesupport (= 3.0.0)
17
+ builder (~> 2.1.2)
18
+ i18n (~> 0.4.1)
19
+ activesupport (3.0.0)
20
+ builder (2.1.2)
21
+ diff-lcs (1.1.2)
22
+ erubis (2.6.6)
23
+ abstract (>= 1.0.0)
24
+ gemcutter (0.6.1)
25
+ git (1.2.5)
26
+ i18n (0.4.1)
27
+ jeweler (1.4.0)
28
+ gemcutter (>= 0.1.0)
29
+ git (>= 1.2.5)
30
+ rubyforge (>= 2.0.0)
31
+ json_pure (1.4.6)
32
+ rack (1.2.1)
33
+ rack-mount (0.6.13)
34
+ rack (>= 1.0.0)
35
+ rack-test (0.5.6)
36
+ rack (>= 1.0)
37
+ rake (0.8.7)
38
+ rspec (2.0.0.rc)
39
+ rspec-core (= 2.0.0.rc)
40
+ rspec-expectations (= 2.0.0.rc)
41
+ rspec-mocks (= 2.0.0.rc)
42
+ rspec-core (2.0.0.rc)
43
+ rspec-expectations (2.0.0.rc)
44
+ diff-lcs (>= 1.1.2)
45
+ rspec-mocks (2.0.0.rc)
46
+ rspec-core (= 2.0.0.rc)
47
+ rspec-expectations (= 2.0.0.rc)
48
+ rubyforge (2.0.4)
49
+ json_pure (>= 1.1.7)
50
+ simplecov (0.3.6)
51
+ simplecov-html (>= 0.3.7)
52
+ simplecov-html (0.3.8)
53
+ tzinfo (0.3.23)
54
+
55
+ PLATFORMS
56
+ ruby
57
+
58
+ DEPENDENCIES
59
+ actionpack (>= 3.0.0)
60
+ jeweler
61
+ json_pure
62
+ rake
63
+ rspec (>= 2.0.0.rc)
64
+ simplecov
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 nathanvda
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,117 @@
1
+ # on_the_spot
2
+
3
+ On-the-spot is a Rails3 compliant unobtrusive javascript in-place-editing plugin, using jEditable, and depends on jQuery.
4
+
5
+ ## Installation
6
+
7
+ Inside your `Gemfile` add the following:
8
+
9
+ gem "on_the_spot"
10
+
11
+ Run the installation task:
12
+
13
+ rails g on_the_spot:install
14
+
15
+ Inside your `routes.rb` you need to provide the following route:
16
+
17
+ resources :posts do
18
+ collection do
19
+ post :update_attribute_on_the_spot
20
+ end
21
+ end
22
+
23
+ You need to do this for each controller that uses the on-the-spot editing.
24
+ For the moment i do not know of any better solution, but i am always open for suggestions!
25
+
26
+ Inside your `application.html.haml` you will need to add below the default javascripts:
27
+
28
+ = javascript_include_tag :on_the_spot
29
+
30
+ or using erb, you write
31
+
32
+ <%= javascript_include_tag :on_the_spot %>
33
+
34
+ That is all you need to do to start using it!
35
+
36
+
37
+ ## Usage
38
+ Inside your controller you write:
39
+
40
+
41
+ class YourController < ApplicationController
42
+
43
+ can_edit_on_the_spot
44
+
45
+ ... leave the rest of your controller alone ...
46
+
47
+ end
48
+
49
+ And inside your view you will have to specify the fields you want to be "editable" :
50
+
51
+ Username: <%= on_the_spot_edit @user, :name %>
52
+
53
+
54
+ It should be as simple as that :)
55
+
56
+ ## Detailed options
57
+
58
+ The `on_the_spot_edit` also accepts options:
59
+
60
+ * `:type` : `:textarea` or `:select` (none means default edit)
61
+ * `:ok_text` : the text for the ok-button
62
+ * `:cancel_text` : the text for the cancel-button
63
+ * `:tooltip` : the tooltip-text
64
+ * `:rows`: for textarea, the number of rows, defaults to 5
65
+ * `:columns`: for textarea, the number of columns, defaults to 40
66
+ * `:data`: for select, the lookup-data, should be in an array of id-value pairs. E.g. `[[1, 'ok'], [2, 'not ok'], [3, 'not decided']]`.
67
+
68
+
69
+ For the texts: if a text is not specified, the default is taken from the `on_the_spot.en.yml` (or your current language).
70
+
71
+ ## Example Usages
72
+
73
+ ### Edit field
74
+
75
+ <%= on_the_spot_edit @user, :name %>
76
+
77
+ ### Textarea
78
+
79
+ <%= on_the_spot_edit @user, :description, :type => :textarea, :rows => 10, :columns => 55 %>
80
+
81
+ ### Select-box
82
+
83
+ <%= on_the_spot_edit @user, :rating, :type => :select, :data => [[1, 'good'], [2, 'mediocre'], [3, 'bad']] %>
84
+
85
+
86
+ ## Example project
87
+
88
+ There is an example rails3-project called [on_the_spot_tester](http://github.com/nathanvda/on_the_spot_tester)
89
+
90
+ ## Prerequisites
91
+
92
+ As jEditable depends on jQuery, your rails3 project needs to use jQuery.
93
+ It will not work if you use Prototype instead, in your rails3 project.
94
+ I have written an article [here](http://www.dixis.com/?p=307) how to start a fresh rails3 project, using jQuery.
95
+ In short, you add the following to your `Gemfile`:
96
+
97
+ gem "jquery-rails"
98
+
99
+ and, after a `bundle install`, you run
100
+
101
+ rails g jquery:install
102
+
103
+ That will download and install all the necessary files for you.
104
+
105
+ ## Note on Patches/Pull Requests
106
+
107
+ * Fork the project.
108
+ * Make your feature addition or bug fix.
109
+ * Add tests for it. This is important so I don't break it in a
110
+ future version unintentionally.
111
+ * Commit, do not mess with rakefile, version, or history.
112
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
113
+ * Send me a pull request. Bonus points for topic branches.
114
+
115
+ ## Copyright
116
+
117
+ Copyright (c) 2010 nathanvda. See LICENSE for details.
@@ -0,0 +1,41 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require "rspec/core/rake_task"
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gem|
8
+ gem.name = "bradleypriest-on_the_spot"
9
+ gem.summary = %Q{unobtrusive in place editing}
10
+ gem.description = %Q{Unobtrusive in place editing, using jEditable; only works in Rails 3}
11
+ gem.email = "nathan@dixis.com"
12
+ gem.homepage = "http://github.com/nathanvda/on_the_spot"
13
+ gem.authors = ["Nathan Van der Auwera"]
14
+ gem.add_development_dependency "rspec", ">= 2.0.0rc"
15
+ gem.add_development_dependency "actionpack", ">= 3.0.0"
16
+ gem.add_dependency "json_pure", ">= 1.4.6"
17
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
22
+ end
23
+
24
+ RSpec::Core::RakeTask.new(:spec)
25
+
26
+ desc "Run all specs with rcov"
27
+ RSpec::Core::RakeTask.new("test_cov") do |t|
28
+ t.rcov = true
29
+ t.rcov_opts = %w{--rails --include views -Ispec --exclude gems\/,spec\/,features\/,seeds\/}
30
+ end
31
+
32
+ require 'rake/rdoctask'
33
+ Rake::RDocTask.new do |rdoc|
34
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
35
+
36
+ rdoc.rdoc_dir = 'rdoc'
37
+ rdoc.title = "on_the_spot #{version}"
38
+ rdoc.rdoc_files.include('README*')
39
+ rdoc.rdoc_files.include('lib/**/*.rb')
40
+ end
41
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.7
@@ -0,0 +1 @@
1
+ Autotest.add_discovery { "rspec2" }
@@ -0,0 +1,19 @@
1
+ module OnTheSpot
2
+ module Generators
3
+ class InstallGenerator < ::Rails::Generators::Base
4
+ source_root File.expand_path('../templates', __FILE__)
5
+ desc "This generator installs jEditable and some glue javascript"
6
+
7
+ def download_jeditable
8
+ # Downloading latest jEditable
9
+ get "http://www.appelsiini.net/download/jquery.jeditable.mini.js", "public/javascripts/jquery.jeditable.mini.js"
10
+ end
11
+
12
+ def copy_glue_javascript
13
+ copy_file "on_the_spot.js", "public/javascripts/on_the_spot.js"
14
+ copy_file "on_the_spot.en.yml", "config/locales/on_the_spot.en.yml"
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,38 @@
1
+
2
+ (function($){$.fn.editable=function(target,options){if('disable'==target){$(this).data('disabled.editable',true);return;}
3
+ if('enable'==target){$(this).data('disabled.editable',false);return;}
4
+ if('destroy'==target){$(this).unbind($(this).data('event.editable')).removeData('disabled.editable').removeData('event.editable');return;}
5
+ var settings=$.extend({},$.fn.editable.defaults,{target:target},options);var plugin=$.editable.types[settings.type].plugin||function(){};var submit=$.editable.types[settings.type].submit||function(){};var buttons=$.editable.types[settings.type].buttons||$.editable.types['defaults'].buttons;var content=$.editable.types[settings.type].content||$.editable.types['defaults'].content;var element=$.editable.types[settings.type].element||$.editable.types['defaults'].element;var reset=$.editable.types[settings.type].reset||$.editable.types['defaults'].reset;var callback=settings.callback||function(){};var onedit=settings.onedit||function(){};var onsubmit=settings.onsubmit||function(){};var onreset=settings.onreset||function(){};var onerror=settings.onerror||reset;if(settings.tooltip){$(this).attr('title',settings.tooltip);}
6
+ settings.autowidth='auto'==settings.width;settings.autoheight='auto'==settings.height;return this.each(function(){var self=this;var savedwidth=$(self).width();var savedheight=$(self).height();$(this).data('event.editable',settings.event);if(!$.trim($(this).html())){$(this).html(settings.placeholder);}
7
+ $(this).bind(settings.event,function(e){if(true===$(this).data('disabled.editable')){return;}
8
+ if(self.editing){return;}
9
+ if(false===onedit.apply(this,[settings,self])){return;}
10
+ e.preventDefault();e.stopPropagation();if(settings.tooltip){$(self).removeAttr('title');}
11
+ if(0==$(self).width()){settings.width=savedwidth;settings.height=savedheight;}else{if(settings.width!='none'){settings.width=settings.autowidth?$(self).width():settings.width;}
12
+ if(settings.height!='none'){settings.height=settings.autoheight?$(self).height():settings.height;}}
13
+ if($(this).html().toLowerCase().replace(/(;|")/g,'')==settings.placeholder.toLowerCase().replace(/(;|")/g,'')){$(this).html('');}
14
+ self.editing=true;self.revert=$(self).html();$(self).html('');var form=$('<form />');if(settings.cssclass){if('inherit'==settings.cssclass){form.attr('class',$(self).attr('class'));}else{form.attr('class',settings.cssclass);}}
15
+ if(settings.style){if('inherit'==settings.style){form.attr('style',$(self).attr('style'));form.css('display',$(self).css('display'));}else{form.attr('style',settings.style);}}
16
+ var input=element.apply(form,[settings,self]);var input_content;if(settings.loadurl){var t=setTimeout(function(){input.disabled=true;content.apply(form,[settings.loadtext,settings,self]);},100);var loaddata={};loaddata[settings.id]=self.id;if($.isFunction(settings.loaddata)){$.extend(loaddata,settings.loaddata.apply(self,[self.revert,settings]));}else{$.extend(loaddata,settings.loaddata);}
17
+ $.ajax({type:settings.loadtype,url:settings.loadurl,data:loaddata,async:false,success:function(result){window.clearTimeout(t);input_content=result;input.disabled=false;}});}else if(settings.data){input_content=settings.data;if($.isFunction(settings.data)){input_content=settings.data.apply(self,[self.revert,settings]);}}else{input_content=self.revert;}
18
+ content.apply(form,[input_content,settings,self]);input.attr('name',settings.name);buttons.apply(form,[settings,self]);$(self).append(form);plugin.apply(form,[settings,self]);$(':input:visible:enabled:first',form).focus();if(settings.select){input.select();}
19
+ input.keydown(function(e){if(e.keyCode==27){e.preventDefault();reset.apply(form,[settings,self]);}});var t;if('cancel'==settings.onblur){input.blur(function(e){t=setTimeout(function(){reset.apply(form,[settings,self]);},500);});}else if('submit'==settings.onblur){input.blur(function(e){t=setTimeout(function(){form.submit();},200);});}else if($.isFunction(settings.onblur)){input.blur(function(e){settings.onblur.apply(self,[input.val(),settings]);});}else{input.blur(function(e){});}
20
+ form.submit(function(e){if(t){clearTimeout(t);}
21
+ e.preventDefault();if(false!==onsubmit.apply(form,[settings,self])){if(false!==submit.apply(form,[settings,self])){if($.isFunction(settings.target)){var str=settings.target.apply(self,[input.val(),settings]);$(self).html(str);self.editing=false;callback.apply(self,[self.innerHTML,settings]);if(!$.trim($(self).html())){$(self).html(settings.placeholder);}}else{var submitdata={};submitdata[settings.name]=input.val();submitdata[settings.id]=self.id;if($.isFunction(settings.submitdata)){$.extend(submitdata,settings.submitdata.apply(self,[self.revert,settings]));}else{$.extend(submitdata,settings.submitdata);}
22
+ if('PUT'==settings.method){submitdata['_method']='put';}
23
+ $(self).html(settings.indicator);var ajaxoptions={type:'POST',data:submitdata,dataType:'html',url:settings.target,success:function(result,status){if(ajaxoptions.dataType=='html'){$(self).html(result);}
24
+ self.editing=false;callback.apply(self,[result,settings]);if(!$.trim($(self).html())){$(self).html(settings.placeholder);}},error:function(xhr,status,error){onerror.apply(form,[settings,self,xhr]);}};$.extend(ajaxoptions,settings.ajaxoptions);$.ajax(ajaxoptions);}}}
25
+ $(self).attr('title',settings.tooltip);return false;});});this.reset=function(form){if(this.editing){if(false!==onreset.apply(form,[settings,self])){$(self).html(self.revert);self.editing=false;if(!$.trim($(self).html())){$(self).html(settings.placeholder);}
26
+ if(settings.tooltip){$(self).attr('title',settings.tooltip);}}}};});};$.editable={types:{defaults:{element:function(settings,original){var input=$('<input type="hidden"></input>');$(this).append(input);return(input);},content:function(string,settings,original){$(':input:first',this).val(string);},reset:function(settings,original){original.reset(this);},buttons:function(settings,original){var form=this;if(settings.submit){if(settings.submit.match(/>$/)){var submit=$(settings.submit).click(function(){if(submit.attr("type")!="submit"){form.submit();}});}else{var submit=$('<button type="submit" />');submit.html(settings.submit);}
27
+ $(this).append(submit);}
28
+ if(settings.cancel){if(settings.cancel.match(/>$/)){var cancel=$(settings.cancel);}else{var cancel=$('<button type="cancel" />');cancel.html(settings.cancel);}
29
+ $(this).append(cancel);$(cancel).click(function(event){if($.isFunction($.editable.types[settings.type].reset)){var reset=$.editable.types[settings.type].reset;}else{var reset=$.editable.types['defaults'].reset;}
30
+ reset.apply(form,[settings,original]);return false;});}}},text:{element:function(settings,original){var input=$('<input />');if(settings.width!='none'){input.width(settings.width);}
31
+ if(settings.height!='none'){input.height(settings.height);}
32
+ input.attr('autocomplete','off');$(this).append(input);return(input);}},textarea:{element:function(settings,original){var textarea=$('<textarea />');if(settings.rows){textarea.attr('rows',settings.rows);}else if(settings.height!="none"){textarea.height(settings.height);}
33
+ if(settings.cols){textarea.attr('cols',settings.cols);}else if(settings.width!="none"){textarea.width(settings.width);}
34
+ $(this).append(textarea);return(textarea);}},select:{element:function(settings,original){var select=$('<select />');$(this).append(select);return(select);},content:function(data,settings,original){if(String==data.constructor){eval('var json = '+data);}else{var json=data;}
35
+ for(var key in json){if(!json.hasOwnProperty(key)){continue;}
36
+ if('selected'==key){continue;}
37
+ var option=$('<option />').val(key).append(json[key]);$('select',this).append(option);}
38
+ $('select',this).children().each(function(){if($(this).val()==json['selected']||$(this).text()==$.trim(original.revert)){$(this).attr('selected','selected');}});}}},addInputType:function(name,input){$.editable.types[name]=input;}};$.fn.editable.defaults={name:'value',id:'id',type:'text',width:'auto',height:'auto',event:'click.editable',onblur:'cancel',loadtype:'GET',loadtext:'Loading...',placeholder:'Click to edit',loaddata:{},submitdata:{},ajaxoptions:{}};})(jQuery);
@@ -0,0 +1,5 @@
1
+ en:
2
+ on_the_spot:
3
+ ok: Ok
4
+ cancel: Cancel
5
+ tooltip: Click to edit ...
@@ -0,0 +1,52 @@
1
+ $(document).ready(function() {
2
+
3
+ $(".on_the_spot_editing").mouseover(function() {
4
+ $(this).css('background-color', '#EEF2A0');
5
+ });
6
+ $(".on_the_spot_editing").mouseout(function() {
7
+ $(this).css('background-color', 'inherit');
8
+ });
9
+ $('.on_the_spot_editing').each(function(n){
10
+ var el = $(this),
11
+ data_url = el.attr('data-url'),
12
+ ok_text = el.attr('data-ok') || 'OK',
13
+ cancel_text = el.attr('data-cancel') || 'Cancel',
14
+ tooltip_text = el.attr('data-tooltip') || 'Click to edit ...',
15
+ edit_type = el.attr('data-edittype'),
16
+ select_data = el.attr('data-select'),
17
+ rows = el.attr('data-rows'),
18
+ columns = el.attr('data-columns'),
19
+ load_url = el.attr('data-loadurl');
20
+
21
+ var options = {
22
+ tooltip: tooltip_text,
23
+ placeholder: tooltip_text,
24
+ cancel: cancel_text,
25
+ submit: ok_text,
26
+ onerror: function (settings, original, xhr) {
27
+ original.reset();
28
+ //just show the error-msg for now
29
+ alert(xhr.responseText);
30
+ }
31
+ };
32
+ if (edit_type != null) {
33
+ options.type = edit_type;
34
+ }
35
+ if (edit_type == 'select') {
36
+ if (select_data != null) {
37
+ options.data = select_data;
38
+ options.submitdata = { 'select_array': select_data }
39
+ }
40
+ if (load_url != null) {
41
+ options.loadurl = load_url;
42
+ }
43
+ }
44
+ else if (edit_type == 'textarea') {
45
+ options.rows = rows;
46
+ options.cols = columns;
47
+ }
48
+
49
+ el.editable(data_url, options)
50
+ })
51
+
52
+ });
@@ -0,0 +1,19 @@
1
+ require 'on_the_spot/controller_extension'
2
+ require 'on_the_spot/on_the_spot_helpers'
3
+
4
+ module OnTheSpot
5
+ class Railtie < ::Rails::Railtie
6
+
7
+ config.before_initialize do
8
+ config.action_view.javascript_expansions[:on_the_spot] = %w(jquery.jeditable.mini.js on_the_spot)
9
+ end
10
+
11
+ # configure our plugin on boot. other extension points such
12
+ # as configuration, rake tasks, etc, are also available
13
+ initializer "on_the_spot.initialize" do |app|
14
+ ActionController::Base.send :include, OnTheSpot::ControllerExtension
15
+ ActionView::Base.send :include, OnTheSpot::Helpers
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,34 @@
1
+ module OnTheSpot
2
+ module ControllerExtension
3
+
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ end
7
+
8
+ # if this method is called inside a controller, the edit-on-the-spot
9
+ # controller action is added that will allow to edit fields in place
10
+ module ClassMethods
11
+ def can_edit_on_the_spot(options = {})
12
+ define_method :update_attribute_on_the_spot do
13
+ klass, field, id = params[:id].split('__')
14
+ select_data = params[:select_array]
15
+ object = klass.camelize.constantize.find(id)
16
+ if options[:cancan]
17
+ authorize!(options[:cancan], object)
18
+ end
19
+ if object.update_attributes(field => params[:value])
20
+ if select_data.nil?
21
+ render :text => CGI::escapeHTML(object.send(field).to_s)
22
+ else
23
+ parsed_data = JSON.parse(select_data.gsub("'", '"'))
24
+ render :text => parsed_data[object.send(field).to_s]
25
+ end
26
+ else
27
+ render :text => object.errors.full_messages.join("\n"), :status => 422
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,88 @@
1
+ module OnTheSpot
2
+ module Helpers
3
+
4
+ EDIT_TYPE_TEXTAREA='textarea'
5
+ EDIT_TYPE_SELECT='select'
6
+
7
+ class OnTheSpotMissingParameters < StandardError; end
8
+
9
+ # Possible options:
10
+ # ok_text : the ok-button text
11
+ # cancel_text : the cancel-button text
12
+ # tooltip : the tooltip to show
13
+ # type : {'textarea' || 'select' }
14
+ # rows : nr of rows for textarea
15
+ # columns : nr of columns for textarea
16
+ # loadurl : (for select) an url that will return the json for the select
17
+ # data : (for select) an array of options in the form [id, value]
18
+ # url : (optional) URL to post to if you don't want to use the standard routes
19
+ def on_the_spot_edit(object, field, options={})
20
+ #!!! to do: translate options to data-fields
21
+ # Possible fields:
22
+ # type: textarea or not
23
+ # button-translations ok-Text, cancel-Text
24
+ #
25
+
26
+
27
+
28
+ options.reverse_merge!(:ok_text => t('on_the_spot.ok'),
29
+ :cancel_text => t('on_the_spot.cancel'),
30
+ :tooltip => t('on_the_spot.tooltip'),
31
+ :rows => 5,
32
+ :columns => 40,
33
+ :url => {:action => 'update_attribute_on_the_spot'}
34
+
35
+ )
36
+
37
+ update_url = url_for(options[:url])
38
+
39
+ field_value = object.send(field.to_sym).to_s
40
+
41
+ html_options = { :id => "#{object.class.name.underscore}__#{field}__#{object.id}",
42
+ :class => 'on_the_spot_editing',
43
+ :'data-url' => update_url}
44
+
45
+ editable_type = options[:type].nil? ? nil : options[:type].to_sym
46
+ html_options[:'data-edittype'] = editable_type.to_s unless editable_type.nil?
47
+ if editable_type == :select
48
+ # we need either a data or loadurl
49
+ unless options[:loadurl].nil?
50
+ html_options[:'data-loadurl'] = options[:loadurl]
51
+ else
52
+ # we should find a hash
53
+ select_data = options[:data]
54
+ raise OnTheSpotMissingParameters.new("Using type select needs either data or loadurl to function!") if select_data.nil?
55
+ html_options[:'data-select'] = convert_array_to_json(select_data, field_value)
56
+ end
57
+ elsif editable_type == :textarea
58
+ html_options[:'data-rows'] = options[:rows]
59
+ html_options[:'data-columns'] = options[:columns]
60
+ end
61
+ html_options[:'data-ok'] = options[:ok_text]
62
+ html_options[:'data-cancel'] = options[:cancel_text]
63
+ html_options[:'data-tooltip'] = options[:tooltip]
64
+
65
+ content_tag("span", html_options) do
66
+ if editable_type == :select
67
+ lookup_display_value(select_data, field_value)
68
+ else
69
+ field_value
70
+ end
71
+ end
72
+ end
73
+
74
+ def lookup_display_value(id_value_array, id_str)
75
+ found_pair = id_value_array.select{ |idv| idv[0].to_s == id_str.to_s }
76
+ found_pair.size == 0 ? '' : found_pair[0][1]
77
+ end
78
+
79
+ def convert_array_to_json(id_value_array, selected_id)
80
+ conv_arr = id_value_array.map{|idv| "'#{idv[0]}':'#{idv[1]}'" }
81
+ result = "{ #{conv_arr.join', '}"
82
+ result += ", 'selected':'#{ selected_id.to_s}'" unless selected_id.nil?
83
+ result += "}"
84
+ result
85
+ end
86
+
87
+ end
88
+ end
@@ -0,0 +1,71 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{on_the_spot}
8
+ s.version = "0.0.7"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Nathan Van der Auwera"]
12
+ s.date = %q{2011-03-23}
13
+ s.description = %q{Unobtrusive in place editing, using jEditable; only works in Rails 3}
14
+ s.email = %q{nathan@dixis.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.markdown"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ ".rspec",
23
+ "Gemfile",
24
+ "Gemfile.lock",
25
+ "LICENSE",
26
+ "README.markdown",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "autotest/discover.rb",
30
+ "lib/generators/on_the_spot/install/install_generator.rb",
31
+ "lib/generators/on_the_spot/install/templates/jquery.jeditable.mini.js",
32
+ "lib/generators/on_the_spot/install/templates/on_the_spot.en.yml",
33
+ "lib/generators/on_the_spot/install/templates/on_the_spot.js",
34
+ "lib/on_the_spot.rb",
35
+ "lib/on_the_spot/controller_extension.rb",
36
+ "lib/on_the_spot/on_the_spot_helpers.rb",
37
+ "on_the_spot.gemspec",
38
+ "spec/on_the_spot_spec.rb",
39
+ "spec/spec.opts",
40
+ "spec/spec_helper.rb"
41
+ ]
42
+ s.homepage = %q{http://github.com/nathanvda/on_the_spot}
43
+ s.rdoc_options = ["--charset=UTF-8"]
44
+ s.require_paths = ["lib"]
45
+ s.rubygems_version = %q{1.3.7}
46
+ s.summary = %q{unobtrusive in place editing}
47
+ s.test_files = [
48
+ "spec/spec_helper.rb",
49
+ "spec/on_the_spot_spec.rb"
50
+ ]
51
+
52
+ if s.respond_to? :specification_version then
53
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
54
+ s.specification_version = 3
55
+
56
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
57
+ s.add_development_dependency(%q<rspec>, [">= 2.0.0rc"])
58
+ s.add_development_dependency(%q<actionpack>, [">= 3.0.0"])
59
+ s.add_runtime_dependency(%q<json_pure>, [">= 1.4.6"])
60
+ else
61
+ s.add_dependency(%q<rspec>, [">= 2.0.0rc"])
62
+ s.add_dependency(%q<actionpack>, [">= 3.0.0"])
63
+ s.add_dependency(%q<json_pure>, [">= 1.4.6"])
64
+ end
65
+ else
66
+ s.add_dependency(%q<rspec>, [">= 2.0.0rc"])
67
+ s.add_dependency(%q<actionpack>, [">= 3.0.0"])
68
+ s.add_dependency(%q<json_pure>, [">= 1.4.6"])
69
+ end
70
+ end
71
+
@@ -0,0 +1,67 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'on_the_spot/on_the_spot_helpers'
3
+
4
+ require 'action_controller'
5
+
6
+ describe "OnTheSpot" do
7
+ describe "Helpers" do
8
+ before(:each) do
9
+
10
+ class TestClass < ActionView::Base
11
+ include OnTheSpot::Helpers
12
+ end
13
+
14
+ @tester = TestClass.new
15
+ @test_array_nr = [[1,"abc"], [2, "def"], [3, "ghi"]]
16
+ @test_array_str = [["key", "value"], ["key2", "value2"]]
17
+ end
18
+
19
+ context "lookup values from array" do
20
+ it "should find value abc for key 1" do
21
+ @tester.lookup_display_value(@test_array_nr, 1).should == 'abc'
22
+ end
23
+
24
+ it "should find value <value2> for key key2" do
25
+ @tester.lookup_display_value(@test_array_str, 'key2').should == 'value2'
26
+ end
27
+
28
+ it "should return an empty string if key does not exist" do
29
+ @tester.lookup_display_value(@test_array_str, 'key1').should == ''
30
+ end
31
+
32
+ end
33
+
34
+ context "convert array to json" do
35
+ it "should convert correctly" do
36
+ @tester.convert_array_to_json(@test_array_nr, 1).should == "{ '1':'abc', '2':'def', '3':'ghi', 'selected':'1'}"
37
+ end
38
+ end
39
+
40
+ context "the helpers" do
41
+ before(:each) do
42
+ @dummy = mock()
43
+ @dummy.stub!(:content).and_return('test')
44
+ @dummy.stub!(:id).and_return('123')
45
+ @tester.should_receive(:t).with('on_the_spot.ok').and_return("ok")
46
+ @tester.should_receive(:t).with('on_the_spot.cancel').and_return("cancel")
47
+ @tester.should_receive(:t).with('on_the_spot.tooltip').and_return("tooltip")
48
+ @tester.should_receive(:url_for).and_return('/bla')
49
+ end
50
+
51
+ it "should make the correct html for an edit-field" do
52
+ @result = @tester.on_the_spot_edit @dummy, :content
53
+ @result.should == "<span class=\"on_the_spot_editing\" data-cancel=\"cancel\" data-ok=\"ok\" data-tooltip=\"tooltip\" data-url=\"/bla\" id=\"r_spec/mocks/mock__content__123\">test</span>"
54
+ end
55
+
56
+ it "should make the correct html for a text-area" do
57
+ @result = @tester.on_the_spot_edit @dummy, :content, :type => :textarea
58
+ @result.should == "<span class=\"on_the_spot_editing\" data-cancel=\"cancel\" data-columns=\"40\" data-edittype=\"textarea\" data-ok=\"ok\" data-rows=\"5\" data-tooltip=\"tooltip\" data-url=\"/bla\" id=\"r_spec/mocks/mock__content__123\">test</span>"
59
+ end
60
+
61
+ it "should make the correct html for a select-box" do
62
+ @result = @tester.on_the_spot_edit @dummy, :content, :type => :select, :data => [['test', 'This a test'], ['prod', 'Pure Production'], ['QA', 'Quality Assurance']]
63
+ @result.should == "<span class=\"on_the_spot_editing\" data-cancel=\"cancel\" data-edittype=\"select\" data-ok=\"ok\" data-select=\"{ 'test':'This a test', 'prod':'Pure Production', 'QA':'Quality Assurance', 'selected':'test'}\" data-tooltip=\"tooltip\" data-url=\"/bla\" id=\"r_spec/mocks/mock__content__123\">This a test</span>"
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'rspec/core'
4
+ #require 'autotest/rspec2'
5
+
6
+ require 'simplecov'
7
+ SimpleCov.start 'rails'
8
+
9
+ RSpec.configure do |c|
10
+ c.color_enabled = true
11
+ end
12
+
metadata ADDED
@@ -0,0 +1,142 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bradleypriest-on_the_spot
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.7
6
+ platform: ruby
7
+ authors:
8
+ - Nathan Van der Auwera
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-04-12 00:00:00 +12:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rake
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: jeweler
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: json_pure
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :runtime
47
+ prerelease: false
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: rspec
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: 2.0.0rc
57
+ type: :development
58
+ prerelease: false
59
+ version_requirements: *id004
60
+ - !ruby/object:Gem::Dependency
61
+ name: actionpack
62
+ requirement: &id005 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: 3.0.0
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: *id005
71
+ - !ruby/object:Gem::Dependency
72
+ name: json_pure
73
+ requirement: &id006 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: 1.4.6
79
+ type: :runtime
80
+ prerelease: false
81
+ version_requirements: *id006
82
+ description: Unobtrusive in place editing, using jEditable; only works in Rails 3
83
+ email: nathan@dixis.com
84
+ executables: []
85
+
86
+ extensions: []
87
+
88
+ extra_rdoc_files:
89
+ - LICENSE
90
+ - README.markdown
91
+ files:
92
+ - .document
93
+ - .rspec
94
+ - Gemfile
95
+ - Gemfile.lock
96
+ - LICENSE
97
+ - README.markdown
98
+ - Rakefile
99
+ - VERSION
100
+ - autotest/discover.rb
101
+ - lib/generators/on_the_spot/install/install_generator.rb
102
+ - lib/generators/on_the_spot/install/templates/jquery.jeditable.mini.js
103
+ - lib/generators/on_the_spot/install/templates/on_the_spot.en.yml
104
+ - lib/generators/on_the_spot/install/templates/on_the_spot.js
105
+ - lib/on_the_spot.rb
106
+ - lib/on_the_spot/controller_extension.rb
107
+ - lib/on_the_spot/on_the_spot_helpers.rb
108
+ - on_the_spot.gemspec
109
+ - spec/on_the_spot_spec.rb
110
+ - spec/spec.opts
111
+ - spec/spec_helper.rb
112
+ has_rdoc: true
113
+ homepage: http://github.com/nathanvda/on_the_spot
114
+ licenses: []
115
+
116
+ post_install_message:
117
+ rdoc_options: []
118
+
119
+ require_paths:
120
+ - lib
121
+ required_ruby_version: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: "0"
127
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
+ none: false
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: "0"
133
+ requirements: []
134
+
135
+ rubyforge_project:
136
+ rubygems_version: 1.5.2
137
+ signing_key:
138
+ specification_version: 3
139
+ summary: unobtrusive in place editing
140
+ test_files:
141
+ - spec/on_the_spot_spec.rb
142
+ - spec/spec_helper.rb