Ü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
eineindex.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 Dateiuebung1.html
. Dasbody
-Element soll einheader
-Element, einnav
-Element, einsection
-Element und einfooter
-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: -
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 Seitenag.html
,hl.html
,mr.html
undsz.html
sollen im OrdnerNN
abgelegt werden, der Unterordner vonUebung1
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 demUebung1
-Ordner liegt. Um die Größe des Bildes festzulegen, können Sie mit Hilfe desstyle
-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 OrdnerUebung2
(also inkl. OrdnerNN
). Ändern Sie darin die Dateiuebung1.html
zuuebung2.html
(umbenennen). Ändern Sie entsprechend alle Links innerhalb der Datei, damit Sie z.B. auf den OrdnerUebung2/NN
zugreifen und nicht mehr aufUebung1/NN
. - Legen Sie sich im
Uebung2
-Ordner einen Ordnerstyles
an. Erstellen Sie in demstyles
-Ordner eine Dateimystyles.css
. - Fügen Sie im
<head>
-Bereich deruebung2.html
eine logische Verknüpfung zurmystyles.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:
- 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. - 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 vonmargin
undpadding
) nach oben und nach unten von jeweils20px
hat.
- Am Ende soll es ungefähr so aussehen:
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 Dateiuebung3.html
. Kopieren Sie diesen Inhalt inuebung3.html
(Rechtsklick auf die Seite undSeitenquelltext 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 denUebung3
-Ordner. - Implementieren Sie die
uebung3.html
so, dass ungefähr folgendes Aussehen entsteht: - 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 Dateiuebung4.html
. - Implementieren Sie die
uebung4.html
mithilfe von Bootstrap so, dass ungefähr folgendes Aussehen entsteht: - 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 demUebung4
-Ordner. - Sind in das Formular Daten eingegeben und wird der
Registrieren
-Button gedrückt, dann erscheint mithilfe einer JavaScript-Funktion:
- 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):
- 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 OrdnerUebung5
in Ihren Projektordner. - In der Datei
uebung5.html
sind einige Dinge vorbereitet:- eine Tabelle mit leerem
<tbody>
. Der<tbody>
hat dieid='tbody'
, - wird die Seite geladen, wird die
init()
-Funktion aufgerufen (onload='init()'
), - eine JavaScript-Funktion
getStaedte()
. Diese Funktion "holt" die Dateistaedte.json
(liegt imUebung5
-Ordner) und gibt sie zurück, - eine Variable
staedtearr
, in der das Array geladen werden soll, das diestaedte.json
enthält. Achtung! das Array selbst ist der Wert, der im JSON unter dem Schlüsselstaedte
steht (schauen Sie sich die Dateistaedte.json
an), - eine JavaScript-Funktion
createTable()
, die Sie verwenden sollen, um die Tabelle mit Werten zu befüllen. Schauen Sie sich auch die Kommentare inuebung5.html
an.
- eine Tabelle mit leerem
- 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 kreiertestr
-Objekt anhängen. Dastr
-Obejkt hängen Sie wiederum an dentbody
. - 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-Klassebtn
; also<a class="btn btn-success btn-sm" href="">Info</a>
. Der Wert fürhref
findet sich jeweils unter demlink
-Eintrag für jede Stadt instaedte.json
. - für das Bild verwenden Sie den
bild
-Link ausstaedte.json
alssrc
. Geben Sie auch dem Attributalt
einen Wert (diestadt
ausstaedte.json
). - die Tabelle sieht dann so aus:
- für jede neu entstehende Tabellenzeile müssen Sie fünf neue
- Bei Eingabe in das Textfeld von
Filter
wird bei jedem Zeichen, das eingegeben wird, die FunktioncreateTable()
aufgerufen (sieheoninput="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 mitBr
beginnen (Groß- und Kleinschreibung egal, siehetoLowerCase()
):
- Wird also z.B.
12
eingegeben, dann erscheinen nur die Städte, deren Gründungsjahr mit12
beginnt:
- 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.
- Wird also z.B.
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
undform
. -
Gestalten Sie
header
,nav
undfooter
so, dass es ungefähr so aussieht:Diese drei Komponenten sollen mittels Komponentenselektoren in die
AppComponent
eingebunden werden. -
Erstellen Sie für die
TableComponent
die Routeread
und für dieFormComponent
die Routecreate
, so dass fürlocalhost:4200/create
ungefähr folgende Ansicht erscheint:Diese Komponente enthält ein Formular. Für
localhost:4200/read
erscheint ungefähr folgende Ansicht: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
Übung 7¶
Übungsaufgabe 7 (JSON, Templates, Service)
- Nutzen Sie Ihre Implementierung aus
Uebung6
- wenn nicht, erstellen Sie ein neues Angular-ProjektUebung7
(siehe hier). -
Erstellen Sie im
public
-Ordner eine Dateimembers.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 diemembers.json
perfetch()
eingelesen wird und der eine Funktion zur Verfügung stellt, die allemembers
als Array zurückgibt. Erstellen Sie ein passendesMembers
-Interface, um die Typsicherheit zu verbessern. -
Befüllen Sie mit den Daten aus
members.json
eine Tabelle: -
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: -
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:
- Geben Sie am Anfang Folgendes im Terminal innerhalb Ihres Projekteordners ein (ohne die Kommentare):
- 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 derusername
bereits verwendet wird und/oder wenn dieemail
bereits verwendet wird:- Weder
username
nochemail
exitieren bereits (Response-Body-Datensatz hier von MongoDB erstellt - sieht in Postgres etwas anders aus_id
,__v
): username
existiert bereits:email
existiert bereits:
- Weder
GET /user/:name
sucht nach demusername
(Response-Body-Datensatz hier von MongoDB erstellt - sieht in Postgres etwas anders aus_id
,__v
):- Die
SQL-Query
für die Erstellung der Tabelleusers
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));'
;
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 |
Anweisung | Webseite |
---|---|
mkdir Uebung8 | Ordner Uebung8 erstellen |
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) |

Ü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 vonng add @angular/material@18
Material Design hinzu. Achtung: die@18
ist wichtig (Stand Januar 2025)! Sie werden gefragt, ob Siematerial
installieren wollen (Enter
). Die anschließenden Fragen können Sie mitEnter
(Theme),Y
(Typography) undEnter
(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 derapp.component.ts
muss dasMatSlideToggleModule
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:Sie können Ihr Farbschema in der
angular.json
imstyles
-Array ändern (siehe hier) -
Erzeugen Sie drei Komponenten
home
,table
undform
und binden diese über die Routen''
,read
undcreate
dynamisch ein. Suchen Sie in dernav.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
mussReactiveFormsModule
imimports
-Array enthalten! -
Eingabefelder (
input
) werden in Angular alsFormControl
-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 EigenschaftmatInput
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 dasimports
-Array entsprechend befüllt werden: -
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 KlasseValidators
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.:
Dazu muss
MatButtonModule
in dasimports
-Array vonform.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 eintrue
zurück, so lange (mindestens) einer der Fehler auftritt, der eine Error-Message erzeugt (siehe oben). Schreiben Sie die FunktionformInvalid()
entsprechend. -
Bei Klick auf den Button (wenn er
enabled
ist), wird die Funktionregister()
aufgerufen. Implementieren Sie diese Funktion so, dass ein Objekt der Artauf 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 einUser
-Interface mithilfe der Angular CLI: -
Definieren Sie im
User
-Interface die Eigenschaftenusername, password, email, role
(allesstring
s). -
Definieren Sie sich im
Backend
-Service Funktionen für die Anbindung der Backend-Endpunkte (GET /users
,POST /users
,GET /users/:name
,DELETE /users/:id
undPUT / 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 denBackend
-Service ein, z.B.private bs = inject(BackendService);
. Lesen Sie alle Werte aus dem Registrierungsformular aus und erzeugen sich damit ein neuesuser
-Objekt. Rufen Sie die FunktioncreateNewUser(user)
aus demBackend
-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 denBackend
-Service ein und erstellen sich dort einereadAll()
-Funktion, in der diegetAllUsers()
-Funktion desBackend
-Services aufgerufen wird.- Befüllen Sie mit der Response ein
users
-Array. - Rufen Sie in der
ngOnInit()
-Funktion der Komponente diereadAll()
-Funktion auf (die Komponente muss dazuOnInit
implementieren). - Lesen Sie in einer Tabelle in der
table.component.html
alle User aus demusers
-Array aus. - Richten Sie in der Tabelle eine Spalte
Delete
ein, deren Einträge aus Buttons bestehen. Für das Klick-Ereignis soll einedelete(id)
-Funktion aufgerufen werden, die den Eintrag aus der Datenbank löscht. Rufen Sie in derdelete(id)
-Funktion auch diereadAll()
-Funktion erneut auf, damit dasusers
-Array aktualisiert wird.
- Befüllen Sie mit der Response ein
-