JavaScript: onclick display mehrere IDs möglich?

M

McMoneysack91

Gast
Liebe Freunde,

Wie immer ein Sachverhalt heruntergebrochen auf einfach begreifliche Analogien:


Ausgangslage

Ich habe mittels HTML einen groooooßen Katalog an Werkzeugen erstellt. Da gibt es zum Beispiel:

Hammer
Bleistift
Lineal
Schere
Säge

Und ich möchte, dass bestimmte Berufsgruppen, wenn sie dieses Tool benutzen, auf den Button mit ihrer eigenen Benutzergruppe klicken und nur die Werkzeuge angezeigt bekommen, die auch wirklich zu ihrer Berufsgruppe passen.

Die Berufsgruppen in diesem Beispiel sollen erstmal sein:

Zimmermann
Architekt
Schneider



Meine bisherigen selbst erstellten Lösungsansätze

Bislang habe ich folgenden Code geschrieben und damit herumexperimentiert:

HTML:
<!DOCTYPE html>
<html lang="de">
<body>
  <div id="tools">
    <p id="Zimmermann" style="display: none;">Hammer</p>
    <p id="Architekt" style="display: none;">Bleistift</p>
    <p id="Architekt" style="display: none;">Lineal</p>
    <p id="Schneider" style="display: none;">Schere</p>
  </div>
 
  <button onclick="displayZimmermann()">Zimmermann</button>
  <button onclick="displayArchitekt()">Architekt</button>
  <button onclick="displaySchneider()">Schneider</button>
</body>
</html>


<script>

function displayZimmermann() {
 var text = document.getElementById("Zimmermann");
 text.style.display = "block";
}

function displayArchitekt() {
 var text = document.getElementById("Architekt");
 text.style.display = "block";
}

function displaySchneider() {
 var text = document.getElementById("Schneider");
 text.style.display = "block";
}

Wie man sieht habe ich den entsprechenden Werkzeugen eine ID vergeben.


1. Problem

Bereits hier ist das erste Problem ersichtlich. Wenn ich auf den "Zimmermann" Button klicke, wird mir "Hammer" ausgeworfen. Soweit so gut. Klicke ich nun aber auf z.B. Schneider, so kommt zwar die "Schere" aber es bleibt der "Hammer" weiterhin bestehen.
Wie kriege ich die Einträge vorheriger Klicks wieder weg?


2. Problem

Wie ihr seht, habe ich zwei Werkzeuge mit der ID "Architekt" versehen, weil sie thematisch einfach zu ihm passen. Wenn ich jedoch den Button "Architekt" anklicke, wird nur eines der Werkzeuge angezeigt, nicht alle.
Wie kriege ich es hin, dass ALLE Werkzeuge, welche dieselbe ID haben, angezeigt werden?


Optimalzustand

Der Optimalzustand geht noch einen einzigen Schritt weiter. Aber auch wirklich nur einen. Ich möchte, dass ein Werkzeug auch MEHREREN Berufsgruppen zugehörig sein kann. Wie z.B. der "Bleistift".
Wie kann ich die IDs so ergänzen oder um "Synonyme" erweitern, dass die Werkzeuge auch dann ausgeworfen werden, wenn wenigstens EINER der ID-Teile zutrifft? Kann man IDs mit Semikolon oder Ähnlichem Trennen? Kann man einfach eine zweite ID vergeben?

Ich tüftle in der Zeit munter weiter.
 
Hallo.
Hier ein paar kurze Tipps:
  • versuch chatgpt zum programmieren!!!
  • du willst keine IDs verwenden sondern classes. Weil was ist wenn man eine Berufsgruppe mehrere Werkzeuge haben? IDs müssen einzigartig sein (sonst ist es kein valides HTML). Verwende also classes. Es kann ein Element auch mehrere classes haben. Und mehrere Elemente können die selbe class haben.
    Damit kannst du dann alle Fälle abdecken:
    • Eine Berufsgruppe kann mehrere Werkzeuge haben
    • Ein Werkzeug kann von mehreren Berufsgruppen verwendet werden.
  • Wenn du eine aktion auslöst zum einblenden müsst du das andere Zeugs auch ausblenden. Geht zb so:

Code:
// Select all elements with the class 'tools'
      var tools = document.querySelectorAll('.tools');

      // Loop through each element and hide it
      for (var i = 0; i < tools.length; i++) {
        tools[i].style.display = 'none';
      }
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: McMoneysack91
Okay, das mit den IDs ist sehr einleuchtend. Danke schonmal für den Tipp. Hätte ich selber drauf kommen müssen.

Ich habe bei W3Schools getElementByClassName entdeckt und die dortigen collections könnten hierfür eine Lösung sein. Ob sie auch des Rätsels Lösung sind für mehrere Classes, sodass ein Werkzeug mehreren Berufsklassen zugeordnet werden kann, muss ich dann noch sehen.

https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_document_getelementsbyclassname
 
Ja, das musst du mit Klassen machen. Wie du zu den Elementen einer Klasse kommst, ist dann zweitrangig.
Jquery wäre auch ne Möglichkeit. Ist vielleicht noch etwas netter zu lesen, aber auch mehr Overhead.

Aber IDs ist wirklich falsch hierfür. Eine ID wird verwendet um genau ein Element auf der gesamten Webseite eindeutig referenzieren zu können.
 
  • Gefällt mir
Reaktionen: Raijin
Klar, wenn du bei jedem onclick nur die Eigenschaft eines Elements änderst, bleiben die Eigenschaften der anderen Elemente erhalten. Willst du ein toggle bauen, das stets nur ein Element anzeigt und die anderen ausblendet, musst du in der Methode eben in einer Zeile das eine Element einblenden und danach zwei Zeilen, die die anderen beiden ausblenden.

Quasi so:

Code:
function displayZimmermann() {
   var text1 = document.getElementById("Zimmermann");
   var text2 = document.getElementById("Architekt");
   var text3 = document.getElementById("Schneider");

   text1.style.display = "block";
   text2.style.display = "none";
   text3.style.display = "none";
}
Ergänzung ()

Dass IDs an dieser Stelle das falsche sind, ist klar, das haben die anderen beiden schon geschrieben. Es ändert aber nichts daran, dass du beim Umschalten jeweils die andere Klasse entsprechend ein- oder ausblenden musst. Wenn du ein Element nicht veränderst, bleibt es erhalten und somit bleibt eben auch alles eingeblendet, was du nicht explizit ausblendest und alles bleibt ausgeblendet, wenn du es nicht explizit einblendest.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: McMoneysack91
Hier vielleicht noch ein wenig sauberer da kompakter:
(Natürlich sollte man HTML, JS und CSS Code von einander trennen. Hab ich nur hier wegen der übersichtlichkeit im Forum gemacht)

Code:
<!DOCTYPE html>
<html>
<head></head>
<body>
  <button onclick="showItems('zimmermann')">zimmermann</button>
  <button onclick="showItems('architekt')">architekt</button>
  <button onclick="showItems('schneider')">schneider</button>

  <ul id="itemList">
    <li class="zimmermann">Item 1</li>
    <li class="architekt zimmermann">Item 2</li>
    <li class="schneider">Item 3</li>
    <li class="zimmermann">Item 4</li>
    <li class="architekt">Item 5</li>
    <li class="schneider zimmermann">Item 6</li>
    <li class="zimmermann">Item 7</li>
    <li class="architekt">Item 8</li>
    <li class="schneider">Item 9</li>
    <li class="zimmermann">Item 10</li>
  </ul>

  <script>
    function showItems(beruf) {
      var itemList = document.getElementById('itemList');
      var items = itemList.getElementsByTagName('li');

      for (var i = 0; i < items.length; i++) {
        var item = items[i];
        if (item.classList.contains(beruf)) {
          item.style.display = 'list-item';
        } else {
          item.style.display = 'none';
        }
      }
    }
  </script>
</body>
</html>
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: McMoneysack91 und Raijin
Ergänzung: Man kann auch mehrere Klassen angeben.

class="zimmermann architekt"

Das Script von @da_reini prüft bereits ob die gewünschte Klasse enthalten ist (classList.contains), also auch wenn sie eine von mehreren ist. So werden auch mehrfach-Klassen abgedeckt.
 
  • Gefällt mir
Reaktionen: da_reini
Raijin schrieb:
Man kann auch mehrere Klassen angeben
DAS war eine Erkenntnis die traf mich gerade wie ein Blitz, als mir Google die Antwort auswarf "yes, elements can have as many classes as you want. Separate them by spaces" :D :D :D

@da_reini ich danke dir SO sehr. Ich habe deinen Code genommen, und mit der Ergänzung von @Raijin vervollständigt:

HTML:
<!DOCTYPE html>
<html>
<head>
  <style>
    .hidden {
      display: none;
    }
  </style>
</head>
<body>
  <button onclick="showItems('zimmermann')">Zimmermann</button>
  <button onclick="showItems('architekt')">Architekt</button>
  <button onclick="showItems('schneider')">Schneider</button>

  <ul id="itemList">
    <li class="zimmermann" style="display:none;">Hammer</li>
    <li class="architekt zimmermann schneider" style="display:none;">Bleistift</li>
    <li class="schneider" style="display:none;">Schere</li>
    <li class="zimmermann architekt" style="display:none;">Lineal</li>
    <li class="architekt" style="display:none;">Winkel</li>
    <li class="schneider" style="display:none;">Nadel</li>
    <li class="zimmermann" style="display:none;">Säge</li>
    <li class="architekt" style="display:none;">Lot</li>
    <li class="schneider" style="display:none;">Spule</li>
    <li class="zimmermann" style="display:none;">Schraubzwinge</li>
  </ul>

  <script>
    function showItems(buttonId) {
      var itemList = document.getElementById('itemList');
      var items = itemList.getElementsByTagName('li');

      for (var i = 0; i < items.length; i++) {
        var item = items[i];
        if (item.classList.contains(buttonId)) {
          item.style.display = 'list-item';
        } else {
          item.style.display = 'none';
        }
      }
    }
  </script>
</body>
</html>

Jetzt sieht man, dass gewisse Gegenstände auch bei anderen Berufsgruppen mit auftauchen, wie etwa der Bleistift, der bei allen dabei ist oder das Lineal, das beim Zimmermann sowie dem Architekten auftaucht.

Was für ein Wahnsinn. Darauf kann ich aufbauen und könnte mit euren Beiträgen zufriedener NICHT sein!
 
Ich hab noch was optimiert. CSS im head habe ich ja dann doch nicht verwendet
War also überflüsssig. bitte noch mal rauf schauen
 
  • Gefällt mir
Reaktionen: McMoneysack91
McMoneysack91 schrieb:
@da_reini Ich habe deinen Code genommen, und mit der Ergänzung von @Raijin vervollständigt:
Der Schlawiner hat das jetzt nacheditiert :D

da_reini schrieb:
Ich hab noch was optimiert.
Optimieren kann man immer, aber ich denke der Groschen ist gefallen. Mit CSS im Hintergrund wie du es ja schon vorbereitet hast, wird's ja noch n bischen übersichtlicher, weil man nicht mit individuellen Element-Styles rumfummeln muss. So machen es ja auch CSS-Frameworks wie bootstrap und co.

Das ist übrigens noch ein allgemeiner Tip an @McMoneysack91:

Schau dir mal beispielsweise Bootstrap an. Das ist ein Framework aus css und js, bei dem viele Standard Anwendungsfälle bereits ausprogrammiert sind. Es gibt da beispielsweise schon Klassen für hidden oder collapse und dergleichen. Selbst wenn man nur einen Bruchteil davon nutzt, ist es stets praktisch, noch ein paar fertige Pfeile im Köcher zu haben, wenn man dann doch mal was neues im Auge hat, was weiß ich, Panels zum ein- und ausklappen, Rote Meldungskästchen für Alerts oder was weiß ich. Bootstrap ist mächtig und wenn man sich anschaut wir dort bestimmte CSS-Klassen gebaut sind, kann man auch ne Menge lernen, ohne von 0 an mit einer leeren site.css zu starten....
 
  • Gefällt mir
Reaktionen: da_reini und McMoneysack91
Raijin schrieb:
Optimieren kann man immer, aber ich denke der Groschen ist gefallen
Ganz genau.

Ich habe ja hier schon eine komplette GUI für den Anwender im Corporate Design fertig. Und dass es nicht um Hämmer und Sägen geht, liegt ja auch auf der Hand :p Das ist nur meine Art, die Dinge möglichst stupide auf das Wesentliche runterzubrechen.

Und ja, der Groschen ist MEHR als nur gefallen! Riesigen Dank für eure Mühen und vielleicht kann dieser kurze knackige Thread anderen Novizen als Nachschlagwerk dienen :)
 
  • Gefällt mir
Reaktionen: Raijin und da_reini
Zurück
Oben