bc-htmlful 0.0.1 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
});
|