Rails 5.1 Consulting und Schulung vom Autor:
www.wintermeyer-consulting.de/rails/

13.3. JavaScript und CoffeeScript in der Asset Pipeline

Die Vorgehensweise mit JavaScript und der Asset Pipeline in einem Rails-Projekt zu programmieren, lässt sich am besten an einem kleinen Beispiel erklären. Wie immer geht es dabei nicht um die Sinnhaftigkeit der Applikation. ;-)

Formular abhängig von Eingaben verändern

Bauen wir eine Zimmerreservierung, in der man ein Einzel- oder ein Doppelzimmer buchen kann und dann im gleichen Formular entweder einen oder zwei Gästenamen eingeben muss. Das Grundgerüst:
Stefan-Wintermeyers-MacBook-Air:~ xyz$ rails new hotel
[...]
Stefan-Wintermeyers-MacBook-Air:~ xyz$ cd hotel 
Stefan-Wintermeyers-MacBook-Air:hotel xyz$ rails generate scaffold reservation start:date end:date room_type:string guest_name1 guest_name2
[...]
Stefan-Wintermeyers-MacBook-Air:hotel xyz$ rake db:migrate
[...]
Stefan-Wintermeyers-MacBook-Air:hotel xyz$
Ziel soll es sein, dass beim Aufruf von http://0.0.0.0:3000/reservations/new die folgende Seite angezeigt wird:
Formular mit einem Einzelzimmer
Sobald der User anstatt Einzelzimmer ein Doppelzimmer auswählt, soll ein zweites Namesfeld erscheinen:
Formular mit einem Doppelzimmer
Dazu verändere ich in der app/views/reservations/_form.html.erb zwei Sachen:
  • Den room_type frage ich per
    f.select(:room_type, options_for_select(['Einzelzimmer', 'Doppelzimmer']))
    ab.
  • Im div Element um den zweiten Namen setze ich
    mit
    <div class="field" id='second_name'>
    eine ID.
Hier ist der gesamte Code zum Formular:
<%= form_for(@reservation) do |f| %>
  <% if @reservation.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@reservation.errors.count, "error") %> prohibited this reservation from being saved:</h2>

      <ul>
      <% @reservation.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :start %><br />
    <%= f.date_select :start %>
  </div>
  <div class="field">
    <%= f.label :end %><br />
    <%= f.date_select :end %>
  </div>
  <div class="field">
    <%= f.label :room_type %><br />
    <%= f.select(:room_type, options_for_select(['Einzelzimmer', 'Doppelzimmer'])) %>
  </div>
  <div class="field">
    <%= f.label :guest_name1 %><br />
    <%= f.text_field :guest_name1 %>
  </div>
  <div class="field" id='second_name'>
    <%= f.label :guest_name2 %><br />
    <%= f.text_field :guest_name2 %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>
In die app/assets/javascripts/reservations.js.coffee definiere ich den CoffeeScript-Code, der das Element mit der ID second_name je nach Inhalt von reservation_room_type sichtbar (show) oder unsichtbar (hide) schaltet:
jQuery ->
  $('#second_name').hide()
  $('#reservation_room_type').change ->
    room_type = $('#reservation_room_type :selected').text()
    if room_type == 'Einzelzimmer'
      $('#second_name').hide()
    else
      $('#second_name').show()

Anmerkung

In der Realität würde man sicherlich die Gästenamen in einer 1:n has_many-Verknüpfung einbinden, aber in diesem Beispiel ging es ja nur darum zu sehen, wie man den Inhalt eines Formulares per JavaScript verändern kann.

Autor

Stefan Wintermeyer