Zum Inhalt

Übungen

Übung 0

Infrastruktur einrichten
  • wählen Sie eine IDE aus und installieren Sie diese
  • richten Sie sich ein Git-Repository ein (z.B. WebTech24)
  • erstellen Sie im Ordner WebTech24 eine index.html und versuchen Sie darin bereits einige Inhalte einzupflegen, z.B. eine kleine persönliche Webseite oder eine Startseite von der aus alle Übungen erreichbar sind o.ä.
  • commiten und pushen Sie Ihr Repository auf einen zentralen Dienst (siehe)
  • laden Sie mich zu Ihrem Git-Dienst ein (siehe)

Übung 1

Übungsaufgabe 1 (HTML)
  • Erstellen Sie in einem Uebung1-Ordner eine Datei uebung1.html. Das body-Element soll ein header-Element, ein nav-Element, ein section-Element und ein footer-Element enthalten.
  • Unter dieser Übungsaufgabe (siehe mockupdata) ist der HTML-Code einer Tabelle mit allen Teilnehmerinnen einer Veranstaltung. Kopieren Sie den Inhalt der Datei so in Ihren HTML-Code, dass folgende Seite erscheint: Uebung1

  • Es sollen 4 Unterseiten erstellt werden. Bei Klick auf diese Seiten soll die Tabelle jeweils nur die Teilnehmerinnen enthalten, deren Nachname mit dem entsprechenden Anfangsbuchstaben beginnt (also in ag.html nur alle Nachnamen, die mit A bis G beginnen). Die Seiten ag.html, hl.html, mr.html und sz.html sollen im Ordner NN abgelegt werden, der Unterordner von Uebung1 ist.

  • Achten Sie darauf, dass man von jeder Unterseite auf jede andere Unterseite und auch auf die Hauptseite (uebung1.html) wechseln können muss.
  • Das einzubindende Logo des Studiengangs liegt hier. Es soll in einen images-Ordner gespeichert werden, der in der Ordner-Hierarchie neben dem Uebung1-Ordner liegt. Um die Größe des Bildes festzulegen, können Sie mit Hilfe des style-Attributes die Höhe und die Breite bestimmen: style="width:53px; height:48px;"
  • Nächste Woche wird Uebung1 um CSS erweitert.
mockupdata
<table>
    <thead>
        <tr>
            <th>Vorname</th>
            <th>Nachname</th>
            <th>E-Mail-Adresse</th>
            <th>IP-Adresse</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Adam</td>
            <td>Anderson</td>
            <td>aanderson8@google.fr</td>
            <td>118.93.83.157</td>
        </tr>
        <tr>
            <td>Susan</td>
            <td>Andrews</td>
            <td>sandrewsn@google.co.jp</td>
            <td>228.214.9.251</td>
        </tr>
        <tr>
            <td>Catherine</td>
            <td>Andrews</td>
            <td>candrewsp@noaa.gov</td>
            <td>112.111.87.178</td>
        </tr>
        <tr>
            <td>Alan</td>
            <td>Bradley</td>
            <td>abradley1c@globo.com</td>
            <td>229.152.117.127</td>
        </tr>
        <tr>
            <td>Anne</td>
            <td>Brooks</td>
            <td>abrooks16@bravesites.com</td>
            <td>243.159.39.234</td>
        </tr>
        <tr>
            <td>Russell</td>
            <td>Brown</td>
            <td>rbrownq@nifty.com</td>
            <td>215.38.120.242</td>
        </tr>
        <tr>
            <td>Ryan</td>
            <td>Burton</td>
            <td>rburton18@foxnews.com</td>
            <td>159.60.107.14</td>
        </tr>
        <tr>
            <td>Roy</td>
            <td>Campbell</td>
            <td>rcampbell1@geocities.com</td>
            <td>237.232.34.20</td>
        </tr>
        <tr>
            <td>Russell</td>
            <td>Campbell</td>
            <td>rcampbell17@eventbrite.com</td>
            <td>251.2.92.63</td>
        </tr>
        <tr>
            <td>Bonnie</td>
            <td>Coleman</td>
            <td>bcoleman11@fc2.com</td>
            <td>109.150.122.102</td>
        </tr>
        <tr>
            <td>Ernest</td>
            <td>Coleman</td>
            <td>ecoleman15@businessweek.com</td>
            <td>213.173.4.7</td>
        </tr>
        <tr>
            <td>Richard</td>
            <td>Cruz</td>
            <td>rcruz7@unc.edu</td>
            <td>235.124.23.221</td>
        </tr>
        <tr>
            <td>Sean</td>
            <td>Cruz</td>
            <td>scruz10@answers.com</td>
            <td>92.255.49.227</td>
        </tr>
        <tr>
            <td>Rebecca</td>
            <td>Cunningham</td>
            <td>rcunninghamd@mac.com</td>
            <td>65.79.191.52</td>
        </tr>
        <tr>
            <td>Margaret</td>
            <td>Evans</td>
            <td>mevansh@pcworld.com</td>
            <td>162.10.86.196</td>
        </tr>
        <tr>
            <td>Jeffrey</td>
            <td>Ford</td>
            <td>jford14@cnet.com</td>
            <td>210.216.54.14</td>
        </tr>
        <tr>
            <td>Andrea</td>
            <td>Gardner</td>
            <td>agardnerv@woothemes.com</td>
            <td>179.91.0.30</td>
        </tr>
        <tr>
            <td>Deborah</td>
            <td>George</td>
            <td>dgeorge6@furl.net</td>
            <td>201.76.47.162</td>
        </tr>
        <tr>
            <td>Sean</td>
            <td>Gibson</td>
            <td>sgibsony@alexa.com</td>
            <td>48.114.103.55</td>
        </tr>
        <tr>
            <td>Virginia</td>
            <td>Graham</td>
            <td>vgrahamk@aol.com</td>
            <td>165.219.171.1</td>
        </tr>
        <tr>
            <td>Steven</td>
            <td>Hamilton</td>
            <td>shamiltonu@state.tx.us</td>
            <td>38.194.91.201</td>
        </tr>
        <tr>
            <td>Virginia</td>
            <td>Hawkins</td>
            <td>vhawkinsf@ehow.com</td>
            <td>93.120.46.203</td>
        </tr>
        <tr>
            <td>Edward</td>
            <td>Hicks</td>
            <td>ehicksc@pcworld.com</td>
            <td>199.153.27.1</td>
        </tr>
        <tr>
            <td>Mark</td>
            <td>Johnson</td>
            <td>mjohnsonj@hostgator.com</td>
            <td>73.87.135.206</td>
        </tr>
        <tr>
            <td>Ruth</td>
            <td>Jordan</td>
            <td>rjordan1a@smugmug.com</td>
            <td>193.140.80.64</td>
        </tr>
        <tr>
            <td>Antonio</td>
            <td>Kim</td>
            <td>akim4@odnoklassniki.ru</td>
            <td>168.244.191.78</td>
        </tr>
        <tr>
            <td>Jennifer</td>
            <td>Marshall</td>
            <td>jmarshallt@gnu.org</td>
            <td>104.191.49.94</td>
        </tr>
        <tr>
            <td>Eric</td>
            <td>Matthews</td>
            <td>ematthews5@independent.co.uk</td>
            <td>138.194.30.1</td>
        </tr>
        <tr>
            <td>Raymond</td>
            <td>Mcdonald</td>
            <td>rmcdonald2@ihg.com</td>
            <td>161.24.42.24</td>
        </tr>
        <tr>
            <td>Eric</td>
            <td>Miller</td>
            <td>emillere@creativecommons.org</td>
            <td>122.159.17.218</td>
        </tr>
        <tr>
            <td>Jonathan</td>
            <td>Morales</td>
            <td>jmoralesa@ovh.net</td>
            <td>97.65.110.105</td>
        </tr>
        <tr>
            <td>Marie</td>
            <td>Morgan</td>
            <td>mmorganb@cloudflare.com</td>
            <td>226.79.152.112</td>
        </tr>
        <tr>
            <td>Amanda</td>
            <td>Nelson</td>
            <td>anelson13@indiatimes.com</td>
            <td>161.185.121.245</td>
        </tr>
        <tr>
            <td>Lisa</td>
            <td>Olson</td>
            <td>lolsonr@telegraph.co.uk</td>
            <td>77.245.172.100</td>
        </tr>
        <tr>
            <td>Alice</td>
            <td>Ortiz</td>
            <td>aortizw@histats.com</td>
            <td>179.52.222.21</td>
        </tr>
        <tr>
            <td>Peter</td>
            <td>Phillips</td>
            <td>pphillipss@1688.com</td>
            <td>11.158.255.76</td>
        </tr>
        <tr>
            <td>Matthew</td>
            <td>Porter</td>
            <td>mporter9@europa.eu</td>
            <td>174.81.178.88</td>
        </tr>
        <tr>
            <td>Tammy</td>
            <td>Ray</td>
            <td>trayx@weather.com</td>
            <td>192.243.38.190</td>
        </tr>
        <tr>
            <td>Mark</td>
            <td>Richardson</td>
            <td>mrichardson1d@ihg.com</td>
            <td>209.217.14.154</td>
        </tr>
        <tr>
            <td>Joan</td>
            <td>Roberts</td>
            <td>jroberts12@alibaba.com</td>
            <td>4.91.143.62</td>
        </tr>
        <tr>
            <td>Kathleen</td>
            <td>Rose</td>
            <td>kroseg@pinterest.com</td>
            <td>222.172.140.56</td>
        </tr>
        <tr>
            <td>Steve</td>
            <td>Sanders</td>
            <td>ssanders1b@wikispaces.com</td>
            <td>91.61.109.245</td>
        </tr>
        <tr>
            <td>Shirley</td>
            <td>Scott</td>
            <td>sscottm@macromedia.com</td>
            <td>219.237.108.82</td>
        </tr>
        <tr>
            <td>Lillian</td>
            <td>Stephens</td>
            <td>lstephens19@hugedomains.com</td>
            <td>89.85.137.204</td>
        </tr>
        <tr>
            <td>Nicole</td>
            <td>Thompson</td>
            <td>nthompson3@admin.ch</td>
            <td>13.183.208.155</td>
        </tr>
        <tr>
            <td>Marie</td>
            <td>Thompson</td>
            <td>mthompsonz@yelp.com</td>
            <td>162.164.5.231</td>
        </tr>
        <tr>
            <td>Alan</td>
            <td>Vasquez</td>
            <td>avasquezo@miibeian.gov.cn</td>
            <td>178.109.86.172</td>
        </tr>
        <tr>
            <td>Mildred</td>
            <td>Watkins</td>
            <td>mwatkins0@miibeian.gov.cn</td>
            <td>150.67.132.64</td>
        </tr>
        <tr>
            <td>Eugene</td>
            <td>Williams</td>
            <td>ewilliamsi@deliciousdays.com</td>
            <td>67.208.26.182</td>
        </tr>
        <tr>
            <td>Catherine</td>
            <td>Williams</td>
            <td>cwilliamsl@360.cn</td>
            <td>154.87.204.51</td>
        </tr>
    </tbody>
</table>
Eine mögliche Lösung für Übung1 (HTML)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Übung 1</title>
</head>
<body>
    <header>
        <h1>Teilnehmerinnen WebTech</h1>
        <img src="../../images/fiw.jpg" alt="FIW Logo" style="width:53px; height:48px;"/>
    </header>
    <nav>
        <a href="#">ALLE</a>
        <a href="./NN/ag.html">A-G</a>
        <a href="./NN/hl.html">H-L</a>
        <a href="./NN/mr.html">M-R</a>
        <a href="./NN/sz.html">S-Z</a>
        <a href="../index.html">Startseite</a>
    </nav>
    <section>
        <table>
            <tr>
                <th>Vorname</th>
                <th>Nachname</th>
                <th>E-Mail-Adresse</th>
                <th>IP-Adresse</th>
            </tr>
            <tr>
                <td>Adam</td>
                <td>Anderson</td>
                <td>aanderson8@google.fr</td>
                <td>118.93.83.157</td>
            </tr>
            <tr>
                <td>Susan</td>
                <td>Andrews</td>
                <td>sandrewsn@google.co.jp</td>
                <td>228.214.9.251</td>
            </tr>
            <tr>
                <td>Catherine</td>
                <td>Andrews</td>
                <td>candrewsp@noaa.gov</td>
                <td>112.111.87.178</td>
            </tr>
            <tr>
                <td>Alan</td>
                <td>Bradley</td>
                <td>abradley1c@globo.com</td>
                <td>229.152.117.127</td>
            </tr>
            <tr>
                <td>Anne</td>
                <td>Brooks</td>
                <td>abrooks16@bravesites.com</td>
                <td>243.159.39.234</td>
            </tr>
            <tr>
                <td>Russell</td>
                <td>Brown</td>
                <td>rbrownq@nifty.com</td>
                <td>215.38.120.242</td>
            </tr>
            <tr>
                <td>Ryan</td>
                <td>Burton</td>
                <td>rburton18@foxnews.com</td>
                <td>159.60.107.14</td>
            </tr>
            <tr>
                <td>Roy</td>
                <td>Campbell</td>
                <td>rcampbell1@geocities.com</td>
                <td>237.232.34.20</td>
            </tr>
            <tr>
                <td>Russell</td>
                <td>Campbell</td>
                <td>rcampbell17@eventbrite.com</td>
                <td>251.2.92.63</td>
            </tr>
            <tr>
                <td>Bonnie</td>
                <td>Coleman</td>
                <td>bcoleman11@fc2.com</td>
                <td>109.150.122.102</td>
            </tr>
            <tr>
                <td>Ernest</td>
                <td>Coleman</td>
                <td>ecoleman15@businessweek.com</td>
                <td>213.173.4.7</td>
            </tr>
            <tr>
                <td>Richard</td>
                <td>Cruz</td>
                <td>rcruz7@unc.edu</td>
                <td>235.124.23.221</td>
            </tr>
            <tr>
                <td>Sean</td>
                <td>Cruz</td>
                <td>scruz10@answers.com</td>
                <td>92.255.49.227</td>
            </tr>
            <tr>
                <td>Rebecca</td>
                <td>Cunningham</td>
                <td>rcunninghamd@mac.com</td>
                <td>65.79.191.52</td>
            </tr>
            <tr>
                <td>Margaret</td>
                <td>Evans</td>
                <td>mevansh@pcworld.com</td>
                <td>162.10.86.196</td>
            </tr>
            <tr>
                <td>Jeffrey</td>
                <td>Ford</td>
                <td>jford14@cnet.com</td>
                <td>210.216.54.14</td>
            </tr>
            <tr>
                <td>Andrea</td>
                <td>Gardner</td>
                <td>agardnerv@woothemes.com</td>
                <td>179.91.0.30</td>
            </tr>
            <tr>
                <td>Deborah</td>
                <td>George</td>
                <td>dgeorge6@furl.net</td>
                <td>201.76.47.162</td>
            </tr>
            <tr>
                <td>Sean</td>
                <td>Gibson</td>
                <td>sgibsony@alexa.com</td>
                <td>48.114.103.55</td>
            </tr>
            <tr>
                <td>Virginia</td>
                <td>Graham</td>
                <td>vgrahamk@aol.com</td>
                <td>165.219.171.1</td>
            </tr>
            <tr>
                <td>Steven</td>
                <td>Hamilton</td>
                <td>shamiltonu@state.tx.us</td>
                <td>38.194.91.201</td>
            </tr>
            <tr>
                <td>Virginia</td>
                <td>Hawkins</td>
                <td>vhawkinsf@ehow.com</td>
                <td>93.120.46.203</td>
            </tr>
            <tr>
                <td>Edward</td>
                <td>Hicks</td>
                <td>ehicksc@pcworld.com</td>
                <td>199.153.27.1</td>
            </tr>
            <tr>
                <td>Mark</td>
                <td>Johnson</td>
                <td>mjohnsonj@hostgator.com</td>
                <td>73.87.135.206</td>
            </tr>
            <tr>
                <td>Ruth</td>
                <td>Jordan</td>
                <td>rjordan1a@smugmug.com</td>
                <td>193.140.80.64</td>
            </tr>
            <tr>
                <td>Antonio</td>
                <td>Kim</td>
                <td>akim4@odnoklassniki.ru</td>
                <td>168.244.191.78</td>
            </tr>
            <tr>
                <td>Jennifer</td>
                <td>Marshall</td>
                <td>jmarshallt@gnu.org</td>
                <td>104.191.49.94</td>
            </tr>
            <tr>
                <td>Eric</td>
                <td>Matthews</td>
                <td>ematthews5@independent.co.uk</td>
                <td>138.194.30.1</td>
            </tr>
            <tr>
                <td>Raymond</td>
                <td>Mcdonald</td>
                <td>rmcdonald2@ihg.com</td>
                <td>161.24.42.24</td>
            </tr>
            <tr>
                <td>Eric</td>
                <td>Miller</td>
                <td>emillere@creativecommons.org</td>
                <td>122.159.17.218</td>
            </tr>
            <tr>
                <td>Jonathan</td>
                <td>Morales</td>
                <td>jmoralesa@ovh.net</td>
                <td>97.65.110.105</td>
            </tr>
            <tr>
                <td>Marie</td>
                <td>Morgan</td>
                <td>mmorganb@cloudflare.com</td>
                <td>226.79.152.112</td>
            </tr>
            <tr>
                <td>Amanda</td>
                <td>Nelson</td>
                <td>anelson13@indiatimes.com</td>
                <td>161.185.121.245</td>
            </tr>
            <tr>
                <td>Lisa</td>
                <td>Olson</td>
                <td>lolsonr@telegraph.co.uk</td>
                <td>77.245.172.100</td>
            </tr>
            <tr>
                <td>Alice</td>
                <td>Ortiz</td>
                <td>aortizw@histats.com</td>
                <td>179.52.222.21</td>
            </tr>
            <tr>
                <td>Peter</td>
                <td>Phillips</td>
                <td>pphillipss@1688.com</td>
                <td>11.158.255.76</td>
            </tr>
            <tr>
                <td>Matthew</td>
                <td>Porter</td>
                <td>mporter9@europa.eu</td>
                <td>174.81.178.88</td>
            </tr>
            <tr>
                <td>Tammy</td>
                <td>Ray</td>
                <td>trayx@weather.com</td>
                <td>192.243.38.190</td>
            </tr>
            <tr>
                <td>Mark</td>
                <td>Richardson</td>
                <td>mrichardson1d@ihg.com</td>
                <td>209.217.14.154</td>
            </tr>
            <tr>
                <td>Joan</td>
                <td>Roberts</td>
                <td>jroberts12@alibaba.com</td>
                <td>4.91.143.62</td>
            </tr>
            <tr>
                <td>Kathleen</td>
                <td>Rose</td>
                <td>kroseg@pinterest.com</td>
                <td>222.172.140.56</td>
            </tr>
            <tr>
                <td>Steve</td>
                <td>Sanders</td>
                <td>ssanders1b@wikispaces.com</td>
                <td>91.61.109.245</td>
            </tr>
            <tr>
                <td>Shirley</td>
                <td>Scott</td>
                <td>sscottm@macromedia.com</td>
                <td>219.237.108.82</td>
            </tr>
            <tr>
                <td>Lillian</td>
                <td>Stephens</td>
                <td>lstephens19@hugedomains.com</td>
                <td>89.85.137.204</td>
            </tr>
            <tr>
                <td>Nicole</td>
                <td>Thompson</td>
                <td>nthompson3@admin.ch</td>
                <td>13.183.208.155</td>
            </tr>
            <tr>
                <td>Marie</td>
                <td>Thompson</td>
                <td>mthompsonz@yelp.com</td>
                <td>162.164.5.231</td>
            </tr>
            <tr>
                <td>Alan</td>
                <td>Vasquez</td>
                <td>avasquezo@miibeian.gov.cn</td>
                <td>178.109.86.172</td>
            </tr>
            <tr>
                <td>Mildred</td>
                <td>Watkins</td>
                <td>mwatkins0@miibeian.gov.cn</td>
                <td>150.67.132.64</td>
            </tr>
            <tr>
                <td>Eugene</td>
                <td>Williams</td>
                <td>ewilliamsi@deliciousdays.com</td>
                <td>67.208.26.182</td>
            </tr>
            <tr>
                <td>Catherine</td>
                <td>Williams</td>
                <td>cwilliamsl@360.cn</td>
                <td>154.87.204.51</td>
            </tr>
        </table>

    </section>
    <footer>
      Übung 1 - Jörn Freiheit
    </footer>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Übung 1</title>
</head>
<body>
    <header>
        <h1>Teilnehmerinnen WebTech A - G</h1>
        <img src="../../../images/fiw.jpg" alt="FIW Logo" style="width:53px; height:48px;"/>
    </header>
    <nav>
        <a href="../uebung1.html">ALLE</a>
        <a href="./ag.html">A-G</a>
        <a href="./hl.html">H-L</a>
        <a href="./mr.html">M-R</a>
        <a href="./sz.html">S-Z</a>
        <a href="../../index.html">Startseite</a>
    </nav>
    <section>
        <h3>Teilnehmerinnen A - G</h3>
        <table>
            <thead>
                <tr>
                    <th>Vorname</th>
                    <th>Nachname</th>
                    <th>E-Mail-Adresse</th>
                    <th>IP-Adresse</th>
                </tr>
            </thead>
            <tbody>
            <tr>
                <td>Adam</td>
                <td>Anderson</td>
                <td>aanderson8@google.fr</td>
                <td>118.93.83.157</td>
            </tr>
            <tr>
                <td>Susan</td>
                <td>Andrews</td>
                <td>sandrewsn@google.co.jp</td>
                <td>228.214.9.251</td>
            </tr>
            <tr>
                <td>Catherine</td>
                <td>Andrews</td>
                <td>candrewsp@noaa.gov</td>
                <td>112.111.87.178</td>
            </tr>
            <tr>
                <td>Alan</td>
                <td>Bradley</td>
                <td>abradley1c@globo.com</td>
                <td>229.152.117.127</td>
            </tr>
            <tr>
                <td>Anne</td>
                <td>Brooks</td>
                <td>abrooks16@bravesites.com</td>
                <td>243.159.39.234</td>
            </tr>
            <tr>
                <td>Russell</td>
                <td>Brown</td>
                <td>rbrownq@nifty.com</td>
                <td>215.38.120.242</td>
            </tr>
            <tr>
                <td>Ryan</td>
                <td>Burton</td>
                <td>rburton18@foxnews.com</td>
                <td>159.60.107.14</td>
            </tr>
            <tr>
                <td>Roy</td>
                <td>Campbell</td>
                <td>rcampbell1@geocities.com</td>
                <td>237.232.34.20</td>
            </tr>
            <tr>
                <td>Russell</td>
                <td>Campbell</td>
                <td>rcampbell17@eventbrite.com</td>
                <td>251.2.92.63</td>
            </tr>
            <tr>
                <td>Bonnie</td>
                <td>Coleman</td>
                <td>bcoleman11@fc2.com</td>
                <td>109.150.122.102</td>
            </tr>
            <tr>
                <td>Ernest</td>
                <td>Coleman</td>
                <td>ecoleman15@businessweek.com</td>
                <td>213.173.4.7</td>
            </tr>
            <tr>
                <td>Richard</td>
                <td>Cruz</td>
                <td>rcruz7@unc.edu</td>
                <td>235.124.23.221</td>
            </tr>
            <tr>
                <td>Sean</td>
                <td>Cruz</td>
                <td>scruz10@answers.com</td>
                <td>92.255.49.227</td>
            </tr>
            <tr>
                <td>Rebecca</td>
                <td>Cunningham</td>
                <td>rcunninghamd@mac.com</td>
                <td>65.79.191.52</td>
            </tr>
            <tr>
                <td>Margaret</td>
                <td>Evans</td>
                <td>mevansh@pcworld.com</td>
                <td>162.10.86.196</td>
            </tr>
            <tr>
                <td>Jeffrey</td>
                <td>Ford</td>
                <td>jford14@cnet.com</td>
                <td>210.216.54.14</td>
            </tr>
            <tr>
                <td>Andrea</td>
                <td>Gardner</td>
                <td>agardnerv@woothemes.com</td>
                <td>179.91.0.30</td>
            </tr>
            <tr>
                <td>Deborah</td>
                <td>George</td>
                <td>dgeorge6@furl.net</td>
                <td>201.76.47.162</td>
            </tr>
            <tr>
                <td>Sean</td>
                <td>Gibson</td>
                <td>sgibsony@alexa.com</td>
                <td>48.114.103.55</td>
            </tr>
            <tr>
                <td>Virginia</td>
                <td>Graham</td>
                <td>vgrahamk@aol.com</td>
                <td>165.219.171.1</td>
            </tr>
        </tbody>
        </table>

    </section>
    <footer>
      Übung 1 - Jörn Freiheit
    </footer>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Übung 1</title>
</head>
<body>
    <header>
        <h1>Teilnehmerinnen WebTech H - L</h1>
        <img src="../../../images/fiw.jpg" alt="FIW Logo" style="width:53px; height:48px;"/>
    </header>
    <nav>
        <a href="../uebung1.html">ALLE</a>
        <a href="./ag.html">A-G</a>
        <a href="./hl.html">H-L</a>
        <a href="./mr.html">M-R</a>
        <a href="./sz.html">S-Z</a>
        <a href="../../index.html">Startseite</a>
    </nav>
    <section>
        <h3>Teilnehmerinnen H - L</h3>
        <table>
            <thead>
                <tr>
                    <th>Vorname</th>
                    <th>Nachname</th>
                    <th>E-Mail-Adresse</th>
                    <th>IP-Adresse</th>
                </tr>
            </thead>
            <tbody>
            <tr>
                <td>Steven</td>
                <td>Hamilton</td>
                <td>shamiltonu@state.tx.us</td>
                <td>38.194.91.201</td>
            </tr>
            <tr>
                <td>Virginia</td>
                <td>Hawkins</td>
                <td>vhawkinsf@ehow.com</td>
                <td>93.120.46.203</td>
            </tr>
            <tr>
                <td>Edward</td>
                <td>Hicks</td>
                <td>ehicksc@pcworld.com</td>
                <td>199.153.27.1</td>
            </tr>
            <tr>
                <td>Mark</td>
                <td>Johnson</td>
                <td>mjohnsonj@hostgator.com</td>
                <td>73.87.135.206</td>
            </tr>
            <tr>
                <td>Ruth</td>
                <td>Jordan</td>
                <td>rjordan1a@smugmug.com</td>
                <td>193.140.80.64</td>
            </tr>
            <tr>
                <td>Antonio</td>
                <td>Kim</td>
                <td>akim4@odnoklassniki.ru</td>
                <td>168.244.191.78</td>
            </tr>
        </tbody>
        </table>

    </section>
    <footer>
      Übung 1 - Jörn Freiheit
    </footer>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Übung 1</title>
</head>
<body>
    <header>
        <h1>Teilnehmerinnen WebTech M - R</h1>
        <img src="../../../images/fiw.jpg" alt="FIW Logo" style="width:53px; height:48px;"/>
    </header>
    <nav>
        <a href="../uebung1.html">ALLE</a>
        <a href="./ag.html">A-G</a>
        <a href="./hl.html">H-L</a>
        <a href="./mr.html">M-R</a>
        <a href="./sz.html">S-Z</a>
        <a href="../../index.html">Startseite</a>
    </nav>
    <section>
        <h3>Teilnehmerinnen M - R</h3>
        <table>
            <thead>
                <tr>
                    <th>Vorname</th>
                    <th>Nachname</th>
                    <th>E-Mail-Adresse</th>
                    <th>IP-Adresse</th>
                </tr>
            </thead>
            <tbody>
            <tr>
                <td>Jennifer</td>
                <td>Marshall</td>
                <td>jmarshallt@gnu.org</td>
                <td>104.191.49.94</td>
            </tr>
            <tr>
                <td>Eric</td>
                <td>Matthews</td>
                <td>ematthews5@independent.co.uk</td>
                <td>138.194.30.1</td>
            </tr>
            <tr>
                <td>Raymond</td>
                <td>Mcdonald</td>
                <td>rmcdonald2@ihg.com</td>
                <td>161.24.42.24</td>
            </tr>
            <tr>
                <td>Eric</td>
                <td>Miller</td>
                <td>emillere@creativecommons.org</td>
                <td>122.159.17.218</td>
            </tr>
            <tr>
                <td>Jonathan</td>
                <td>Morales</td>
                <td>jmoralesa@ovh.net</td>
                <td>97.65.110.105</td>
            </tr>
            <tr>
                <td>Marie</td>
                <td>Morgan</td>
                <td>mmorganb@cloudflare.com</td>
                <td>226.79.152.112</td>
            </tr>
            <tr>
                <td>Amanda</td>
                <td>Nelson</td>
                <td>anelson13@indiatimes.com</td>
                <td>161.185.121.245</td>
            </tr>
            <tr>
                <td>Lisa</td>
                <td>Olson</td>
                <td>lolsonr@telegraph.co.uk</td>
                <td>77.245.172.100</td>
            </tr>
            <tr>
                <td>Alice</td>
                <td>Ortiz</td>
                <td>aortizw@histats.com</td>
                <td>179.52.222.21</td>
            </tr>
            <tr>
                <td>Peter</td>
                <td>Phillips</td>
                <td>pphillipss@1688.com</td>
                <td>11.158.255.76</td>
            </tr>
            <tr>
                <td>Matthew</td>
                <td>Porter</td>
                <td>mporter9@europa.eu</td>
                <td>174.81.178.88</td>
            </tr>
            <tr>
                <td>Tammy</td>
                <td>Ray</td>
                <td>trayx@weather.com</td>
                <td>192.243.38.190</td>
            </tr>
            <tr>
                <td>Mark</td>
                <td>Richardson</td>
                <td>mrichardson1d@ihg.com</td>
                <td>209.217.14.154</td>
            </tr>
            <tr>
                <td>Joan</td>
                <td>Roberts</td>
                <td>jroberts12@alibaba.com</td>
                <td>4.91.143.62</td>
            </tr>
            <tr>
                <td>Kathleen</td>
                <td>Rose</td>
                <td>kroseg@pinterest.com</td>
                <td>222.172.140.56</td>
            </tr>
        </tbody>
        </table>

    </section>
    <footer>
      Übung 1 - Jörn Freiheit
    </footer>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Übung 1</title>
</head>
<body>
    <header>
        <h1>Teilnehmerinnen WebTech S - Z</h1>
        <img src="../../../images/fiw.jpg" alt="FIW Logo" style="width:53px; height:48px;"/>
    </header>
    <nav>
        <a href="../uebung1.html">ALLE</a>
        <a href="./ag.html">A-G</a>
        <a href="./hl.html">H-L</a>
        <a href="./mr.html">M-R</a>
        <a href="./sz.html">S-Z</a>
        <a href="../../index.html">Startseite</a>
    </nav>
    <section>
        <h3>Teilnehmerinnen M - Z</h3>
        <table>
            <thead>
            <tr>
                <th>Vorname</th>
                <th>Nachname</th>
                <th>E-Mail-Adresse</th>
                <th>IP-Adresse</th>
            </tr>
            </thead>
            <tbody>
            <tr>
                <td>Steve</td>
                <td>Sanders</td>
                <td>ssanders1b@wikispaces.com</td>
                <td>91.61.109.245</td>
            </tr>
            <tr>
                <td>Shirley</td>
                <td>Scott</td>
                <td>sscottm@macromedia.com</td>
                <td>219.237.108.82</td>
            </tr>
            <tr>
                <td>Lillian</td>
                <td>Stephens</td>
                <td>lstephens19@hugedomains.com</td>
                <td>89.85.137.204</td>
            </tr>
            <tr>
                <td>Nicole</td>
                <td>Thompson</td>
                <td>nthompson3@admin.ch</td>
                <td>13.183.208.155</td>
            </tr>
            <tr>
                <td>Marie</td>
                <td>Thompson</td>
                <td>mthompsonz@yelp.com</td>
                <td>162.164.5.231</td>
            </tr>
            <tr>
                <td>Alan</td>
                <td>Vasquez</td>
                <td>avasquezo@miibeian.gov.cn</td>
                <td>178.109.86.172</td>
            </tr>
            <tr>
                <td>Mildred</td>
                <td>Watkins</td>
                <td>mwatkins0@miibeian.gov.cn</td>
                <td>150.67.132.64</td>
            </tr>
            <tr>
                <td>Eugene</td>
                <td>Williams</td>
                <td>ewilliamsi@deliciousdays.com</td>
                <td>67.208.26.182</td>
            </tr>
            <tr>
                <td>Catherine</td>
                <td>Williams</td>
                <td>cwilliamsl@360.cn</td>
                <td>154.87.204.51</td>
            </tr>
        </tbody>
        </table>

    </section>
    <footer>
      Übung 1 - Jörn Freiheit
    </footer>
</body>
</html>

Übung 2

Übungsaufgabe 2 (CSS)
  • Erstellen Sie (falls noch nicht geschehen) eine index.html-Datei in Ihrem Repository-Ordner (also z.B. WebTech24) derart, dass diese direkte Links auf Ihre Lösungen der Übungen enthalten (z.B. in einer Tabelle oder einer Liste).
  • Kopieren Sie den Ordner Uebung1 in den Ordner Uebung2 (also inkl. Ordner NN). Ändern Sie darin die Datei uebung1.html zu uebung2.html (umbenennen). Ändern Sie entsprechend alle Links innerhalb der Datei, damit Sie z.B. auf den Ordner Uebung2/NN zugreifen und nicht mehr auf Uebung1/NN.
  • Legen Sie sich im Uebung2-Ordner einen Ordner styles an. Erstellen Sie in dem styles-Ordner eine Datei mystyles.css.
  • Fügen Sie im <head>-Bereich der uebung2.html eine logische Verknüpfung zur mystyles.css-Datei ein (<link href="./styles/mystyles.css" rel="stylesheet">).
  • In mystyles.css definieren Sie (versuchen Sie so viel wie möglich der folgenden Punkte umzusetzen, probieren Sie auch ruhig selbst etwas aus):
    • Verdana als Schriftart für das ganze Dokument
    • der <header> soll das HTW-Grau als Hintergrundfarbe, HTW-Orange als Schriftfarbe und der Text zentriert sein (siehe HTW Corporate Design).
    • die Tabelle soll ungefähr wie dargestellt aussehen: Uebung2
    • d.h. mit Rahmen, mit einem Schatten, die Spaltenüberschriften in weiß, mit HTW-grünem Hintergrund.
    • <a>-Elemente in einem <nav>-Element haben einen grauen Rand, deren Ecken abgerundet sind. Die Hintergrundfarbe ist HTW-blau. Schriftart ist weiß und bold. <a>-Elemente in einem <nav>-Element sind nicht unterstrichen!
    • Fährt man mit der Maus über ein <a>-Element in einem <nav>-Element ändert sich die Hintergrundfarbe in HTW-grau und die Schriftfarbe in HTW-orange. Mouseover
    • Der <footer> ist in HTW-Orange, die Schrift ist schwarz, der Text ist mittig und die Schrift ist kleiner. Die Höhe des footers entsteht dadurch, dass die Schrift einen Abstand (informieren Sie sich über den Unterschied von margin und padding) nach oben und nach unten von jeweils 20px hat.
  • Am Ende soll es ungefähr so aussehen:
    Uebung2
Eine mögliche Lösung für Übung 2 (CSS)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Uebung 2</title>
    <link href="./styles/mystyles.css" rel="stylesheet">
</head>

<body>
    <header>
        <h1>Teilnehmerinnen Webtech</h1>
        <img src="../images/fiw.jpg" alt="FIW Logo" style="width:53px; height: 48px;">
    </header>
    <nav>
        <a href="#">ALLE</a>
        <a href="NN/ag.html" title="Alle Nachnamen A-G">A-G</a>
        <a href="NN/hl.html">H-L</a>
        <a href="NN/mr.html">M-R</a>
        <a href="NN/sz.html">S-Z</a>
        <a href="../index.html">Startseite</a>
    </nav>
    <section>
        <table>
            <thead>
                <tr>
                    <th>Vorname</th>
                    <th>Nachname</th>
                    <th>E-Mail-Adresse</th>
                    <th>IP-Adresse</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>Adam</td>
                    <td>Anderson</td>
                    <td>aanderson8@google.fr</td>
                    <td>118.93.83.157</td>
                </tr>
                <tr>
                    <td>Susan</td>
                    <td>Andrews</td>
                    <td>sandrewsn@google.co.jp</td>
                    <td>228.214.9.251</td>
                </tr>
                <tr>
                    <td>Catherine</td>
                    <td>Andrews</td>
                    <td>candrewsp@noaa.gov</td>
                    <td>112.111.87.178</td>
                </tr>
                <tr>
                    <td>Alan</td>
                    <td>Bradley</td>
                    <td>abradley1c@globo.com</td>
                    <td>229.152.117.127</td>
                </tr>
                <tr>
                    <td>Anne</td>
                    <td>Brooks</td>
                    <td>abrooks16@bravesites.com</td>
                    <td>243.159.39.234</td>
                </tr>
                <tr>
                    <td>Russell</td>
                    <td>Brown</td>
                    <td>rbrownq@nifty.com</td>
                    <td>215.38.120.242</td>
                </tr>
                <tr>
                    <td>Ryan</td>
                    <td>Burton</td>
                    <td>rburton18@foxnews.com</td>
                    <td>159.60.107.14</td>
                </tr>
                <tr>
                    <td>Roy</td>
                    <td>Campbell</td>
                    <td>rcampbell1@geocities.com</td>
                    <td>237.232.34.20</td>
                </tr>
                <tr>
                    <td>Russell</td>
                    <td>Campbell</td>
                    <td>rcampbell17@eventbrite.com</td>
                    <td>251.2.92.63</td>
                </tr>
                <tr>
                    <td>Bonnie</td>
                    <td>Coleman</td>
                    <td>bcoleman11@fc2.com</td>
                    <td>109.150.122.102</td>
                </tr>
                <tr>
                    <td>Ernest</td>
                    <td>Coleman</td>
                    <td>ecoleman15@businessweek.com</td>
                    <td>213.173.4.7</td>
                </tr>
                <tr>
                    <td>Richard</td>
                    <td>Cruz</td>
                    <td>rcruz7@unc.edu</td>
                    <td>235.124.23.221</td>
                </tr>
                <tr>
                    <td>Sean</td>
                    <td>Cruz</td>
                    <td>scruz10@answers.com</td>
                    <td>92.255.49.227</td>
                </tr>
                <tr>
                    <td>Rebecca</td>
                    <td>Cunningham</td>
                    <td>rcunninghamd@mac.com</td>
                    <td>65.79.191.52</td>
                </tr>
                <tr>
                    <td>Margaret</td>
                    <td>Evans</td>
                    <td>mevansh@pcworld.com</td>
                    <td>162.10.86.196</td>
                </tr>
                <tr>
                    <td>Jeffrey</td>
                    <td>Ford</td>
                    <td>jford14@cnet.com</td>
                    <td>210.216.54.14</td>
                </tr>
                <tr>
                    <td>Andrea</td>
                    <td>Gardner</td>
                    <td>agardnerv@woothemes.com</td>
                    <td>179.91.0.30</td>
                </tr>
                <tr>
                    <td>Deborah</td>
                    <td>George</td>
                    <td>dgeorge6@furl.net</td>
                    <td>201.76.47.162</td>
                </tr>
                <tr>
                    <td>Sean</td>
                    <td>Gibson</td>
                    <td>sgibsony@alexa.com</td>
                    <td>48.114.103.55</td>
                </tr>
                <tr>
                    <td>Virginia</td>
                    <td>Graham</td>
                    <td>vgrahamk@aol.com</td>
                    <td>165.219.171.1</td>
                </tr>
                <tr>
                    <td>Steven</td>
                    <td>Hamilton</td>
                    <td>shamiltonu@state.tx.us</td>
                    <td>38.194.91.201</td>
                </tr>
                <tr>
                    <td>Virginia</td>
                    <td>Hawkins</td>
                    <td>vhawkinsf@ehow.com</td>
                    <td>93.120.46.203</td>
                </tr>
                <tr>
                    <td>Edward</td>
                    <td>Hicks</td>
                    <td>ehicksc@pcworld.com</td>
                    <td>199.153.27.1</td>
                </tr>
                <tr>
                    <td>Mark</td>
                    <td>Johnson</td>
                    <td>mjohnsonj@hostgator.com</td>
                    <td>73.87.135.206</td>
                </tr>
                <tr>
                    <td>Ruth</td>
                    <td>Jordan</td>
                    <td>rjordan1a@smugmug.com</td>
                    <td>193.140.80.64</td>
                </tr>
                <tr>
                    <td>Antonio</td>
                    <td>Kim</td>
                    <td>akim4@odnoklassniki.ru</td>
                    <td>168.244.191.78</td>
                </tr>
                <tr>
                    <td>Jennifer</td>
                    <td>Marshall</td>
                    <td>jmarshallt@gnu.org</td>
                    <td>104.191.49.94</td>
                </tr>
                <tr>
                    <td>Eric</td>
                    <td>Matthews</td>
                    <td>ematthews5@independent.co.uk</td>
                    <td>138.194.30.1</td>
                </tr>
                <tr>
                    <td>Raymond</td>
                    <td>Mcdonald</td>
                    <td>rmcdonald2@ihg.com</td>
                    <td>161.24.42.24</td>
                </tr>
                <tr>
                    <td>Eric</td>
                    <td>Miller</td>
                    <td>emillere@creativecommons.org</td>
                    <td>122.159.17.218</td>
                </tr>
                <tr>
                    <td>Jonathan</td>
                    <td>Morales</td>
                    <td>jmoralesa@ovh.net</td>
                    <td>97.65.110.105</td>
                </tr>
                <tr>
                    <td>Marie</td>
                    <td>Morgan</td>
                    <td>mmorganb@cloudflare.com</td>
                    <td>226.79.152.112</td>
                </tr>
                <tr>
                    <td>Amanda</td>
                    <td>Nelson</td>
                    <td>anelson13@indiatimes.com</td>
                    <td>161.185.121.245</td>
                </tr>
                <tr>
                    <td>Lisa</td>
                    <td>Olson</td>
                    <td>lolsonr@telegraph.co.uk</td>
                    <td>77.245.172.100</td>
                </tr>
                <tr>
                    <td>Alice</td>
                    <td>Ortiz</td>
                    <td>aortizw@histats.com</td>
                    <td>179.52.222.21</td>
                </tr>
                <tr>
                    <td>Peter</td>
                    <td>Phillips</td>
                    <td>pphillipss@1688.com</td>
                    <td>11.158.255.76</td>
                </tr>
                <tr>
                    <td>Matthew</td>
                    <td>Porter</td>
                    <td>mporter9@europa.eu</td>
                    <td>174.81.178.88</td>
                </tr>
                <tr>
                    <td>Tammy</td>
                    <td>Ray</td>
                    <td>trayx@weather.com</td>
                    <td>192.243.38.190</td>
                </tr>
                <tr>
                    <td>Mark</td>
                    <td>Richardson</td>
                    <td>mrichardson1d@ihg.com</td>
                    <td>209.217.14.154</td>
                </tr>
                <tr>
                    <td>Joan</td>
                    <td>Roberts</td>
                    <td>jroberts12@alibaba.com</td>
                    <td>4.91.143.62</td>
                </tr>
                <tr>
                    <td>Kathleen</td>
                    <td>Rose</td>
                    <td>kroseg@pinterest.com</td>
                    <td>222.172.140.56</td>
                </tr>
                <tr>
                    <td>Steve</td>
                    <td>Sanders</td>
                    <td>ssanders1b@wikispaces.com</td>
                    <td>91.61.109.245</td>
                </tr>
                <tr>
                    <td>Shirley</td>
                    <td>Scott</td>
                    <td>sscottm@macromedia.com</td>
                    <td>219.237.108.82</td>
                </tr>
                <tr>
                    <td>Lillian</td>
                    <td>Stephens</td>
                    <td>lstephens19@hugedomains.com</td>
                    <td>89.85.137.204</td>
                </tr>
                <tr>
                    <td>Nicole</td>
                    <td>Thompson</td>
                    <td>nthompson3@admin.ch</td>
                    <td>13.183.208.155</td>
                </tr>
                <tr>
                    <td>Marie</td>
                    <td>Thompson</td>
                    <td>mthompsonz@yelp.com</td>
                    <td>162.164.5.231</td>
                </tr>
                <tr>
                    <td>Alan</td>
                    <td>Vasquez</td>
                    <td>avasquezo@miibeian.gov.cn</td>
                    <td>178.109.86.172</td>
                </tr>
                <tr>
                    <td>Mildred</td>
                    <td>Watkins</td>
                    <td>mwatkins0@miibeian.gov.cn</td>
                    <td>150.67.132.64</td>
                </tr>
                <tr>
                    <td>Eugene</td>
                    <td>Williams</td>
                    <td>ewilliamsi@deliciousdays.com</td>
                    <td>67.208.26.182</td>
                </tr>
                <tr>
                    <td>Catherine</td>
                    <td>Williams</td>
                    <td>cwilliamsl@360.cn</td>
                    <td>154.87.204.51</td>
                </tr>
            </tbody>
        </table>
    </section>
    <footer>
        Jörn Freiheit - Übung 2
    </footer>
</body>

</html>
body {
    font-family: Verdana;
}

header {
    background-color: #AFAFAF;
    color: #FF5F00;
    text-align: center;
}

nav {
    margin-top: 3%;
    margin-bottom: 3%;
}

table {
    border-collapse: collapse;
    width: 80%;
    box-shadow: 10px 10px 5px grey;
}

table thead {
    background-color: #76B900;
    color: white;
}

table td,
table th {
    border: 1px solid #ddd;
    padding: 8px;
}

table tr:nth-child(even) {
    background-color: #f2f2f2;
}

table tr:hover {
    background-color: #ddd;
}

nav a {
    text-decoration: none;
    border: 1px solid #0082D1;
    background-color: #0082D1;
    border-radius: 7px;
    color: white;
    font-weight: bold;
    text-align: center;
    padding: 10px;
    box-shadow: 5px 5px 5px grey;
}

nav a:hover {
    border: 1px solid #AFAFAF;
    background-color: #AFAFAF;
    color: #FF5F00;
}

footer {
    background-color: #FF5F00;
    color: black;
    text-align: center;
    padding: 20px;
}

Übung 3

Übungsaufgabe 3 (Grid und Einheiten)
  • Erstellen Sie einen Uebung3-Ordner und darin eine Datei uebung3.html. Kopieren Sie diesen Inhalt in uebung3.html (Rechtsklick auf die Seite und Seitenquelltext anzeigen - falls ein <script>-Element unten ist, können Sie es löschen; Sie können es auch unten kopieren).
  • Laden Sie sich hier die Datei images.zip herunter, entpacken Sie sie und schieben Sie den images-Ordner samt Inhalt in den Uebung3-Ordner.
  • Implementieren Sie die uebung3.html so, dass ungefähr folgendes Aussehen entsteht: Uebung3
  • Sie können die CSS-Eigenschaften innerhalb der uebung3.html im <style>-Element definieren oder wieder in einer externen Datei.
  • Ziele der Übung sind die Anwendung von CSS-Grid (siehe z.B. hier) sowie die Verwendung von Größen und Einheiten (siehe z.B. hier). Lassen Sie Ihrer Kreativität freien Lauf!
Vorlage uebung3.html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Uebung 3</title>
</head>

<body>
    <header>
        <h2>STÄDTE</h2>
    </header>
    <main>


        <section class="wrapper">
            <div class="citycard">

                <div class="cityimage">
                    <img src="./images/berlin.png" alt="Berlin">
                </div>
                <div class="cityname">
                    <p>Berlin</p>
                </div>
            </div>

            <div class="citycard">
                <div class="cityimage">
                    <img src="./images/bernau.png" alt="Bernau">
                </div>
                <div class="cityname">
                    <p>Bernau</p>
                </div>
            </div>

            <div class="citycard">
                <div class="cityimage">
                    <img src="./images/brandenburg.png" alt="Brandenburg">
                </div>
                <div class="cityname">
                    <p>Brandenburg</p>
                </div>
            </div>

            <div class="citycard">
                <div class="cityimage">
                    <img src="./images/bremen.png" alt="Bremen">
                </div>
                <div class="cityname">
                    <p>Bremen</p>
                </div>
            </div>

            <div class="citycard">
                <div class="cityimage">
                    <img src="./images/bremerhaven.png" alt="Bremerhaven">
                </div>
                <div class="cityname">
                    <p>Bremerhaven</p>
                </div>
            </div>

            <div class="citycard">
                <div class="cityimage">
                    <img src="./images/madrid.png" alt="Madrid">
                </div>
                <div class="cityname">
                    <p>Madrid</p>
                </div>
            </div>

            <div class="citycard">
                <div class="cityimage">
                    <img src="./images/magdeburg.png" alt="Magdeburg">
                </div>
                <div class="cityname">
                    <p>Magdeburg</p>
                </div>
            </div>

            <div class="citycard">
                <div class="cityimage">
                    <img src="./images/mainz.png" alt="Mainz">
                </div>
                <div class="cityname">
                    <p>Mainz</p>
                </div>
            </div>

            <div class="citycard">
                <div class="cityimage">
                    <img src="./images/mannheim.png" alt="Mannheim">
                </div>
                <div class="cityname">
                    <p>Mannheim</p>
                </div>
            </div>

            <div class="citycard">
                <div class="cityimage">
                    <img src="./images/Marburg.png" alt="Marburg">
                </div>
                <div class="cityname">
                    <p>Marburg</p>
                </div>
            </div>

            <div class="citycard">
                <div class="cityimage">
                    <img src="./images/newyork.png" alt="New York">
                </div>
                <div class="cityname">
                    <p>New York</p>
                </div>
            </div>

            <div class="citycard">
                <div class="cityimage">
                    <img src="./images/stockholm.png" alt="Stockholm">
                </div>
                <div class="cityname">
                    <p>Stockholm</p>
                </div>
            </div>

        </section>
    </main>
    <footer>

    </footer>
</body>

</html>
Eine mögliche Lösung für Übung 3 (Grid und Einheiten)
<style>
    body {
        margin: 1%;
    }

    header {
        background-color: rgb(45, 93, 45);
        color: whitesmoke;
        padding: 2%;
        text-align: center;
        font-size:x-large;
        box-shadow: rgba(17, 12, 46, 0.15) 0px 48px 100px 0px;
        margin-bottom: 2%;
    }
    .wrapper {
        margin-top: 2%;
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        column-gap: 2%;
        row-gap: 2%;
        margin-bottom: 2%;
    }

    .citycard {
        display: grid;
        grid-template-rows: 5fr 1fr;
        box-shadow: rgba(50, 50, 93, 0.25) 0px 6px 12px -2px, rgba(0, 0, 0, 0.3) 0px 3px 7px -3px;
    }

    .cityimage {
        text-align: center;
        padding-top: 10%;
    }

    .cityimage img {
        height: 80%;
    }

    .cityname {
        font-weight: bold;
        text-align: center;
        text-transform: uppercase;
        padding-top: 2%;
    }

</style>

Übung 4

Übungsaufgabe 4 (Bootstrap)
  • Erstellen Sie einen Uebung4-Ordner und darin eine Datei uebung4.html.
  • Implementieren Sie die uebung4.html mithilfe von Bootstrap so, dass ungefähr folgendes Aussehen entsteht: Uebung4
  • Ziel der Übung ist die Anwendung von CSS-Bootstrap und das Erstellen von Formularen.
Eine mögliche Lösung für Übung 4 (Bootstrap - Formular)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="../../styles/css/bootstrap.min.css" rel="stylesheet">

    <title>Übung 4</title>
</head>
<body class="container">

    <h1 class="m-5">Teilnehmerin Registrierung</h1>

    <div class="row g-3">
        <div class="form-floating col-6">
          <input type="text" class="form-control" id="firstName" placeholder="First name" aria-label="First name">
          <label for="firstName">First name</label>
          <div class="valid-feedback">
            Korrekt!
          </div>
          <div class="invalid-feedback">
            Bitte Vornamen eingeben!
          </div>
        </div>
        <div class="form-floating col-6">
            <input type="text" class="form-control" id="lastName" placeholder="Last name" aria-label="First name">
            <label for="lastName">Last name</label>
        </div>
        <div class="form-floating col-6">
            <input type="email" class="form-control" id="email" placeholder="E-Mail" aria-label="First name">
            <label for="email">E-Mail</label>
        </div>
        <div class="form-floating col-6">
            <input type="password" class="form-control" id="password" placeholder="Password" aria-label="First name">
            <label for="password">Password</label>
        </div>
        <div class="col-3">
            <button type="reset" class="btn btn-secondary">Abbrechen</button>
        </div>
        <div class="col-3">
            <button type="submit" class="btn btn-success">Registrieren</button>
        </div>
    </div>
</body>
</html>

Übung 4a

Übungsaufgabe 4a (JavaScript)
  • Erweitern Sie einen die Datei uebung4.html aus dem Uebung4-Ordner.
  • Sind in das Formular Daten eingegeben und wird der Registrieren-Button gedrückt, dann erscheint mithilfe einer JavaScript-Funktion:

    Uebung4
  • Wird der Abbrechen-Button gedrückt, werden alle bereits eingegebenen Daten wieder aus den Textfeldern entfernt.
  • Prüfen Sie außerdem die Eingaben (siehe Validation):

    Uebung4 Uebung4
  • Ziel der Übung ist die Anwendung von JavaScript.
aktueller Stand der Lösung für Übung 4a (JavaScript) - machen wir am 20.11. weiter
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <link href="../../styles/css/bootstrap.min.css" rel="stylesheet">

    <title>Übung 4</title>
</head>
<body class="container">

    <h1 class="m-5">Teilnehmerin Registrierung</h1>

    <div class="row g-3">
        <div class="form-floating col-6">
          <input type="text" class="form-control" id="firstName" placeholder="First name" aria-label="First name">
          <label for="firstName">First name</label>
          <div class="valid-feedback">
            Korrekt!
          </div>
          <div class="invalid-feedback">
            Bitte Vornamen eingeben!
          </div>
        </div>
        <div class="form-floating col-6">
            <input type="text" class="form-control" id="lastName" placeholder="Last name" aria-label="First name">
            <label for="lastName">Last name</label>
        </div>
        <div class="form-floating col-6">
            <input type="email" class="form-control" id="email" placeholder="E-Mail" aria-label="First name">
            <label for="email">E-Mail</label>
        </div>
        <div class="form-floating col-6">
            <input type="password" class="form-control" id="password" placeholder="Password" aria-label="First name">
            <label for="password">Password</label>
        </div>
        <div class="col-3">
            <button type="reset" class="btn btn-secondary">Abbrechen</button>
        </div>
        <div class="col-3">
            <button type="submit" class="btn btn-success" onclick="submit()">Registrieren</button>
        </div>
    </div>
    <h4 class="mt-5">Eingegebene Werte</h4>
    <ul id="results" class="list-group">

    </ul>
</body>
<script>
    function submit() {
        console.log('Button submit geklickt...');

        let lastName = document.querySelector('#lastName');
        let lastNameValue = lastName.value;

        let firstName = document.querySelector('#firstName');
        let firstNameValue = firstName.value;

        let email = document.querySelector('#email');
        let emailValue = email.value;

        let password = document.querySelector('#password');
        let passwordValue = password.value;

        console.log('first name value : ', firstNameValue)
        console.log('last name value : ', lastNameValue)
        console.log('email value : ', emailValue)
        console.log('password value : ', passwordValue)

        let resultsList = document.querySelector('#results');
        resultsList.innerHTML = '<li class="list-group-item">' + firstNameValue + '</li>';
        resultsList.innerHTML +=' <li class="list-group-item">' + lastNameValue + '</li>';
        resultsList.innerHTML +=' <li class="list-group-item">' + emailValue + '</li>';
        resultsList.innerHTML +=' <li class="list-group-item">' + passwordValue + '</li>';
    }
</script>
</html>
Eine mögliche Lösung für Übung 4a (JavaScript)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <link href="../../styles/css/bootstrap.min.css" rel="stylesheet">

    <title>Übung 4</title>
    <style>
        #korrekt {
            display:none;
        }

        #inkorrekt {
            display:none;
            color: red;
        }
    </style>
</head>
<body class="container">

    <h1 class="m-5">Teilnehmerin Registrierung</h1>

    <div class="row g-3">
        <div class="form-floating col-6">
          <input type="text" class="form-control" id="firstName" placeholder="First name" aria-label="First name">
          <label for="firstName">First name</label>
          <div class="valid-feedback">
            Korrekt!
          </div>
          <div class="invalid-feedback">
            Bitte Vornamen eingeben!
          </div>
        </div>
        <div class="form-floating col-6">
            <input type="text" class="form-control" id="lastName" placeholder="Last name" aria-label="Last name">
            <label for="lastName">Last name</label>
            <div class="valid-feedback">
                Korrekt!
            </div>
            <div class="invalid-feedback">
                Bitte Nachnamen eingeben!
            </div>
        </div>
        <div class="form-floating col-6">
            <input type="email" class="form-control" id="email" placeholder="E-Mail" aria-label="Email">
            <label for="email">E-Mail</label>
            <div class="valid-feedback">
                Korrekt!
            </div>
            <div class="invalid-feedback">
                Bitte E-Mail eingeben!
            </div>
        </div>
        <div class="form-floating col-6">
            <input type="password" class="form-control" id="password" placeholder="Password" aria-label="Password">
            <label for="password">Password</label>
            <div class="valid-feedback">
                Korrekt!
            </div>
            <div class="invalid-feedback">
                Bitte Passwort eingeben!
            </div>
        </div>
        <div class="col-3">
            <button type="reset" class="btn btn-secondary" onclick="reset()">Abbrechen</button>
        </div>
        <div class="col-3">
            <button type="submit" class="btn btn-success" onclick="submit()">Registrieren</button>
        </div>
    </div>
    <div id="korrekt">
        <h4 class="mt-5">Eingegebene Werte</h4>
        <ul id="results" class="list-group">
        </ul>
    </div>
    <div id="inkorrekt">
        <h4 class="mt-5">Bitte Eingaben korrigieren</h4>
    </div>

</body>
<script>
    function submit() {

        console.log('Button submit geklickt...');

        let lastName = document.querySelector('#lastName');
        let lastNameValue = lastName.value;

        let firstName = document.querySelector('#firstName');
        let firstNameValue = firstName.value;

        let email = document.querySelector('#email');
        let emailValue = email.value;

        let password = document.querySelector('#password');
        let passwordValue = password.value;

        if(firstNameValue == '')
        {
            firstName.classList.add('is-invalid')
            firstName.classList.remove('is-valid')
        }
        else
        {
            firstName.classList.add('is-valid')
            firstName.classList.remove('is-invalid')
        }

        if(lastNameValue == '')
        {
            lastName.classList.add('is-invalid')
            lastName.classList.remove('is-valid')
        }
        else
        {
            lastName.classList.add('is-valid')
            lastName.classList.remove('is-invalid')
        }

        if(emailValue == '' || !emailValue.includes('@') || !validateEmail(emailValue))
        {
            email.classList.add('is-invalid')
            email.classList.remove('is-valid')
        }
        else
        {
            email.classList.add('is-valid')
            email.classList.remove('is-invalid')
        }


        if(passwordValue == '' || !validatePassword(passwordValue))
        {
            password.classList.add('is-invalid')
            password.classList.remove('is-valid')
        }
        else
        {
            password.classList.add('is-valid')
            password.classList.remove('is-invalid')
        }

        let korrekt = (firstNameValue != '') && (lastNameValue != '') 
                    && (emailValue != '') && validateEmail(emailValue) 
                    && (passwordValue != '' && validatePassword(passwordValue))

        console.log('first name value : ', firstNameValue)
        console.log('last name value : ', lastNameValue)
        console.log('email value : ', emailValue)
        console.log('password value : ', passwordValue)

        if(korrekt)
        {
            document.querySelector('#inkorrekt').style.display = 'none';
            document.querySelector('#korrekt').style.display = 'block';
            let resultsList = document.querySelector('#results');
            resultsList.innerHTML = `<li class="list-group-item"> ${firstNameValue} </li>
                                    <li class="list-group-item"> ${lastNameValue} </li>
                                    <li class="list-group-item"> ${emailValue} </li>
                                    <li class="list-group-item"> ${passwordValue} </li>`;
        }
        else
        {
            document.querySelector('#inkorrekt').style.display = 'block';
            document.querySelector('#korrekt').style.display = 'none';
        }
    }

    function validateEmail(email) {
        const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        return emailRegex.test(email);
    }

    function validatePassword(password) {
        // (?=.*[az]) mind ein Kleinbuchstabe
        // (?=.*[AZ]) mind ein Grossbuchstabe
        // (?=.*\d)   mind eine Ziffer
        // (?=.*[@$!%*?&]) mind. ein Sonderzeichen
        // {8,}       mind Laenge 8
        const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@.#$!%*?&])[A-Za-z\d@.#$!%*?&]{8,}$/;
        return passwordRegex.test(password);
    }

    function reset() {
        document.querySelector('#firstName').value = ''
        document.querySelector('#lastName').value = ''
        document.querySelector('#email').value = ''
        document.querySelector('#password').value = ''

        document.querySelector('#firstName').classList.remove('is-valid', 'is-invalid')
        document.querySelector('#lastName').classList.remove('is-valid', 'is-invalid')
        document.querySelector('#email').classList.remove('is-valid', 'is-invalid')
        document.querySelector('#password').classList.remove('is-valid', 'is-invalid')
    }

</script>
</html>

Übung 5

Übungsaufgabe 5 (JavaScript, DOM)
  • Laden Sie hier die Datei Uebung5.zip herunter, entpacken Sie sie und schieben den Ordner Uebung5 in Ihren Projektordner.
  • In der Datei uebung5.html sind einige Dinge vorbereitet:
    • eine Tabelle mit leerem <tbody>. Der <tbody> hat die id='tbody',
    • wird die Seite geladen, wird die init()-Funktion aufgerufen (onload='init()'),
    • eine JavaScript-Funktion getStaedte(). Diese Funktion "holt" die Datei staedte.json (liegt im Uebung5-Ordner) und gibt sie zurück,
    • eine Variable staedtearr, in der das Array geladen werden soll, das die staedte.json enthält. Achtung! das Array selbst ist der Wert, der im JSON unter dem Schlüssel staedte steht (schauen Sie sich die Datei staedte.json an),
    • eine JavaScript-Funktion createTable(), die Sie verwenden sollen, um die Tabelle mit Werten zu befüllen. Schauen Sie sich auch die Kommentare in uebung5.html an.
  • Befüllen Sie die Tabelle unter Verwendung der Daten aus staedte.json
    • für jede neu entstehende Tabellenzeile müssen Sie fünf neue td-Objekte kreieren und diese an ein neu kreiertes tr-Objekt anhängen. Das tr-Obejkt hängen Sie wiederum an den tbody.
    • die Nummer in der ersten Spalte erstellen Sie einfach fortlaufend mit dem Wert von nr, den Sie für jede Zeile erhöhen.
    • der Info-Button ist ein Hyperlink mit der Bootstrap-Klasse btn; also <a class="btn btn-success btn-sm" href="">Info</a>. Der Wert für href findet sich jeweils unter dem link-Eintrag für jede Stadt in staedte.json.
    • für das Bild verwenden Sie den bild-Link aus staedte.json als src. Geben Sie auch dem Attribut alt einen Wert (die stadt aus staedte.json).
    • die Tabelle sieht dann so aus: Uebung5
  • Bei Eingabe in das Textfeld von Filter wird bei jedem Zeichen, das eingegeben wird, die Funktion createTable() aufgerufen (siehe oninput="createTable()"). Es sollen nun nur noch die Städte angezeigt werden, deren Stadtnamen oder deren Gründungsjahr zur Eingabe passt.
    • Wird also z.B. br eingegeben, dann erscheinen nur die Städte, die mit Br beginnen (Groß- und Kleinschreibung egal, siehe toLowerCase()):
      Uebung5
    • Wird also z.B. 12 eingegeben, dann erscheinen nur die Städte, deren Gründungsjahr mit 12 beginnt:
      Uebung5
    • Tipp: Sie laufen in einer Schleife durch das Array, um alle Städte auszulesen. Fügen Sie darin eine Bedingung ein, dass Sie nur die Städte der Tabelle hinzufügen, die der Filter-Eingabe entsprechen.
Eine mögliche Lösung für Übung 5
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="../css/bootstrap.min.css" rel="stylesheet">
    <title>Übung 5</title>
    <style>
        img {
            width: 50px;
        }
    </style>
</head>
<body class="container" onload="init()">
    <h1>Städte</h1>
    <div class="row my-4">
        <div class="col-2">
            <label for="filter">Filter:</label>
        </div>
        <div class="col-10">
            <input type="text" class="form-control" id="filter" oninput="createTable()"/>
        </div>     
    </div>
    <table class="table table-striped table-hover align-middle">
        <thead>
            <tr>
                <th scope="col">Nr</th>
                <th scope="col">Jahr</th>
                <th scope="col">Stadt</th>
                <th scope="col">Link</th>
                <th scope="col">Bild</th>
            </tr>
        </thead>
        <tbody id="tbody">

        </tbody>
    </table>
    <script>
        let staedtearr = [];

        async function getStaedte() {

            const request = new Request('staedte.json', {
                    method: 'GET',      // GET ist default
                    headers: {
                        'Accept': 'application/json'
                    }
                });

            const response = await fetch('staedte.json');
            console.log(response);
            return response.json();
        }

        function createTable() {
            let input = document.getElementById('filter').value; 

            if(staedtearr.length > 0)
            {
                let tbody = document.getElementById('tbody');
                tbody.innerHTML = '';
                let nr = 1;
                for(let stadtObj of staedtearr) {
                    console.log('stadt : ', stadtObj.stadt)
                    if(input.toLowerCase() == stadtObj.stadt.substring(0,input.length).toLowerCase()) {
                        let tr = document.createElement('tr');

                        let td1 = document.createElement('td');
                        td1.innerText = nr++;
                        tr.appendChild(td1);

                        let td2 = document.createElement('td');
                        td2.innerText = stadtObj.jahr;
                        tr.appendChild(td2);

                        let td3 = document.createElement('td');
                        td3.innerText = stadtObj.stadt;
                        tr.appendChild(td3);

                        let td4 = document.createElement('td');
                        td4.innerHTML = `<a class="btn btn-success btn-sm" href="${stadtObj.link}">Link</a>`;
                        tr.appendChild(td4);

                        let td5 = document.createElement('td');
                        td5.innerHTML = `<img src="${stadtObj.bild}" als="${stadtObj.stadt}" />`;
                        tr.appendChild(td5);

                        tbody.appendChild(tr);
                    }
                }


                // hier muessen jetzt die einzelnen Zeilen in die Tabelle eingelesen werden
                // das Staedte-Array muss ausgelesen werden (z.B. for(stadt of staedtearr)
                // Tipp: zunaechst einfach alle anzeigen lassen und erst dann das Filtern einbauen
                // Filtern: die Eingabe mit dem jeweiligen Gruendungsjahr bzw. der jeweiligen Stadt
                // vergleichen (siehe z.B. substring(0, input.length) und toLowerCase())
                // wenn match, dann entsprechende Zeile einfuegen; sonst nicht
            }
        }

        function init() {

            getStaedte()
            .then( jsonObj => {
                console.log( 'body --> ', jsonObj);
                return jsonObj.staedte;
            })
            .then (alleStaedteAlsArray => {
                console.log('staedte array -->', alleStaedteAlsArray);
                staedtearr = alleStaedteAlsArray;
                createTable();
            })

            // hier getStaedte() aufrufen und
            // staedtearr befuellen!
            // siehe Promises!



        }


    </script>
</body>
</html>

Übung 6

Übungsaufgabe 6 (Angular - Komponenten)
  • Erstellen Sie ein neues Angular-Projekt Uebung6 (siehe hier).
  • Erstellen Sie mindestens folgende Komponenten: header, nav, footer, table und form.
  • Gestalten Sie header, nav und footer so, dass es ungefähr so aussieht:

    uebung6

    Diese drei Komponenten sollen mittels Komponentenselektoren in die AppComponent eingebunden werden.

  • Erstellen Sie für die TableComponent die Route read und für die FormComponent die Route create, so dass für localhost:4200/create ungefähr folgende Ansicht erscheint:

    uebung6

    Diese Komponente enthält ein Formular. Für localhost:4200/read erscheint ungefähr folgende Ansicht:

    uebung6

    Diese Komponente enthält eine Tabelle. Es ist nur der Tabellenkopf mit den Spaltenüberschriften zu sehen.

  • In der nächsten Übung befüllen wir die Tabelle mithilfe eines Services.

Eine mögliche Lösung für Übung 6
ng new uebung6
cd uebung
ng g c header
ng g c nav
ng g c footer
ng g c table
ng g c form
ng serve
<app-header></app-header>
<app-nav></app-nav>
<router-outlet />
<app-footer></app-footer>
:host {
    font-family:Verdana, Geneva, Tahoma, sans-serif
}
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { HeaderComponent } from './header/header.component';
import { NavComponent } from './nav/nav.component';
import { FooterComponent } from './footer/footer.component';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet, HeaderComponent, NavComponent, FooterComponent],
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent {
  title = 'uebung6';
}
<div class="header">
    <h1>Uebung 6</h1>
</div>
.header {
    background-color: grey;
    padding: 1%;
    text-align: center;
    color: white;
}
<div class="footer">
    <p>J. Freiheit</p>
</div>
.footer {
    position: fixed;
    bottom: 0;
    background-color: grey;
    width: 100%;
    color: white;
    text-align: center;
}
<div class="nav">
    <ul>
        <li><a routerLink="">Home</a></li>
        <li><a routerLink="/create">Create</a></li>
        <li><a routerLink="/read">Read</a></li>
    </ul>
</div>
ul {
    list-style-type: none;
    margin: 0;
    padding: 0;
    overflow: hidden;
    background-color: #333;
  }

  li {
    float: left;
  }

  li a {
    display: block;
    color: white;
    text-align: center;
    padding: 14px 16px;
    text-decoration: none;
  }

  li a:hover {
    background-color: #111;
  }
import { Component } from '@angular/core';
import { RouterLink } from '@angular/router';

@Component({
  selector: 'app-nav',
  standalone: true,
  imports: [RouterLink],
  templateUrl: './nav.component.html',
  styleUrl: './nav.component.css'
})
export class NavComponent {

}
1
2
3
4
5
6
7
8
import { Routes } from '@angular/router';
import { TableComponent } from './table/table.component';
import { FormComponent } from './form/form.component';

export const routes: Routes = [
    { path: 'read', component: TableComponent},
    { path: 'create', component: FormComponent}
];

Übung 7

Übungsaufgabe 7 (JSON, Templates, Service)
  • Nutzen Sie Ihre Implementierung aus Uebung6 - wenn nicht, erstellen Sie ein neues Angular-Projekt Uebung7 (siehe hier).
  • Erstellen Sie im public-Ordner eine Datei members.json mit folgendem Inhalt:

    assets/members.json
    [{
        "forename": "Catherine",
        "surname": "Williams",
        "email": "cwilliamsl@360.cn"
    },
    {
        "forename": "Adam",
        "surname": "Anderson",
        "email": "aanderson8@google.fr"
    },
    {
        "forename": "Susan",
        "surname": "Andrews",
        "email": "sandrewsn@google.co.jp"
    },
    {
        "forename": "Catherine",
        "surname": "Andrews",
        "email": "candrewsp@noaa.gov"
    },
    {
        "forename": "Alan",
        "surname": "Bradley",
        "email": "abradley1c@globo.com"
    },
    {
        "forename": "Anne",
        "surname": "Brooks",
        "email": "abrooks16@bravesites.com"
    },
    {
        "forename": "Russell",
        "surname": "Brown",
        "email": "rbrownq@nifty.com"
    },
    {
        "forename": "Ryan",
        "surname": "Burton",
        "email": "rburton18@foxnews.com"
    },
    {
        "forename": "Roy",
        "surname": "Campbell",
        "email": "rcampbell1@geocities.com"
    },
    {
        "forename": "Russell",
        "surname": "Campbell",
        "email": "rcampbell17@eventbrite.com"
    },
    {
        "forename": "Bonnie",
        "surname": "Coleman",
        "email": "bcoleman11@fc2.com"
    },
    {
        "forename": "Ernest",
        "surname": "Coleman",
        "email": "ecoleman15@businessweek.com"
    },
    {
        "forename": "Richard",
        "surname": "Cruz",
        "email": "rcruz7@unc.edu"
    },
    {
        "forename": "Sean",
        "surname": "Cruz",
        "email": "scruz10@answers.com"
    },
    {
        "forename": "Rebecca",
        "surname": "Cunningham",
        "email": "rcunninghamd@mac.com"
    },
    {
        "forename": "Margaret",
        "surname": "Evans",
        "email": "mevansh@pcworld.com"
    },
    {
        "forename": "Jeffrey",
        "surname": "Ford",
        "email": "jford14@cnet.com"
    },
    {
        "forename": "Andrea",
        "surname": "Gardner",
        "email": "agardnerv@woothemes.com"
    },
    {
        "forename": "Deborah",
        "surname": "George",
        "email": "dgeorge6@furl.net"
    },
    {
        "forename": "Sean",
        "surname": "Gibson",
        "email": "sgibsony@alexa.com"
    },
    {
        "forename": "Virginia",
        "surname": "Graham",
        "email": "vgrahamk@aol.com"
    },
    {
        "forename": "Steven",
        "surname": "Hamilton",
        "email": "shamiltonu@state.tx.us"
    },
    {
        "forename": "Virginia",
        "surname": "Hawkins",
        "email": "vhawkinsf@ehow.com"
    },
    {
        "forename": "Edward",
        "surname": "Hicks",
        "email": "ehicksc@pcworld.com"
    },
    {
        "forename": "Mark",
        "surname": "Johnson",
        "email": "mjohnsonj@hostgator.com"
    },
    {
        "forename": "Ruth",
        "surname": "Jordan",
        "email": "rjordan1a@smugmug.com"
    },
    {
        "forename": "Antonio",
        "surname": "Kim",
        "email": "akim4@odnoklassniki.ru"
    },
    {
        "forename": "Jennifer",
        "surname": "Marshall",
        "email": "jmarshallt@gnu.org"
    },
    {
        "forename": "Eric",
        "surname": "Matthews",
        "email": "ematthews5@independent.co.uk"
    },
    {
        "forename": "Raymond",
        "surname": "Mcdonald",
        "email": "rmcdonald2@ihg.com"
    },
    {
        "forename": "Eric",
        "surname": "Miller",
        "email": "emillere@creativecommons.org"
    },
    {
        "forename": "Jonathan",
        "surname": "Morales",
        "email": "jmoralesa@ovh.net"
    },
    {
        "forename": "Marie",
        "surname": "Morgan",
        "email": "mmorganb@cloudflare.com"
    },
    {
        "forename": "Amanda",
        "surname": "Nelson",
        "email": "anelson13@indiatimes.com"
    },
    {
        "forename": "Lisa",
        "surname": "Olson",
        "email": "lolsonr@telegraph.co.uk"
    },
    {
        "forename": "Alice",
        "surname": "Ortiz",
        "email": "aortizw@histats.com"
    },
    {
        "forename": "Peter",
        "surname": "Phillips",
        "email": "pphillipss@1688.com"
    },
    {
        "forename": "Matthew",
        "surname": "Porter",
        "email": "mporter9@europa.eu"
    },
    {
        "forename": "Tammy",
        "surname": "Ray",
        "email": "trayx@weather.com"
    },
    {
        "forename": "Mark",
        "surname": "Richardson",
        "email": "mrichardson1d@ihg.com"
    },
    {
        "forename": "Joan",
        "surname": "Roberts",
        "email": "jroberts12@alibaba.com"
    },
    {
        "forename": "Kathleen",
        "surname": "Rose",
        "email": "kroseg@pinterest.com"
    },
    {
        "forename": "Steve",
        "surname": "Sanders",
        "email": "ssanders1b@wikispaces.com"
    },
    {
        "forename": "Shirley",
        "surname": "Scott",
        "email": "sscottm@macromedia.com"
    },
    {
        "forename": "Lillian",
        "surname": "Stephens",
        "email": "lstephens19@hugedomains.com"
    },
    {
        "forename": "Nicole",
        "surname": "Thompson",
        "email": "nthompson3@admin.ch"
    },
    {
        "forename": "Marie",
        "surname": "Thompson",
        "email": "mthompsonz@yelp.com"
    },
    {
        "forename": "Alan",
        "surname": "Vasquez",
        "email": "avasquezo@miibeian.gov.cn"
    },
    {
        "forename": "Mildred",
        "surname": "Watkins",
        "email": "mwatkins0@miibeian.gov.cn"
    },
    {
        "forename": "Eugene",
        "surname": "Williams",
        "email": "ewilliamsi@deliciousdays.com"
    }
    ]
    
  • Erstellen Sie einen Service members.service.ts, in dem die members.json per fetch() eingelesen wird und der eine Funktion zur Verfügung stellt, die alle members als Array zurückgibt. Erstellen Sie ein passendes Members-Interface, um die Typsicherheit zu verbessern.

  • Befüllen Sie mit den Daten aus members.json eine Tabelle:

    uebung7

  • Implementieren Sie für das Suchfeld die Behandlung des input-Ereignisses so, dass nur die Teilnehmerinnen in der Tabelle erscheinen, deren Vor- oder Nachnamen den Suchstring enthalten:

    uebung7

  • Alle Bilder sind nur Anregungen, kann gerne ganz anders aussehen. Gerne können Sie auch Bootstrap einbinden und verwenden (siehe z.B. hier).

Eine mögliche Lösung für Übung 7

sie WebTech-Repo Weiterentwicklung von Übung 6

Übung 8

Übungsaufgabe 8 (REST-API mit PostgreSQL)

  • Erstellen Sie eine REST-API mit folgenden Endpunkten:





  • Endpunkt Erläuterung
    GET /users gebe alle user-Einträge zurück
    POST /users erstelle einen neuen user
    GET /users/:name gibt den user mit username == name zurück
    DELETE /users/:id löscht den user mit _id == id
    PUT /users/:id ändert Daten von user mit _id == id

  • Geben Sie am Anfang Folgendes im Terminal innerhalb Ihres Projekteordners ein (ohne die Kommentare):







  • Anweisung Webseite
    mkdir Uebung8 Ordner Uebung8erstellen
    npm init Erstellt das Node.js-Projekt
    npm i express express.js
    npm i dotenv dotenv
    npm i cors cors
    npm i pg pg
    npm i pg-format pg-format (brauchen Sie hier aber nicht)

  • Vewenden Sie PostgreSQL als Datenbankmanagementsystem. Sie können sich entweder eine lokale Instanz installieren oder den HTW-Server Ocean.f4.htw-berlin.de nutzen.
  • Implementieren Sie obige CRUD-Funktionalitäten.
  • Beachten Sie!: Es soll kein neuer User angelegt werden, wenn der username bereits verwendet wird und/oder wenn die email bereits verwendet wird:
    • Weder username noch email exitieren bereits (Response-Body-Datensatz hier von MongoDB erstellt - sieht in Postgres etwas anders aus _id, __v):
    • Uebung7
    • username existiert bereits:
    • Uebung7
    • email existiert bereits:
    • Uebung7
  • GET /user/:name sucht nach dem username (Response-Body-Datensatz hier von MongoDB erstellt - sieht in Postgres etwas anders aus _id, __v):

  • Uebung7

  • Die SQL-Query für die Erstellung der Tabelle users kann so aussehen: let query = ' DROP TABLE IF EXISTS users; CREATE TABLE users(id serial PRIMARY KEY, username VARCHAR(50), password VARCHAR(50), email VARCHAR(50), role VARCHAR(50));';

Übung 9

Übungsaufgabe 9 (Angular, Material Design und Formulare)
  • Erstellen Sie ein neues Angular-Projekt Uebung9.

  • Wechseln Sie in den Uebung9-Ordner und fügen Sie dem Projekt mithilfe von ng add @angular/material@18 Material Design hinzu. Achtung: die @18 ist wichtig (Stand Januar 2025)! Sie werden gefragt, ob Sie material installieren wollen (Enter). Die anschließenden Fragen können Sie mit Enter (Theme), Y (Typography) und Enter (Animations) beantworten.

  • Testen Sie, ob Material Design funktioniert, indem Sie in der app.component.html alles löschen und stattdessen <mat-slide-toggle>Toggle me!</mat-slide-toggle> hinzufügen. In der app.component.ts muss das MatSlideToggleModule importiert werden:

    import { Component } from '@angular/core';
    import { RouterOutlet } from '@angular/router';
    import { MatSlideToggleModule } from '@angular/material/slide-toggle';
    
    @Component({
      selector: 'app-root',
      standalone: true,
      imports: [RouterOutlet, MatSlideToggleModule],
      templateUrl: './app.component.html',
      styleUrl: './app.component.css'
    })
    export class AppComponent {
      title = 'uebung9';
    }
    
  • Starten Sie das Projekt mit ng serve. Je nachdem, welches Farbschema Sie gewählt haben, sieht die Seite nun ungefähr so aus:

    uebung9

    Sie können Ihr Farbschema in der angular.json im styles-Array ändern (siehe hier)

  • Erzeugen Sie drei Komponenten home, table und form und binden diese über die Routen '', read und create dynamisch ein. Suchen Sie in der nav.component.html nach den Menüeinträgen und passen Sie das Menü so an, dass die drei Komponenten darüber aufgerufen werden können.

  • In der FormComponent erzeugen wir uns ein Formular. Schauen Sie sich dazu den Abschnitt Reactive Forms unter Angular.dev sowie die Abschnitte Form fields und Input unter Angular Material an.

    • Die FormComponent muss ReactiveFormsModule im imports-Array enthalten!

    • Eingabefelder (input) werden in Angular als FormControl-Objekte defininiert, z.B.:

      export class FormComponent {
      
          username = new FormControl('');
          password = new FormControl('');
          email = new FormControl('');
          role = new FormControl('');
      
      }
      

      FormControl muss aus @angular/forms importiert werden.

    • Die Verbindung zwischen View (html) und Controller (ts) wird per [formControl]="username" hergestellt, z.B.:

      <label for="user-name">username</label>
      <input id="user-name" type="text" [formControl]="username" />
      
      <label for="pwd">password</label>
      <input id="pwd" type="password" [formControl]="password" />
      
      <label for="e-mail">email</label>
      <input id="e-mail" type="email" [formControl]="email" />
      
      <label for="role">role</label>
      <select id="role" [formControl]="role">
        <option value="">--Rolle auswählen--</option>
        <option value="user">user</option>
        <option value="admin">admin</option>
      </select>
      
    • Unter Verwendung von Material Design werden die Elemente <mat-form-field>, <mat-label> und die Eigenschaft matInput verwendet:

      <mat-form-field>
        <mat-label for="user-name">username</mat-label>
        <input matInput id="user-name" type="text" [formControl]="username" />
      </mat-form-field>
      <br/>
      <mat-form-field>
        <mat-label for="pwd">password</mat-label>
        <input matInput id="pwd" type="password" [formControl]="password" />
      </mat-form-field>
      <br />
      <mat-form-field>
        <mat-label for="e-mail">email</mat-label>
        <input matInput id="e-mail" type="email" [formControl]="email" />
      </mat-form-field>
      <br />
      <mat-form-field>
        <mat-label for="role">role</mat-label>
        <select matNativeControl id="role" [formControl]="role">
          <option value="">--Rolle auswählen--</option>
          <option value="user">user</option>
          <option value="admin">admin</option>
        </select>
      </mat-form-field>
      

      In der form.component.ts muss dazu das imports-Array entsprechend befüllt werden:

      imports: [FormsModule, MatFormFieldModule, MatInputModule, ReactiveFormsModule],
      
    • Den einzelnen input-Elementen können Validatoren hinzugefügt werden, mit denen überprüft werden kann, ob die Eingabe den Anforderungen genügt. Dazu wird die Klasse Validators aus @angular/forms verwendet (siehe hier und hier), z.B.:

          username = new FormControl('', [Validators.required]);
          password = new FormControl('', [Validators.required, Validators.minLength(8)]);
          email = new FormControl('', [Validators.required, Validators.email]);
          role = new FormControl('', [Validators.required]);
      
          getErrorMessageUsername(){
            if(this.username.hasError('required')) return 'Bitte ausfüllen';
            else return '';
          }
      
          getErrorMessagePassword(){
            if(this.password.hasError('required')) return 'Bitte ausfüllen';
            else if(this.password.hasError('minlength')) return 'Mindestens 8 Zeichen';
            else return '';
          }
      
          getErrorMessageEmail(){
            if(this.email.hasError('required')) return 'Bitte ausfüllen';
            else if(this.email.hasError('email')) return 'Keine gültige E-Mail-Adresse';
            else return '';
          }
      
          getErrorMessageRole(){
            if(this.role.hasError('required')) return 'Bitte ausfüllen';
            else return '';
          }
      

      Die getErrorMessage-Funktionen können dann z.B. so im HTML-Code verwendet werden:

      <mat-form-field class="wide-width">
        <mat-label for="user-name">username</mat-label>
        <input matInput id="user-name" type="text" [formControl]="username" />
        @if (username.invalid) {
        <mat-error>{{getErrorMessageUsername()}}</mat-error>
        }
      </mat-form-field>
      <br/>
      <mat-form-field class="wide-width">
        <mat-label for="pwd">password</mat-label>
        <input matInput id="pwd" type="password" [formControl]="password" />
        @if (password.invalid) {
        <mat-error>{{getErrorMessagePassword()}}</mat-error>
        }
      </mat-form-field>
      <br />
      <mat-form-field class="wide-width">
        <mat-label for="e-mail">email</mat-label>
        <input matInput id="e-mail" type="email" [formControl]="email" />
        @if (email.invalid) {
        <mat-error>{{getErrorMessageEmail()}}</mat-error>
        }
      </mat-form-field>
      <br />
      <mat-form-field class="wide-width">
        <mat-label for="role">role</mat-label>
        <select matNativeControl id="role" [formControl]="role" placeholder="role">
          <option value="user">user</option>
          <option value="admin">admin</option>
        </select>
        @if (role.invalid) {
        <mat-error>{{getErrorMessageRole()}}</mat-error>
        }
      </mat-form-field>
      
    • Button hinzufügen: Für Matrial Design Buttons siehe hier, z.B.:

      <button mat-raised-button [disabled]="formInvalid()" (click)="register()">Registrieren</button>
      

      Dazu muss MatButtonModule in das imports-Array von form.component.ts eingefügt werden.

    • Der Button ist so lange disabled, so lange das Formular nicht korrekt ausgefüllt ist, d.h. formInvalid() liefert so lange ein true zurück, so lange (mindestens) einer der Fehler auftritt, der eine Error-Message erzeugt (siehe oben). Schreiben Sie die Funktion formInvalid() entsprechend.

    • Bei Klick auf den Button (wenn er enabled ist), wird die Funktion register() aufgerufen. Implementieren Sie diese Funktion so, dass ein Objekt der Art

      uebung9

      auf die Konsole ausgegeben wird.

    • In Übung 10 werden wir die so erzeugten Objekte an das Backend senden und in die Datenbank speichern. Außerdem befüllen wir dann die TableComponent mit Objekten aus der Datenbank.

Übung 10

Übungsaufgabe 10 (Frontend-Backend-Anbindung)
  • Starten Sie das Backend aus Übung 8.

  • Nutzen Sie das Frontend aus Übung 9 und erweitern es wie folgt:

    • Binden Sie in die app.config.ts das HttpClientModule ein:

      import { ApplicationConfig, importProvidersFrom } from '@angular/core';
      import { provideRouter } from '@angular/router';
      
      import { routes } from './app.routes';
      import { HttpClientModule } from '@angular/common/http';
      
      export const appConfig: ApplicationConfig = {
        providers: [provideRouter(routes), importProvidersFrom(HttpClientModule)]
      };
      

    • Erstellen Sie sich einen Backend-Service und ein User-Interface mithilfe der Angular CLI:

      ng g s shared/backend
      ng g i shared/user
      

    • Definieren Sie im User-Interface die Eigenschaften username, password, email, role (alles strings).

    • Definieren Sie sich im Backend-Service Funktionen für die Anbindung der Backend-Endpunkte (GET /users, POST /users, GET /users/:name, DELETE /users/:id und PUT / users/:id). Beachten Sie, dass jeweils ein Observable zurückgegeben wird, z.B.:

      import { HttpClient } from '@angular/common/http';
      import { Injectable } from '@angular/core';
      import { User } from './user';
      import { Observable } from 'rxjs';
      
      @Injectable({
        providedIn: 'root'
      })
      export class BackendService {
        backendUrl = 'http://localhost:4000';
      
        constructor(private http: HttpClient) { }
      
        getAllUsers(): Observable<User[]> {
          let endpoint = '/users';
          return this.http.get<User[]>(this.backendUrl + endpoint);
        }
      
        deleteOneMember(id: string): Observable<any> {
          let endpoint = '/users';
          return this.http.delete<any>(this.backendUrl + endpoint + "/" + id);
        }
      
        createNewUser(user: User): Observable<User> {
          let endpoint = '/users';
          return this.http.post<User>(this.backendUrl + endpoint, user);
        }
      }
      
    • Binden Sie in die Register-Komponente den Backend-Service ein, z.B. private bs = inject(BackendService);. Lesen Sie alle Werte aus dem Registrierungsformular aus und erzeugen sich damit ein neues user-Objekt. Rufen Sie die Funktion createNewUser(user) aus dem Backend-Service auf, z.B.:

      this.bs.createNewUser(user).subscribe({
        next: (response) => console.log('response', response),
        error: (err) => console.log(err),
        complete: () => console.log('register completed')
      });
      

      Prüfen Sie, ob die Daten in die Datenbank gespeichert werden.

    • Binden Sie in die Table-Komponente den Backend-Service ein und erstellen sich dort eine readAll()-Funktion, in der die getAllUsers()-Funktion des Backend-Services aufgerufen wird.

      • Befüllen Sie mit der Response ein users-Array.
      • Rufen Sie in der ngOnInit()-Funktion der Komponente die readAll()-Funktion auf (die Komponente muss dazu OnInit implementieren).
      • Lesen Sie in einer Tabelle in der table.component.html alle User aus dem users-Array aus.
      • Richten Sie in der Tabelle eine Spalte Delete ein, deren Einträge aus Buttons bestehen. Für das Klick-Ereignis soll eine delete(id)-Funktion aufgerufen werden, die den Eintrag aus der Datenbank löscht. Rufen Sie in der delete(id)-Funktion auch die readAll()-Funktion erneut auf, damit das users-Array aktualisiert wird.