Założenia są proste (podam w składni Rails) jest jakaś lista select, na przykład:
<%= select_tag :event_container %>i chciałbym do tej listy dorzucać pracowników z listy
<%= select_tag(:employee_id,
options_for_select(Employee.all.map { |employee| [employee.full_name, employee.id] }) %>
Chcę sobie kliknąć na listę z pracownikami, a po kliknięciu zaznaczony pracownik ma "przeskoczyć" z jednej listy na drugą. "Przeskoczyć" to znaczy zniknąć z jednej listy, a pojawić się na drugiej i vice versa.Do widoku wrzucam więc obserwatory:
<%= observe_field "employee_id",
:url => {:action => :move_employee_name},
:with => "employee_id" %>
<%= observe_field "event_container",
:url => {:action => :remove_employee_from_event},
:with => "event_container" %>
i tworzę dla nich pliki RJS odpowiednio: move_employee_name.rjs i remove_employee_from_event.rjs. Muszą one być skorelowane z metodami o takich samych nazwach w kontrolerze! Nie zapomnieć!Wpisy w move_employee_name.rjs dotyczą oczywiście kontrolek select:
page[:event_container].addNewOption @employee.full_name, @employee.id page[:employee_id].removeSelectedOptionWpisy w remove_employee_from_event.rjs są analogiczne
page[:employee_id].addNewOption @employee.full_name, @employee.id page[:event_container].removeSelectedOption
I tu pytanie za 12 punktów: skąd RJS zna te dziwne metody? Mowa oczywiście o ".addNewOption" i ".removeSelectedOption". I od razu odpowiedź: wpisałem je w /public/javascripts/application.js w postaci:
/* Dodawanie metod do szablonów RJS. */
Element.addMethods({
/* Dodawanie nowej opcji do kontrolki select. W tym przypadku jest to "element". */
addNewOption: function(element, option, id) {
element.options.add(new Option(option, id));
return element;
},
/* Usuwanie zaznaczonej opcji w kontrolce select. Bez parametrów, gdyż funkcja leci po wszystkich. */
removeSelectedOption: function(element) {
var i;
for (i = element.length - 1; i >= 0; i--) {
if (element.options[i].selected) {
element.remove(i);
return;
}
}
}
});
Tam jest właśnie cała magia :-)Sposób opisany tu przeze mnie jest jak najbardziej zgodny z ideą Rails. Daje się łatwo utrzymać w kodzie aplikacji i jest czytelny. Nic tylko brać!