Module: FormtasticJQueryUI::Autocomplete

Defined in:
lib/formtastic_jquery_ui/autocomplete.rb

Instance Method Summary collapse

Instance Method Details

#autocomplete_input(method, options) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/formtastic_jquery_ui/autocomplete.rb', line 4

def autocomplete_input(method, options)
  html_options = options.delete(:input_html) || {}
  options = set_include_blank(options)
  html_options[:multiple] = html_options[:multiple] || options.delete(:multiple)
  html_options.delete(:multiple) if html_options[:multiple].nil?
  autocomplete_options = options.delete(:autocomplete) || {}
  autocomplete_option_min_length = autocomplete_options[:min_length] || 2
  autocomplete_option_min_length_js =  "minLength: #{autocomplete_option_min_length},"

  html = ""
  reflection = self.reflection_for(method)
  input_name = "autocomplete_for_#{sanitized_object_name}_#{method}"
  param_name = options[:param_name] || 'term'
  url = options[:url] || ''

  if reflection && [:has_many, :has_and_belongs_to_many].include?(reflection.macro)
    selections_name = generate_html_id(method, 'selections')
    selection_name = "#{sanitized_object_name}[#{method.to_s.singularize}_ids][]"
    html << template.(:ul, object.send(method).map { |i| template.(:li, "<input type=\"hidden\" name=\"#{selection_name}\" value=\"#{i.id}\" />#{i.to_label} <a href=\"#\" onclick=\"$(this).closest('li').remove(); return false;\">Remove</a>".html_safe) }.join.html_safe, :id => selections_name)
    html << template.tag(:input, :type => 'hidden', :name => selection_name, :value => '')
    html << template.text_field_tag(input_name)
    autocomplete_js = <<-EOT
  <script type="text/javascript">
  $('##{input_name}').autocomplete({
source: function(request, response) {
  $.ajax({
    url: '#{url}',
    dataType: 'json',
    data: {
      search: { #{param_name}: request.term }
    },
    success: function(data) {
      response(data);
    }
  });
},
#{autocomplete_option_min_length_js}
select: function(event, selection) {
  if($('##{selections_name} input[value=' + selection.item.value + ']').length == 0)
    $('##{selections_name}').append('<li><input type="hidden" name="#{selection_name}" value="' + selection.item.value + '" />' + selection.item.label + ' <a href="#" onclick="$(this).closest(\\'li\\').remove(); return false;">Remove</a></li>');
  $('##{input_name}').val('');
  return false;
},
focus: function(event, ui) { return false; }
  });
  </script>
EOT
    html << autocomplete_js.html_safe
  elsif (reflection && [:belongs_to].include?(reflection.macro)) || reflection.nil?
    hidden_field_name = reflection.try(:primary_key_name) || "#{method}_id"
    html << self.hidden_field(hidden_field_name)
    html << template.text_field_tag(input_name, object.send(method).try(detect_label_method([object.send(method)])))
    html << template.(:script, :type => 'text/javascript') do
      <<-EOT
  $('##{input_name}').autocomplete({
source: function(request, response) {
  $.ajax({
    url: '#{url}',
    dataType: 'json',
    data: {
      search: { #{param_name}: request.term }
    },
    success: function(data) {
      response(data);
    }
  });
},
#{autocomplete_option_min_length_js}
select: function(event, selection) {
  $('##{sanitized_object_name}_#{hidden_field_name}').val(selection.item.value);
  $('##{input_name}').val(selection.item.label);
  return false;
},
focus: function(event, ui) { return false; }
  });
  $('##{input_name}').blur(function(event){
if($(this).val() == '')
  $('##{sanitized_object_name}_#{hidden_field_name}').val('');
  })
EOT
    end
  end
  template.(:label, localized_string(method, options[:label].is_a?(::String) ? options[:label] : nil, :label) || humanized_attribute_name(method), :for => input_name) << Formtastic::Util.html_safe(html)
end