Mit HTML und CSS ein Suchfeld erstellen?
Hallöchen liebe Experten und Hobby Coder!
Ich soll für die Schule als Projekt eine Website coden. Ich würde gerne eine Website mit Rezepten, Angaben, Videos, Kommentaren,... machen. Ich habe schon im Internet gesucht, leider finde ich aber nicht wie man eine Suchleiste macht (so wie bei Google) und dass dann wenn man Enter drückt / eine "Suchen" Taste anclickt, alle Ergebnisse die diese Begriffe enthalten aufgelistet werden. Der Lehrer meinte übrigens dass man die Website gerne mit Hilfe des Internets machen darf, ihr könnt mir also ruhig helfen :).
Ich bedanke mich schon mal vorab für eure Hilfe,
Liebe Grüsse, Nicolas
(PS: es wäre mir ganz Recht wenn das ohne JS gehen würde sondern nur mit Hilfe von HTML.. (Keine Ahnung ob das geht))
2 Antworten
Mit reinem HTML geht das nicht. Dafür brauchst du JavaScript.
Normalerweise verwendet man dafür ein Backend + Datenbank, oder ein CMS, aber so weit bist du denke ich noch nicht.
Mein erster Vorschlag war, die Daten in eine JSON-Datei zu tun, diese dann per JavaScript einzulesen und daraus die Seite zu generieren. Indem man die Daten filtert könnte man somit auch filtern, was die Seite darstellt.
Für einen kompletten Anfänger ist das aber trotzdem noch too much. Daher nun in den Kommentaren ein neuer einfacherer Ansatz à la Daten in ein einfach strukturiertes HTML packen und Elemente darin aus/einblenden. ↓
Oh ok, ja, das ist zwar ein super Projekt für Programmier-Anfäger, um JavaScript zu lernen, aber für jemanden der gerade mal mit HTML begonnen hat ist es wohl etwas viel.
Dann wohl doch lieber die Daten direkt ins HTML und da Elemente aus/einblenden, auch wenn ich das etwas unschön finde, aber ist wohl am einfachsten.
Hier mal ein Beispiel HTML mit zwei Rezepten und einer Suchleiste. Ich habe hier alles mittels einer "searchable" Klasse markiert, wonach gesucht werden können soll. (Das HTML ist ohne head, body, usw., das kannst du selber noch dazu tun)
<input id="search">
<div class="recipe">
<h2 class="title searchable">Spiegelei</h2>
<div class="tutorial">
<div>Anleitung</div>
<ol class="searchable">
<li>Ei in Pfanne geben.</li>
<li>Pfeffer und Salz drauf streuen.</li>
</ol>
</div>
<div class="ingredients">
<div>Zutaten</div>
<ul class="searchable">
<li>Ei</li>
<li>Salz</li>
<li>Pfeffer</li>
</ul>
</div>
</div>
<div class="recipe">
<h2 class="title searchable">Müsli</h2>
<div class="tutorial">
<div>Anleitung</div>
<ol class="searchable">
<li>Müsli in Schüssel geben</li>
<li>Milch hinzugeben</li>
</ol>
</div>
<div class="ingredients">
<div>Zutaten</div>
<ul class="searchable">
<li>Müsli</li>
<li>Milch</li>
</ul>
</div>
</div>
Und hier das JavaScript, das die Elemente dann einblendet, wenn du nach einem relevanten Begriff suchst:
const recipes = document.querySelectorAll(".recipe");
// Vorerst alles ausblenden (via CSS-Eigenschaft `display: none`)
recipes.forEach(el => el.style.display = "none");
// Funktion festlegen, die aufgerufen wird, wenn man im Suchfeld eine Taste drückt
document.getElementById("search").addEventListener("keydown", (event) => {
// Prüfen ob die gedrückte Taste "Enter" ist, wenn ja, Inhalte filtern
if(event.key === 'Enter') {
// Eingabe des Users
const searchInput = event.target.value;
// Erstmal alle Elemente ausblenden, später dann alle einblenden die passen.
recipes.forEach(el => el.style.display = "none");
recipes.forEach(el => {
// Titel, Anleitung und Zutaten jedes Elements checken
// Dafür holen wir uns alle Elemente die kein Kind-Element haben, und checken deren Text
const childElements = Array.from(el.querySelectorAll(".searchable, .searchable *")).filter( e => !e.children.length);
// Einkommentieren falls du mal sehen willst welche Sachen hier durchsucht werden:
//console.log(childElements.map(x => x.innerText || x.textContent));
// Schauen ob einer der zu durchsuchenden Texte dieses Rezepts die Eingabe des Users enthält
if (childElements.some(child => (child.innerText || child.textContent).toLowerCase().includes(searchInput.toLowerCase()))) {
// Rezept inblenden, indem wir display: none wieder entfernen.
el.style.display = "";
}
});
}
});
Wenn etwas unklar ist kann ich's dir gerne erklären.
Aber vermutlich ist fast alles unklar, in dem Fall erstmal ein JavaScript Tutorial reinziehen bitte :D
Ich kenne dich zwar nicht aber ICH LIEBE DICH MANN XDD!! Kannst du mir noch gerade sagen wie ich ein "Kein Ergebnis gefunden" Screen einbauen kann? Du bist einfach unglaublich!
Dafür würde ich hier erstmal ein Element machen, in dem das "Kein Ergebnis gefunden" steht.
Dieses dann standardmäßig ausgeblenden per display: none;
Jetzt bei jeder Suche folgendes:
Das Element standardmäßig einblenden
-> Wenn ein Ergebnis gefunden wurde das Element ausblenden
Code:
HTML (der neue Teil):
<p id="noResults">
Kein Ergebnis gefunden
</p>
JS:
const recipes = document.querySelectorAll(".recipe");
const noResultsElement = document.getElementById("noResults");
// Vorerst alles ausblenden (via CSS-Eigenschaft `display: none`)
recipes.forEach(el => el.style.display = "none");
// Selbiges für die "Kein Ergebnis"-Fehlermeldung
noResultsElement.style.display = "none";
// Funktion festlegen, die aufgerufen wird, wenn man im Suchfeld eine Taste drückt
document.getElementById("search").addEventListener("keydown", (event) => {
// Prüfen ob die gedrückte Taste "Enter" ist, wenn ja, Inhalte filtern
if(event.key === 'Enter') {
// Eingabe des Users
const searchInput = event.target.value;
// Erstmal alle Elemente ausblenden, später dann alle einblenden die passen.
recipes.forEach(el => el.style.display = "none");
// Die Fehlermeldung vorerst einblenden, später dann ausblenden wenn ein Ergebnis gefunden wurde
// Bei echten Anwendungen kann man das aber nicht so machen, da es da deutlich länger dauert, bis ein Ergebnis gefunden wurde, da die Daten da von Server + Datenbank abgefragt werden. In dem Fall würde das Element quasi kurz sichtbar sein, bis ein Ergebnis da ist, was unschön wäre. Aber hier egal.
noResultsElement.style.display = "";
recipes.forEach(el => {
// Titel, Anleitung und Zutaten jedes Elements checken
// Dafür holen wir uns alle Elemente die kein Kind-Element haben, und checken deren Text
const childElements = Array.from(el.querySelectorAll(".searchable, .searchable *")).filter( e => !e.children.length);
// Einkommentieren falls du mal sehen willst welche Sachen hier durchsucht werden:
//console.log(childElements.map(x => x.innerText || x.textContent));
// Schauen ob einer der zu durchsuchenden Texte dieses Rezepts die Eingabe des Users enthält
if (childElements.some(child => (child.innerText || child.textContent).toLowerCase().includes(searchInput.toLowerCase()))) {
// Rezept einblenden, indem wir display: none wieder entfernen.
el.style.display = "";
// Fehlermeldung ausblenden, da ein Ergebnis gefunden wurde
noResultsElement.style.display = "none";
}
});
}
});
Nice!! Dann habe ich nur noch eine letzte Frage :)
Es ist ja so eingestellt dass ich auch unter "Pfeffer" das Spiegelei finde (mit der "searchable" class). Er sucht aber in dem ANLEITUNG Text nach Wörtern und nicht im ZUTATEN Text. Das bedeutet dass ich Spiegelei auch finde, wenn ich "Pfanne" eingebe. Das würde ich gerne ändern, so dass nur die Elemente bei Zutaten in der "searchable" class sind und die in der Anleitung nicht. Sobald ich das aber versuche, mache ich alles kaputt xD.
Normal kannst du dafür einfach die searchable-Klasse bei der Anleitung entfernen.
Also das hier (und auch wirklich nur den Teil):
class="searchable"
komplett weglöschen.
Ja jetzt fehlt nur noch dass die "ingredients" auch in der searchable class sind. Es steht zwar class="searchable" drin, aber wenn ich zum Beispiel "Salz" oder "Pfeffer" suche, findet er nichts..
Ich habe folgenden Code aus dem Internet (Ich fand die Animation cool). Kann ich den Code so umschreiben, dass die Animation so ist, es aber mit deinem JS Code geht?
HTML:
<div class="container">
<input type="text" name="text" class="input" required="" placeholder="Type to search...">
<div class="icon">
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512">
<title>Search</title>
<path d="M221.09 64a157.09 157.09 0 10157.09 157.09A157.1 157.1 0 00221.09 64z" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32"></path>
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32" d="M338.29 338.29L448 448"></path>
</svg>
</div>
</div>
CSS:
.container {
position: relative;
--size-button: 40px;
color: white;
}
.input {
padding-left: var(--size-button);
height: var(--size-button);
font-size: 15px;
border: none;
color: #fff;
outline: none;
width: var(--size-button);
transition: all ease 0.3s;
background-color: #191A1E;
box-shadow: 1.5px 1.5px 3px #0e0e0e, -1.5px -1.5px 3px rgb(95 94 94 / 25%), inset 0px 0px 0px #0e0e0e, inset 0px -0px 0px #5f5e5e;
border-radius: 50px;
cursor: pointer;
}
.input:focus,
.input:not(:invalid) {
width: 200px;
cursor: text;
box-shadow: 0px 0px 0px #0e0e0e, 0px 0px 0px rgb(95 94 94 / 25%), inset 1.5px 1.5px 3px #0e0e0e, inset -1.5px -1.5px 3px #5f5e5e;
}
.input:focus + .icon,
.input:not(:invalid) + .icon {
pointer-events: all;
cursor: pointer;
}
.container .icon {
position: absolute;
width: var(--size-button);
height: var(--size-button);
top: 0;
left: 0;
padding: 8px;
pointer-events: none;
}
.container .icon svg {
width: 100%;
height: 100%;
}
Ja, klar.
Entferne meinen alten <input> und füg dafür den neuen ein. (Wobei ich finde dass der ein bisschen broken aussieht, weil man den Placeholder halb sieht, und das Lupen-Icon nach unten verschoben ist, aber egal haha)
Jetzt schau dir mal meinen JS-Code an, da steht:
document.getElementById("search").addEventListener(...);
Heisst damit es diese neue Suchleiste hernimmt musst du dem darin enthaltenen <input> Element (= das Element, in dem man dann den Text eingibt) einfach nur die id "search" geben, und zwar mittels id="search", wie es bei dem alten <input> auch schon war. Dann klappt's direkt.
Also nochmal kurz:
- Altes Input-Element entfernen
- Neuen Code einfügen
- Beim neuen input-Element das id="search" ergänzen
Tut mir Leid aber ich bin zu dumm für das Zeug... Ich hänge hier mal alles an was im Moment in dem index.html drin ist und wenn du mir sagen könntest wie ich jetzt diesen neuen Button einfüge, ohne dass mir alles in die Luft geht, wäre ich dir seehr dankbar (du bist gerade die einzige Person wo ich merke dass sie richtig Ahnung vom Thema hat und ich weiss nicht wenn ich sonst fragen soll :/)
<head>
<style>
#categorie
{
font-family: fantasy;
font-size: large;
}
body
{
background-image: url(holz.jpg);
background-repeat: no-repeat;
background-size: 100%;
background-position: center;
}
body:hover
{
background-position: center center;
}
body
{
text-align: left;
}
#Ergebnisse
{
text-align: center;
}
#search
{
text-align: center;
}
.cta {
border: none;
background: none;
cursor: pointer;
}
.cta span {
padding-bottom: 7px;
letter-spacing: 4px;
font-size: 14px;
padding-right: 15px;
text-transform: uppercase;
}
.cta svg {
transform: translateX(-8px);
transition: all 0.3s ease;
}
.cta:hover svg {
transform: translateX(0);
}
.cta:active svg {
transform: scale(0.9);
}
.hover-underline-animation {
position: relative;
color: rgb(0, 0, 0);
padding-bottom: 20px;
}
.hover-underline-animation:after {
content: "";
position: absolute;
width: 100%;
transform: scaleX(0);
height: 2px;
bottom: 0;
left: 0;
background-color: #000000;
transform-origin: bottom right;
transition: transform 0.25s ease-out;
}
.cta:hover .hover-underline-animation:after {
transform: scaleX(1);
transform-origin: bottom left;
}
</style>
</head>
<body>
<h4>
<input id="search">
<a href="Gateau au chocolat fondant rapide.html">
<button class="cta">
<div id="categorie">
Gateau
</div>
</button>
</a>
</h4>
<div id="Ergebnisse">
<p id="noResults">
Kein Ergebnis gefunden
</p>
<!-- ERSTES REZEPT -->
<div class="recipe">
<h2 class="title searchable">
<a href="Gateau au chocolat fondant rapide.html">
<button class="cta">
<span class="hover-underline-animation"> Gateau au chocolat fondant rapide </span>
<svg
id="arrow-horizontal"
xmlns="http://www.w3.org/2000/svg"
width="30"
height="10"
viewBox="0 0 46 16"
>
<path
id="Path_10"
data-name="Path 10"
d="M8,0,6.545,1.455l5.506,5.506H-30V9.039H12.052L6.545,14.545,8,16l8-8Z"
transform="translate(30)"
></path>
</svg>
</button>
</a>
</h2>
</div>
<!-- ZWEITES REZEPT -->
<div class="recipe">
<h2 class="title searchable">Aurélie</h2>
</div>
<!-- DRITTES REZEPT -->
<div class="recipe">
<h2 class="title searchable">
<a href="Nathan.html">
<button class="cta">
<span class="hover-underline-animation"> Nathan </span>
<svg
id="arrow-horizontal"
xmlns="http://www.w3.org/2000/svg"
width="30"
height="10"
viewBox="0 0 46 16"
>
<path
id="Path_10"
data-name="Path 10"
d="M8,0,6.545,1.455l5.506,5.506H-30V9.039H12.052L6.545,14.545,8,16l8-8Z"
transform="translate(30)"
></path>
</svg>
</button>
</a>
</h2>
</div>
<!-- VIERTES REZEPT -->
<div class="recipe">
<h2 class="title searchable">Ludivine</h2>
</div>
</div>
<script src="index.js"></script>
</body>
<input id="search">
löschen
und an der selben Stelle das neue HTML
<div class="container">
<input type="text" name="text" class="input" required="" placeholder="Type to search...">
<div class="icon">
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512">
<title>Search</title>
<path d="M221.09 64a157.09 157.09 0 10157.09 157.09A157.1 157.1 0 00221.09 64z" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32"></path>
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32" d="M338.29 338.29L448 448"></path>
</svg>
</div>
</div>
einfügen
Aber da ist ja jetzt nirgendwo id="search" für das Script..?
Oh true, vergessen. Einfach beim input-Element hinzufügen:
Ändere im neuen Code das
<input type="text" name="text" class="input" required="" placeholder="Type to search...">
zu
<input id="search" type="text" name="text" class="input" required="" placeholder="Type to search...">
Perfekt danke!! Ich weiß nicht was ich ohne deine Hilfe machen würde! Kann man auch irgendwie privat mit dir schreiben (Discord oder so)?🤣😭
Eine suchfunktion in diesem Fall ist ausschließlich (im Sinne der Effizienz) mit PHP möglich. Der Server durchsucht hierbei die Daten und bereitet die Ergebnisse zu einer Ansicht auf. Für ein Schulprojekt sollte hierbei ein Windows, Linux oder macOS bzw. Was eben zur Verfügung steht, Apache oder Nginx als Webserver, PHP und u.U. Mariadb als Datenbankserver sofern benötigt ausreichen.
Oder mit einer beliebigen anderen Backend-Programmiersprache... Also "ausschließlich" zu sagen ist Quatsch. Gibt heutzutage besseres als PHP.
Außerdem hat er gerade mal mit HTML angefanden, was will er jetzt schon mit Datenbank und Nginx Server... Damit überforderst du denke ich nur.
Ja. Beispielsweise Python. Zu PHP gibt es aber aufgrund der langen Tradition und der erprobten Kombination Lamp bzw. Wamp bzw. Mamp mehr Ressourcen. Deswegen ist im geschilderten Fall des Schulprojekts PHP empfehlenswerter. Außerdem ist sie stand jetzt verbreiteter als die Alternativen.
Kannst du mir auch sagen wie man das ganze macht? (Nach dem eingegebenen Suchbegriff suchen zum Beispiel.. Was in diese JSON Datei reinmuss weiß ich leider auch nicht) ich bin halt wirklich kompletter Anfänger und bräuchte für diese Suchleiste von Grund auf Hilfe.. :/