record_collection 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +217 -0
- data/Rakefile +16 -0
- data/app/assets/images/record_collection/.keep +0 -0
- data/app/assets/javascripts/record_collection/application.js.coffee +1 -0
- data/app/assets/javascripts/record_collection/multi_select.js.coffee +66 -0
- data/app/assets/javascripts/record_collection/optionals.js.coffee +101 -0
- data/app/assets/stylesheets/record_collection/application.css +15 -0
- data/app/assets/stylesheets/record_collection/multi_select.css.sass +20 -0
- data/app/assets/stylesheets/record_collection/optionals.css.sass +48 -0
- data/app/controllers/record_collection/application_controller.rb +4 -0
- data/app/helpers/record_collection/application_helper.rb +4 -0
- data/app/views/layouts/record_collection/application.html.erb +14 -0
- data/lib/record_collection.rb +12 -0
- data/lib/record_collection/base.rb +98 -0
- data/lib/record_collection/engine.rb +5 -0
- data/lib/record_collection/name.rb +7 -0
- data/lib/record_collection/rails/form_options_helper.rb +48 -0
- data/lib/record_collection/rails/routes.rb +21 -0
- data/lib/record_collection/version.rb +3 -0
- data/record_collection.gemspec +43 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js.coffee +10 -0
- data/spec/dummy/app/assets/stylesheets/application.css.sass +4 -0
- data/spec/dummy/app/assets/stylesheets/components/_forms.css.sass +0 -0
- data/spec/dummy/app/assets/stylesheets/components/_structure.css.sass +0 -0
- data/spec/dummy/app/assets/stylesheets/scaffolds.scss +69 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/controllers/employees_controller.rb +75 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/models/employee.rb +2 -0
- data/spec/dummy/app/models/employee/collection.rb +6 -0
- data/spec/dummy/app/models/project.rb +2 -0
- data/spec/dummy/app/views/application/_form_errors.html.slim +8 -0
- data/spec/dummy/app/views/employees/_form.html.erb +25 -0
- data/spec/dummy/app/views/employees/batch_actions.html.slim +13 -0
- data/spec/dummy/app/views/employees/edit.html.erb +6 -0
- data/spec/dummy/app/views/employees/index.html.slim +25 -0
- data/spec/dummy/app/views/employees/new.html.erb +5 -0
- data/spec/dummy/app/views/employees/show.html.erb +14 -0
- data/spec/dummy/app/views/layouts/application.html.slim +10 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +29 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +26 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +41 -0
- data/spec/dummy/config/environments/production.rb +79 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/locales/models.en.yml +5 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/db/migrate/20150203124634_create_employees.rb +10 -0
- data/spec/dummy/db/migrate/20150204103712_add_vegan_to_employees.rb +5 -0
- data/spec/dummy/db/migrate/20150204103925_add_admin_to_employees.rb +5 -0
- data/spec/dummy/db/migrate/20150204125014_create_projects.rb +11 -0
- data/spec/dummy/db/schema.rb +33 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/features/multi_select_spec.rb +23 -0
- data/spec/fixtures/collections.rb +0 -0
- data/spec/record_selection/base_spec.rb +113 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/validations_spec.rb +19 -0
- metadata +482 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any styles
|
10
|
+
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
|
11
|
+
* file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,20 @@
|
|
1
|
+
@import font-awesome
|
2
|
+
// Checkboxes
|
3
|
+
.selection-toggle-all
|
4
|
+
cursor: pointer
|
5
|
+
&.unchecked
|
6
|
+
@extend .fa, .fa-lg, .fa-square-o
|
7
|
+
&.checked
|
8
|
+
@extend .fa, .fa-2x, .fa-check-square-o
|
9
|
+
color: #449
|
10
|
+
.checker
|
11
|
+
cursor: pointer
|
12
|
+
&.unchecked
|
13
|
+
@extend .fa, .fa-lg, .fa-square-o
|
14
|
+
color: #999
|
15
|
+
&.checked
|
16
|
+
@extend .fa, .fa-lg, .fa-check-square-o
|
17
|
+
color: #050
|
18
|
+
table.with-selection
|
19
|
+
td.selection
|
20
|
+
width: 46px
|
@@ -0,0 +1,48 @@
|
|
1
|
+
@import font-awesome
|
2
|
+
$alert-color: #f04124
|
3
|
+
$checked-color: #43AC6A
|
4
|
+
$unchecked-color: #999
|
5
|
+
.optional-input-activator-container
|
6
|
+
display: inline-block
|
7
|
+
.optional-input-activator-toggle
|
8
|
+
margin-right: 7px
|
9
|
+
&.active
|
10
|
+
.optional-input-activator-toggle
|
11
|
+
color: #3636BD
|
12
|
+
@extend .fa, .fa-2x, .fa-toggle-on
|
13
|
+
&.error
|
14
|
+
color: $alert-color
|
15
|
+
.optional-input-activator-toggle
|
16
|
+
color: $alert-color
|
17
|
+
&.inactive
|
18
|
+
color: #999
|
19
|
+
.optional-input-activator-toggle
|
20
|
+
@extend .fa, .fa-2x, .fa-toggle-off
|
21
|
+
.optional-attribute-container
|
22
|
+
.optional-boolean-label
|
23
|
+
display: inline-block
|
24
|
+
margin-left: 8px
|
25
|
+
margin-right: 8px
|
26
|
+
&.inactive
|
27
|
+
display: none
|
28
|
+
&.optional-boolean
|
29
|
+
&.active
|
30
|
+
.optional-boolean-activator-toggle
|
31
|
+
color: #3636BD
|
32
|
+
@extend .fa, .fa-2x, .fa-toggle-on
|
33
|
+
.optional-boolean-toggle
|
34
|
+
&.active
|
35
|
+
color: $checked-color
|
36
|
+
@extend .fa, .fa-2x, .fa-check-square-o
|
37
|
+
&.inactive
|
38
|
+
color: $unchecked-color
|
39
|
+
@extend .fa, .fa-2x, .fa-square-o
|
40
|
+
&.inactive
|
41
|
+
display: block
|
42
|
+
.optional-boolean-activator-toggle
|
43
|
+
color: $unchecked-color
|
44
|
+
@extend .fa, .fa-2x, .fa-toggle-off
|
45
|
+
.optional-boolean-label
|
46
|
+
color: $unchecked-color
|
47
|
+
.optional-boolean-toggle
|
48
|
+
display: none
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>RecordCollection</title>
|
5
|
+
<%= stylesheet_link_tag "record_collection/application", media: "all" %>
|
6
|
+
<%= javascript_include_tag "record_collection/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'active_attr'
|
2
|
+
require 'active_model'
|
3
|
+
require "record_collection/version"
|
4
|
+
require "record_collection/name"
|
5
|
+
require "record_collection/base"
|
6
|
+
require 'record_collection/rails/routes'
|
7
|
+
require 'record_collection/rails/form_options_helper'
|
8
|
+
require 'record_collection/engine'
|
9
|
+
|
10
|
+
module RecordCollection
|
11
|
+
# Your code goes here...
|
12
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module RecordCollection
|
2
|
+
class Base
|
3
|
+
include Enumerable
|
4
|
+
include ActiveAttr::Model
|
5
|
+
|
6
|
+
attr_reader :collection
|
7
|
+
protected :collection
|
8
|
+
delegate :first, :last, :size, :length, :count, :empty?, :any?, to: :collection
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def model_name
|
12
|
+
RecordCollection::Name.new(self)
|
13
|
+
end
|
14
|
+
# Find all attributes that are specified with type boolean
|
15
|
+
def boolean_attributes
|
16
|
+
attributes.select{|k,v| v[:type] == ActiveAttr::Typecasting::Boolean}.keys.map(&:to_sym)
|
17
|
+
end
|
18
|
+
|
19
|
+
def human_attribute_name(*args)
|
20
|
+
raise "No record_class defined and could not be inferred based on the inheritance namespace. Please define self.record_clas = ClassNameOfIndividualRecords in the collection" unless record_class.present?
|
21
|
+
record_class.human_attribute_name(*args)
|
22
|
+
end
|
23
|
+
|
24
|
+
def inherited(collection_class)
|
25
|
+
# Try to infer the baseclass from the collection inheritance and set it if possible
|
26
|
+
collection_class.send :cattr_accessor, :record_class
|
27
|
+
if base_class = collection_class.name.deconstantize.safe_constantize
|
28
|
+
collection_class.record_class = base_class
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
def initialize(collection = [], params = {})
|
35
|
+
super(params) # active attr initialize with params
|
36
|
+
@collection = collection
|
37
|
+
end
|
38
|
+
|
39
|
+
# implement enumerable logic for collection
|
40
|
+
def each(&block)
|
41
|
+
collection.each do |record|
|
42
|
+
if block_given?
|
43
|
+
block.call record
|
44
|
+
else
|
45
|
+
yield record
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def save
|
51
|
+
valid? && update_collection_attributes!
|
52
|
+
end
|
53
|
+
|
54
|
+
def update_collection_attributes!
|
55
|
+
each { |r| r.update changed_attributes }
|
56
|
+
end
|
57
|
+
|
58
|
+
def changed_attributes
|
59
|
+
@changed_attributes ||= attributes.reject{|attr, val| val.nil? }
|
60
|
+
end
|
61
|
+
|
62
|
+
def persisted?
|
63
|
+
# Behave like an update in forms
|
64
|
+
true
|
65
|
+
end
|
66
|
+
|
67
|
+
def new_record?
|
68
|
+
# Behave like an update in forms
|
69
|
+
false
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
# This method returns nil when the values of `attr` in the collection
|
74
|
+
# are mixed. Otherwise the value itself. For boolean attributes the
|
75
|
+
# check is wether the values are truthy or falsy. If the
|
76
|
+
# set_if_nil: true
|
77
|
+
# option is given, a uniform value will be set as the collection value if
|
78
|
+
# it is not already set. This is important since there might be a uniform
|
79
|
+
# value in the collection, but the values of the collection are a result of
|
80
|
+
# an invalid form submission. In this case you want to keep the values of the
|
81
|
+
# submitted form as collection values, not the current uniform attribute.
|
82
|
+
def uniform_collection_attribute(attr, options = {})
|
83
|
+
attribute_spec = self.class.attributes[attr]
|
84
|
+
raise "Attribute #{attr} not defined on collection" unless attribute_spec
|
85
|
+
if attribute_spec[:type] == Boolean
|
86
|
+
# For boolean attributes presence is the true or false difference
|
87
|
+
# not the value itself
|
88
|
+
results = map{|r| r.public_send(attr).present? }.uniq
|
89
|
+
else
|
90
|
+
results = map{|r| r.public_send(attr) }.uniq
|
91
|
+
end
|
92
|
+
return nil unless results.size == 1 # one value found
|
93
|
+
public_send("#{attr}=", results.first) if options[:set_if_nil] and public_send(attr).nil? # set value on the object if it is uniform and not yet set
|
94
|
+
results.first
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'action_view/helpers/form_options_helper'
|
2
|
+
class ActionView::Helpers::FormBuilder
|
3
|
+
# This method adds the collection ids to the form if not already
|
4
|
+
# added. For the lazy peaple that forget to add them manually and
|
5
|
+
# use an optional tag
|
6
|
+
def add_collection_ids(content)
|
7
|
+
return content if @collection_ids_already_added
|
8
|
+
collection_ids + content
|
9
|
+
end
|
10
|
+
|
11
|
+
# Return inputs for the collection ids
|
12
|
+
def collection_ids
|
13
|
+
@collection_ids_already_added = true
|
14
|
+
object.map{|record| @template.hidden_field_tag('ids[]', record.id, id: nil) }.join.html_safe
|
15
|
+
end
|
16
|
+
|
17
|
+
def optional_boolean(attr)
|
18
|
+
classes = get_optional_classes(attr, base_class: 'optional-boolean')
|
19
|
+
label_tag = label(attr, options[:label])
|
20
|
+
check_box_tag = check_box(attr, options)
|
21
|
+
add_collection_ids @template.content_tag(:div, label_tag + check_box_tag , class: classes, data: { attribute: attr })
|
22
|
+
end
|
23
|
+
|
24
|
+
def optional_input(attr, options = {})
|
25
|
+
classes = get_optional_classes(attr, base_class: 'optional-input')
|
26
|
+
add_collection_ids @template.content_tag(:div, input(attr, options), class: classes, data: { attribute: attr })
|
27
|
+
end
|
28
|
+
|
29
|
+
def optional_text_field(attr, options={})
|
30
|
+
classes = get_optional_classes(attr, base_class: 'optional-text-field')
|
31
|
+
add_collection_ids @template.content_tag(:div, label(attr, options[:label]) + text_field(attr, options), class: classes, data: { attribute: attr })
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_optional_classes(attr, options = {})
|
35
|
+
active = false
|
36
|
+
if object.respond_to?(:uniform_collection_attribute)
|
37
|
+
uniform_value = object.uniform_collection_attribute(attr, set_if_nil: true)
|
38
|
+
# The field is active when the uniform value is not nil
|
39
|
+
active = !uniform_value.nil?
|
40
|
+
end
|
41
|
+
active = true unless object.public_send(attr).nil? # Activate if collection attribute is not nil
|
42
|
+
classes = [options[:base_class] || 'optional-input', 'optional-attribute-container', attr]
|
43
|
+
classes << (active ? 'active' : 'inactive')
|
44
|
+
classes << 'error' if object.errors[attr].present?
|
45
|
+
classes
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ActionDispatch::Routing
|
2
|
+
class Mapper
|
3
|
+
# Add two collection routes to the normal resources definition.
|
4
|
+
# This call behaves exactly as the normal resources :... call,
|
5
|
+
# but adds:
|
6
|
+
# collection do
|
7
|
+
# get :batch_actions
|
8
|
+
# post :process_batch
|
9
|
+
# end
|
10
|
+
def batch_resources(*resources, &blk)
|
11
|
+
batch_blk = Proc.new do
|
12
|
+
collection do
|
13
|
+
get :batch_actions
|
14
|
+
match :process_batch, via: [:post, :patch, :put]
|
15
|
+
end
|
16
|
+
blk.call if blk
|
17
|
+
end
|
18
|
+
resources(*resources, &batch_blk)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'record_collection/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "record_collection"
|
8
|
+
spec.version = RecordCollection::VERSION
|
9
|
+
spec.authors = ["Benjamin ter Kuile"]
|
10
|
+
spec.email = ["bterkuile@gmail.com"]
|
11
|
+
spec.summary = %q{Manage collections of records in Ruby on Rails}
|
12
|
+
spec.description = %q{This gem is there to aid you to work on subsets or rails models. This gem helps you to create forms and controllers that act on collections of models}
|
13
|
+
spec.homepage = "http://www.companytools.nl/"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency "rspec", ">= 3.1.0"
|
24
|
+
spec.add_development_dependency "rspec-rails", ">= 3.1.0"
|
25
|
+
spec.add_development_dependency "pry", ">= 0.1"
|
26
|
+
spec.add_development_dependency "rails", ">= 4.2.0"
|
27
|
+
spec.add_development_dependency "sqlite3"
|
28
|
+
spec.add_development_dependency "slim-rails"
|
29
|
+
spec.add_development_dependency "coffee-rails"
|
30
|
+
spec.add_development_dependency "sass-rails"
|
31
|
+
spec.add_development_dependency "font-awesome-rails"
|
32
|
+
spec.add_development_dependency "jquery-rails"
|
33
|
+
spec.add_development_dependency "js-routes"
|
34
|
+
spec.add_development_dependency "capybara"
|
35
|
+
spec.add_development_dependency "poltergeist"
|
36
|
+
spec.add_development_dependency "launchy"
|
37
|
+
spec.add_development_dependency "database_cleaner"
|
38
|
+
|
39
|
+
|
40
|
+
spec.add_runtime_dependency 'active_attr', '>= 0.8.5'
|
41
|
+
spec.add_runtime_dependency 'activemodel', '>= 4.1'
|
42
|
+
spec.add_runtime_dependency "railties", ">= 3.1"
|
43
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
== README
|
2
|
+
|
3
|
+
This README would normally document whatever steps are necessary to get the
|
4
|
+
application up and running.
|
5
|
+
|
6
|
+
Things you may want to cover:
|
7
|
+
|
8
|
+
* Ruby version
|
9
|
+
|
10
|
+
* System dependencies
|
11
|
+
|
12
|
+
* Configuration
|
13
|
+
|
14
|
+
* Database creation
|
15
|
+
|
16
|
+
* Database initialization
|
17
|
+
|
18
|
+
* How to run the test suite
|
19
|
+
|
20
|
+
* Services (job queues, cache servers, search engines, etc.)
|
21
|
+
|
22
|
+
* Deployment instructions
|
23
|
+
|
24
|
+
* ...
|
25
|
+
|
26
|
+
|
27
|
+
Please feel free to use a different markup language if you do not plan to run
|
28
|
+
<tt>rake doc:app</tt>.
|
data/spec/dummy/Rakefile
ADDED
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,69 @@
|
|
1
|
+
body {
|
2
|
+
background-color: #fff;
|
3
|
+
color: #333;
|
4
|
+
font-family: verdana, arial, helvetica, sans-serif;
|
5
|
+
font-size: 13px;
|
6
|
+
line-height: 18px;
|
7
|
+
}
|
8
|
+
|
9
|
+
p, ol, ul, td {
|
10
|
+
font-family: verdana, arial, helvetica, sans-serif;
|
11
|
+
font-size: 13px;
|
12
|
+
line-height: 18px;
|
13
|
+
}
|
14
|
+
|
15
|
+
pre {
|
16
|
+
background-color: #eee;
|
17
|
+
padding: 10px;
|
18
|
+
font-size: 11px;
|
19
|
+
}
|
20
|
+
|
21
|
+
a {
|
22
|
+
color: #000;
|
23
|
+
&:visited {
|
24
|
+
color: #666;
|
25
|
+
}
|
26
|
+
&:hover {
|
27
|
+
color: #fff;
|
28
|
+
background-color: #000;
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
div {
|
33
|
+
&.field, &.actions {
|
34
|
+
margin-bottom: 10px;
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
#notice {
|
39
|
+
color: green;
|
40
|
+
}
|
41
|
+
|
42
|
+
.field_with_errors {
|
43
|
+
padding: 2px;
|
44
|
+
background-color: red;
|
45
|
+
display: table;
|
46
|
+
}
|
47
|
+
|
48
|
+
#error_explanation {
|
49
|
+
width: 450px;
|
50
|
+
border: 2px solid red;
|
51
|
+
padding: 7px;
|
52
|
+
padding-bottom: 0;
|
53
|
+
margin-bottom: 20px;
|
54
|
+
background-color: #f0f0f0;
|
55
|
+
h2 {
|
56
|
+
text-align: left;
|
57
|
+
font-weight: bold;
|
58
|
+
padding: 5px 5px 5px 15px;
|
59
|
+
font-size: 12px;
|
60
|
+
margin: -7px;
|
61
|
+
margin-bottom: 0px;
|
62
|
+
background-color: #c00;
|
63
|
+
color: #fff;
|
64
|
+
}
|
65
|
+
ul li {
|
66
|
+
font-size: 12px;
|
67
|
+
list-style: square;
|
68
|
+
}
|
69
|
+
}
|