addressbook 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +21 -0
- data/app/assets/images/addressbook/default.png +0 -0
- data/app/assets/javascripts/addressbook/application.js +15 -0
- data/app/assets/stylesheets/addressbook/application.css +15 -0
- data/app/controllers/addressbook/application_controller.rb +11 -0
- data/app/controllers/addressbook/contacts_controller.rb +96 -0
- data/app/controllers/addressbook/groups_controller.rb +53 -0
- data/app/helpers/addressbook/application_helper.rb +25 -0
- data/app/models/concerns/addressbook_owner.rb +29 -0
- data/app/views/addressbook/contacts/_address.html.erb +35 -0
- data/app/views/addressbook/contacts/_email.html.erb +15 -0
- data/app/views/addressbook/contacts/_form.html.erb +97 -0
- data/app/views/addressbook/contacts/_phone.html.erb +19 -0
- data/app/views/addressbook/contacts/destroy.js.erb +1 -0
- data/app/views/addressbook/contacts/edit.html.erb +3 -0
- data/app/views/addressbook/contacts/index.html.erb +115 -0
- data/app/views/addressbook/contacts/new.html.erb +3 -0
- data/app/views/addressbook/groups/_form.html.erb +25 -0
- data/app/views/addressbook/groups/destroy.js.erb +1 -0
- data/app/views/addressbook/groups/edit.html.erb +3 -0
- data/app/views/addressbook/groups/index.html.erb +29 -0
- data/app/views/addressbook/groups/new.html.erb +3 -0
- data/app/views/layouts/addressbook/application.html.erb +24 -0
- data/config/initializers/addressbook.rb +1 -0
- data/config/locales/en.yml +73 -0
- data/config/routes.rb +10 -0
- data/db/migrate/20141110080715_add_addressbook_account_id_to_user_table.rb +11 -0
- data/lib/addressbook.rb +23 -0
- data/lib/addressbook/account.rb +27 -0
- data/lib/addressbook/base_uploader.rb +33 -0
- data/lib/addressbook/contact.rb +128 -0
- data/lib/addressbook/engine.rb +10 -0
- data/lib/addressbook/group.rb +18 -0
- data/lib/addressbook/import_file_uploader.rb +7 -0
- data/lib/addressbook/photo_uploader.rb +27 -0
- data/lib/addressbook/resource.rb +24 -0
- data/lib/addressbook/version.rb +3 -0
- data/lib/generators/addressbook/controllers/controllers_generator.rb +42 -0
- data/lib/generators/addressbook/initializer/initializer_generator.rb +9 -0
- data/lib/generators/addressbook/views/views_generator.rb +42 -0
- data/lib/tasks/addressbook_tasks.rake +4 -0
- data/spec/controllers/addressbook/contacts_controller_spec.rb +169 -0
- data/spec/controllers/addressbook/groups_controller_spec.rb +106 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/account.rb +3 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -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/config.ru +4 -0
- data/spec/dummy/config/application.rb +29 -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 +78 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/addressbook.rb +8 -0
- data/spec/dummy/config/initializers/assets.rb +8 -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/routes.rb +4 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20141119152457_create_accounts.rb +11 -0
- data/spec/dummy/db/migrate/20141119152801_add_addressbook_account_id_to_user_table.addressbook.rb +12 -0
- data/spec/dummy/db/schema.rb +27 -0
- data/spec/dummy/db/seeds.rb +1 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +13510 -0
- data/spec/dummy/log/test.log +1468 -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/dummy/public/uploads/addressbook/contact/imported/test.csv +10 -0
- data/spec/dummy/public/uploads/addressbook/contact/imported/test.vcf +23 -0
- data/spec/dummy/spec/factories/accounts.rb +9 -0
- data/spec/dummy/spec/models/account_spec.rb +5 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/006961e21c4f6a44101d2e9587f863f4 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/032ca99c7bed652dbad8de691558648d +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/06b00b7743f1b8c8020fabbb5c63e13a +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/0765e86c020fb088284e8f45c584f8c6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/1648d5d40aa02876f2cbb311ab2c4712 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/17405e31165e7d8129c846ceabaafec0 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/1dcb75c883fc0e57d08de7a76f0ada73 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/30f5fe3df78dce04aa1f998f6d790113 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/4b14ea7024b3a7934c5cf77c17cc92aa +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/604356b7aab9d373aa02548bf52b266b +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/69fcb234f5e891fcb7fbeb727a703968 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/6ec3857048c9b608a152271ff3991df6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/786158650544be3da3cd56983ff6540f +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/790fb0d33aad92cb9a1745822d4668aa +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/7954e67edaec86854ad0d70dfdc1df99 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/816240bd34b73344a7ac901c29906f1d +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/8a8a4eebb0809e6e5a1d1dc83dafb50d +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/8e844acaef03b740a1d21aafa3030124 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/91d3ad598e6e79937286c98b2b259cee +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/98e43302695126215ff9abe4b05eda56 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/aa5e472ff34ac18d968ac316ca9caff2 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/aa9a9307e1b4596e0b92b403107a2cfb +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/aee3f8a82c799313c63b922ed8b0f975 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c1f56035111b730c0c3807bf5ca35251 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c497b90d7dd45d368ec4e83d97d0a2b9 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d23b864a4a8239210d53e50644405687 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/dee437547d5fb5fab72af8a8d8582d4d +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/e9553c97dc4fe95dc10736ee0475dc45 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/ec3c091506a3d1ea73ac726b7ee9b3c2 +0 -0
- data/spec/fixtures/test.csv +10 -0
- data/spec/fixtures/test.vcf +23 -0
- data/spec/model/addressbook/account_spec.rb +33 -0
- data/spec/model/addressbook/contact_spec.rb +79 -0
- data/spec/model/addressbook/group_spec.rb +11 -0
- data/spec/model/addressbook/resource_spec.rb +10 -0
- data/spec/spec_helper.rb +65 -0
- metadata +517 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b8aff253d5a90d4f64a3372cfe66cc09a81e8633
|
4
|
+
data.tar.gz: f2a00cc3e504194ff3066c87c2ea7cda6e8a807f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 09d30d669baad9f50ac0fbb73e20895f99d3bfe04a8d683bde5d3b66774809ad09e9a9106bc72c826d7b58647f6dccaaf5e39521937ec350bbfca7f55e4fe888
|
7
|
+
data.tar.gz: a98172a9c64a7ca456aa718ade64d9b03c64713a75c77c04ddfc118de8fd27b5439c90a87bc608df2537c5ac4282d6dee054b41bea9aa1beb0d0725d21d97831
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2014 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
8
|
+
|
9
|
+
load 'rails/tasks/engine.rake'
|
10
|
+
|
11
|
+
Bundler::GemHelper.install_tasks
|
12
|
+
|
13
|
+
Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
|
14
|
+
|
15
|
+
require 'rspec/core'
|
16
|
+
require 'rspec/core/rake_task'
|
17
|
+
|
18
|
+
desc "Run all specs in spec directory (excluding plugin specs)"
|
19
|
+
RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
|
20
|
+
|
21
|
+
task :default => :spec
|
Binary file
|
@@ -0,0 +1,15 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require jquery
|
14
|
+
//= require jquery_ujs
|
15
|
+
//= require_tree .
|
@@ -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 vendor/assets/stylesheets of plugins, if any, 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,11 @@
|
|
1
|
+
module Addressbook
|
2
|
+
class ApplicationController < ActionController::Base
|
3
|
+
#layout 'layouts/application'
|
4
|
+
|
5
|
+
helper_method :current_addressbook_account
|
6
|
+
|
7
|
+
def current_addressbook_account
|
8
|
+
@current_addressbook_account = send("current_#{Addressbook.user_class.to_s.underscore}").addressbook_account
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require_dependency "addressbook/application_controller"
|
2
|
+
|
3
|
+
module Addressbook
|
4
|
+
class ContactsController < ApplicationController
|
5
|
+
|
6
|
+
before_filter :load_resource, only: [:edit, :update, :destroy]
|
7
|
+
before_filter :store_photo, only: [:update]
|
8
|
+
|
9
|
+
def index
|
10
|
+
contacts = Addressbook::Contact.search(params.merge(account_id: current_addressbook_account.id))
|
11
|
+
@contacts = Kaminari::PaginatableArray.new(
|
12
|
+
contacts, {
|
13
|
+
limit: contacts.http_response['X-limit'].to_i,
|
14
|
+
offset: contacts.http_response['X-offset'].to_i,
|
15
|
+
total_count: contacts.http_response['X-total'].to_i
|
16
|
+
})
|
17
|
+
end
|
18
|
+
|
19
|
+
def new
|
20
|
+
@contact = Addressbook::Contact.new
|
21
|
+
@contact.groups = []
|
22
|
+
@contact.emails = []
|
23
|
+
@contact.addresses = []
|
24
|
+
@contact.phones = []
|
25
|
+
end
|
26
|
+
|
27
|
+
def create
|
28
|
+
@contact = current_addressbook_account.contacts.new(contact_params)
|
29
|
+
store_photo
|
30
|
+
|
31
|
+
if @contact.save
|
32
|
+
redirect_to contacts_path, notice: t('addressbook.contact.create_notice')
|
33
|
+
else
|
34
|
+
render :new
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def edit
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
def update
|
43
|
+
if @contact.update_attributes(contact_params)
|
44
|
+
redirect_to contacts_path, notice: t('addressbook.contact.update_notice')
|
45
|
+
else
|
46
|
+
render :edit
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def destroy
|
51
|
+
@contact.destroy
|
52
|
+
end
|
53
|
+
|
54
|
+
def import_vcard
|
55
|
+
if !params[:vcard].nil? && /(.*)?\.vcf/ =~ params[:vcard].original_filename
|
56
|
+
contacts = Addressbook::Contact.import_vcard(current_addressbook_account, params[:vcard])
|
57
|
+
redirect_to contacts_path, notice: t('addressbook.contact.import_notice', count: contacts.length)
|
58
|
+
else
|
59
|
+
redirect_to contacts_path, alert: t('addressbook.contact.invalid_vcard')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def import_csv
|
64
|
+
if !params[:csv].nil? && /(.*)?\.csv/ =~ params[:csv].original_filename
|
65
|
+
contacts = Addressbook::Contact.import_csv(current_addressbook_account, params[:csv])
|
66
|
+
redirect_to contacts_path, notice: t('addressbook.contact.import_notice', count: contacts.length)
|
67
|
+
else
|
68
|
+
redirect_to contacts_path, alert: t('addressbook.contact.invalid_csv')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def load_resource
|
76
|
+
@contact = Addressbook::Contact.find(params[:id])
|
77
|
+
end
|
78
|
+
|
79
|
+
def store_photo
|
80
|
+
return unless params[:contact] && params[:contact][:photo]
|
81
|
+
@contact.token = SecureRandom.urlsafe_base64 if @contact.token.blank?
|
82
|
+
@contact.photo = params[:contact][:photo]
|
83
|
+
@contact.store_photo!
|
84
|
+
@contact.photo_file_name = @contact.photo.filename
|
85
|
+
end
|
86
|
+
|
87
|
+
def contact_params
|
88
|
+
params.fetch(:contact, {})
|
89
|
+
.permit(:first_name, :last_name, :nickname, :title, :gender, :dob, :company, :homepage, group_ids: [],
|
90
|
+
emails_attributes: [:id, :email, :preferred, :_destroy],
|
91
|
+
addresses_attributes: [:id, :line1, :line2, :line3, :city, :zipcode, :country, :state, :_destroy],
|
92
|
+
phones_attributes: [:id, :number, :phone_type, :preferred, :_destroy]
|
93
|
+
)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require_dependency "addressbook/application_controller"
|
2
|
+
|
3
|
+
module Addressbook
|
4
|
+
class GroupsController < ApplicationController
|
5
|
+
|
6
|
+
before_filter :load_resource, except: [:index, :new, :create]
|
7
|
+
|
8
|
+
def index
|
9
|
+
@groups = Addressbook::Group.find(:all, params: { account_id: current_addressbook_account.id })
|
10
|
+
end
|
11
|
+
|
12
|
+
def new
|
13
|
+
@group = Addressbook::Group.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def create
|
17
|
+
@group = current_addressbook_account.groups.new(group_params)
|
18
|
+
|
19
|
+
if @group.save
|
20
|
+
redirect_to :back, notice: t('addressbook.group.create_notice')
|
21
|
+
else
|
22
|
+
render :new
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def edit
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
def update
|
31
|
+
if @group.update_attributes(group_params)
|
32
|
+
redirect_to :back, notice: t('addressbook.group.update_notice')
|
33
|
+
else
|
34
|
+
render :edit
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def destroy
|
39
|
+
@group.destroy
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def load_resource
|
46
|
+
@group = Addressbook::Group.find(params[:id])
|
47
|
+
end
|
48
|
+
|
49
|
+
def group_params
|
50
|
+
params.fetch(:group, {}).permit(:name, :description)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Addressbook
|
2
|
+
module ApplicationHelper
|
3
|
+
def bootstrap_class_for(flash_type)
|
4
|
+
case flash_type.to_sym
|
5
|
+
when :alert
|
6
|
+
"warning"
|
7
|
+
when :notice
|
8
|
+
"info"
|
9
|
+
else
|
10
|
+
flash_type.to_s
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def phone_icon_class(phone_type)
|
15
|
+
case phone_type
|
16
|
+
when 'home', 'cell'
|
17
|
+
'earphone'
|
18
|
+
when 'mobile', 'iPhone'
|
19
|
+
'phone'
|
20
|
+
else
|
21
|
+
'phone-alt'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module AddressbookOwner
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
|
6
|
+
def addressbook_account
|
7
|
+
if addressbook_account_id.blank?
|
8
|
+
addressbook_account = Addressbook::Account.create(email: email, name: owner_name)
|
9
|
+
self.update(addressbook_account_id: addressbook_account.id)
|
10
|
+
else
|
11
|
+
addressbook_account = Addressbook::Account.find(addressbook_account_id)
|
12
|
+
end
|
13
|
+
|
14
|
+
addressbook_account
|
15
|
+
end
|
16
|
+
|
17
|
+
def owner_name
|
18
|
+
if respond_to? :name
|
19
|
+
name
|
20
|
+
elsif respond_to? :full_name
|
21
|
+
full_name
|
22
|
+
elsif respond_to? :first_name && :last_name
|
23
|
+
[first_name, last_name].reject(&:blank?).join(' ')
|
24
|
+
else
|
25
|
+
''
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
<div class="nested-fields addressbook-contact-fields">
|
2
|
+
<%= hidden_field_tag "contact[addresses_attributes][][id]", address.id if address.id.present? %>
|
3
|
+
<%= hidden_field_tag "contact[addresses_attributes][][_destroy]", false, class: 'destroy_association_field' %>
|
4
|
+
|
5
|
+
<div class="field">
|
6
|
+
<%= label_tag :line1, t('addressbook.contact.line1') %>
|
7
|
+
<%= text_field_tag "contact[addresses_attributes][][line1]", address.line1 %>
|
8
|
+
</div>
|
9
|
+
<div class="field">
|
10
|
+
<%= label_tag :line2, t('addressbook.contact.line2') %>
|
11
|
+
<%= text_field_tag "contact[addresses_attributes][][line2]", address.line2 %>
|
12
|
+
</div>
|
13
|
+
<div class="field">
|
14
|
+
<%= label_tag :line3, t('addressbook.contact.line3') %>
|
15
|
+
<%= text_field_tag "contact[addresses_attributes][][line3]", address.line3 %>
|
16
|
+
</div>
|
17
|
+
<div class="field">
|
18
|
+
<%= label_tag :zipcode, t('addressbook.contact.zipcode') %>
|
19
|
+
<%= text_field_tag "contact[addresses_attributes][][zipcode]", address.zipcode %>
|
20
|
+
</div>
|
21
|
+
<div class="field">
|
22
|
+
<%= label_tag :city, t('addressbook.contact.city') %>
|
23
|
+
<%= text_field_tag "contact[addresses_attributes][][city]", address.city %>
|
24
|
+
</div>
|
25
|
+
<div class="field">
|
26
|
+
<%= label_tag :state, t('addressbook.contact.state') %>
|
27
|
+
<%= text_field_tag "contact[addresses_attributes][][state]", address.state %>
|
28
|
+
</div>
|
29
|
+
<div class="field">
|
30
|
+
<%= label_tag :country, t('addressbook.contact.country') %>
|
31
|
+
<%= text_field_tag "contact[addresses_attributes][][country]", address.country %>
|
32
|
+
</div>
|
33
|
+
|
34
|
+
<a class="remove_contact_associaton" href="#"><%= t('addressbook.contact.remove_address') %></a>
|
35
|
+
</div>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<div class="nested-fields addressbook-contact-fields">
|
2
|
+
<%= hidden_field_tag "contact[emails_attributes][][id]", email.id if email.id.present? %>
|
3
|
+
<%= hidden_field_tag "contact[emails_attributes][][_destroy]", false, class: 'destroy_association_field' %>
|
4
|
+
|
5
|
+
<div class="field">
|
6
|
+
<%= label_tag :email, t('addressbook.contact.email') %>
|
7
|
+
<%= text_field_tag "contact[emails_attributes][][email]", email.email %>
|
8
|
+
</div>
|
9
|
+
<div class="field">
|
10
|
+
<%= label_tag :preferred, t('addressbook.contact.preferred') %>
|
11
|
+
<%= check_box_tag "contact[emails_attributes][][preferred]", true, (email.try(:preferred) || false) %>
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<a class="remove_contact_associaton" href="#"><%= t('addressbook.contact.remove_email') %></a>
|
15
|
+
</div>
|
@@ -0,0 +1,97 @@
|
|
1
|
+
<%= form_for @contact do |f| %>
|
2
|
+
<% if @contact.errors.any? %>
|
3
|
+
<div id="error_explanation">
|
4
|
+
<h2><%= t('addressbook.contact.error_explanation', count: @contact.errors.count) %></h2>
|
5
|
+
<ul>
|
6
|
+
<% @contact.errors.full_messages.each do |msg| %>
|
7
|
+
<li><%= msg %></li>
|
8
|
+
<% end %>
|
9
|
+
</ul>
|
10
|
+
</div>
|
11
|
+
<% end %>
|
12
|
+
|
13
|
+
<div class="field">
|
14
|
+
<%= f.label :first_name, t('addressbook.contact.first_name') %>
|
15
|
+
<%= f.text_field :first_name %>
|
16
|
+
</div>
|
17
|
+
<div class="field">
|
18
|
+
<%= f.label :last_name, t('addressbook.contact.last_name') %>
|
19
|
+
<%= f.text_field :last_name %>
|
20
|
+
</div>
|
21
|
+
<div class="field">
|
22
|
+
<%= f.label :nickname, t('addressbook.contact.nickname') %>
|
23
|
+
<%= f.text_field :nickname %>
|
24
|
+
</div>
|
25
|
+
<div class="field">
|
26
|
+
<%= f.label :gender, t('addressbook.contact.gender') %>
|
27
|
+
<%= f.select :gender, options_for_select(Addressbook::Contact::GENDER, f.object.gender), {} %>
|
28
|
+
</div>
|
29
|
+
<div class="field">
|
30
|
+
<%= f.label :company, t('addressbook.contact.company') %>
|
31
|
+
<%= f.text_field :company %>
|
32
|
+
</div>
|
33
|
+
<div class="field">
|
34
|
+
<%= f.label :photo, t('addressbook.contact.photo') %>
|
35
|
+
<%= f.file_field :photo %>
|
36
|
+
</div>
|
37
|
+
<div class="field">
|
38
|
+
<%= f.label :homepage, t('addressbook.contact.homepage') %>
|
39
|
+
<%= f.text_field :homepage %>
|
40
|
+
</div>
|
41
|
+
<div class="field">
|
42
|
+
<%= f.label :dob, t('addressbook.contact.dob') %>
|
43
|
+
<%= f.text_field :dob %>
|
44
|
+
</div>
|
45
|
+
|
46
|
+
<div class="field">
|
47
|
+
<%= f.label :group, t('addressbook.contact.group') %>
|
48
|
+
<%= f.select :group_ids, options_from_collection_for_select(current_addressbook_account.groups, "id", "name", selected: (@contact.groups.map(&:id) rescue [])), {}, { class: "groups_select form-control", multiple: true } %>
|
49
|
+
<%= link_to t('addressbook.group.new_group'), new_group_path %>
|
50
|
+
</div>
|
51
|
+
|
52
|
+
<div id="contact-emails">
|
53
|
+
<h4><%= t('addressbook.contact.email').pluralize %></h4>
|
54
|
+
<%= render partial: 'email', collection: @contact.try(:emails) || @contact.try(:emails_attributes) %>
|
55
|
+
<a class="add-contact-association" href="#" data-template='<%= render "email", email: Addressbook::Contact::Email.new %>'><%= t('addressbook.contact.add_email') %></a>
|
56
|
+
</div>
|
57
|
+
|
58
|
+
<div id="contact-addresses">
|
59
|
+
<h4><%= t('addressbook.contact.address').pluralize %></h4>
|
60
|
+
<%= render partial: 'address', collection: @contact.try(:addresses) || @contact.try(:addresses_attributes) %>
|
61
|
+
<a class="add-contact-association" href="#" data-template='<%= render "address", address: Addressbook::Contact::Address.new %>'><%= t('addressbook.contact.add_address') %></a>
|
62
|
+
</div>
|
63
|
+
|
64
|
+
<div id="contact-phones">
|
65
|
+
<h4><%= t('addressbook.contact.phone').pluralize %></h4>
|
66
|
+
<%= render partial: 'phone', collection: @contact.try(:phones) || @contact.try(:phones_attributes) %>
|
67
|
+
<a class="add-contact-association" href="#" data-template='<%= render "phone", phone: Addressbook::Contact::Phone.new %>'><%= t('addressbook.contact.add_phone') %></a>
|
68
|
+
</div>
|
69
|
+
|
70
|
+
<div class="form-actions">
|
71
|
+
<%= f.submit t('addressbook.actions.save') %>
|
72
|
+
</div>
|
73
|
+
<% end %>
|
74
|
+
|
75
|
+
<script>
|
76
|
+
var initNestedFields = function($el) {
|
77
|
+
$el.find('.remove_contact_associaton').click(function(e) {
|
78
|
+
e.preventDefault();
|
79
|
+
var $parent = $(this).parents('.nested-fields');
|
80
|
+
$parent.find('.destroy_association_field').val(true);
|
81
|
+
$parent.fadeOut();
|
82
|
+
return false;
|
83
|
+
});
|
84
|
+
}
|
85
|
+
|
86
|
+
$(document).ready(function() {
|
87
|
+
initNestedFields($('form'));
|
88
|
+
|
89
|
+
$('.add-contact-association').click(function(e) {
|
90
|
+
e.preventDefault();
|
91
|
+
var $newFields = $($(this).data('template'));
|
92
|
+
$newFields.insertBefore($(this));
|
93
|
+
initNestedFields($newFields);
|
94
|
+
return false;
|
95
|
+
});
|
96
|
+
})
|
97
|
+
</script>
|