Methods
Public Instance methods
attachment_tag(object_name, method, options={})

Returns html for upload one image or generic file.

Options can be one of the following:

:image:Indicate if the attachments are ONLY images.
:only_upload:Indicate that is not necessary manage the old attachments.

Examples:

  class Category < ActiveRecord::Base
    has_one_attachments    :file,   :dependent => :destroy
  ...

Then in our view we can simply add this:

  attachments_tag(:category, :file)

Remember that al labels can be translated. See Locales for Backend.

     # File lib/view/helpers/backend_helper.rb, line 213
213:         def attachment_tag(object_name, method, options={})
214:           variable = instance_variable_get("@#{object_name}")
215:           html     = []
216:           html    << '<!-- Generated from Lipsiadmin -->'
217:           
218:           unless options[:only_upload]
219:             html    << '<ul id="' + "#{method}-order" + '" class="label">'
220:             
221:             if attachment = variable.send(method)
222:               # Create first the remove link
223:               remove_link = link_to_remote(tl(:remove), :url => "/backend/attachments/#{attachment.id}", 
224:                                                         :method => :delete, 
225:                                                         :success => "$('#{method}_#{attachment.id}').remove();")
226:             
227:               if options[:image]
228:                 fstyle  = "float:left;margin:5px;margin-left:0px;"
229:                 fclass  = "box-image"
230:                 ftag    = '<div>' + image_tag(attachment.url(:thumb)) + '</div>'
231:                 ftag   += '<div style="text-align:center;padding:5px;cursor:pointer">'
232:                 ftag   += '  ' + remove_link
233:                 ftag   += '</div>'
234:               else
235:                 fstyle  = "padding:5px;border-bottom:1px solid #DDE7F5;"
236:                 fclass  = "box-file"
237:                 ftag    = '<div style="float:left;cursor:pointer">'
238:                 ftag   += ' ' + link_to(attachment.attached_file_name, attachment.url) + ' ' + number_to_human_size(attachment.attached_file_size)
239:                 ftag   += '</div>'
240:                 ftag   += '<div style="float:right;cursor:pointer">'
241:                 ftag   += '  ' + remove_link
242:                 ftag   += '</div>'
243:                 ftag   += '<br style="clear:both" />'
244:               end
245:             
246:               html << '<li id="' + "#{method}_#{attachment.id}" + '" class="' + fclass + '" style="' + fstyle + '">'
247:               html << ' ' + ftag
248:               html << '</li>'
249:             end # End of Loop
250:             
251:             html << '</ul>'
252:             html << '<br style="clear:both" />'
253:           end
254: 
255:           flbl = options[:image] ? :upload_image : :upload_file
256:           html << '<div class="label-title">' + tl(flbl) + '</div>'
257:           html << '<table>'
258:           rowa  = '  <tr class="attachment">'
259:           rowa << '    <td>' + human_name_for(:attachment, :attached_file_name) + '</td>'
260:           rowa << '    <td>' + file_field_tag("#{object_name}[#{method}_attributes][file]", :style => "width:250px") + '</td>'
261:           rowa << '  </tr>'
262:           html << rowa
263:           html << '</table>'
264:           html.join("\n")
265:         end
attachments_tag(object_name, method, options={})

Returns html for upload multiple images or generic files.

Options can be one of the following:

:image:Indicate if the attachments are ONLY images.
:only_upload:Indicate that is not necessary manage the old attachments.
:order:Indicate if user can order files.

Examples:

  class Category < ActiveRecord::Base
    has_many_attachments    :images,   :dependent => :destroy
    validates_attachment_content_type_for :images, /^image/
  ...

Then in our view we can simply add this:

  attachments_tag(:category, :images, :image => true, :order => true)

Remember that al labels can be translated. See Locales for Backend.

     # File lib/view/helpers/backend_helper.rb, line 288
288:         def attachments_tag(object_name, method, options={})
289:           variable = instance_variable_get("@#{object_name}")
290:           html     = []
291:           html    << '<!-- Generated from Lipsiadmin -->'
292:           unless options[:only_upload]
293:             html    << '<ul id="' + "#{method}-order" + '" class="label">'
294:             
295:             for attachment in variable.send(method).all(:order => :position)
296:               # Create first the remove link
297:               remove_link = link_to_remote(tl(:remove), :url => "/backend/attachments/#{attachment.id}", 
298:                                                         :method => :delete, 
299:                                                         :success => "$('#{method}_#{attachment.id}').remove();")
300:             
301:               if options[:image]
302:                 fstyle  = "float:left;margin:5px;margin-left:0px;"
303:                 fstyle += "cursor:move;" if options[:order]
304:                 fclass  = "box-image"
305:                 ftag    = '<div>' + image_tag(attachment.url(:thumb)) + '</div>'
306:                 ftag   += '<div style="text-align:center;padding:5px;cursor:pointer">'
307:                 ftag   += '  ' + remove_link
308:                 ftag   += '</div>'
309:               else
310:                 fstyle  = "padding:5px;border-bottom:1px solid #DDE7F5;"
311:                 fstyle += "cursor:move;" if options[:order]
312:                 fclass  = "box-file"
313:                 ftag    = '<div style="float:left;cursor:pointer">'
314:                 ftag   += ' ' + link_to(attachment.attached_file_name, attachment.url) + ' ' + number_to_human_size(attachment.attached_file_size)
315:                 ftag   += '</div>'
316:                 ftag   += '<div style="float:right;cursor:pointer">'
317:                 ftag   += '  ' + remove_link
318:                 ftag   += '</div>'
319:                 ftag   += '<br style="clear:both" />'
320:               end
321:             
322:               html << '<li id="' + "#{method}_#{attachment.id}" + '" class="' + fclass + '" style="' + fstyle + '">'
323:               html << ' ' + ftag
324:               html << '</li>'
325:             end # End of Loop
326:             
327:             html << '</ul>'
328:             html << '<br style="clear:both" />'
329:           
330: 
331:             if options[:order]
332:               constraint = options[:image] ? "horizontal" : "vertical"
333:               html << '<div id="' + "#{method}-message" + '" style="padding:5px">&nbsp;</div>'
334:               html << sortable_element("#{method}-order", :url => "/backend/attachments/order", :update => "#{method}-message", :constraint => constraint,
335:                                                           :complete => visual_effect(:highlight, "#{method}-message", :duration => 0.5))
336:             end
337:           end
338:           
339:           flbl = options[:image] ? :upload_images : :upload_files
340:           html << '<div class="label-title">'+ tl(flbl) +'</div>'
341:           html << '<table>'
342:           rowa  = '  <tr class="attachment">'
343:           rowa << '    <td>' + human_name_for(:attachment, :attached_file_name) + '</td>'
344:           rowa << '    <td>' + file_field_tag("#{object_name}[#{method}_attributes][][file]", :style => "width:250px") + '</td>'
345:           rowa << '    <td>' + link_to_function(tl(:remove), "this.up('.attachment').remove()") + '</td>'
346:           rowa << '  </tr>'
347:           html << rowa
348:           html << ' <tr id="' + "add-#{method}" + '">'
349:           html << '  <td colspan="2">&nbsp;</td>'
350:           html << '  <td style="padding-top:15px">'
351:           html << '     ' + link_to_function(tl(:add)) { |page| page.insert_html(:before, "add-#{method}", rowa) }
352:           html << '  </td>'
353:           html << ' </tr>'
354:           html << '</table>'
355:           html.join("\n")
356:         end
back_to(location)

Store the location to come back from for example an extjs grid

     # File lib/view/helpers/backend_helper.rb, line 183
183:         def back_to(location)
184:           content_tag(:script, "Backend.app.backTo(#{url_for(location)})", :type => Mime::JS)
185:         end
backend_menu()

Generate the menu from the Lispiadmin::AccessControl

     # File lib/view/helpers/backend_helper.rb, line 188
188:         def backend_menu
189:           config = AccountAccess.maps_for(current_account).collect(&:project_modules).flatten.uniq.collect(&:config)
190:           config << { :text => I18n.t("backend.menus.help", :default => "Help"), :handler => "function() { Backend.app.openHelp() }".to_l }
191:           return config.to_json
192:         end
box(title=nil, subtitle=nil, options={}, &block)

This method generates a new ExtJs BoxComponent.

  Examples:

    -box "My Title", "My Subtitle", :submit => true, :collapsible => true, :style => "padding:none", :start => :close do
      my content

Defaults:

  • :submit => false
  • :collapsible => false
  • :start => :close
     # File lib/view/helpers/backend_helper.rb, line 519
519:         def box(title=nil, subtitle=nil, options={}, &block)
520:           options[:style] ||= "width:100%;"
521:           options[:start] ||= :open
522:           concat "<div class=\"x-box\" style=\"\#{options[:style]}\">\n<div class=\"x-box-tl\">\n<div class=\"x-box-tr\">\n<div class=\"x-box-tc\">&nbsp;</div>\n</div>\n</div>\n<div class=\"x-box-ml\">\n<div class=\"x-box-mr\">\n<div class=\"x-box-mc\">\n<div id=\"x-body-title\" style=\"\#{\"cursor:pointer\" if options[:collapsible]}\" onclick=\"\#{\"Backend.app.collapseBoxes(this);\" if options[:collapsible]}\">\n\#{\"<h3 style=\\\"margin-bottom:0px;padding-bottom:0px;float:left;\\\">\"+title+\"</h3>\" unless title.blank?}\n\#{\"<div style=\\\"float:right\\\"><em>\"+subtitle+\"</em></div>\" unless subtitle.blank?}\n\#{\"<br class=\\\"clear\\\" />\" if !title.blank? || !subtitle.blank?}\n\#{\"<div style=\\\"font-size:0px\\\">&nbsp;</div>\" if !title.blank? || !subtitle.blank?}\n</div>\n<div class=\"\#{\"x-box-collapsible\" if options[:collapsible]}\" style=\"width:99%;\#{\"display:none\" if options[:collapsible] && options[:start] == :close}\">\n\#{\"<div style=\\\"font-size:10px\\\">&nbsp;</div>\" if !title.blank? || !subtitle.blank?}\n\#{capture(&block)}\n\#{\"<div style=\\\"text-align:right;margin-top:10px\\\">\#{submit_tag(I18n.t(\"lipsiadmin.buttons.save\"), :onclick=>\"Backend.app.submitForm()\")}</div>\" if options[:submit]}\n</div>\n</div>\n</div>\n</div>\n<div class=\"x-box-bl\">\n<div class=\"x-box-br\">\n<div class=\"x-box-bc\">&nbsp;</div>\n</div>\n</div>\n</div>\n"
523:         end
build_grid(text, url, grid, options={})

Build a new windows that can contain an existent grid

The first argument name is used as the link text.

The second argument is the url where js of grid are stored.

The third argument is the name of the gird var usually gridPanel or editorGridPanel.

The four argument are callbacks that may be specified:

:before:Called before request is initiated.
:update:Called after user press select button. This call are performed in an handler where you have access to two variables:
:win:Backend.window
:selections:Records selected in the grid
  # Generates: <a onclick="
  #   new Backend.window({
  #     url: '/backend/categories.js',
  #     grid: 'gridPanel',
  #     listeners: {
  #       selected: function(win, selections){
  #         $('post_category_ids').value = selections.collect(function(s) { return s.id }).join(',');
  #         $('category_names').innerHTML = selections.collect(function(s) { return s.data['categories.name'] }).join(', ');
  #       }
  #     }
  #   }).show();
  #   return false;" href="#">Select a Category</a>
  build_grid "Select a Category", "/backend/categories.js", "gridPanel",
    :update => "$('post_category_ids').value = selections.collect(function(s) { return s.id }).join(',');" +
    "$('category_names').innerHTML = selections.collect(function(s) { return s.data['categories.name'] }).join(', ');"
This method is also aliased as open_grid
     # File lib/view/helpers/backend_helper.rb, line 391
391:         def build_grid(text, url, grid, options={})
392:           options[:before] = options[:before] + ";" if options[:before]
393:           javascript = "\#{options[:before]}\nnew Backend.window({\nurl: '\#{url}',\ngrid: '\#{grid}',\nlisteners: {\nselected: function(win, selections){\n\#{options[:update]}\n}\n}\n}).show()\n"
394:           link_to_function(text, javascript.gsub(/\n|\s+/, " "))
395:         end
edit_title_for(text, value)

Get the title for edit action of a form based on your current locale

The locale file for this translation is located: config/locales/backend

  # Generate: Edit Account 18
  edit_title_for(Account, @account.id)

  # Generate: Edit My Account Foo Bar
  edit_title_for("My Account", @account.full_name)
     # File lib/view/helpers/backend_helper.rb, line 119
119:         def edit_title_for(text, value)
120:           title I18n.t("backend.general.editForm", :model => text.is_a?(String) ? text : text.send(:human_name), :value => value)
121:         end
human_name_for(instance, method)

Return the translated attribute based on your current locale

  # In config/locales/backend/models/en.yml
  en:
    activerecord:
      attributes:
        account:
          name: "Account Name"
          suranme: "Custom Title For Surname"
          role: "Im a"

  # Generates:
  #   Account Name
  #   Custom Title For Surname
  #   Im a
  #   Attribute not translated
  human_name_for :account, :name
  human_name_for :account, :surname
  human_name_for :account, :role
  human_name_for :account, :attribute_not_translated
     # File lib/view/helpers/backend_helper.rb, line 178
178:         def human_name_for(instance, method)
179:           I18n.t("activerecord.attributes.#{instance}.#{method}", :default => method.to_s.humanize)
180:         end
link_to_remote_with_wait(name, options={}, html_options={})

This method call a remote_function and in the same time do a

  Backend.app.mask()

and when the function is complete

  Backend.app.unmask()
     # File lib/view/helpers/backend_helper.rb, line 500
500:         def link_to_remote_with_wait(name, options={}, html_options={})
501:           options[:complete] = "Backend.app.unmask();"
502:           options[:before]  = "Backend.app.mask('#{I18n.t('backend.javascripts.messages.wait.message')}')";
503:           link_to_function(name, remote_function(options), html_options || options.delete(:html))
504:         end
list_title_for(text)

Get the title for grids of the specified model based on your current locale.

The locale file for this translation is located: config/locales/backend

  # Generate: List all Accounts
  list_title_for(Account)

  # Generate: List all My Accounts
  list_title_for("My Accounts")
     # File lib/view/helpers/backend_helper.rb, line 105
105:         def list_title_for(text)
106:           I18n.t("backend.general.list", :model => text.is_a?(String) ? text : text.send(:human_name))
107:         end
new_title_for(text)

Get the title for new action of a form based on your current locale

The locale file for this translation is located: config/locales/backend

  # Generate: New Account
  new_title_for(Account)

  # Generate: New My Account
  new_title_for("My Account")
     # File lib/view/helpers/backend_helper.rb, line 133
133:         def new_title_for(text)
134:           title I18n.t("backend.general.newForm", :model => text.is_a?(String) ? text : text.send(:human_name))
135:         end
open_form(text, url, options={})

Open a new windows that can contain a form that you can reuse

The first argument name is used as the link text.

The second argument is the url where html of form are stored.

The third argument are callbacks that may be specified:

:before:Called before request is initiated.
:after:Called after request is initiated.
:on_save:Called after user press save button. This call are performed in an handler where you have access to one variables:
:win:Backend.window
  # Generates: <a onclick="
  #     new Backend.window({
  #       url: '/backend/posts/'+$('comment_post_id').value+'/edit',
  #       form: true,
  #       listeners: {
  #         saved: function(win){
  #           someFn();
  #         }
  #       }
  #     }).show();
  # return false;" href="#">Edit Post</a>
  open_form "Edit Post", "/backend/posts/'+$('comment_post_id').value+'/edit", :update => "someFn(win);"
     # File lib/view/helpers/backend_helper.rb, line 475
475:         def open_form(text, url, options={})
476:           options[:before] = options[:before] + ";" if options[:before]
477:           javascript = "\#{options[:before]}\nnew Backend.window({\nurl: '\#{url}',\nform: true,\nlisteners: {\nsaved: function(win){ \#{options[:on_save]} },\nclose: function(panel){ \#{options[:after]} }\n}\n}).show();\n"
478:           link_to_function(text, javascript.gsub(/\n/, " "))
479:         end
open_grid(text, url, grid, options={})

Alias for build_grid

open_standard_grid(object_name, ext_object, value, display, options={})

Open a Standard window that can contain a standard existent grid

Options can be one of the following:

:grid:The name of the grid var. Default "gridPanel"
:url:The url where the grid is stored. Default is autogenerated.
:name:The name of the link that open the window grid. Default a image.
  # Generates: <a onclick="
  #   new Backend.window({
  #     url: '/backend/suppliers.js',
  #     grid: 'gridPanel',
  #     listeners: {
  #       selected: function(win, selections){
  #         $('warehouse_supplier_id').value = selections.first().id;
  #         $('warehouse_supplier_name').innerHTML = selections.first().data['suppliers.name']
  #       }
  #     }
  #   }).show(); return false;">
  # <img alt="New" src="/images/backend/new.gif?1242655402" style="vertical-align:bottom" /></a>
  # <input id="warehouse_supplier_id" name="warehouse[supplier_id]" type="hidden" value="16" />
  open_standard_grid :warehouse, :supplier, :id, :name
     # File lib/view/helpers/backend_helper.rb, line 433
433:         def open_standard_grid(object_name, ext_object, value, display, options={})
434:           current_value       = instance_variable_get("@#{object_name}").send(ext_object).send(display) rescue "Nessuno"
435:           value_field         = value.to_s.downcase == "id" ? "id" : "data['#{ext_object.to_s.pluralize}.#{value}']"
436:           options[:grid]    ||= "gridPanel"
437:           options[:url]     ||= "/backend/#{ext_object.to_s.pluralize}.js"
438:           options[:name]    ||= image_tag("backend/new.gif", :style => "vertical-align:bottom")
439:           update_function     = "$('#{object_name}_#{ext_object}_#{value}').value = selections.first().#{value_field}; " + 
440:                                 "$('#{object_name}_#{ext_object}_#{display}').innerHTML = selections.first().data['#{ext_object.to_s.pluralize}.#{display}']"
441: 
442:           content_tag(:span, current_value, :id => "#{object_name}_#{ext_object}_#{display}" ) + ' ' +
443:           build_grid(options[:name], options[:url], options[:grid], :update => update_function) +
444:           hidden_field(object_name, "#{ext_object}_#{value}")
445:         end
simple_error_messages_for(*params)

This method work like builtin Rails error_message_for but use an Ext.Message.show({..})

    # File lib/view/helpers/backend_helper.rb, line 6
 6:         def simple_error_messages_for(*params)
 7:           options = params.extract_options!.symbolize_keys
 8: 
 9:           if object = options.delete(:object)
10:             objects = [object].flatten
11:           else
12:             objects = params.collect {|object_name| instance_variable_get("@#{object_name}") }.compact
13:           end
14: 
15:           count  = objects.inject(0) {|sum, object| sum + object.errors.count }
16:           unless count.zero?
17:             html = {}
18:             [:id, :class].each do |key|
19:               if options.include?(key)
20:                 value = options[key]
21:                 html[key] = value unless value.blank?
22:               else
23:                 html[key] = 'errorExplanation'
24:               end
25:             end
26:             options[:object_name] ||= params.first
27: 
28:             I18n.with_options :locale => options[:locale], :scope => [:activerecord, :errors, :template] do |locale|
29:               header_message = if options.include?(:header_message)
30:                 options[:header_message]
31:               else
32:                 object_name = options[:object_name].to_s.gsub('_', ' ')
33:                 object_name = I18n.t(object_name, :default => object_name, :scope => [:activerecord, :models], :count => 1)
34:                 locale.t :header, :count => count, :model => object_name
35:               end
36:               message = options.include?(:message) ? options[:message] : locale.t(:body)
37:               error_messages = objects.sum {|object| object.errors.full_messages.map {|msg| content_tag(:li, ERB::Util.html_escape(msg)) } }.join
38: 
39:               contents = ''
40:               contents << content_tag(:p, message) unless message.blank?
41:               contents << content_tag(:ul, error_messages, :class => :list)
42:               
43:               content_tag(:script, "Ext.Msg.show({
44:                           title: '#{header_message}',
45:                           msg: '<ul>#{contents}</ul>',
46:                           buttons: Ext.Msg.OK,
47:                           minWidth: 400 
48:                         });", :type => Mime::JS)
49:             end
50:           else
51:             ''
52:           end
53:         end
tab(name, padding=true, options={}, &block)

This method add tab for in your view.

First argument is the name and title of the tab, an interesting thing wose that this helper try to translate itself to your current locale ex:

  # Look for: I18n.t("backend.tabs.settings", :default => "Settings")
  tab :settings do
    ...

The second argument specify if is necessary 10px of padding inside the tab, default is true

Third argument is an hash that accepts:

:id:The id of the tab
:style:Custom style of the tab
    # File lib/view/helpers/backend_helper.rb, line 71
71:         def tab(name, padding=true, options={}, &block)
72:           options[:id]    ||= name.to_s.downcase.gsub(/[^a-z0-9]+/, '_').gsub(/-+$/, '').gsub(/^-+$/, '')
73:           options[:style] ||= "padding:10px;#{options[:style]}" if padding
74:           options[:title]  = I18n.t("backend.tabs.#{name.to_s.downcase}", :default => name.to_s.humanize)
75:           options[:tabbed] = true
76:           options[:class]  = "x-hide-display"
77:           container = content_tag(:div, capture(&block), :class => :full) # Is necessary for IE6+
78:           concat content_tag(:div, container, options)
79:         end
title(title)

Set the title of the page.

An interesting thing wose that this helper try to translate itself to your current locale ex:

  # Look for: I18n.t("backend.titles.welcome_here", :default => "Welcome Here")
  title :welcome_here
    # File lib/view/helpers/backend_helper.rb, line 89
89:         def title(title)
90:           title = I18n.t("backend.titles.#{title.to_s.downcase}", :default => title.to_s.humanize)
91:           content_tag(:script, "Backend.app.setTitle(#{title.to_json})", :type => Mime::JS)
92:         end
tl(text)

Alias for translate_label

translate_label(text)

Try to translate the given word

  # Generate: I18n.t("backend.labels.add", :default => "Add")
  tl("Add")
This method is also aliased as tl
     # File lib/view/helpers/backend_helper.rb, line 142
142:         def translate_label(text)
143:           I18n.t("backend.labels.#{text.to_s.downcase.gsub(/\s/, "_")}", :default => text.to_s.humanize)
144:         end
translate_text(text)

Try to translate the given pharse

  # Generate: I18n.t("backend.labels.lipsiadmin_is_beautifull", :default => "Lipsiadmin is beautifull")
  tt("Lipsiadmin is beautifull")
This method is also aliased as tt
     # File lib/view/helpers/backend_helper.rb, line 152
152:         def translate_text(text)
153:           I18n.t("backend.texts.#{text.to_s.downcase.gsub(/\s/, "_")}", :default => text.to_s.humanize)
154:         end
tt(text)

Alias for translate_text