x-editable-rails 1.5.1 → 1.5.5.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: f211902f307559fafdeb55542265063b6aed1b74
4
- data.tar.gz: b01c23c18a006cd2079bf562621df7774830942c
3
+ metadata.gz: fee9739c77324495b6e7a6227d85fdb2f77c972b
4
+ data.tar.gz: fd6565d1908e346778674f1f42f95f235c335f01
5
5
  SHA512:
6
- metadata.gz: 9fe4a918b0d2e3da58d6105c8646f757780855011bd347c814d3b7b073abb6d6e40b77d52dc7dde206fb7d3d61b1d792b28ddc9521605ceeac297c4e8fd90842
7
- data.tar.gz: da69e8902b82d4f9fe578e02a9bb2f2e8b17598a346168b198cd2dc57f8cac572406bdf90436a6f15290c490bbd9f2b547943fc35000b46f661fa2aa8d4c21fa
6
+ metadata.gz: 5d3c95a332e7da5252af57f86fb0ae39d171566d7f616b09f9d691073fbd1051e64b53e35ff9f13dbd124f57b55901e2a2cbc3295451749f1a2997627b55ff05
7
+ data.tar.gz: d43ebe0f3957a31e1c8c6476494f869f37bd456af8878d4993363130de8b41795df1dd9012ed1948e32c1ba74fdad34af06085062a03a4e46368d0b703a6740a
data/README.md CHANGED
@@ -1,7 +1,13 @@
1
1
  # X::Editable::Rails
2
2
 
3
+ [![Build Status](https://travis-ci.org/werein/x-editable-rails.svg)](https://travis-ci.org/werein/x-editable-rails) [![Code Climate](https://codeclimate.com/github/werein/x-editable-rails/badges/gpa.svg)](https://codeclimate.com/github/werein/x-editable-rails) [![Test coverage](https://codeclimate.com/github/werein/x-editable-rails/badges/coverage.svg)](https://codeclimate.com/github/werein/x-editable-rails) [![Version](https://badge.fury.io/rb/x-editable-rails.svg)](https://badge.fury.io/rb/x-editable-rails) [![Dependencies](https://gemnasium.com/werein/x-editable-rails.svg)](https://gemnasium.com/werein/x-editable-rails)
4
+
3
5
  X-editable for Rails
4
6
 
7
+ ## Live demo
8
+
9
+ Checkout live demo [here](https://x-editable-rails.herokuapp.com/?denied=true)
10
+
5
11
  ## Installation
6
12
 
7
13
  Add this line to your application's Gemfile:
@@ -75,8 +81,8 @@ And related stylesheets:
75
81
 
76
82
  ### Making Things Editable
77
83
 
78
- `x-editable-rails` provides a helper method in your view to make your model values editable.
79
- By default, you need to specify the model and property that should be editable.
84
+ `x-editable-rails` provides a helper method in your view to make your model values editable.
85
+ By default, you need to specify the model and property that should be editable.
80
86
  A `span` element is rendered with `data-*` attributes used by `x-editable`.
81
87
 
82
88
  ```ruby
@@ -120,7 +126,7 @@ classes = { "Active" => "label-success", "Disabled" => "label-default" }
120
126
  editable @model, :enabled, source: source, classes: classes, class: "label"
121
127
  ```
122
128
 
123
- * **nested** - Name of a nested attributes (such as [gobalize](https://github.com/globalize/globalize)'s `translations`)
129
+ * **nested** - Name of a nested attributes (such as [globalize](https://github.com/globalize/globalize)'s `translations`)
124
130
  * **nid** - ID of the nested attribute
125
131
 
126
132
  ```ruby
@@ -135,18 +141,16 @@ editable @model, :enabled, source: source, classes: classes, class: "label"
135
141
  Add a helper method to your controllers to indicate if `x-editable` should be enabled.
136
142
 
137
143
  ```ruby
138
- def xeditable?
144
+ def xeditable? object = nil
139
145
  true # Or something like current_user.xeditable?
140
146
  end
141
147
  ```
142
148
 
143
- This gem requires [CanCan](https://github.com/ryanb/cancan) and checks the `:edit` permission for the model being edited.
149
+ You can use [CanCan](https://github.com/ryanb/cancan) and checks the `:edit` permission for the model being edited.
144
150
 
145
151
  ```ruby
146
- if xeditable? && can?(:edit, model)
147
- ... output x-editable HTML ...
148
- else
149
- ... output uneditable value ...
152
+ def xeditable? object = nil
153
+ can?(:edit, object) ? true : false
150
154
  end
151
155
  ```
152
156
 
@@ -154,14 +158,14 @@ end
154
158
 
155
159
  ### "Don't Repeat Yourself" Templates
156
160
 
157
- To make your views cleaner, you can specify all your options for each class and attribute in a YAML configuration file.
161
+ To make your views cleaner, you can specify all your options for each class and attribute in a YAML configuration file.
158
162
  Attributes where the `title` or `placeholder` are not different except maybe capitalized can be left out because they are automatically capitalized when rendered (see above).
159
163
 
160
- This example uses the `MailingList` class and its attributes.
161
- The attribute value can be a string, which is used as the `title` and `placeholder`.
164
+ This example uses the `MailingList` class and its attributes.
165
+ The attribute value can be a string, which is used as the `title` and `placeholder`.
162
166
  If you want to specify other options, create a hash of options.
163
167
 
164
- Install configuration file like this: `rails g x_editable_rails:install`, this step is not necessary
168
+ Install configuration file like this: `rails g x_editable_rails:install`, this step is not necessary
165
169
 
166
170
  ```yaml
167
171
  class_options:
@@ -1,7 +1,7 @@
1
1
  module X
2
2
  module Editable
3
3
  module Rails
4
- VERSION = "1.5.1"
4
+ VERSION = "1.5.5.1"
5
5
  end
6
6
  end
7
- end
7
+ end
@@ -1,3 +1,5 @@
1
+ require 'base64'
2
+
1
3
  module X
2
4
  module Editable
3
5
  module Rails
@@ -16,63 +18,86 @@ module X
16
18
  # - enumerable shorthand ['Yes', 'No', 'Maybe'] becomes { 'Yes' => 'Yes', 'No' => 'No', 'Maybe' => 'Maybe' }
17
19
  # classes: a Hash of classes to add based on the value (same format and shorthands as source)
18
20
  # value: override the object's value
19
- #
21
+ #
20
22
  def editable(object, method, options = {})
21
23
  options = Configuration.method_options_for(object, method).deep_merge(options).with_indifferent_access
22
24
  # merge data attributes for backwards-compatibility
23
25
  options.merge! options.delete(:data){ Hash.new }
24
-
26
+
25
27
  url = options.delete(:url){ polymorphic_path(object) }
26
28
  object = object.last if object.kind_of?(Array)
27
29
  value = options.delete(:value){ object.send(method) }
28
30
  source = options[:source] ? format_source(options.delete(:source), value) : default_source_for(value)
29
31
  classes = format_source(options.delete(:classes), value)
30
32
  error = options.delete(:e)
31
-
32
- if xeditable? and can?(:edit, object)
33
- model = object.class.name.split('::').last.underscore
33
+ html_options = options.delete(:html){ Hash.new }
34
+
35
+ if xeditable?(object)
36
+ model = object.class.model_name.param_key
34
37
  nid = options.delete(:nid)
35
38
  nested = options.delete(:nested)
36
39
  title = options.delete(:title) do
37
- klass = nested ? object.class.const_get(nested.to_s.singularize.capitalize) : object.class
40
+ klass = nested ? object.class.const_get(nested.to_s.classify) : object.class
38
41
  klass.human_attribute_name(method)
39
42
  end
40
-
43
+
41
44
  output_value = output_value_for(value)
42
- css_list = options.delete(:class).to_s.split(/s+/).unshift('editable')
45
+ css_list = options.delete(:class).to_s.split(/\s+/).unshift('editable')
43
46
  css_list << classes[output_value] if classes
44
-
47
+ type = options.delete(:type){ default_type_for(value) }
45
48
  css = css_list.compact.uniq.join(' ')
46
49
  tag = options.delete(:tag){ 'span' }
47
50
  placeholder = options.delete(:placeholder){ title }
48
-
51
+
49
52
  # any remaining options become data attributes
50
53
  data = {
51
- type: options.delete(:type){ default_type_for(value) },
52
- model: model,
53
- name: method,
54
- value: output_value,
55
- placeholder: placeholder,
56
- classes: classes,
57
- source: source,
58
- url: url,
59
- nested: nested,
54
+ type: type,
55
+ model: model,
56
+ name: method,
57
+ value: ( type == 'wysihtml5' ? Base64.encode64(output_value) : output_value ),
58
+ placeholder: placeholder,
59
+ classes: classes,
60
+ source: source,
61
+ url: url,
62
+ nested: nested,
60
63
  nid: nid
61
- }.merge(options)
62
-
64
+ }.merge(options.symbolize_keys)
65
+
63
66
  data.reject!{|_, value| value.nil?}
64
-
65
- content_tag tag, class: css, title: title, data: data do
66
- source_values_for(value, source).join('<br/>').html_safe
67
+
68
+ html_options.update({
69
+ class: css,
70
+ title: title,
71
+ data: data
72
+ })
73
+
74
+ content_tag tag, html_options do
75
+ if %w(select checklist).include?(data[:type].to_s) && !source.is_a?(String)
76
+ source = normalize_source(source)
77
+ content = source.detect { |t| output_value == output_value_for(t[0]) }
78
+ content.present? ? content[1] : ""
79
+ else
80
+ safe_join(source_values_for(value, source), tag(:br))
81
+ end
67
82
  end
68
83
  else
69
- # create a friendly value using the source to display a default value (if no error message given)
70
- error || source_values_for(value, source).join('<br/>').html_safe
84
+ error || safe_join(source_values_for(value, source), tag(:br))
71
85
  end
72
86
  end
73
-
87
+
74
88
  private
75
-
89
+
90
+ def normalize_source(source)
91
+ return [] unless source
92
+ source.map do |el|
93
+ if el.is_a? Array
94
+ el
95
+ else
96
+ [el[:value], el[:text]]
97
+ end
98
+ end
99
+ end
100
+
76
101
  def output_value_for(value)
77
102
  value = case value
78
103
  when TrueClass
@@ -86,22 +111,22 @@ module X
86
111
  else
87
112
  value.to_s
88
113
  end
89
-
90
- value.html_safe
114
+
115
+ value
91
116
  end
92
-
117
+
93
118
  def source_values_for(value, source = nil)
94
119
  source ||= default_source_for value
95
-
120
+
96
121
  values = Array.wrap(value)
97
-
98
- if source
122
+
123
+ if source && ( source.first.is_a?(String) || source.kind_of?(Hash) )
99
124
  values.map{|item| source[output_value_for item]}
100
125
  else
101
126
  values
102
127
  end
103
128
  end
104
-
129
+
105
130
  def default_type_for(value)
106
131
  case value
107
132
  when TrueClass, FalseClass
@@ -112,14 +137,14 @@ module X
112
137
  'text'
113
138
  end
114
139
  end
115
-
140
+
116
141
  def default_source_for(value)
117
142
  case value
118
143
  when TrueClass, FalseClass
119
144
  { '1' => 'Yes', '0' => 'No' }
120
145
  end
121
146
  end
122
-
147
+
123
148
  # helper method that take some shorthand source definitions and reformats them
124
149
  def format_source(source, value)
125
150
  formatted_source = case value
@@ -127,15 +152,15 @@ module X
127
152
  if source.is_a?(Array) && source.first.is_a?(String) && source.size == 2
128
153
  { '1' => source[0], '0' => source[1] }
129
154
  end
130
- when String
155
+ else
131
156
  if source.is_a?(Array) && source.first.is_a?(String)
132
- source.inject({}){|hash, key| hash.merge(key => key)}
157
+ source.map { |v| { value: v, text: v } }
133
158
  end
134
159
  end
135
-
160
+
136
161
  formatted_source || source
137
162
  end
138
-
163
+
139
164
  end
140
165
  end
141
166
  end