bc-htmlful 0.0.1 → 0.0.5
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.
- data/README +2 -0
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/bc-htmlful.gemspec +6 -5
- data/javascripts/dynamic-fields.js +82 -0
- data/javascripts/{dynamic_fields.prototype.js → dynamic-fields.prototype.js} +18 -11
- data/lib/htmlful/dynamic_fields.rb +75 -4
- data/lib/htmlful.rb +1 -0
- data/rails/init.rb +1 -0
- data/tasks/htmlful.rake +12 -0
- metadata +5 -4
- data/javascripts/dynamic_fields.js +0 -56
data/README
CHANGED
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.5
|
data/bc-htmlful.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{bc-htmlful}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.5"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Duarte Henriques", "Vasco Andrade e Silva"]
|
12
|
-
s.date = %q{2010-02-
|
12
|
+
s.date = %q{2010-02-26}
|
13
13
|
s.description = %q{Form dynamic fields}
|
14
14
|
s.email = %q{info@byclosure.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -21,12 +21,13 @@ Gem::Specification.new do |s|
|
|
21
21
|
"Rakefile",
|
22
22
|
"VERSION",
|
23
23
|
"bc-htmlful.gemspec",
|
24
|
-
"javascripts/
|
25
|
-
"javascripts/
|
24
|
+
"javascripts/dynamic-fields.js",
|
25
|
+
"javascripts/dynamic-fields.prototype.js",
|
26
26
|
"lib/htmlful.rb",
|
27
27
|
"lib/htmlful/dynamic_fields.rb",
|
28
28
|
"rails/init.rb",
|
29
|
-
"stylesheets/dynamic_fields.sass"
|
29
|
+
"stylesheets/dynamic_fields.sass",
|
30
|
+
"tasks/htmlful.rake"
|
30
31
|
]
|
31
32
|
s.homepage = %q{http://github.com/Byclosure/}
|
32
33
|
s.rdoc_options = ["--charset=UTF-8"]
|
@@ -0,0 +1,82 @@
|
|
1
|
+
$(function() {
|
2
|
+
$('input[type="hidden"]').addClass('hide');
|
3
|
+
// buttons UI
|
4
|
+
$('.create_element').addClass('ui-state-default ui-corner-all').hover(function() {
|
5
|
+
$(this).addClass("ui-state-hover");
|
6
|
+
}, function() {
|
7
|
+
$(this).removeClass("ui-state-hover");
|
8
|
+
}).mousedown(function() {
|
9
|
+
$(this).addClass("ui-state-active");
|
10
|
+
}).mouseup(function() {
|
11
|
+
$(this).removeClass("ui-state-active");
|
12
|
+
});
|
13
|
+
// make sure something is submitted even if no option is selected
|
14
|
+
$('li.select select[multiple="multiple"]').each(function() {
|
15
|
+
$(this).parent().append($('<input type="hidden" />').attr({name: this.name}));
|
16
|
+
});
|
17
|
+
// allow users to clear multi-select without requiring them to ctrl-click
|
18
|
+
$('a.clear_multi_select').click(function(event) {
|
19
|
+
if (event.which != 3) {
|
20
|
+
$(this).parents('li').prev().find('select').val(null);
|
21
|
+
return false;
|
22
|
+
}
|
23
|
+
return true;
|
24
|
+
});
|
25
|
+
// allow removal of documents in forms
|
26
|
+
$('.delete_document').click(function(event) {
|
27
|
+
if (event.which != 3) {
|
28
|
+
var classNames = this.className.split(/\s+/);
|
29
|
+
var index = $.inArray('delete_document', classNames);
|
30
|
+
var name = classNames[index+1] + '[delete_' + classNames[index+2] + ']';
|
31
|
+
$(this).parent().prev().append($('<input type="hidden" />').attr({name: name}).val(1));
|
32
|
+
$(this).parent().hide('blind');
|
33
|
+
return false;
|
34
|
+
}
|
35
|
+
return true;
|
36
|
+
});
|
37
|
+
// dynamic fields
|
38
|
+
$('.remove_fieldset').live('click', function(event) {
|
39
|
+
if (event.which != 3) {
|
40
|
+
$(this).parent().prev().find('input[type=hidden]').val(1);
|
41
|
+
$($(this).closest('fieldset')).hide('blind');
|
42
|
+
return false;
|
43
|
+
}
|
44
|
+
return true;
|
45
|
+
});
|
46
|
+
$('form div.new_nested_element').each(function() {
|
47
|
+
var create_button = $(this).children('a.create_element');
|
48
|
+
var remove_button = $(this).children('a.remove_element').remove();
|
49
|
+
var fragment = $($(this).find('fieldset')[0]).remove();
|
50
|
+
var remove_button_function = function(event) {
|
51
|
+
if (event.which != 3) {
|
52
|
+
$($(this).closest('fieldset')).hide('blind', {}, 1000, function(){$(this).remove();});
|
53
|
+
return false;
|
54
|
+
}
|
55
|
+
return true;
|
56
|
+
}
|
57
|
+
create_button.click(function(event) {
|
58
|
+
var new_fragment = fragment.clone().hide();
|
59
|
+
|
60
|
+
var new_remove_button = remove_button.clone();
|
61
|
+
new_remove_button.click(remove_button_function);
|
62
|
+
|
63
|
+
var nested_inputs = $(this).parent().children('div.nested_inputs');
|
64
|
+
nested_inputs.append(new_fragment);
|
65
|
+
|
66
|
+
// this is a necessary hack for rails http://groups.google.com.au/group/formtastic/browse_thread/thread/9358a13bd26a6108
|
67
|
+
var unique_id = new Date().getTime();
|
68
|
+
new_fragment.find('input,select,textarea').each(function() {
|
69
|
+
this.id = this.id && this.id.replace(/NEW_RECORD/, unique_id);
|
70
|
+
this.name = this.name && this.name.replace(/NEW_RECORD/, unique_id);
|
71
|
+
});
|
72
|
+
new_fragment.find('label').each(function() {
|
73
|
+
this.htmlFor = this.htmlFor && this.htmlFor.replace(/NEW_RECORD/, unique_id);
|
74
|
+
});
|
75
|
+
|
76
|
+
$($(this).closest('form')).trigger('element-added', new_fragment);
|
77
|
+
new_fragment.append(new_remove_button);
|
78
|
+
new_fragment.show('blind');
|
79
|
+
return false;
|
80
|
+
});
|
81
|
+
});
|
82
|
+
});
|
@@ -1,31 +1,38 @@
|
|
1
|
-
//
|
1
|
+
// WARNING: not up-to-date
|
2
2
|
document.observe('click', function(event) {
|
3
3
|
if (element = event.findElement('.remove_fieldset')) {
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
// IE is not recognizing left click, but it's OK because it handles right clicks itself
|
5
|
+
if (Prototype.Browser.IE || event.isLeftClick()) {
|
6
|
+
element.up().previous().down('input[type=hidden]').value = 1;
|
7
|
+
element.up('fieldset').hide();
|
8
|
+
event.stop();
|
9
|
+
}
|
7
10
|
}
|
8
11
|
});
|
12
|
+
|
9
13
|
$$('form div.new_nested_element').each(function(element) {
|
10
14
|
var create_button = element.down('a.create_element');
|
11
15
|
var remove_button = element.down('a.remove_element').remove();
|
12
16
|
var fragment = element.down('fieldset').remove();
|
13
17
|
var remove_button_function = function(event) {
|
14
|
-
|
15
|
-
event.
|
18
|
+
// IE is not recognizing left click, but it's OK because it handles right clicks itself
|
19
|
+
if (Prototype.Browser.IE || event.isLeftClick()) {
|
20
|
+
this.up('fieldset').remove();
|
21
|
+
event.stop();
|
22
|
+
}
|
16
23
|
}
|
17
24
|
create_button.observe('click', function(event) {
|
18
25
|
var new_fragment = fragment.cloneNode(true);
|
19
|
-
|
26
|
+
|
20
27
|
var new_remove_button = remove_button.cloneNode(true);
|
21
28
|
new_remove_button.observe('click', remove_button_function);
|
22
|
-
|
23
|
-
var nested_inputs = create_button.
|
29
|
+
|
30
|
+
var nested_inputs = create_button.up().down('div.nested_inputs');
|
24
31
|
nested_inputs.insert(new_fragment);
|
25
|
-
|
32
|
+
|
26
33
|
// this is a necessary hack for rails http://groups.google.com.au/group/formtastic/browse_thread/thread/9358a13bd26a6108
|
27
34
|
var unique_id = new Date().getTime();
|
28
|
-
new_fragment.select('input').each(function(e) {
|
35
|
+
new_fragment.select('input,select,textarea').each(function(e) {
|
29
36
|
e.id = e.id && e.id.gsub(/NEW_RECORD/, unique_id);
|
30
37
|
e.name = e.name && e.name.gsub(/NEW_RECORD/, unique_id);
|
31
38
|
});
|
@@ -1,13 +1,14 @@
|
|
1
1
|
module Htmlful
|
2
2
|
module DynamicFields
|
3
3
|
def _dynamic_fields(form, resource, relationship_name, block1, block2)
|
4
|
+
relationship_i18n_name = resource.class.human_attribute_name(relationship_name).to_s
|
4
5
|
form.inputs :title => relationship_name do
|
5
6
|
unless resource.send(relationship_name).empty?
|
6
7
|
form.semantic_fields_for(relationship_name) do |sub_form|
|
7
8
|
sub_form.inputs do
|
8
9
|
block1.call(sub_form)
|
9
10
|
concat sub_form.input(:_delete, :as => :hidden, :wrapper_html => {:class => 'remove'}, :input_html => {:class => "checkbox_remove"})
|
10
|
-
concat content_tag(:li, link_to(t(:remove_nested_element, :resource_name =>
|
11
|
+
concat content_tag(:li, link_to(t(:remove_nested_element, :resource_name => relationship_i18n_name), '#', :class => "remove_fieldset"))
|
11
12
|
end
|
12
13
|
end
|
13
14
|
end
|
@@ -19,7 +20,6 @@ module Htmlful
|
|
19
20
|
end
|
20
21
|
end
|
21
22
|
}
|
22
|
-
relationship_i18n_name = resource.class.human_attribute_name(relationship_name).to_s
|
23
23
|
concat link_to(t(:remove_nested_element, :resource_name => relationship_i18n_name), '#', :class => "remove_element")
|
24
24
|
concat link_to(t(:create_nested_element, :resource_name => relationship_i18n_name), "#", :class => "create_element")
|
25
25
|
}
|
@@ -63,7 +63,7 @@ module Htmlful
|
|
63
63
|
def show_dynamic_fields(form, resource, relationship_name, *attributes)
|
64
64
|
form.inputs :title => relationship_name do
|
65
65
|
if resource.send(relationship_name).empty?
|
66
|
-
concat t(:no_resource_name_plural, :resource_name_plural => resource.class.
|
66
|
+
concat t(:no_resource_name_plural, :resource_name_plural => resource.class.human_attribute_name(relationship_name, :count => 2).mb_chars.downcase)
|
67
67
|
else
|
68
68
|
form.semantic_fields_for(relationship_name) do |sub_form|
|
69
69
|
sub_form.inputs do
|
@@ -76,6 +76,27 @@ module Htmlful
|
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
+
# TODO: use concat and usage will be nicer
|
80
|
+
def show_attribute_outside_form(resource, attribute, options=nil, &block)
|
81
|
+
if is_date(resource, attribute)
|
82
|
+
resource.send(attribute) # TODO: add the controversial abbr method here, or just use title
|
83
|
+
elsif is_document(resource, attribute)
|
84
|
+
if is_document_empty?(resource, attribute)
|
85
|
+
t(:no_document)
|
86
|
+
else
|
87
|
+
if is_image(resource, attribute)
|
88
|
+
image_style = (options.nil? || options[:image_style].nil?)? :thumb : options[:image_style]
|
89
|
+
image_tag(resource.send(attribute).url(image_style))
|
90
|
+
else
|
91
|
+
link_to(resource.send("#{attribute}_file_name"), resource.send(attribute).url)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
else
|
95
|
+
yield
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# inside of a form
|
79
100
|
def show_attribute(form, resource, attribute)
|
80
101
|
if is_date(resource, attribute)
|
81
102
|
form.input(attribute, :as => :string, :wrapper_html => {:class => 'datepick'}, :input_html => {:disabled => true})
|
@@ -101,7 +122,7 @@ module Htmlful
|
|
101
122
|
|
102
123
|
def show_subcollection(form, resource, association)
|
103
124
|
collection = resource.send(association)
|
104
|
-
resource_name_plural = resource.class.reflect_on_association(association.to_sym).klass.human_name(:count => 2)
|
125
|
+
resource_name_plural = localized_attribute_string(resource, association.to_sym)#resource.class.reflect_on_association(association.to_sym).klass.human_name(:count => 2)
|
105
126
|
content_tag(:label, resource_name_plural) +
|
106
127
|
if collection.empty?
|
107
128
|
content_tag(:p, I18n.t(:no_resource_name_plural, :resource_name_plural => resource_name_plural.mb_chars.downcase))
|
@@ -111,8 +132,58 @@ module Htmlful
|
|
111
132
|
}, :class => "sub-collection")
|
112
133
|
end
|
113
134
|
end
|
135
|
+
|
136
|
+
def multi_select_input(form, association, options={})
|
137
|
+
form.input(association, options) + content_tag(:li, content_tag(:div, link_to(t(:clear_selected), "#", :class => "clear_multi_select"), :class => "clear_multi_select"))
|
138
|
+
end
|
139
|
+
|
140
|
+
def form_inputs(form, *attributes)
|
141
|
+
options = attributes.extract_options!
|
142
|
+
resource = form.object
|
143
|
+
returning("") do |html|
|
144
|
+
attributes.each do |attribute|
|
145
|
+
html << form.input(attribute)
|
146
|
+
if is_document(resource, attribute)
|
147
|
+
unless is_document_empty?(resource, attribute)
|
148
|
+
html << "<li>"
|
149
|
+
if is_image(resource, attribute)
|
150
|
+
image_style = (options.nil? || options[:image_style].nil?)? :thumb : options[:image_style]
|
151
|
+
html << image_tag(form.object.send(attribute).url(image_style))
|
152
|
+
else
|
153
|
+
html << link_to(sub_object.send("#{attribute}_file_name"), resource.send(attribute).url)
|
154
|
+
end
|
155
|
+
html << content_tag(:br)
|
156
|
+
html << content_tag(:a, t(:delete_resource, :resource => resource.class.human_attribute_name(attribute)), :href => "#", :class => "delete_document #{resource.class.name.underscore} #{attribute}")
|
157
|
+
html << "</li>"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
114
163
|
|
115
164
|
protected
|
165
|
+
|
166
|
+
## copied and adapted from formtastic
|
167
|
+
def localized_attribute_string(resource, attr_name)
|
168
|
+
model_name = resource.class.name.underscore
|
169
|
+
action_name = template.params[:action].to_s rescue ''
|
170
|
+
attribute_name = attr_name.to_s
|
171
|
+
|
172
|
+
i18n_scopes = ['{{model}}.{{action}}.{{attribute}}', '{{model}}.{{attribute}}', '{{attribute}}']
|
173
|
+
defaults = i18n_scopes.collect do |i18n_scope|
|
174
|
+
i18n_path = i18n_scope.dup
|
175
|
+
i18n_path.gsub!('{{action}}', action_name)
|
176
|
+
i18n_path.gsub!('{{model}}', model_name)
|
177
|
+
i18n_path.gsub!('{{attribute}}', attribute_name)
|
178
|
+
i18n_path.gsub!('..', '.')
|
179
|
+
i18n_path.to_sym
|
180
|
+
end
|
181
|
+
defaults << ''
|
182
|
+
|
183
|
+
i18n_value = ::I18n.t(defaults.shift, :default => defaults, :scope => "formtastic.labels")
|
184
|
+
i18n_value.blank? ? nil : i18n_value
|
185
|
+
end
|
186
|
+
|
116
187
|
def is_date(resource, attribute)
|
117
188
|
col = resource.column_for_attribute(attribute)
|
118
189
|
col && col.type == :date
|
data/lib/htmlful.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/htmlful/dynamic_fields"
|
data/rails/init.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
puts "Please run rake htmlful:update:javascript, with an appropriate FRAMEWORK env variable" unless File.exist?("#{Rails.root}/public/javascripts/dynamic-fields.js")
|
data/tasks/htmlful.rake
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
namespace :htmlful do
|
2
|
+
namespace :update do
|
3
|
+
desc "Update htmlful javascript from the gem source. Use FRAMEWORK=prototype for prototype version"
|
4
|
+
task :javascript do
|
5
|
+
if ENV["FRAMEWORK"] == "prototype"
|
6
|
+
`cp #{File.basedir(__FILE__)}/../javascripts/dynamic-fields.prototype.js #{Rails.root}/public/javascripts/dynamic-fields.js`
|
7
|
+
else
|
8
|
+
`cp #{File.basedir(__FILE__)}/../javascripts/dynamic-fields.js #{Rails.root}/public/javascripts`
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bc-htmlful
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Duarte Henriques
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2010-02-
|
13
|
+
date: 2010-02-26 00:00:00 +00:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|
@@ -28,12 +28,13 @@ files:
|
|
28
28
|
- Rakefile
|
29
29
|
- VERSION
|
30
30
|
- bc-htmlful.gemspec
|
31
|
-
- javascripts/
|
32
|
-
- javascripts/
|
31
|
+
- javascripts/dynamic-fields.js
|
32
|
+
- javascripts/dynamic-fields.prototype.js
|
33
33
|
- lib/htmlful.rb
|
34
34
|
- lib/htmlful/dynamic_fields.rb
|
35
35
|
- rails/init.rb
|
36
36
|
- stylesheets/dynamic_fields.sass
|
37
|
+
- tasks/htmlful.rake
|
37
38
|
has_rdoc: true
|
38
39
|
homepage: http://github.com/Byclosure/
|
39
40
|
licenses: []
|
@@ -1,56 +0,0 @@
|
|
1
|
-
$('input[type="hidden"]').addClass('hide');
|
2
|
-
// buttons UI
|
3
|
-
$('.create_element').addClass('ui-state-default ui-corner-all').hover(function() {
|
4
|
-
$(this).addClass("ui-state-hover");
|
5
|
-
}, function() {
|
6
|
-
$(this).removeClass("ui-state-hover");
|
7
|
-
}).mousedown(function() {
|
8
|
-
$(this).addClass("ui-state-active");
|
9
|
-
}).mouseup(function() {
|
10
|
-
$(this).removeClass("ui-state-active");
|
11
|
-
});
|
12
|
-
|
13
|
-
$('.remove_fieldset').live('click', function(event) {
|
14
|
-
if (event.which != 3) {
|
15
|
-
$(this).parent().prev().find('input[type=hidden]').val(1);
|
16
|
-
$($(this).closest('fieldset')).hide('blind');
|
17
|
-
return false;
|
18
|
-
}
|
19
|
-
return true;
|
20
|
-
});
|
21
|
-
$('form div.new_nested_element').each(function() {
|
22
|
-
var create_button = $(this).children('a.create_element');
|
23
|
-
var remove_button = $(this).children('a.remove_element').remove();
|
24
|
-
var fragment = $($(this).find('fieldset')[0]).remove();
|
25
|
-
var remove_button_function = function(event) {
|
26
|
-
if (event.which != 3) {
|
27
|
-
$($(this).closest('fieldset')).hide('blind', {}, 1000, function(){$(this).remove();});
|
28
|
-
return false;
|
29
|
-
}
|
30
|
-
return true;
|
31
|
-
}
|
32
|
-
create_button.click(function(event) {
|
33
|
-
var new_fragment = fragment.clone().hide();
|
34
|
-
|
35
|
-
var new_remove_button = remove_button.clone();
|
36
|
-
new_remove_button.click(remove_button_function);
|
37
|
-
|
38
|
-
var nested_inputs = $(this).parent().children('div.nested_inputs');
|
39
|
-
nested_inputs.append(new_fragment);
|
40
|
-
|
41
|
-
// this is a necessary hack for rails http://groups.google.com.au/group/formtastic/browse_thread/thread/9358a13bd26a6108
|
42
|
-
var unique_id = new Date().getTime();
|
43
|
-
new_fragment.find('input').each(function() {
|
44
|
-
this.id = this.id && this.id.replace(/NEW_RECORD/, unique_id);
|
45
|
-
this.name = this.name && this.name.replace(/NEW_RECORD/, unique_id);
|
46
|
-
});
|
47
|
-
new_fragment.find('label').each(function() {
|
48
|
-
this.htmlFor = this.htmlFor && this.htmlFor.replace(/NEW_RECORD/, unique_id);
|
49
|
-
});
|
50
|
-
|
51
|
-
$($(this).closest('form')).trigger('element-added', new_fragment);
|
52
|
-
new_fragment.append(new_remove_button);
|
53
|
-
new_fragment.show('blind');
|
54
|
-
return false;
|
55
|
-
});
|
56
|
-
});
|