Mit HTML und CSS ein Suchfeld erstellen?

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. ↓


MythosTV 
Fragesteller
 16.05.2024, 20:32

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.. :/

0
MrAmazing2  16.05.2024, 21:17
@MythosTV

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

1
MythosTV 
Fragesteller
 16.05.2024, 22:00
@MrAmazing2

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!

0
MrAmazing2  16.05.2024, 22:15
@MythosTV

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";
      }
    });
 }
});
1
MythosTV 
Fragesteller
 16.05.2024, 22:47
@MrAmazing2

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.

0
MrAmazing2  16.05.2024, 23:45
@MythosTV

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.

1
MythosTV 
Fragesteller
 17.05.2024, 08:01
@MrAmazing2

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..

0
MythosTV 
Fragesteller
 17.05.2024, 15:13
@MrAmazing2

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%;
}
0
MrAmazing2  17.05.2024, 17:06
@MythosTV

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:

  1. Altes Input-Element entfernen
  2. Neuen Code einfügen
  3. Beim neuen input-Element das id="search" ergänzen
1
MythosTV 
Fragesteller
 17.05.2024, 18:23
@MrAmazing2

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>
0
MrAmazing2  17.05.2024, 21:00
@MythosTV
<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

0
MythosTV 
Fragesteller
 17.05.2024, 21:11
@MrAmazing2

Aber da ist ja jetzt nirgendwo id="search" für das Script..?

0
MrAmazing2  17.05.2024, 21:13
@MythosTV

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...">
1
MythosTV 
Fragesteller
 17.05.2024, 21:40
@MrAmazing2

Perfekt danke!! Ich weiß nicht was ich ohne deine Hilfe machen würde! Kann man auch irgendwie privat mit dir schreiben (Discord oder so)?🤣😭

0

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.

Woher ich das weiß:Berufserfahrung

MrAmazing2  16.05.2024, 21:18

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.

0
Tux20240301  16.05.2024, 21:21
@MrAmazing2

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.

0