autocomplete vs. autocomplete 0

Posted by fwoeck
on Tuesday, April 21

Nachdem ich mein aktuelles Railsprojekt von Prototype auf jQuery umgesattelt hatte, war die autocomplete-Funktion für die Formularelemente gebrochen.

Also altes Plugin raus, neues rein – z. B. das von Dylan Verheul. Man muss sich die einzelnen Files ein bisschen zusammenklauben:

cd public/javascripts/
wget http://dyve.net/jquery/js/jquery.autocomplete.js

cd ../images/
wget http://dyve.net/jquery/img/indicator.gif

cd ../stylesheets/
vi ui.autocomplete.css

mit:

1
2
3
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
.ac_input {
  width: 200px;
}
.ac_results {
  padding: 0px;
  border: 1px solid WindowFrame;
  background-color: Window;
  overflow: hidden;
}

.ac_results ul {
  width: 100%;
  list-style-position: outside;
  list-style: none;
  padding: 0;
  margin: 0;
}

.ac_results iframe {
  display:none;
  display/**/:block;
  position:absolute;
  top:0;
  left:0;
  z-index:-1;
  filter:mask();
  width:3000px;
  height:3000px;
}

.ac_results li {
  margin: 0px;
  padding: 2px 5px;
  cursor: pointer;
  display: block;
  width: 100%;
  font: menu;
  font-size: 12px;
  overflow: hidden;
}
.ac_loading {
  background : url('/images/indicator.gif') right center no-repeat;
}
.ac_over {
  background-color: Highlight;
  color: HighlightText;
}

Und schließlich das alte Plugin gelöscht:

cd ../..
rm -rf vendor/plugins/auto_complete/

ein neues Setup

Die neuen Files wollen eingebettet sein. Im Head:

1
2
<%= javascript_include_tag 'jquery.autocomplete' %>
<%= stylesheet_link_tag 'ui.autocomplete' %>

und die Views

Die Formularfelder baue ich jetzt, wie unten gezeigt. Das ist ganz sicher nicht so, wie von den ursprünglichen autocomplete-Helfern gedacht, denn die answer.id wird hier ziemlich un-RESTmäßig als Parameter übergeben – aber es funktioniert für mich…:

1
2
3
4
5
6
7
<input autocomplete="off" id="answer_<%= answer.id -%>" 
      name="answer[<%= answer.id -%>]" type="text" value="<%= answer.value_str -%>" />

<script type="text/javascript">
  $("input#answer_<%= answer.id -%>").autocomplete("/projects/<%= @project.id -%>
                     /proforms/auto_complete_for_answer_id?answer=<%= answer.id -%>")
</script>

Die Verschachtelung mit projects stammt von der Route her:

1
2
3
4
map.resources :projects do |projects|
  projects.resources :proforms, :collection => 
                   { :auto_complete_for_answer_id => :get }
...

jetzt der Controller

Dies ist die Funktion im proforms-Controller – sie sucht vergleichbare Ausdrücke in meinem Answer-Modell. Wie man hier sieht, übergibt das jQuery-autocomplete-Plugin den Suchstring als q-Parameter:

1
2
3
4
5
6
7
def auto_complete_for_answer_id
  search = params[:q]
  answer_id = params[:answer].to_i
  @vals = Answer.find(answer_id).entity.footprints.map(&:value_str).select{|v| 
                                                v =~ /#{search}/i}.uniq
  render :partial => "q_string"
end

Das Partial “q_string” rendert nur eine Ascii-Liste von Wertepaaren, und das müsste eigentlich schon Alles sein:

1
2
3
<% for val in @vals.to_a -%>
  <%= val -%>|<%= val %>
<% end -%>

Weblinks

  1. dyve.net/jquery/?autocomplete
  2. www.bassistance.de/jquery-plugin-autocomplete
  3. update-on-rails-jquery-autocomplete

Tausche Prototype gegen jQuery 0

Posted by fwoeck
on Tuesday, April 21
  1. jQuery ist irgendwie unobtrusiv und schlank
  2. die Mobilplattform, mit der ich grade angefangen habe zu experimentieren benutzt jQuery
  3. für Rails gibt es jRails, wenn man will

Zeit für einen Wechsel! Ich fang’ mit dem laufenden Railsprojekt an.

Um die gewohnten Helfer in Rails und RJS weiter zu unterstützen und den Migrationsaufwand klein zu halten installiere ich jRails:

script/plugin install http://ennerchi.googlecode.com/svn/trunk/plugins/jrails

Manuell würde man jetzt die …/application.html.erb ändern:

1
2
3
<script src="/javascripts/jquery.js" type="text/javascript"></script>
<script src="/javascripts/jquery-ui.js" type="text/javascript"></script>
<script src="/javascripts/jrails.js" type="text/javascript"></script>

Falls man allerdings die übliche Zeile zum Einbetten der Skripte verwendet:


<%= javascript_include_tag :defaults, :cache => 'jquery' %>

ist es damit schon getan – anstelle der Prototype-Files werden nun die neuen geladen. Das

:cache => 'jquery'

veranlasst Rails in der Produktion die Skripte zu einer einzigen .js-Datei zusammenzufassen, um http-Requests zu sparen.

Aus unklaren Gründen funktioniert die Sache mit dem cache… in der Produktivumgebung gut, allerdings führt sie in meiner Selenium-Testumgebung zu Problemen. Gelegentlich tauchen solche Fehler auf:

$("#project_active_1").delayedObserver is not a function

Timingproblem? Deshalb deaktiviere ich das Caching erstmal wieder.

Einiges anders

Hier folgen ein paar Änderungen, die ich anbringen musste, um die Tests zu passieren:

Alle Helferaufrufe benötigen nun ein # für ids im Selektor – die waren vorher nicht nötig:


<%= link_to_function "Person anlegen", "$('#personselect').toggle();" %>

.up() wird .parent() oder .parents():

1
2
3
4
<div class="delme">
  <p>
    <%= link_to_function "<img alt='Bild' src='delete.png' />", 
        "$(this).up('.delme').remove()" %>
wird:
1
2
3
4
<div class="delme">
  <p>
    <%= link_to_function "<img alt='Bild' src='delete.png' />", 
        "$(this).parents('.delme').remove()" %>

.value= wird .val()


$('#answer_#{answer.id}_blank_value_date').value = '1';
wird:

$('#answer_#{answer.id}_blank_value_date').val('1');

Der Autocompleter streikt

Der autocompleter ist ja schon vor längerer Zeit in ein Plugin ausgegliedert worden und mein Viewcode

1
2
3
4
5
6
7
8
<script type="text/javascript">
  //<![CDATA[ 
   var answer_<%= answer.id -%>_auto_completer = new Ajax.Autocompleter(
    'answer_<%= answer.id -%>', 'answer_<%= answer.id -%>_auto_complete', 
    '/projects/<%= @project.id -%>/proforms/auto_complete_for_answer_id', 
    {method:'get'}) 
  //]]>
</script>

erzeugt eine Fehlermeldung “Ajax is not defined” im Firebug. Arghh, na ich denke, das wird eigener Post.

Weblinks

  1. ennerchi.com/projects/jrails
  2. dev.jqueryui.com/browser/tags/latest