5. Web-Apps mit Elm

5.2 Einen Dom-Baum in Elm erzeugen

Ein Html-Element besteht aus dem Tag-Namen, einer Attribut-Liste und einer Kinder-Liste. Außer Text-Elementen, die nur aus Text bestehen. In Elm gibt es ein Modul Html, und in diesem Modul gibt es zu jedem Html-Tag eine gleichnamige Funktion. Beispielsweise:

elm repl                        
import Html exposing (Html)
Html.em
<function> : List (Html.Attribute msg) -> List (Html msg) -> Html msg
Html.h2
<function> : List (Html.Attribute msg) -> List (Html msg) -> Html msg

Wie gesagt: ein Text-Element hat in Html weder Tag-Namen noch Attribute noch Kinder. In Elm:

Html.text                        
<function> : String -> Html msg

Eine Elm-App zum Laufen bekommen

Legen Sie in Ihrem Elm-Ordner neben dem Verzeichnis src/ ein Verzeichnis web/ an. Speichern Sie dort die Datei Web01Static.elm. Starten Sie in Ihrem Elm-Ordner den Elm-Reactor: elm reactor und gehen im Browser auf localhost:8000. Klicken Sie sich durch bis zu Web01Static.elm.

Vergleichen wir nun, wie der DOM-Baum in Html und in Elm konstruiert wird. Ich zeige dabei nur die relevanten Code-Zeilen.

In Html:

    <div>
        <h2>Einfache Beispielwebseite</h2>
        <p>
            Diese Seite hat einen ganz kleinen
            <em>DOM-Baum</em> und sonst nichts.
        </p>
    </div>

In Elm:

view : Model -> Html Msg
view model =
    Html.div []
        [ Html.h2
            []
            [ Html.text "Einfache Beispielseite" ]
        , Html.p []
            [ Html.text "Diese Seite hat einen ganz kleinen "
            , Html.em [] [ Html.text "DOM-Baum" ]
            , Html.text " und sonst nichts."
            ]
        ]

Wenn Ihre Webseite große Mengen an formatiertem Text enthalten, dann ist Elm natürlich nicht der richtige Weg. Auch dieses Vorlesungsskript habe ich zum Großteil per Hand in Html geschrieben. Anders schaut es aus, wenn große Teile des Inhalts automatisch erzeugt werden sollen. Hier müssen Sie sich ins Gedächtnis rufen: die Funktionen wie Html.p, die ein DOM-Element erzeugt, kann wie eine normale Elm-Funktion aufgerufen werden, zum Beispiel selbst der Funktion List.map übergeben werden. Konkretes Beispiel: ich will auf meiner Webseite die ersten 100 Fibonacci-Zahlen darstellen, will das aber nicht per Hand in Html schreiben. Was brauche ich?

  • Eine Funktion fib, die es bis mindestens 100 schafft.
  • Eine Funktion, die ein Int nimmt und es in ein Html-Element umwandelt, nämlich ein p-Element (Absatz); die also x umwandelt in <p>x</p>. Nennen wir diese Funktion intToParagraph : Int -> Html Msg

Dann kann ich mit List.range 0 99 die Liste der ersten 100 natürlichen Zahlen erzeugen und per List.map die dann Stück für Stück in p-Elemente übersetzen. Der entscheidende Code-Ausschnitt ist

intToParagraph : Int -> Html Msg
intToParagraph n =
    Html.p [] [ Html.text (String.fromInt n) ]


view : Model -> Html Msg
view model =
    Html.div []
        [ Html.h2 [] [ Html.text "Die ersten 100 Fibonacci-Zahlen" ]
        , Html.div []
            (List.map intToParagraph (List.range 0 99))
        ]

Das zweite div-Element hat nun 100 Kinder, die wir nicht per Hand, sondern per List.map erzeugen. Den gesamten Elm-Code finden Sie in Web02Fib.elm

Bulletpoints

Listen stellt man in Html üblicherweise mit Bulletpoints oder numeriert dar. Die entsprechende Html-Tags sind ul (steht für unordered list) und li (steht für list item). In Html schaut das dann so aus:

    <h2>Die ersten 5 Fibonacci-Zahlen</h2>
    <ul>
        <li>0</li>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>

Übungsaufgabe Legen Sie eine Kopie von Web02Fib.elm und ändern Sie den Elm-Code so ab, dass eine Liste von Bulletpoints erstellt wird. Die li-Elemente können Sie in Elm mit Html.li erstellen.

Css und Bootstrap

Ich habe ja im letzten Teilkapitel angekündigt, nicht über Css reden zu wollen. Dennoch will ich es gerne verwenden. Glücklicherweise gibt es online viele Css-Bibliotheken wie Bootstrap, die viele Layouts bereits definieren. Sie müssen nicht verstehen, wie man das in Elm einbaut (ist nicht schwierig; ist einfach im Moment irrelevant); laden Sie sich lieber die Datei Web03FibBootstrap.elm herunter.

Übungsaufgabe Wiederholen Sie die letzte Übung (die mit Bulletpoints), jetzt mit der Vorlage Web03FibBootstrap.elm.

Tabellen

Tabellen erstellen Sie in Html mit dem Tag-Namen table. Vorteil gegenüber ul ist, dass Sie mehrere Spalten darstellen können, zum Beispiel \(n\) und \(F_n\) parallel, wie hier (klicken Sie aufs Bild):

Schauen Sie sich den Html-Quelltext von 05-table.html an. Auch für die Tags table, tbody, tr (table row), th (table header) und td (table data, also eine einzelne Zelle) gibt es in Elm die entsprechenden Funktionen Html.table, Html.tr und so weiter.

Übungsaufgabe Schreiben Sie eine Elm-App, die automatisch eine Tabelle mit den ersten 100 Fibonacci-Zahlen erstellt. Sie brauchen eine Funktion intToTableRow, die zum Beispiel aus der Zahl 7 das Html-Element <tr><td>7</td><td>13</td></tr> erstellt.

Verwenden Sie als Vorlgae, wie man in Elm Tabellen erstellt, die Datei Web04TableTemplate.elm.