e9_crm 0.1.13 → 0.1.14

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,12 +9,13 @@ class E9Crm::CampaignSubclassController < E9Crm::ResourcesController
9
9
  end
10
10
 
11
11
  protected
12
+
12
13
  def parent_redirect_path
13
14
  campaigns_path(:type => type_param)
14
15
  end
15
16
 
16
17
  def type_param
17
- resource_class.name[/(.*)Campaign/, 1].underscore
18
+ resource_class.name[/(.*)Campaign/, 1].underscore rescue nil
18
19
  end
19
20
 
20
21
  def add_index_breadcrumb
@@ -20,7 +20,7 @@ class E9Crm::ContactEmailsController < E9Crm::ResourcesController
20
20
  ContactEmail.new_from_template(template, :contact_ids => params[:uids])
21
21
  end
22
22
 
23
- object.from_email ||= current_user.email
23
+ object.from_email = object.from_email.presence || current_user.email
24
24
 
25
25
  object.valid?
26
26
 
@@ -1,15 +1,21 @@
1
- class E9Crm::DatedCostsController < E9Crm::CampaignSubclassController
1
+ class E9Crm::DatedCostsController < E9Crm::ResourcesController
2
2
  belongs_to :advertising_campaign, :optional => true
3
3
  defaults :resource_class => DatedCost
4
4
  include E9Rails::Controllers::Orderable
5
5
 
6
+ self.should_paginate_index = true
7
+
6
8
  filter_access_to :bulk_create, :require => :create, :context => :admin
7
9
 
10
+ prepend_before_filter :association_chain
8
11
  before_filter :add_breadcrumbs
9
12
  before_filter :generate_temp_id, :only => :new
10
13
 
14
+ respond_to :json, :only => :new
15
+
11
16
  def index
12
17
  if params[:advertising_campaign_id]
18
+ @index_title = "Advertising Costs for #{parent.name}" if parent
13
19
  index!
14
20
  else
15
21
  @advertising_campaigns = AdvertisingCampaign.all
@@ -17,6 +23,13 @@ class E9Crm::DatedCostsController < E9Crm::CampaignSubclassController
17
23
  end
18
24
  end
19
25
 
26
+ def new
27
+ new! do |format|
28
+ format.html
29
+ format.json { render :json => { :html => render_html_for_action } }
30
+ end
31
+ end
32
+
20
33
  def bulk_create
21
34
  params[:id].zip(params[:cost]) do |id, cost|
22
35
  DatedCost.create(
@@ -33,8 +46,16 @@ class E9Crm::DatedCostsController < E9Crm::CampaignSubclassController
33
46
 
34
47
  protected
35
48
 
36
- def collection
37
- get_collection_ivar || set_collection_ivar(end_of_association_chain.all)
49
+ def render_html_for_action(action = nil)
50
+ action ||= params[:action]
51
+
52
+ html = nil
53
+
54
+ lookup_context.update_details(:formats => [Mime::HTML.to_sym]) do
55
+ html = render_to_string(action, :layout => false)
56
+ end
57
+
58
+ html
38
59
  end
39
60
 
40
61
  def default_ordered_on
@@ -45,11 +66,17 @@ class E9Crm::DatedCostsController < E9Crm::CampaignSubclassController
45
66
  'ASC'
46
67
  end
47
68
 
48
- def add_breadcrumbs
49
- if parent?
69
+ def add_index_breadcrumb
70
+ #association_chain
71
+
72
+ add_breadcrumb! Campaign.model_name.collection.titleize, campaigns_path
73
+
74
+ if parent
50
75
  add_breadcrumb! parent.name, edit_advertising_campaign_path(parent)
51
76
  end
77
+ end
52
78
 
79
+ def add_breadcrumbs
53
80
  add_breadcrumb! e9_t(:index_title)
54
81
  end
55
82
 
@@ -39,10 +39,11 @@ class E9Crm::LeadsController < ApplicationController
39
39
 
40
40
  def build_resource
41
41
  get_resource_ivar || set_resource_ivar(
42
+ # NOTE mailing list ids come from the form (to allow opt-outs)
42
43
  Deal.leads.new((params[resource_instance_name] || {}).reverse_merge(
43
- :user => current_user,
44
- :offer => @offer,
45
- :campaign => tracking_campaign
44
+ :user => current_user,
45
+ :offer => @offer,
46
+ :campaign => tracking_campaign
46
47
  ))
47
48
  )
48
49
  end
@@ -0,0 +1,22 @@
1
+ class E9Crm::UsersController < ApplicationController
2
+ inherit_resources
3
+
4
+ respond_to :html, :except => :new
5
+ respond_to :json, :only => :new
6
+
7
+ def new
8
+ new! do |format|
9
+ format.json { render :json => resource }
10
+ end
11
+ end
12
+
13
+ protected
14
+
15
+ def build_resource
16
+ get_resource_ivar || begin
17
+ user = User.new(params[resource_instance_name] || {})
18
+ user.valid?
19
+ set_resource_ivar(user)
20
+ end
21
+ end
22
+ end
@@ -6,9 +6,9 @@ module E9Crm::BaseHelper
6
6
 
7
7
  alias :k :kramdown
8
8
 
9
- def help_tooltip(string)
9
+ def help_tooltip(string, data_title = nil)
10
10
  return <<-HTML.strip.html_safe
11
- <span class="help" rel="tooltip" title="#{CGI.escape_html(string)}">#{t(:inline_help_link)}</span>
11
+ <span class="help" rel="tooltip" #{data_title ? %Q[data-title="#{data_title}"] : nil } title="#{CGI.escape_html(string)}">#{t(:inline_help_link)}</span>
12
12
  HTML
13
13
  end
14
14
 
@@ -20,7 +20,7 @@ module E9Crm::BaseHelper
20
20
  str = ''.html_safe
21
21
  str.safe_concat resource_humanize(key)
22
22
  str.safe_concat ' '
23
- str.safe_concat help_tooltip(help_title)
23
+ str.safe_concat help_tooltip(help_title, options.delete(:header))
24
24
 
25
25
  if form_or_id.respond_to?(:label)
26
26
  form_or_id.label(key, str, options)
@@ -12,6 +12,10 @@ class DatedCost < ActiveRecord::Base
12
12
 
13
13
  attr_accessor :temp_id
14
14
 
15
+ def self.default_scope
16
+ order('dated_costs.created_at ASC')
17
+ end
18
+
15
19
  def as_json(options={})
16
20
  {}.tap do |hash|
17
21
  hash[:id] = self.id
data/app/models/deal.rb CHANGED
@@ -46,7 +46,7 @@ class Deal < ActiveRecord::Base
46
46
 
47
47
  # If a lead with no user, find the user by email or create it, then if mailing_lists
48
48
  # were passed, assign the user those mailing lists
49
- after_create :find_or_create_user, :assign_user_mailing_lists, :add_user_contact
49
+ after_create :handle_user_if_lead
50
50
 
51
51
  # money column definitions for pseudo attributes (added on the reports scope)
52
52
  %w(total_value average_value total_cost average_cost).each do |money_column|
@@ -55,6 +55,8 @@ class Deal < ActiveRecord::Base
55
55
 
56
56
  delegate :name, :to => :owner, :prefix => true, :allow_nil => true
57
57
 
58
+ # mailing_list_ids may be set on Deals when they are being created as leads, this is
59
+ # done via opt-in checkboxes on the form
58
60
  attr_accessor :mailing_list_ids
59
61
 
60
62
  #
@@ -230,21 +232,21 @@ class Deal < ActiveRecord::Base
230
232
  end
231
233
  end
232
234
 
233
- def find_or_create_user
234
- if lead? && user.blank? && lead_email
235
- u = User.find_by_email(lead_email) || create_prospect
236
- update_attribute(:user_id, u.id)
237
- end
238
- end
239
-
240
- def add_user_contact
241
- user.create_contact_if_missing!
242
- self.contacts << user.contact
243
- end
244
-
245
- def assign_user_mailing_lists
246
- if @mailing_list_ids
247
- user.mailing_list_ids |= @mailing_list_ids
235
+ def handle_user_if_lead
236
+ if lead?
237
+ if user.blank? && lead_email
238
+ user = User.find_by_email(lead_email) || create_prospect
239
+ update_attribute(:user_id, u.id)
240
+ end
241
+
242
+ if user.present?
243
+ user.create_contact_if_missing!
244
+ self.contacts << user.contact
245
+
246
+ if @mailing_list_ids
247
+ user.mailing_list_ids |= @mailing_list_ids
248
+ end
249
+ end
248
250
  end
249
251
  end
250
252
 
@@ -5,9 +5,7 @@ class EmailTemplate < Email
5
5
  # TODO the email class hierarchy needs a major refactoring, it's backwards and convoluted
6
6
  before_save :generate_html_body_from_text_body
7
7
 
8
- validates :text_body, :presence => true
9
- validates :subject, :presence => true
10
- validates :from_email, :presence => true, :email => { :allow_blank => true }
8
+ validates :from_email, :email => { :allow_blank => true }
11
9
 
12
10
  def as_json(options = {})
13
11
  {}.tap do |hash|
@@ -3,7 +3,7 @@
3
3
  %fieldset
4
4
  %legend= e9_t(:affiliate_information_legend, :scope => 'e9_crm.campaigns')
5
5
  .field
6
- = f.label :affilate, nil, :class => :req, :for => 'campaign_affiliate_id'
6
+ = f.label :affiliate, :class => :req, :for => 'campaign_affiliate_id'
7
7
  = f.collection_select :affiliate_id, Contact.affiliates.ordered.all, :id, :name, {:prompt => true}, :id => 'campaign_affiliate_id'
8
8
  .field
9
9
  = help_label f, :affiliate_fee
@@ -1,6 +1,6 @@
1
1
  .field
2
2
  = f.label :name, nil, :class => :req
3
3
  = f.text_field :name
4
- .field.tinymce
5
- = f.label :info
4
+ .field
5
+ = help_label(f, :info, :key => :markdown_help, :header => 'Markdown Help')
6
6
  = f.text_area :info
@@ -30,14 +30,14 @@
30
30
 
31
31
  %fieldset.contact-contact-fields
32
32
  %legend= e9_t(:form_legend_contact)
33
- = render_record_attribute_form(:phone_number_attributes , f)
34
- = render_record_attribute_form(:instant_messaging_handle_attributes , f)
35
- = render_record_attribute_form(:website_attributes , f)
36
- = render_record_attribute_form(:address_attributes , f)
33
+ = render_record_attribute_form(:phone_number_attributes, f)
34
+ = render_record_attribute_form(:instant_messaging_handle_attributes, f)
35
+ = render_record_attribute_form(:website_attributes, f)
36
+ = render_record_attribute_form(:address_attributes, f)
37
37
 
38
38
  %fieldset.contact-background-info
39
- %legend= f.label(:info)
40
- .field.tinymce
39
+ %legend= help_label(f, :info, :key => :markdown_help, :header => 'Markdown Help')
40
+ .field
41
41
  = f.text_area :info
42
42
 
43
43
  - content_for :bottom_javascripts do
@@ -2,22 +2,13 @@
2
2
  = link_to_new_resource(Contact)
3
3
  = link_to_collection(Company)
4
4
 
5
- -# Email actions (template, newsletter)
6
- -#- etag, ntag = contact_email_template_select_tag, contact_newsletter_select_tag
7
- -#- if [etag, ntag].any?(&:present?)
8
- - if (etag = contact_newsletter_select_tag).present?
5
+ - if (etag = contact_email_template_select_tag).present?
9
6
  %fieldset
10
7
  %legend= e9_t(:email_actions_legend)
11
- - if etag
12
- = form_tag new_contact_email_path, :method => :get, :id => 'contact_email_form', 'data-empty' => e9_t(:no_contacts_notification), 'data-count' => @contact_ids.length do
13
- = etag
14
- = hidden_field_tag 'uids', @contact_ids.join(','), :id => 'contact_email_uids'
15
- = submit_tag e9_t(:send_email_template), :name => nil
16
- -#- if ntag
17
- -#= form_tag send_email_admin_user_email_path('__ID__'), :method => :put, :id => 'contact_newsletter_form', 'data-confirm' => e9_t(:contact_newsletter_confirmation, :count => collection.length), 'data-empty' => e9_t(:no_contacts_notification), 'data-count' => @contact_ids.length do
18
- -#= ntag
19
- -#= hidden_field_tag 'uids', @contact_ids.join(','), :id => 'contact_newsletter_uids'
20
- -#= submit_tag e9_t(:send_email_newsletter), :name => nil
8
+ = form_tag new_contact_email_path, :method => :get, :id => 'contact_email_form', 'data-empty' => e9_t(:no_contacts_notification), 'data-count' => @contact_ids.length do
9
+ = etag
10
+ = hidden_field_tag 'uids', @contact_ids.join(','), :id => 'contact_email_uids'
11
+ = submit_tag e9_t(:send_email_template), :name => nil
21
12
 
22
13
  -# Search filter options
23
14
  %fieldset
@@ -25,6 +25,7 @@
25
25
  %label= Contact.human_attribute_name(:website_attributes)
26
26
  - resource.website_attributes.each do |website_attribute|
27
27
  .contact-website
28
+ - url = website_attribute.value =~/^\w+:\/\// ? website_attribute.value : "http://#{website_attribute.value}"
28
29
  = link_to(website_attribute.to_s, website_attribute.to_s, :rel => "external nofollow")
29
30
 
30
31
  - if resource.address_attributes.any?
@@ -6,7 +6,7 @@
6
6
  - unless request.xhr?
7
7
  = f.label :date, nil, :class => :req, :for => id
8
8
  = f.text_field :date, :class => 'date-picker', :value => l(f.object.date), :id => id
9
- .field
9
+ .field.cost
10
10
  - fid = "dated_cost_cost_#{id}"
11
11
  - unless request.xhr?
12
12
  = f.label :cost, nil, :class => :req, :for => id
@@ -5,11 +5,11 @@
5
5
  .dated-cost-labels
6
6
  .field
7
7
  = resource_class.human_attribute_name(:date)
8
- .field
8
+ .field.cost
9
9
  = resource_class.human_attribute_name(:cost)
10
10
 
11
11
  = render collection
12
12
 
13
13
  .actions
14
- = link_to_new_resource(resource_class, :remote => true)
14
+ = link_to_new_resource(resource_class, :class => 'new-resource')
15
15
 
@@ -22,14 +22,13 @@
22
22
  = f.text_field :value
23
23
  .field.select
24
24
  = f.label :owner
25
- = f.collection_select :contact_id, Contact.all, :id, :name, :prompt => true
25
+ = f.collection_select :contact_id, Contact.sales_persons.all, :id, :name, :prompt => true
26
26
  .field.select
27
27
  = f.label :contacts
28
- %select.list{'data-iname' => resource_instance_name, 'data-field' => '[contact_ids]'}
29
- = deal_contact_select_options
28
+ %input#contact_autocomplete.list{:type => 'text', 'data-values' => f.object.contact_ids.join(','), 'data-iname' => resource_instance_name, 'data-field' => '[contact_ids]'}
30
29
  %ul.select
31
30
  - f.object.contacts.each do |contact|
32
- %li
33
- %span= contact.name
31
+ %li.ui-state-default
32
+ %span.content= contact.name
34
33
  %input{:type => :hidden, :name => "contact[contact_ids][]", :value => contact.id}
35
34
  %a{:class => :remove, :title => "Remove", :alt => "Remove"} Remove
@@ -2,11 +2,11 @@
2
2
  = f.label :name, nil, :class => :req
3
3
  = f.text_field :name
4
4
  .field
5
- = f.label :from_email, nil, :class => :req
5
+ = f.label :from_email
6
6
  = f.text_field :from_email
7
7
  .field
8
- = f.label :subject, nil, :class => :req
8
+ = f.label :subject
9
9
  = f.text_field :subject
10
10
  .field
11
- = f.label :text_body, nil, :class => :req
11
+ = f.label :text_body
12
12
  = f.text_area :text_body
@@ -7,8 +7,8 @@
7
7
  .field
8
8
  = f.object.email
9
9
  - else
10
- .field
11
- = f.email_field :email
10
+ .field.contact-email
11
+ = f.text_field :email
12
12
 
13
13
  = f.fields_for f.object.options do |ff|
14
14
  - if (types = User.email_types).present?
@@ -17,6 +17,11 @@ en:
17
17
  add_record_attribute: Add
18
18
  destroy_record_attribute: Remove
19
19
 
20
+ # activemodel translation looks to %{i18n_scope}.attributes.%{model_name}.%{attribute}
21
+ # then simply attributes.%{attribute}, dropping i18n_scope, e.g "activerecord"
22
+ attributes:
23
+ markdown_help: "You can style the text in this field using the Markdown syntax as follows:\n\nA line break is created by putting 2 spaces\n\nat the end of the line above and then a return.\n\nA paragraph is created by putting a blank line between the first paragraph and the second paragraph.\n\nThis is the start of the next paragraph.\n\n*italics*\n\n**bold**\n\n***bold and italic text***\n\n* Item in a bulleted list\n\t* A sub-item, indented with 4 spaces\n* Another item in a bulleted list\n\n1. Item in numbered list\n2. Another Item in numbered list\n3. Another Item in numbered list\n\n# First-level heading\n\n## Second-level heading\n\n### Third-level heading\n\n#### Fourth-level heading\n\n> This is a blockquote.\n> Blockquote with hard wrap\n>\n> This is the second paragraph in the blockquote.\n>\n> ## This is an H2 in a blockquote\n\n[This is a link](http://www.google.com \"Google\")\n\n![Image Alt Text](image url \"Image Title\")\n\n--- Horizontal rules are created by 3 hyphens\n\nIf you need to actually render the following characters AND they are NOT rendering, place a backslash before the character like \*italics\* will actually render with the asterisks instead of italicizing the word.\n\n\\\tbackslash\n*\tasterisk\n_\tunderscore\n{}\tcurly braces\n[]\tsquare brackets\n()\tparentheses\n#\thash mark\n+\tplus sign\n-\tminus sign (hyphen)\n.\tdot\n!\texclamation mark"
24
+
20
25
  activerecord:
21
26
  titles:
22
27
  show: 'Show %{model}'
@@ -24,10 +29,12 @@ en:
24
29
  show: '%{model}'
25
30
 
26
31
  links:
27
- edit: "Edit %{model}"
28
- destroy: "Delete %{model}"
29
- show: "View %{model}"
30
32
  index: "Manage %{models}"
33
+ new: "New %{model}"
34
+ edit: "Edit"
35
+ destroy: "Delete"
36
+ show: "View"
37
+ confirm_destroy: Are you sure? This cannot be undone.
31
38
 
32
39
  campaign_group:
33
40
  confirm_destroy: Are you sure? This cannot be undone. Any campaigns which are associated with this group will become groupless.
@@ -108,8 +115,8 @@ en:
108
115
  info: Background Information
109
116
  not_ok_to_email: "This contact will not receive bulk email."
110
117
  tag_instructions: "Tags are words or phrases that describe or categorize this contact.\n\nWhen searching a particular tag, the system will show all contacts with that tag."
111
- no_deals: There are no deals associated with this contact.
112
- no_leads: There are no leads associated with this contact.
118
+ no_deals: 'There are no deals associated with this contact.'
119
+ no_leads: 'There are no leads associated with this contact.'
113
120
  company:
114
121
  info: Background Information
115
122
  deal:
@@ -119,6 +126,7 @@ en:
119
126
  campaign_code: Code
120
127
  offer_name: Offer
121
128
  created_at: Date
129
+ owner: Responsible
122
130
  offer:
123
131
  template: Teaser Text
124
132
  alert_email_instructions: (Enter an email if you want to be notified of conversions)
data/config/routes.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  Rails.application.routes.draw do
2
2
  crm_path = 'admin/crm'
3
3
 
4
+ get '/autocomplete/contacts' => E9Crm::Rack::ContactAutoCompleter
5
+ get '/autocomplete/companies' => E9Crm::Rack::CompanyAutoCompleter
6
+
4
7
  scope :module => :e9_crm do
5
8
  resources :offers, :as => :public_offer, :only => :show do
6
9
  resources :leads, :as => :deals, :only => [:new, :create], :path => ''
@@ -8,6 +11,10 @@ Rails.application.routes.draw do
8
11
  end
9
12
 
10
13
  scope :path => crm_path, :module => :e9_crm do
14
+ # NOTE this should be handled by base, and is here because base doesn't have a sensible
15
+ # user api, which crm needs to check for email uniqueness errors
16
+ resources :users, :only => :new
17
+
11
18
  resources :companies, :except => :show
12
19
  resources :contacts do
13
20
  # page_views currently not routed, but near working
@@ -0,0 +1,30 @@
1
+ module E9Crm::Rack
2
+ #
3
+ # Returns contacts and joins their primary user for their email if it exists,
4
+ # and will return a string like "firstname lastname (email)". If for whatever
5
+ # reason the contact has no primary user, it will drop the email.
6
+ #
7
+ class CompanyAutoCompleter
8
+ DEFAULT_LIMIT = 10
9
+
10
+ def self.call(env)
11
+ if env["PATH_INFO"] =~ /^\/autocomplete\/companies/
12
+ params = Rack::Request.new(env).params
13
+
14
+ if term = params['term']
15
+ relation = Company.limit(params['limit'] || DEFAULT_LIMIT).select('name').attr_like('name', term, :matcher => '%s%%')
16
+
17
+ companies = ::ActiveRecord::Base.connection.send(:select, relation.to_sql, 'Company Autocomplete').map do |row|
18
+ { :label => row['name'], :value => row['name'] }
19
+ end
20
+ else
21
+ companies = []
22
+ end
23
+
24
+ [200, {"Content-Type" => "application/json", "Cache-Control" => "max-age=3600, must-revalidate"}, [companies.to_json]]
25
+ else
26
+ [404, {"Content-Type" => "text/html", "X-Cascade" => "pass"}, ["Not Found"]]
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,42 @@
1
+ module E9Crm::Rack
2
+ #
3
+ # Returns contacts and joins their primary user for their email if it exists,
4
+ # and will return a string like "firstname lastname (email)". If for whatever
5
+ # reason the contact has no primary user, it will drop the email.
6
+ #
7
+ class ContactAutoCompleter
8
+ DEFAULT_LIMIT = 10
9
+
10
+ def self.call(env)
11
+ if env["PATH_INFO"] =~ /^\/autocomplete\/contacts/
12
+ params = Rack::Request.new(env).params
13
+
14
+ if query = params['query']
15
+ relation =
16
+ Contact.any_attrs_like('first_name', 'last_name', query).
17
+ limit(params['limit'] || DEFAULT_LIMIT).
18
+ joins("LEFT JOIN users on users.contact_id = contacts.id").
19
+ where(%{users.options REGEXP "primary: [\\"']?true" OR users.options IS NULL}).
20
+ select('contacts.id id, contacts.first_name first_name, contacts.last_name last_name, users.email email').
21
+ order('contacts.first_name ASC')
22
+
23
+ if params['except'] && (except = params['except'].scan(/(\d+),?/)) && !except.empty?
24
+ relation = relation.where( Contact.arel_table[:id].not_in(except.flatten) )
25
+ end
26
+
27
+ contacts = ::ActiveRecord::Base.connection.send(:select, relation.to_sql, 'Contact Autocomplete').map do |row|
28
+ name = row.values_at('first_name', 'last_name').join(' ').strip
29
+ name << " (#{row['email']})" if row['email']
30
+ { :label => name, :value => name, :id => row['id'] }
31
+ end
32
+ else
33
+ contacts = []
34
+ end
35
+
36
+ [200, {"Content-Type" => "application/json", "Cache-Control" => "max-age=3600, must-revalidate"}, [contacts.to_json]]
37
+ else
38
+ [404, {"Content-Type" => "text/html", "X-Cascade" => "pass"}, ["Not Found"]]
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,3 +1,3 @@
1
1
  module E9Crm
2
- VERSION = '0.1.13'
2
+ VERSION = '0.1.14'
3
3
  end
data/lib/e9_crm.rb CHANGED
@@ -11,11 +11,16 @@ require 'e9_base'
11
11
  require 'e9_crm/rails_extensions'
12
12
 
13
13
  module E9Crm
14
- autoload :VERSION, 'e9_crm/version'
15
- autoload :Controller, 'e9_crm/controller'
16
- autoload :Model, 'e9_crm/model'
17
- autoload :Email, 'e9_crm/email'
18
- autoload :TrackingController, 'e9_crm/tracking_controller'
14
+ autoload :VERSION, 'e9_crm/version'
15
+ autoload :Controller, 'e9_crm/controller'
16
+ autoload :Model, 'e9_crm/model'
17
+ autoload :Email, 'e9_crm/email'
18
+ autoload :TrackingController, 'e9_crm/tracking_controller'
19
+
20
+ module Rack
21
+ autoload :ContactAutoCompleter, 'e9_crm/rack/contact_auto_completer'
22
+ autoload :CompanyAutoCompleter, 'e9_crm/rack/company_auto_completer'
23
+ end
19
24
 
20
25
  mattr_accessor :cookie_name
21
26
  @@cookie_name = '_e9_tc'
@@ -19,8 +19,19 @@
19
19
  /*
20
20
  *
21
21
  */
22
- $('.dated-costs > .actions a').bind('ajax:success', function(e, data, status, xhr) {
23
- $(data).insertBefore($(this).closest('.actions'));
22
+ $('.dated-costs a.new-resource').click(function(e) {
23
+ e.preventDefault();
24
+
25
+ var $this = $(this);
26
+
27
+ $.ajax({
28
+ url: $this.attr('href'),
29
+ dataType: 'json',
30
+ success: function(data) {
31
+ $(data.html).insertBefore($this.closest('.actions'));
32
+ }
33
+ });
34
+
24
35
  });
25
36
 
26
37
  $("#campaign_code_field input").keyup(function() {
@@ -130,6 +141,8 @@
130
141
 
131
142
 
132
143
  $('#contact_email_form', $selector).live('submit', function(e) {
144
+ e.preventDefault();
145
+
133
146
  var $f = $(this);
134
147
 
135
148
  if ($f.attr('data-count') == '0') {
@@ -137,6 +150,15 @@
137
150
  $f.undisable();
138
151
  return false;
139
152
  }
153
+
154
+ $.ajax({
155
+ url: $f.attr('action'),
156
+ data: $f.serializeArray(),
157
+ type: 'get',
158
+ success: function(data) {
159
+ $.colorbox({ html: data });
160
+ }
161
+ });
140
162
  });
141
163
 
142
164
  //$('#contact_newsletter_form', $selector).live('submit', function(e) {
@@ -298,4 +320,95 @@
298
320
  }
299
321
  });
300
322
  });
323
+
324
+
325
+ function doNothing(e) {
326
+ var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
327
+
328
+ alert(keyCode);
329
+
330
+ if( keyCode == 13 ) {
331
+ if(!e) var e = window.event;
332
+
333
+ e.cancelBubble = true;
334
+ e.returnValue = false;
335
+
336
+ if (e.stopPropagation) {
337
+ e.stopPropagation();
338
+ e.preventDefault();
339
+ }
340
+ }
341
+ }
342
+
343
+ /*
344
+ * Contact autocomplete
345
+ */
346
+ var $contact_autocomplete = $('#contact_autocomplete');
347
+ //var search_cache = {};
348
+
349
+ $contact_autocomplete
350
+ // stop enter from submitting our form
351
+ .bind('keypress', function(e) {
352
+ if (e.keyCode == 13) e.preventDefault();
353
+ })
354
+ .autocomplete({
355
+ delay: 400,
356
+
357
+ // on select, add the template (code is in widgets.js) and
358
+ // clear the input field
359
+ select: function(e, ui) {
360
+ $contact_autocomplete
361
+ .add_select_template(ui.item.value, ui.item.id)
362
+ .val('');
363
+
364
+ // return false to prevent autocomplete from filling the field
365
+ return false;
366
+ },
367
+ source: function(request, response) {
368
+
369
+ var data = 'query=' + request.term,
370
+ excl = $contact_autocomplete.attr('data-values');
371
+
372
+ // add 'except' ids if they exist in values.
373
+ if (excl.length) data += '&except=' + excl;
374
+
375
+ $.ajax({
376
+ url: "/autocomplete/contacts",
377
+ dataType: "json",
378
+ data: data,
379
+ success: function(data) {
380
+ // caching code, not impl
381
+ //search_cache.term = request.term;
382
+ //search_cache.content = data;
383
+ response(data);
384
+ }
385
+ });
386
+ }
387
+ })
388
+ ;
389
+
390
+ var $company_autocomplete = $('#contact_company_name');
391
+
392
+ $company_autocomplete
393
+ .autocomplete({
394
+ delay: 400,
395
+ focus: function(e, ui) {
396
+ $company_autocomplete.val(ui.item.value);
397
+ return false;
398
+ },
399
+ source: function(request, response) {
400
+ $.ajax({
401
+ url: "/autocomplete/companies",
402
+ dataType: "json",
403
+ data: request,
404
+ success: function(data) {
405
+ // caching code, not impl
406
+ //search_cache.term = request.term;
407
+ //search_cache.content = data;
408
+ response(data);
409
+ }
410
+ });
411
+ }
412
+ })
413
+ ;
301
414
  });
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: e9_crm
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.13
5
+ version: 0.1.14
6
6
  platform: ruby
7
7
  authors:
8
8
  - Travis Cox
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-05-31 00:00:00 -04:00
13
+ date: 2011-06-07 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -170,6 +170,7 @@ files:
170
170
  - app/controllers/e9_crm/page_views_controller.rb
171
171
  - app/controllers/e9_crm/resources_controller.rb
172
172
  - app/controllers/e9_crm/sales_campaigns_controller.rb
173
+ - app/controllers/e9_crm/users_controller.rb
173
174
  - app/controllers/e9_crm/video_offers_controller.rb
174
175
  - app/helpers/e9_crm/base_helper.rb
175
176
  - app/helpers/e9_crm/campaign_groups_helper.rb
@@ -319,6 +320,8 @@ files:
319
320
  - lib/e9_crm/e9_extensions.rb
320
321
  - lib/e9_crm/email.rb
321
322
  - lib/e9_crm/model.rb
323
+ - lib/e9_crm/rack/company_auto_completer.rb
324
+ - lib/e9_crm/rack/contact_auto_completer.rb
322
325
  - lib/e9_crm/rails_extensions.rb
323
326
  - lib/e9_crm/tracking_controller.rb
324
327
  - lib/e9_crm/version.rb