in_place_edit_with_datepicker 0.0.1

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,20 @@
1
+ /*
2
+ * BestInPlace 3.0.0.alpha (2014)
3
+ *
4
+ * Depends:
5
+ * best_in_place.js
6
+ * jquery.purr.js
7
+ */
8
+ /*global BestInPlaceEditor */
9
+
10
+ BestInPlaceEditor.defaults.purrErrorContainer = "<span class='bip-flash-error'></span>";
11
+
12
+ jQuery(document).on('best_in_place:error', function (event, request, error) {
13
+ 'use strict';
14
+ // Display all error messages from server side validation
15
+ jQuery.each(jQuery.parseJSON(request.responseText), function (index, value) {
16
+ if (typeof value === "object") {value = index + " " + value.toString(); }
17
+ var container = jQuery(BestInPlaceEditor.defaults.purrErrorContainer).html(value);
18
+ container.purr();
19
+ });
20
+ });
@@ -0,0 +1,52 @@
1
+ (function() {
2
+ var datetime;
3
+
4
+ datetime = {
5
+ "datetime": {
6
+ activateForm: function() {
7
+ var input_elt, options, output, overrideOptions, that, _defaults;
8
+ that = this;
9
+ _defaults = {
10
+ dateFormat: "yy-mm-dd",
11
+ timeFormat: "HH:mm:ss",
12
+ parse: 'loose',
13
+ onClose: function() {
14
+ return that.update();
15
+ }
16
+ };
17
+ overrideOptions = $(this.element[0]).data('datetimepicker-options');
18
+ options = $.extend({}, _defaults, overrideOptions);
19
+ output = jQuery(document.createElement('form')).addClass('form_in_place').attr('action', 'javascript:void(0);').attr('style', 'display:inline');
20
+ input_elt = jQuery(document.createElement('input')).attr('type', 'text').attr('name', this.attributeName).attr('value', this.sanitizeValue(this.display_value));
21
+ if (this.inner_class !== null) {
22
+ input_elt.addClass(this.inner_class);
23
+ }
24
+ output.append(input_elt);
25
+ this.element.html(output);
26
+ this.setHtmlAttributes();
27
+ this.element.find('input')[0].select();
28
+ this.element.find("form").bind('submit', {
29
+ editor: this
30
+ }, BestInPlaceEditor.forms.input.submitHandler);
31
+ this.element.find("input").bind('keyup', {
32
+ editor: this
33
+ }, BestInPlaceEditor.forms.input.keyupHandler);
34
+ return this.element.find('input').datetimepicker(options).datepicker('show');
35
+ },
36
+ getValue: function() {
37
+ return this.sanitizeValue(this.element.find("input").val());
38
+ },
39
+ submitHandler: function(event) {
40
+ return event.data.editor.update();
41
+ },
42
+ keyupHandler: function(event) {
43
+ if (event.keyCode === 27) {
44
+ return event.data.editor.abort();
45
+ }
46
+ }
47
+ }
48
+ };
49
+
50
+ $.extend(BestInPlaceEditor.forms, datetime);
51
+
52
+ }).call(this);
@@ -0,0 +1,56 @@
1
+ #= require best_in_place
2
+ #= require jquery-ui
3
+ #= require jquery-ui-timepicker-addon
4
+
5
+ datetime =
6
+ "datetime" :
7
+ activateForm: ->
8
+ that = this
9
+
10
+ _defaults =
11
+ dateFormat: "yy-mm-dd"
12
+ timeFormat: "HH:mm:ss"
13
+ parse: 'loose'
14
+ onClose: ->
15
+ that.update()
16
+ overrideOptions = jQuery(this.element[0]).data('datetimepicker-options')
17
+ options = $.extend {}, _defaults, overrideOptions
18
+
19
+ output = jQuery(document.createElement('form'))
20
+ .addClass('form_in_place')
21
+ .attr('action', 'javascript:void(0);')
22
+ .attr('style', 'display:inline')
23
+ input_elt = jQuery(document.createElement('input'))
24
+ .attr('type', 'text')
25
+ .attr('name', this.attributeName)
26
+ .attr('value', this.sanitizeValue(this.display_value))
27
+
28
+ if (this.inner_class != null)
29
+ input_elt.addClass(this.inner_class)
30
+
31
+ output.append(input_elt)
32
+
33
+ this.element.html(output)
34
+ this.setHtmlAttributes()
35
+ this.element.find('input')[0].select()
36
+ this.element.find("form").bind('submit', {editor: this}, BestInPlaceEditor.forms.input.submitHandler)
37
+ this.element.find("input").bind('keyup', {editor: this}, BestInPlaceEditor.forms.input.keyupHandler)
38
+
39
+ this.element.find('input')
40
+ .datetimepicker(options)
41
+ .datepicker('show')
42
+ ,
43
+
44
+ getValue: ->
45
+ this.sanitizeValue(this.element.find("input").val())
46
+ ,
47
+
48
+ submitHandler : (event) ->
49
+ event.data.editor.update()
50
+ ,
51
+
52
+ keyupHandler : (event) ->
53
+ if (event.keyCode == 27)
54
+ event.data.editor.abort()
55
+
56
+ $.extend BestInPlaceEditor.forms, datetime
@@ -0,0 +1,33 @@
1
+ require 'rails/railtie'
2
+ require 'action_view/railtie'
3
+ require 'action_controller/railtie'
4
+
5
+ module BestInPlace
6
+ def self.configure
7
+ @configuration ||= Configuration.new
8
+ yield @configuration if block_given?
9
+ end
10
+
11
+ def self.method_missing(method_name, *args, &block)
12
+ @configuration.respond_to?(method_name) ?
13
+ @configuration.send(method_name, *args, &block) : super
14
+ end
15
+
16
+ class Configuration
17
+ attr_accessor :container, :skip_blur
18
+
19
+ def initialize
20
+ @container = :span
21
+ @skip_blur = false
22
+ end
23
+ end
24
+
25
+ configure
26
+ end
27
+
28
+ require 'best_in_place/engine'
29
+ require 'best_in_place/utils'
30
+ require 'best_in_place/helper'
31
+ require 'best_in_place/railtie'
32
+ require 'best_in_place/controller_extensions'
33
+ require 'best_in_place/display_methods'
@@ -0,0 +1,25 @@
1
+ module BestInPlace
2
+ module ControllerExtensions
3
+ def respond_with_bip(obj, options = {})
4
+ obj.errors.any? ? respond_bip_error(obj) : respond_bip_ok(obj, options)
5
+ end
6
+
7
+ private
8
+
9
+ def respond_bip_ok(obj, options = {})
10
+ param_key = options[:param] ||= BestInPlace::Utils.object_to_key(obj)
11
+
12
+ updating_attr = params[param_key].keys.first
13
+
14
+ if renderer = BestInPlace::DisplayMethods.lookup(obj.class, updating_attr)
15
+ render json: renderer.render_json(obj)
16
+ else
17
+ head :no_content
18
+ end
19
+ end
20
+
21
+ def respond_bip_error(obj)
22
+ render json: obj.errors.full_messages, status: :unprocessable_entity
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,49 @@
1
+ module BestInPlace
2
+ module DisplayMethods #:nodoc:
3
+ module_function
4
+
5
+ class Renderer < Struct.new(:opts)
6
+ def render_json(object)
7
+ case opts[:type]
8
+ when :model
9
+ { display_as: object.send(opts[:method]) }.to_json
10
+ when :helper
11
+ value = if opts[:helper_options]
12
+ BestInPlace::ViewHelpers.send(opts[:method], object.send(opts[:attr]), opts[:helper_options])
13
+ else
14
+ BestInPlace::ViewHelpers.send(opts[:method], object.send(opts[:attr]))
15
+ end
16
+ { display_as: value }.to_json
17
+ when :proc
18
+ { display_as: opts[:proc].call(object.send(opts[:attr])) }.to_json
19
+ else
20
+ '{}'
21
+ end
22
+ end
23
+ end
24
+
25
+ @@table = Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) }
26
+
27
+ def lookup(klass, attr)
28
+ foo = model_attributes(klass)[attr.to_s]
29
+ foo == {} ? nil : foo
30
+ end
31
+
32
+ def add_model_method(klass, attr, display_as)
33
+ model_attributes(klass)[attr.to_s] = Renderer.new method: display_as.to_sym, type: :model
34
+ end
35
+
36
+ def add_helper_method(klass, attr, helper_method, helper_options = nil)
37
+ model_attributes(klass)[attr.to_s] = Renderer.new method: helper_method.to_sym, type: :helper, attr: attr, helper_options: helper_options
38
+ end
39
+
40
+ def add_helper_proc(klass, attr, helper_proc)
41
+ model_attributes(klass)[attr.to_s] = Renderer.new type: :proc, attr: attr, proc: helper_proc
42
+ end
43
+
44
+ def model_attributes(klass)
45
+ key = Utils.object_to_key(klass)
46
+ @@table[key]
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,8 @@
1
+ module BestInPlace
2
+ class Engine < Rails::Engine
3
+ initializer 'best_in_place' do
4
+ ActionView::Base.send(:include, BestInPlace::Helper)
5
+ ActionController::Base.send(:include, BestInPlace::ControllerExtensions)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,204 @@
1
+ module BestInPlace
2
+ module Helper
3
+ def best_in_place(object, field, opts = {})
4
+
5
+ best_in_place_assert_arguments(opts)
6
+ type = opts[:as] || :input
7
+ field = field.to_s
8
+
9
+ options = {}
10
+ options[:data] = HashWithIndifferentAccess.new(opts[:data])
11
+ options[:data]['bip-type'] = type
12
+ options[:data]['bip-attribute'] = field
13
+
14
+ real_object = best_in_place_real_object_for object
15
+
16
+ display_value = best_in_place_build_value_for(real_object, field, opts)
17
+
18
+ value = real_object.send(field)
19
+
20
+ if opts[:collection] or type == :checkbox
21
+ collection = opts[:collection]
22
+ value = value.to_s
23
+ collection = best_in_place_default_collection if collection.blank?
24
+ collection = best_in_place_collection_builder(type, collection)
25
+ display_value = collection.flat_map{|a| a[0].to_s == value ? a[1] : nil }.compact[0]
26
+ collection = collection.to_json
27
+ options[:data]['bip-collection'] = html_escape(collection)
28
+ end
29
+
30
+ options[:class] = ['best_in_place'] + Array(opts[:class] || opts[:classes])
31
+ options[:id] = opts[:id] || BestInPlace::Utils.build_best_in_place_id(real_object, field)
32
+
33
+ pass_through_html_options(opts, options)
34
+
35
+ options[:data]['bip-activator'] = opts[:activator].presence
36
+
37
+ options[:data]['bip-html-attrs'] = opts[:html_attrs].to_json unless opts[:html_attrs].blank?
38
+ options[:data]['bip-inner-class'] = opts[:inner_class].presence
39
+
40
+ options[:data]['bip-placeholder'] = html_escape(opts[:place_holder]).presence
41
+
42
+ options[:data]['bip-object'] = opts[:param] || BestInPlace::Utils.object_to_key(real_object)
43
+ options[:data]['bip-ok-button'] = opts[:ok_button].presence
44
+ options[:data]['bip-ok-button-class'] = opts[:ok_button_class].presence
45
+ options[:data]['bip-cancel-button'] = opts[:cancel_button].presence
46
+ options[:data]['bip-cancel-button-class'] = opts[:cancel_button_class].presence
47
+ options[:data]['bip-original-content'] = html_escape(opts[:value] || value).presence
48
+
49
+ options[:data]['bip-skip-blur'] = opts.has_key?(:skip_blur) ? opts[:skip_blur].presence : BestInPlace.skip_blur
50
+
51
+ options[:data]['bip-url'] = url_for(opts[:url] || object)
52
+
53
+ options[:data]['bip-confirm'] = opts[:confirm].presence
54
+ options[:data]['bip-value'] = html_escape(value).presence
55
+
56
+ if opts[:raw]
57
+ options[:data]['bip-raw'] = 'true'
58
+ end
59
+
60
+ # delete nil keys only
61
+ options[:data].delete_if { |_, v| v.nil? }
62
+ container = opts[:container] || BestInPlace.container
63
+ content_tag(container, display_value, options, opts[:raw].blank?)
64
+ end
65
+
66
+ def best_in_place_if(condition, object, field, opts = {})
67
+ if condition
68
+ best_in_place(object, field, opts)
69
+ else
70
+ best_in_place_build_value_for best_in_place_real_object_for(object), field, opts
71
+ end
72
+ end
73
+
74
+ def best_in_place_unless(condition, object, field, opts = {})
75
+ best_in_place_if(!condition, object, field, opts)
76
+ end
77
+
78
+ private
79
+
80
+ def pass_through_html_options(opts, options)
81
+ known_keys = [:id, :type, :nil, :classes, :collection, :data,
82
+ :activator, :cancel_button, :cancel_button_class, :html_attrs, :inner_class, :nil,
83
+ :object_name, :ok_button, :ok_button_class, :display_as, :display_with, :path, :value,
84
+ :use_confirm, :confirm, :sanitize, :raw, :helper_options, :url, :place_holder, :class,
85
+ :as, :param, :container]
86
+ uknown_keys = opts.keys - known_keys
87
+ uknown_keys.each { |key| options[key] = opts[key] }
88
+ end
89
+
90
+ def best_in_place_build_value_for(object, field, opts)
91
+ klass = object.class
92
+ if opts[:display_as]
93
+ BestInPlace::DisplayMethods.add_model_method(klass, field, opts[:display_as])
94
+ object.send(opts[:display_as]).to_s
95
+
96
+ elsif opts[:display_with].try(:is_a?, Proc)
97
+ BestInPlace::DisplayMethods.add_helper_proc(klass, field, opts[:display_with])
98
+ opts[:display_with].call(object.send(field))
99
+
100
+ elsif opts[:display_with]
101
+ BestInPlace::DisplayMethods.add_helper_method(klass, field, opts[:display_with], opts[:helper_options])
102
+ if opts[:helper_options]
103
+ BestInPlace::ViewHelpers.send(opts[:display_with], object.send(field), opts[:helper_options])
104
+ else
105
+ field_value = object.send(field)
106
+
107
+ if field_value.blank?
108
+ ''
109
+ else
110
+ BestInPlace::ViewHelpers.send(opts[:display_with], field_value)
111
+ end
112
+ end
113
+
114
+ else
115
+ object.send(field).to_s
116
+ end
117
+ end
118
+
119
+ def best_in_place_real_object_for(object)
120
+ (object.is_a?(Array) && object.last.class.respond_to?(:model_name)) ? object.last : object
121
+ end
122
+
123
+ def best_in_place_assert_arguments(args)
124
+ best_in_place_deprecated_options(args)
125
+
126
+ if args[:display_as] && args[:display_with]
127
+ fail ArgumentError, 'Can`t use both `display_as`` and `display_with` options at the same time'
128
+ end
129
+
130
+ if args[:display_with] && !args[:display_with].is_a?(Proc) && !ViewHelpers.respond_to?(args[:display_with])
131
+ fail ArgumentError, "Can't find helper #{args[:display_with]}"
132
+ end
133
+ end
134
+
135
+ def best_in_place_deprecated_options(args)
136
+ if deprecated_option = args.delete(:path)
137
+ args[:url] = deprecated_option
138
+ ActiveSupport::Deprecation.warn('[Best_in_place] :path is deprecated in favor of :url ')
139
+ end
140
+
141
+ if deprecated_option = args.delete(:object_name)
142
+ args[:param] = deprecated_option
143
+ ActiveSupport::Deprecation.warn('[Best_in_place] :object_name is deprecated in favor of :param ')
144
+ end
145
+
146
+ if deprecated_option = args.delete(:type)
147
+ args[:as] = deprecated_option
148
+ ActiveSupport::Deprecation.warn('[Best_in_place] :type is deprecated in favor of :as ')
149
+ end
150
+
151
+ if deprecated_option = args.delete(:classes)
152
+ args[:class] = deprecated_option
153
+ ActiveSupport::Deprecation.warn('[Best_in_place] :classes is deprecated in favor of :class ')
154
+ end
155
+
156
+ if deprecated_option = args.delete(:nil)
157
+ args[:place_holder] = deprecated_option
158
+ ActiveSupport::Deprecation.warn('[Best_in_place] :nil is deprecated in favor of :place_holder ')
159
+ end
160
+
161
+ if deprecated_option = args.delete(:use_confirm)
162
+ args[:confirm] = deprecated_option
163
+ ActiveSupport::Deprecation.warn('[Best_in_place] :use_confirm is deprecated in favor of :confirm ')
164
+ end
165
+
166
+ if deprecated_option = args.delete(:sanitize)
167
+ args[:raw] = !deprecated_option
168
+ ActiveSupport::Deprecation.warn('[Best_in_place] :sanitize is deprecated in favor of :raw ')
169
+ end
170
+ end
171
+
172
+ def best_in_place_collection_builder(type, collection)
173
+ collection = case collection
174
+ when Array
175
+ if type == :checkbox
176
+ if collection.length == 2
177
+ [['false', collection[0]], ['true', collection[1]]]
178
+ else
179
+ fail ArgumentError, '[Best_in_place] :collection array should have 2 values'
180
+ end
181
+ else # :select
182
+ case collection[0]
183
+ when Array
184
+ collection
185
+ else
186
+ if collection[0].length == 2
187
+ collection.to_a
188
+ else
189
+ collection.each_with_index.map{|a,i| [i+1,a]}
190
+ end
191
+ end
192
+ end
193
+ else
194
+ collection.to_a
195
+ end
196
+ collection
197
+ end
198
+
199
+ def best_in_place_default_collection
200
+ {'true' => t(:'best_in_place.yes', default: 'Yes'),
201
+ 'false' => t(:'best_in_place.no', default: 'No')}
202
+ end
203
+ end
204
+ end