Module: ApplicationHelper

Defined in:
app/helpers/application_helper.rb

Overview

Fat Free CRM Copyright © 2008-2011 by Michael Dvorkin

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License along with this program. If not, see <www.gnu.org/licenses/>.


Instance Method Summary collapse

Instance Method Details

#address_field(form, object, attribute, extra_styles) ⇒ Object

Render a text field that is part of compound address.




350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
# File 'app/helpers/application_helper.rb', line 350

def address_field(form, object, attribute, extra_styles)
  hint = "#{t(attribute)}..."
  if object.send(attribute).blank?
    object.send("#{attribute}=", hint)
    form.text_field(attribute,
      :hint    => true,
      :style   => "margin-top: 6px; color:silver; #{extra_styles}",
      :onfocus => "crm.hide_hint(this)",
      :onblur  => "crm.show_hint(this, '#{hint}')"
    )
  else
    form.text_field(attribute,
      :hint    => false,
      :style   => "margin-top: 6px; #{extra_styles}",
      :onfocus => "crm.hide_hint(this, '#{escape_javascript(object.send(attribute))}')",
      :onblur  => "crm.show_hint(this, '#{hint}')"
    )
  end
end

#arrow_for(id) ⇒ Object




107
108
109
# File 'app/helpers/application_helper.rb', line 107

def arrow_for(id)
  (:span, "&#9658;".html_safe, :id => "#{id}_arrow", :class => :arrow)
end

#avatar_for(model, args = {}) ⇒ Object

Users can upload their avatar, and if it’s missing we’re going to use gravatar. For leads and contacts we always use gravatars.




315
316
317
318
319
320
321
322
323
324
# File 'app/helpers/application_helper.rb', line 315

def avatar_for(model, args = {})
  args = { :class => 'gravatar', :size => '75x75' }.merge(args)
  if model.avatar
    image_tag(model.avatar.image.url(Avatar.styles[args[:size]]), args)
  elsif model.email
    gravatar_image_tag(model.email, { :gravatar => { :default => default_avatar_url } }.merge(args))
  else
    image_tag("avatar.jpg", args)
  end
end

#confirm_delete(model, params = {}) ⇒ Object




222
223
224
225
226
227
228
229
230
# File 'app/helpers/application_helper.rb', line 222

def confirm_delete(model, params = {})
  question = %(<span class="warn">#{t(:confirm_delete, model.class.to_s.downcase)}</span>).html_safe
  yes = link_to(t(:yes_button), params[:url] || model, :method => :delete)
  no = link_to_function(t(:no_button), "$('menu').update($('confirm').innerHTML)")
  update_page do |page|
    page << "$('confirm').update($('menu').innerHTML)"
    page[:menu].replace_html "#{question} #{yes} : #{no}"
  end
end

#default_avatar_urlObject




334
335
336
# File 'app/helpers/application_helper.rb', line 334

def default_avatar_url
  "#{request.protocol + request.host_with_port}" + Setting.base_url.to_s + "/assets/avatar.jpg"
end

#exposedObject



192
# File 'app/helpers/application_helper.rb', line 192

def exposed;   { :style => "display:block;"      }; end

#get_browser_timezone_offsetObject

Ajax helper to pass browser timezone offset to the server.




294
295
296
297
298
299
300
301
# File 'app/helpers/application_helper.rb', line 294

def get_browser_timezone_offset
  unless session[:timezone_offset]
    remote_function(
      :url  => timezone_path,
      :with => "'offset='+(new Date()).getTimezoneOffset()"
    )
  end
end

#get_default_permissions_intro(access, text) ⇒ Object

Returns default permissions intro.




340
341
342
343
344
345
346
# File 'app/helpers/application_helper.rb', line 340

def get_default_permissions_intro(access, text)
  case access
    when "Private" then t(:permissions_intro_private, text)
    when "Public"  then t(:permissions_intro_public,  text)
    when "Shared"  then t(:permissions_intro_shared,  text)
  end
end

#gravatar_for(model, args = {}) ⇒ Object

Gravatar helper that adds default CSS class and image URL.




328
329
330
331
# File 'app/helpers/application_helper.rb', line 328

def gravatar_for(model, args = {})
  args = { :class => 'gravatar', :gravatar => { :default => default_avatar_url } }.merge(args)
  gravatar_image_tag(model.email, args)
end

#hiddenObject




191
# File 'app/helpers/application_helper.rb', line 191

def hidden;    { :style => "display:none;"       }; end

#hidden_if(you_ask) ⇒ Object




202
203
204
# File 'app/helpers/application_helper.rb', line 202

def hidden_if(you_ask)
  you_ask ? hidden : exposed
end

#highlightable(id = nil, color = {}) ⇒ Object




212
213
214
215
216
217
218
219
# File 'app/helpers/application_helper.rb', line 212

def highlightable(id = nil, color = {})
  color = { :on => "seashell", :off => "white" }.merge(color)
  show = (id ? "$('#{id}').style.visibility='visible'" : "")
  hide = (id ? "$('#{id}').style.visibility='hidden'" : "")
  { :onmouseover => "this.style.background='#{color[:on]}'; #{show}",
    :onmouseout  => "this.style.background='#{color[:off]}'; #{hide}"
  }
end

#invisibleObject



193
# File 'app/helpers/application_helper.rb', line 193

def invisible; { :style => "visibility:hidden;"  }; end

#invisible_if(you_ask) ⇒ Object




207
208
209
# File 'app/helpers/application_helper.rb', line 207

def invisible_if(you_ask)
  you_ask ? invisible : visible
end

#jumpbox(current) ⇒ Object




177
178
179
180
181
182
183
# File 'app/helpers/application_helper.rb', line 177

def jumpbox(current)
  tabs = [ :campaigns, :accounts, :leads, :contacts, :opportunities ]
  current = tabs.first unless tabs.include?(current)
  tabs.map do |tab|
    link_to_function(t("tab_#{tab}"), "crm.jumper('#{tab}')", :class => (tab == current ? 'selected' : ''))
  end.join(" | ").html_safe
end


409
410
411
412
413
414
415
# File 'app/helpers/application_helper.rb', line 409

def link_to_add_fields(name, f, type)
  new_object = f.object.send "build_#{type}"
  fields = f.send("#{type}_fields", new_object, :child_index => "new_#{type}") do |builder|
    render(type.to_s + "_fields", :f => builder)
  end
  link_to name, nil, :class => "add_fields", "data-field-type" => type, "data-content" => "#{fields}"
end



147
148
149
150
151
152
153
# File 'app/helpers/application_helper.rb', line 147

def link_to_cancel(url, params = {})
  url = params[:url] if params[:url]
  link_to(t(:cancel),
    url + "#{url.include?('?') ? '&' : '?'}cancel=true",
    :remote => true
  )
end



156
157
158
159
160
161
162
# File 'app/helpers/application_helper.rb', line 156

def link_to_close(url)
  link_to("x", url + "#{url.include?('?') ? '&' : '?'}cancel=true",
    :remote => true,
    :class => "close",
    :title => t(:close_form)
  )
end



122
123
124
125
126
127
128
129
130
# File 'app/helpers/application_helper.rb', line 122

def link_to_delete(model, params = {})
  name = (params[:klass_name] || model.class.name).underscore.downcase
  link_to(t(:delete) + "!",
    params[:url] || url_for(model),
    :method => :delete,
    :remote => true,
    :onclick => visual_effect(:highlight, dom_id(model), :startcolor => "#ffe4e1")
  )
end



133
134
135
136
137
138
139
140
141
142
143
144
# File 'app/helpers/application_helper.rb', line 133

def link_to_discard(model)
  name = model.class.name.downcase
  current_url = (request.xhr? ? request.referer : request.fullpath)
  parent, parent_id = current_url.scan(%r|/(\w+)/(\d+)|).flatten

  link_to(t(:discard),
    url_for(:controller => parent, :action => :discard, :id => parent_id, :attachment => model.class.name, :attachment_id => model.id),
    :method  => :post,
    :remote  => true,
    :onclick => visual_effect(:highlight, dom_id(model), :startcolor => "#ffe4e1")
  )
end



112
113
114
115
116
117
118
119
# File 'app/helpers/application_helper.rb', line 112

def link_to_edit(model, params = {})
  name = (params[:klass_name] || model.class.name).underscore.downcase
  link_to(t(:edit),
    params[:url] || send(:"edit_#{name}_path", model),
    :remote  => true,
    :onclick => "this.href = this.href.split('?')[0] + '?previous='+crm.find_form('edit_#{name}');"
  )
end

Bcc: to dropbox address if the dropbox has been set up.




166
167
168
169
170
171
172
173
174
# File 'app/helpers/application_helper.rb', line 166

def link_to_email(email, length = nil)
  name = (length ? truncate(email, :length => length) : email)
  if Setting.email_dropbox && Setting.email_dropbox[:address].present?
    mailto = "#{email}?bcc=#{Setting.email_dropbox[:address]}"
  else
    mailto = email
  end
  link_to(h(name), "mailto:#{mailto}", :title => email)
end



94
95
96
97
98
99
100
101
102
103
104
# File 'app/helpers/application_helper.rb', line 94

def link_to_inline(id, url, options = {})
  text = options[:text] || t(id, :default => id.to_s.titleize)
  text = (arrow_for(id) + text) unless options[:plain]
  related = (options[:related] ? "&related=#{options[:related]}" : '')

  link_to(text,
    url + "#{url.include?('?') ? '&' : '?'}cancel=false" + related,
    :remote => true,
    :onclick => "this.href = this.href.replace(/cancel=(true|false)/,'cancel='+ Element.visible('#{id}'));"
  )
end


417
418
419
# File 'app/helpers/application_helper.rb', line 417

def link_to_remove_fields(name, f)
  link_to image_tag('delete.png', :size => '16x16', :alt => name), nil, :class => "remove_fields"
end

Helper to display links to supported data export formats.




382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
# File 'app/helpers/application_helper.rb', line 382

def links_to_export
  token = @current_user.single_access_token
  path = if controller.controller_name == 'home'
    activities_path
  elsif controller.class.to_s.starts_with?("Admin::")
    send("admin_#{controller.controller_name}_path")
  else
    send("#{controller.controller_name}_path")
  end

  exports = %w(xls csv).map do |format|
    link_to(format.upcase, "#{path}.#{format}", :title => I18n.t(:"to_#{format}"))
  end

  feeds = %w(rss atom).map do |format|
    link_to(format.upcase, "#{path}.#{format}?authentication_credentials=#{token}", :title => I18n.t(:"to_#{format}"))
  end

  (exports + feeds).join(' | ')
end

#load_select_popups_for(related, *assets) ⇒ Object




74
75
76
77
78
79
80
81
82
# File 'app/helpers/application_helper.rb', line 74

def load_select_popups_for(related, *assets)
  js = assets.map do |asset|
    render(:partial => "shared/select_popup", :locals => { :related => related, :popup => asset })
  end.join

  content_for(:javascript_epilogue) do
    raw "document.observe('dom:loaded', function() { #{js} });"
  end
end

#localize_calendar_date_selectObject




304
305
306
307
308
309
310
# File 'app/helpers/application_helper.rb', line 304

def localize_calendar_date_select
  update_page_tag do |page|
    page.assign '_translations', { 'OK' => t('calendar_date_select.ok'), 'Now' => t('calendar_date_select.now'), 'Today' => t('calendar_date_select.today'), 'Clear' => t('calendar_date_select.clear') }
    page.assign 'Date.weekdays', t('date.abbr_day_names')
    page.assign 'Date.months', t('date.month_names')[1..-1]
  end
end

#one_submit_only(form) ⇒ Object




197
198
199
# File 'app/helpers/application_helper.rb', line 197

def one_submit_only(form)
  { :onsubmit => "$$('#'+this.id+' input[type=\"submit\"]')[0].disabled = true" }
end

#options_menu_item(option, key, url = nil) ⇒ Object




280
281
282
283
284
285
286
287
288
289
290
# File 'app/helpers/application_helper.rb', line 280

def options_menu_item(option, key, url = nil)
  name = t("option_#{key}")
  "{ name: \"#{name.titleize}\", on_select: function() {" +
  remote_function(
    :url       => url || send("redraw_#{controller.controller_name}_path"),
    :with      => "'#{option}=#{key}'",
    :condition => "$('#{option}').innerHTML != '#{name}'",
    :loading   => "$('#{option}').update('#{name}'); $('loading').show()",
    :complete  => "$('loading').hide()"
  ) + "}}"
end

#rating_select(name, options = {}) ⇒ Object

We need this because standard Rails [select] turns &#9733; into &amp;#9733;




86
87
88
89
90
91
# File 'app/helpers/application_helper.rb', line 86

def rating_select(name, options = {})
  stars = Hash[ (1..5).map { |star| [ star, "&#9733;" * star ] } ].sort
  options_for_select = %Q(<option value="0"#{options[:selected].to_i == 0 ? ' selected="selected"' : ''}>#{t :select_none}</option>)
  options_for_select << stars.map { |star| %(<option value="#{star.first}"#{options[:selected] == star.first ? ' selected="selected"' : ''}>#{star.last}</option>) }.join
  select_tag name, options_for_select.html_safe, options
end

#redraw(option, value, url = nil) ⇒ Object

Ajax helper to refresh current index page once the user selects an option.




266
267
268
269
270
271
272
273
274
275
276
277
# File 'app/helpers/application_helper.rb', line 266

def redraw(option, value, url = nil)
  if value.is_a?(Array)
    param, value = value.first, value.last
  end
  remote_function(
    :url       => url || send("redraw_#{controller.controller_name}_path"),
    :with      => "'#{option}=#{param || value}'",
    :condition => "$('#{option}').innerHTML != '#{value}'",
    :loading   => "$('#{option}').update('#{value}'); $('loading').show()",
    :complete  => "$('loading').hide()"
  )
end

#refresh_sidebar(action = nil, shake = nil) ⇒ Object

Reresh sidebar using the action view within the current controller.




239
240
241
# File 'app/helpers/application_helper.rb', line 239

def refresh_sidebar(action = nil, shake = nil)
  refresh_sidebar_for(controller.controller_name, action, shake)
end

#refresh_sidebar_for(view, action = nil, shake = nil) ⇒ Object

Refresh sidebar using the action view within an arbitrary controller.




245
246
247
248
249
250
# File 'app/helpers/application_helper.rb', line 245

def refresh_sidebar_for(view, action = nil, shake = nil)
  update_page do |page|
    page[:sidebar].replace_html :partial => "layouts/sidebar", :locals => { :view => view, :action => action }
    page[shake].visual_effect(:shake, :duration => 0.2, :distance => 3) if shake
  end
end

#section(related, assets) ⇒ Object




59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'app/helpers/application_helper.rb', line 59

def section(related, assets)
  asset = assets.to_s.singularize
  create_id  = "create_#{asset}"
  select_id  = "select_#{asset}"
  create_url = controller.send(:"new_#{asset}_path")

  html = tag(:br)
  html << (:div, link_to(t(select_id), "#", :id => select_id), :class => "subtitle_tools")
  html << (:div, "&nbsp;|&nbsp;".html_safe, :class => "subtitle_tools")
  html << (:div, link_to_inline(create_id, create_url, :related => dom_id(related), :text => t(create_id)), :class => "subtitle_tools")
  html << (:div, t(assets), :class => :subtitle, :id => "create_#{asset}_title")
  html << (:div, "", :class => :remote, :id => create_id, :style => "display:none;")
end

#show_flash(options = { :sticky => false }) ⇒ Object

Show existing flash or embed hidden paragraph ready for flash




38
39
40
41
42
43
44
45
46
# File 'app/helpers/application_helper.rb', line 38

def show_flash(options = { :sticky => false })
  [:error, :warning, :info, :notice].each do |type|
    if flash[type]
      html = (:p, h(flash[type]), :id => "flash")
      return html << (:script, "crm.flash('#{type}', #{options[:sticky]})", :type => "text/javascript")
    end
  end
  (:p, nil, :id => "flash", :style => "display:none;")
end

#shown_on_landing_page?Boolean

Return true if:

- it's an Ajax request made from the asset landing page (i.e. create opportunity
  from a contact landing page) OR
- we're actually showing asset landing page.

Returns:

  • (Boolean)


375
376
377
378
# File 'app/helpers/application_helper.rb', line 375

def shown_on_landing_page?
  !!((request.xhr? && request.referer =~ %r|/\w+/\d+|) ||
     (!request.xhr? && request.fullpath =~ %r|/\w+/\d+|))
end

#spacer(width = 10) ⇒ Object




233
234
235
# File 'app/helpers/application_helper.rb', line 233

def spacer(width = 10)
  image_tag "1x1.gif", :width => width, :height => 1, :alt => nil
end

#styles_for(*models) ⇒ Object




186
187
188
# File 'app/helpers/application_helper.rb', line 186

def styles_for(*models)
  render :partial => "shared/inline_styles", :locals => { :models => models }
end

#subtitle(id, hidden = true, text = id.to_s.split("_").last.capitalize) ⇒ Object




49
50
51
52
53
54
55
56
# File 'app/helpers/application_helper.rb', line 49

def subtitle(id, hidden = true, text = id.to_s.split("_").last.capitalize)
  ("div",
    link_to("<small>#{ hidden ? "&#9658;" : "&#9660;" }</small> #{text}".html_safe,
      url_for(:controller => :home, :action => :toggle, :id => id),
      :remote => true,
      :onclick => "crm.flip_subtitle(this)"
    ), :class => "subtitle")
end

#tabless_layout?Boolean


Returns:

  • (Boolean)


31
32
33
34
# File 'app/helpers/application_helper.rb', line 31

def tabless_layout?
  %w(authentications passwords).include?(controller.controller_name) ||
  ((controller.controller_name == "users") && (%w(create new).include?(controller.action_name)))
end

#tabs(tabs = nil) ⇒ Object



20
21
22
23
24
25
26
27
28
# File 'app/helpers/application_helper.rb', line 20

def tabs(tabs = nil)
  tabs ||= controller_path =~ /admin/ ? FatFreeCRM::Tabs.admin : FatFreeCRM::Tabs.main
  if tabs
    @current_tab ||= tabs.first[:text] # Select first tab by default.
    tabs.each { |tab| tab[:active] = (@current_tab == tab[:text] || @current_tab == tab[:url][:controller]) }
  else
    raise FatFreeCRM::MissingSettings, "Tab settings are missing, please run <b>rake ffcrm:setup</b> command."
  end
end

#template_fields(f, type) ⇒ Object



403
404
405
406
407
# File 'app/helpers/application_helper.rb', line 403

def template_fields(f, type)
  f.grouping_fields f.object.new_grouping, :object_name => "new_object_name", :child_index => "new_grouping" do |builder|
    render('grouping_fields', :f => builder)
  end
end

#visibleObject



194
# File 'app/helpers/application_helper.rb', line 194

def visible;   { :style => "visibility:visible;" }; end

#web_presence_icons(person) ⇒ Object

Display web presence mini-icons for Contact or Lead.




254
255
256
257
258
259
260
261
262
# File 'app/helpers/application_helper.rb', line 254

def web_presence_icons(person)
  [ :blog, :linkedin, :facebook, :twitter, :skype ].map do |site|
    url = person.send(site)
    unless url.blank?
      url = "http://" << url unless url.match(/^https?:\/\//)
      link_to(image_tag("#{site}.gif", :size => "15x15"), url, :"data-popup" => true, :title => t(:open_in_window, url))
    end
  end.compact.join("\n").html_safe
end