assoc_whisperer 1.2.1 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e3b0faee0f011a70f467c0952840bf4f9769b2d7
4
- data.tar.gz: 3c79fa3dd430cd87812df970f2587c3582fedbf0
3
+ metadata.gz: c12d3a84dff2b3fcedf60c2abd790d235626c566
4
+ data.tar.gz: aacfc5036d39c470b1301cc6b7f853f0dded41d0
5
5
  SHA512:
6
- metadata.gz: 03278adaba130fbe47971380cfb6c34c3835fd19d1aa8fd2df0a7f018f658ecfac25a976e642761ec4bd0c3a9b0cfd8cb06e09f5f2bb01bd080a7138514d915d
7
- data.tar.gz: c368cf1dcb3f33d4fb6c258d810d6a197403da440f411cff62aafe43b46d02edca3424db4383ee965c5c707ee0a29e8d934653045c64573970b9bb2fd4a31883
6
+ metadata.gz: 760054c15cc9fc0aea5357f11db45cfb81e5245a3747f574ba6fccc1abeb3a50aac045d17a08e26a09122f238e5744ea18239fb4775977ef388cc82bc481c9ce
7
+ data.tar.gz: 6309409f36c8087a4460dc542eaaf2b3d05fa1850f0df4cd5f2d20a4dd145eb97812a5cd4eafb542d946b9f9658576e0233bfb9c0f4917f75e33d0c45939c3bc
@@ -15,7 +15,7 @@ document.AssocWhisperer = (function () {
15
15
 
16
16
  // This is where Whisperer Object is created - with all hidden inner methods.
17
17
  function createWhisperer(dom_node) {
18
- var el, w, _nodes, opts, params, _timer;
18
+ var el, w, opts, _nodes, _timer;
19
19
 
20
20
  el = $(dom_node);
21
21
  _nodes = {
@@ -25,22 +25,25 @@ document.AssocWhisperer = (function () {
25
25
  list: null
26
26
  };
27
27
  opts = el.data('opts');
28
- if (!opts['action']) throw 'Missing action in '+JSON.stringify(opts);
29
- if (!opts['url']) throw 'Missing url in '+JSON.stringify(opts);
28
+ if (!opts['action']) throw 'Missing action path in '+JSON.stringify(opts);
30
29
  if (typeof opts['params']!=='object') opts['params'] = {};
30
+ // opts['cs'] = parseInt(opts['cs']);
31
31
 
32
32
  w = Object.create(proto, {
33
33
  nodes: {value: _nodes},
34
- action: {value: opts['action']},
35
- url: {value: opts['url']},
36
- params: {value: opts['params']},
37
34
  focused: {value: false, writable: true},
38
35
  filled: {value: _nodes['value_field'].val()!=='', writable: true},
39
- client_side: {value: opts['cs']===true},
40
- preload: {value: opts['pre']===true},
41
- full_data: {value: null, writable: true}
36
+ // setting
37
+ action: {value: opts['action']},
38
+ params: {value: opts['params']}
42
39
  });
43
- w.params['data_action'] = w.action;
40
+ // if (!isNaN(opts['cs'])) {
41
+ // // client side
42
+ // Object.defineProperties({
43
+ // client_side: {value: opts['cs']},
44
+ // full_data: {value: null, writable: true}
45
+ // });
46
+ // }
44
47
 
45
48
  _nodes.text_field.on('keyup', function(e){
46
49
  var input_text;
@@ -67,11 +70,11 @@ document.AssocWhisperer = (function () {
67
70
  }
68
71
  _timer = setTimeout(function () {
69
72
  if (w.client_side) {
70
- if (!w.full_data) query(w, null, function (html_text) {
71
- w.full_data = $(html_text);
72
- showList(digest(input_text));
73
- });
74
- else showList(digest(input_text));
73
+ // if (!w.full_data) query(w, null, function (html_text) {
74
+ // w.full_data = $(html_text);
75
+ // showList(digest(input_text));
76
+ // });
77
+ // else showList(digest(input_text));
75
78
  }
76
79
  else query(w, input_text, function (html_text) {
77
80
  showList($(html_text));
@@ -86,20 +89,20 @@ document.AssocWhisperer = (function () {
86
89
  var f;
87
90
  if (_timer) clearTimeout(_timer);
88
91
  if (w.client_side) {
89
- f = function () {
90
- var input_text;
91
- if (w.filled) showList(w.full_data);
92
- else {
93
- input_text = _nodes['text_field'].val();
94
- showList(digest(input_text==='' ? null : input_text));
95
- }
96
- _nodes['list'].focus();
97
- };
98
- if (!w.full_data) query(w, null, function (html_text) {
99
- w.full_data = $(html_text);
100
- f();
101
- });
102
- else f();
92
+ // f = function () {
93
+ // var input_text;
94
+ // if (w.filled) showList(w.full_data);
95
+ // else {
96
+ // input_text = _nodes['text_field'].val();
97
+ // showList(digest(input_text==='' ? null : input_text));
98
+ // }
99
+ // _nodes['list'].focus();
100
+ // };
101
+ // if (!w.full_data) query(w, null, function (html_text) {
102
+ // w.full_data = $(html_text);
103
+ // f();
104
+ // });
105
+ // else f();
103
106
  }
104
107
  else {
105
108
  query(w, (w.filled ? null : _nodes['text_field'].val()), function (html_text) {
@@ -110,19 +113,19 @@ document.AssocWhisperer = (function () {
110
113
  });
111
114
  el.children('.dropdown_button').removeClass('querying'); // css class is set, hence gif gets pre-loaded
112
115
 
113
- // For local full_data finds matching rows and shows them.
114
- function digest(input_text) {
115
- var narrowed_list = w.full_data;
116
- if (input_text && input_text!=='') {
117
- input_text = input_text.toLowerCase();
118
- narrowed_list = $(narrowed_list[0].cloneNode());
119
- w.full_data.children().each(function () {
120
- if (this.innerText.toLowerCase().indexOf(input_text)!==-1)
121
- narrowed_list.append($(this).clone());
122
- });
123
- }
124
- return narrowed_list;
125
- }
116
+ // // For local full_data finds matching rows and shows them.
117
+ // function digest(input_text) {
118
+ // var narrowed_list = w.full_data;
119
+ // if (input_text && input_text!=='') {
120
+ // input_text = input_text.toLowerCase();
121
+ // narrowed_list = $(narrowed_list[0].cloneNode());
122
+ // w.full_data.children().each(function () {
123
+ // if (this.innerText.toLowerCase().indexOf(input_text)!==-1)
124
+ // narrowed_list.append($(this).clone());
125
+ // });
126
+ // }
127
+ // return narrowed_list;
128
+ // }
126
129
 
127
130
  // Attaches a List sent by html string within Whisperer's tag. Positions it underneath the text field.
128
131
  function showList (list) {
@@ -187,8 +190,8 @@ document.AssocWhisperer = (function () {
187
190
  klass.querying = true;
188
191
  btn = w.nodes['base'].find('.dropdown_button');
189
192
  btn.addClass('querying');
190
- w.params['input'] = input || '';
191
- $.ajax(w.url, {
193
+ w.params['input'] = input;
194
+ $.ajax(w.action, {
192
195
  type: 'GET',
193
196
  dataType: 'html',
194
197
  data: w.params,
@@ -206,7 +209,6 @@ document.AssocWhisperer = (function () {
206
209
  // public interface //
207
210
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
208
211
 
209
-
210
212
  klass = Object.create(Object, {querying: {value: false, writable: true}});
211
213
 
212
214
  // Return a Whisperer instance by its data-action attribute.
@@ -214,7 +216,7 @@ document.AssocWhisperer = (function () {
214
216
  var i, w;
215
217
  for (i = 0; i < all_array.length; i += 1) {
216
218
  w = all_array[i];
217
- if (w.action===action) return w;
219
+ if (w.params['action']===action || w.action.indexOf(action)!==-1) return w;
218
220
  }
219
221
  return null;
220
222
  }
@@ -3,54 +3,29 @@ module ActionView
3
3
 
4
4
  module AssocWhispererHelper
5
5
 
6
- # Createa an association whisperer tag, that will attach javascript object to self
7
- # allowing user to select a text but stores something differend (mostly respective id).
8
- #
9
- # ==== Examples
10
- # assoc_whisperer :task, :worker, :workers, size: 25, url: '/whisp'
11
- # # => <span class="assoc_whisperer" data-action="workers" data-url="/whisp">
12
- # <input class="value_field" id="task_worker_id" name="task[worker_id]" type="hidden" value="">
13
- # <input autocomplete="off" class="text_field unfilled" id="task_worker_txt" name="task[worker_txt]" size="25" type="text" value="">
14
- # <span class="dropdown_button">▾</span></span>
15
- #
16
- # Let's say your association looks like this:
17
- #
18
- # class Task
19
- # belongs_to :worker, class_name: 'Worker', foreign_key: :manager
20
- # end
21
- # class Worker
22
- # def full_name; end
23
- # def manager_id; end
24
- # end
25
- #
26
- # assoc_whisperer :task, :worker, :workers, name: :manager, value_method: :manager_id, text_method: :full_name
27
- # # => <span class="assoc_whisperer" data-action="workers" data-url="">
28
- # <input class="value_field" id="task_manager" name="task[manager]" type="hidden" value="">
29
- # <input autocomplete="off" class="text_field unfilled" id="task_manager_txt" name="task[manager_txt]" size="12" type="text" value="">
30
- # <span class="dropdown_button">▾</span></span>
31
- #
32
- # And the 'value_field' would be filled by +manager_id+ of +worker+ associated to +task+, 'text_field' by his +full_name+
33
- #
34
- def assoc_whisperer(object_name, method, data_action, options={})
35
- raise "Helper '#assoc_whisperer' is for Rails >= 4.x. Use '#assoc_whisperer_tag' instead." if Rails::VERSION::STRING.to_i < 4
36
- wrapper_assoc_whisperer_assets
6
+ def whisperer(object_name, method, template, field_attrs={})
7
+ raise "Helper '#whisperer' cannot be used in Rails < 4.x. Use '#whisperer_tag' instead." if Rails::VERSION::STRING.to_i < 4
8
+ wrapper_whisperer_assets
37
9
 
38
- Tags::AssocWhispererField.new(object_name, method, self, data_action, options).render
10
+ Tags::AssocWhispererField.new(object_name, method, self, template, field_attrs).render
39
11
  end
40
12
 
41
- def assoc_whisperer_tag(name, data_action, options = {})
42
- wrapper_assoc_whisperer_assets
13
+ def whisperer_tag(name, template, field_attrs={})
14
+ wrapper_whisperer_assets
43
15
 
44
- template = AssocWhisperer::Template.new data_action, options
45
- content_tag :span, template.simple_tag_contents(name).html_safe, 'class' => 'assoc_whisperer',
46
- 'data-opts' => template.whisperer_options.to_json
16
+ content_tag :span, template.tag_contents(name, field_attrs).html_safe, 'class' => 'assoc_whisperer',
17
+ 'data-opts' => template.whisperer_settings.to_json
18
+ end
19
+
20
+ def whisperer_template(action, opts={})
21
+ AssocWhisperer::Template.new action, opts
47
22
  end
48
23
 
49
24
  private
50
25
 
51
- def wrapper_assoc_whisperer_assets
26
+ def wrapper_whisperer_assets
52
27
  unless @assoc_whisp_attached
53
- attach_method = AssocWhisperer.attach_assets_method
28
+ attach_method = AssocWhisperer.attach_assets
54
29
  self.send attach_method if attach_method && self.respond_to?(attach_method)
55
30
  @assoc_whisp_attached = true
56
31
  end
@@ -59,8 +34,8 @@ module ActionView
59
34
  end
60
35
 
61
36
  class FormBuilder
62
- def assoc_whisperer(method, data_action, options = {})
63
- @template.assoc_whisperer @object_name, method, data_action, objectify_options(options)
37
+ def whisperer(method, template, field_attrs={})
38
+ @template.assoc_whisperer @object_name, method, template, objectify_options(field_attrs)
64
39
  end
65
40
  end
66
41
 
@@ -3,20 +3,20 @@ module ActionView
3
3
  module Tags # :nodoc:
4
4
  class AssocWhispererField < Base # :nodoc:
5
5
 
6
- def initialize(object_name, method_name, template_object, action, options={})
7
- options[:value_method] = AssocWhisperer.def_value_method unless options.has_key? :value_method
8
- options[:text_method] = AssocWhisperer.def_text_method unless options.has_key? :text_method
6
+ def initialize(object_name, method_name, template_object, whisp_template, options={})
7
+ @whisp_template = whisp_template
9
8
  super object_name, method_name, template_object, options
10
- @template = AssocWhisperer::Template.new action, @options
11
9
  end
12
10
 
13
11
  def render
14
- contents = @template.value_field_tag value_tag_id, value_tag_name, value_tag_value
15
- contents += @template.text_field_tag text_tag_id, text_tag_name, text_tag_value, !whispered_object
16
- contents += @template.dropdown_button_tag
12
+ @whisp_template.value_text whispered_object
13
+
14
+ contents = @whisp_template.value_field_tag value_tag_id, value_tag_name
15
+ contents += @whisp_template.text_field_tag text_tag_id, text_tag_name, @options
16
+ contents += @whisp_template.dropdown_button_tag
17
17
 
18
18
  content_tag :span, contents.html_safe, 'class' => 'assoc_whisperer',
19
- 'data-opts' => @template.whisperer_options.to_json
19
+ 'data-opts' => @whisp_template.whisperer_settings.to_json
20
20
  end
21
21
 
22
22
  private
@@ -25,11 +25,6 @@ module ActionView
25
25
  @whispered_object ||= value @object
26
26
  end
27
27
 
28
- def whispered_object_attribute(method)
29
- wo = whispered_object
30
- wo.send method if wo && wo.respond_to?(method)
31
- end
32
-
33
28
  def text_tag_name
34
29
  "#{@object_name}[#{text_sanitized_method_name}]"
35
30
  end
@@ -38,18 +33,8 @@ module ActionView
38
33
  "#{sanitized_object_name}_#{text_sanitized_method_name}"
39
34
  end
40
35
 
41
- def text_tag_value
42
- text = @template.opts[:text_method]
43
- text = if text.respond_to? :call
44
- text.call whispered_object
45
- else
46
- whispered_object_attribute(text)
47
- end
48
- ERB::Util.html_escape text
49
- end
50
-
51
36
  def text_sanitized_method_name
52
- @text_sanitized_method_name ||= "#{@template.opts[:name] || @method_name}_txt".sub(/\?$/,"")
37
+ @text_sanitized_method_name ||= "#{@whisp_template.opts[:name] || @method_name}_txt".sub(/\?$/,"")
53
38
  end
54
39
 
55
40
  def value_tag_name
@@ -60,18 +45,14 @@ module ActionView
60
45
  "#{sanitized_object_name}_#{value_sanitized_method_name}"
61
46
  end
62
47
 
63
- def value_tag_value
64
- whispered_object_attribute @template.opts[:value_method]
65
- end
66
-
67
48
  def value_sanitized_method_name
68
49
  return @value_sanitized_method_name if defined? @value_sanitized_method_name
69
- wsmn = if @template.opts[:name]
70
- @template.opts[:name].to_s
50
+ name = if @whisp_template.opts[:name]
51
+ @whisp_template.opts[:name].to_s
71
52
  else
72
- "#{@method_name}_#{@template.opts[:value_method]}"
53
+ "#{@method_name}_#{@template.opts[:value]}"
73
54
  end
74
- @value_sanitized_method_name = wsmn.sub(/\?$/,"")
55
+ @value_sanitized_method_name = name.sub(/\?$/, '')
75
56
  end
76
57
 
77
58
  end
@@ -1,9 +1,9 @@
1
1
  <%
2
2
  text_method = local_assigns[:text] || :to_s
3
- val_method = local_assigns[:val] || :id
3
+ value_method = local_assigns[:value] || :id
4
4
  %>
5
5
  <div tabindex=0 class="list">
6
6
  <% @objects.each do |o| %>
7
- <div data-value="<%= o.send val_method %>"><%= o.send text_method %></div>
7
+ <div data-value="<%= o.send value_method %>"><%= o.send text_method %></div>
8
8
  <% end %>
9
9
  </div>
@@ -2,47 +2,64 @@
2
2
 
3
3
  module AssocWhisperer
4
4
  class Template
5
- attr_reader :action, :opts
5
+ attr_reader :opts
6
6
 
7
7
  def initialize(action, opts={})
8
- @action = action
8
+ @action = action[0]=='/' ? action : "#{AssocWhisperer.def_url}/#{action}"
9
9
  @opts = opts
10
10
  end
11
11
 
12
- def simple_tag_contents(input_name)
12
+ def params(params)
13
+ @params = params
14
+ self
15
+ end
16
+
17
+ def value_text(object_or_params, name=nil)
18
+ if object_or_params.is_a?(Hash) && name
19
+ @value = object_or_params[name]
20
+ @text = object_or_params["#{name}_txt"]
21
+ elsif object_or_params
22
+ value = @opts[:value] || AssocWhisperer.def_value
23
+ text = @opts[:text] || AssocWhisperer.def_text
24
+ @value = (object_or_params.send value if object_or_params.respond_to? value)
25
+ @text = (object_or_params.send text if object_or_params.respond_to? text)
26
+ else
27
+ @value = nil
28
+ @text = nil
29
+ end
30
+ self
31
+ end
32
+
33
+ def tag_contents(input_name, field_attrs={})
13
34
  input_name = input_name.to_s
14
35
  sanitized_id = input_name.dup.delete(']').gsub(/[^-a-zA-Z0-9:.]/, "_")
15
36
  text_tag_name = input_name.dup
16
37
  text_tag_name.insert (text_tag_name[-1]==']' ? -2 : -1), '_txt'
17
38
 
18
- contents = value_field_tag sanitized_id, input_name, @opts[:value]
19
- contents += text_field_tag "#{sanitized_id}_txt", text_tag_name, @opts[:text], @opts[:value].blank?
39
+ contents = value_field_tag sanitized_id, input_name
40
+ contents += text_field_tag "#{sanitized_id}_txt", text_tag_name, field_attrs
20
41
  contents + dropdown_button_tag
21
42
  end
22
43
 
23
- def whisperer_options
24
- h = {url: (@opts[:url]||AssocWhisperer.def_url), action: @action}
25
- h.merge cs: true, pre: !!@opts[:preload] if @opts[:client_side]
26
- h[:params] = @opts[:params] unless @opts[:params].blank?
44
+ def whisperer_settings
45
+ h = {action: @action}
46
+ # h[:cs] = @opts[:client_side] if @opts[:client_side]
47
+ h[:params] = @params if @params
27
48
  h
28
49
  end
29
50
 
30
- def value_field_tag(id, name, value)
31
- %(<input type="hidden" id="#{id}" name="#{name}" value="#{value}" class="value_field">)
51
+ def value_field_tag(id, name)
52
+ %(<input type="hidden" id="#{id}" name="#{name}" value="#{@value}" class="value_field">)
32
53
  end
33
54
 
34
- def text_field_tag(id, name, value, unfilled=true)
35
- opts = @opts[:text_field]
36
- if opts
37
- opts[:size] ||= 12
38
- keys_whitelist = (opts.keys & [:size, :placeholder, :maxlength, :title])
39
- opts = keys_whitelist.inject [] do |arr, k|
40
- arr << %(#{k}="#{opts[k]}")
41
- arr
42
- end
43
- opts = opts * ' '
55
+ def text_field_tag(id, name, attrs={})
56
+ attrs[:size] = 12 unless attrs.has_key? :size
57
+ keys_whitelist = (attrs.keys & [:size, :placeholder, :maxlength, :title])
58
+ attrs = keys_whitelist.inject [] do |arr, k|
59
+ arr << %(#{k}="#{attrs[k]}")
60
+ arr
44
61
  end
45
- %(<input type="text" autocomplete="off" id="#{id}" name="#{name}" value="#{value}" class="text_field#{' unfilled' if unfilled}"#{opts}>)
62
+ %(<input type="text" autocomplete="off" id="#{id}" name="#{name}" value="#{@text}" class="text_field#{' unfilled' unless @value}"#{attrs * ' '}>)
46
63
  end
47
64
 
48
65
  def dropdown_button_tag
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
  module AssocWhisperer
3
- VERSION = "1.2.1"
3
+ VERSION = "2.0.1"
4
4
 
5
5
  end
@@ -5,7 +5,7 @@ require 'assoc_whisperer/template'
5
5
  module AssocWhisperer
6
6
 
7
7
  class << self
8
- attr_accessor :def_url, :attach_assets_method, :def_value_method, :def_text_method
8
+ attr_accessor :def_url, :attach_assets, :def_value, :def_text
9
9
  end
10
10
 
11
11
  module Rails
@@ -13,23 +13,10 @@ module AssocWhisperer
13
13
  end
14
14
  end
15
15
 
16
- def self.value_field_html(id, name, value)
17
- %(<input type="hidden" id="#{id}" name="#{name}" value="#{value}" class="value_field">)
18
- end
19
-
20
- def self.text_field_html(id, name, value, unfilled=true, opts={})
21
- opts = opts.keys.inject([]){|arr, k| arr << %(#{k}="#{opts[k]}"); arr }*' '
22
- %(<input type="text" id="#{id}" name="#{name}" value="#{value} class="text_field#{' unfilled' if unfilled}"#{opts}>)
23
- end
24
-
25
- def self.dropdown_button_html
26
- @dropdown_button_html ||= "<span class=\"dropdown_button\">\u25BE</span>"
27
- end
28
-
29
16
  end
30
17
 
31
18
  AssocWhisperer.def_url = '/whisp'
32
- AssocWhisperer.attach_assets_method = :attach_assoc_whisperer_assets
19
+ AssocWhisperer.attach_assets = :attach_whisperer_assets
33
20
 
34
- AssocWhisperer.def_value_method = :id
35
- AssocWhisperer.def_text_method = :to_s
21
+ AssocWhisperer.def_value = :id
22
+ AssocWhisperer.def_text = :to_s
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: assoc_whisperer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ondřej Želazko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-31 00:00:00.000000000 Z
11
+ date: 2014-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler