tobmes
Goto Top

JavaScript Map

Hi,

ich bins mal wider face-smile.

Ich spiele immernoch mit JavaScript herum und hänge jetzt mal wieder. Ich habe diese HTML Datei

<snip>
<img class="unsharp" src="pizza.png" width="104" height="90" alt="lecker Veggi Pizza" onclick="add(this.id);calc('veggie',5.50);" id="veggie" />  
<img src="pizza.png" width="104" height="90" alt="lecker Magherita Pizza" onclick="add(this.id);calc('magherita',3.50);" id="magherita" value="3.50" />  
<img src="pizza.png" width="104" height="90" alt="lecker Funghi Pizza" onclick="add(this.id);calc('funghi',4.50);" id="funghi" />  
<br>
<p id="summe">Summe</p>  
</snip>

und diesen JavaScript Code
<snip>
function calc(name,price) {
var m = new Map();
m[name] = price;
var value = m[name];
x = document.getElementById("summe")  
x.innerHTML = value;
}
</snip>
Die add funktion ist hier jetzt nicht interessant (Hoffe ich mal) face-smile

Also wenn ich auf das Bild klicke, dann wird die Pizza in einen Warenkorb gelegt, jetzt wäre es ja noch interessant zu wissen was denn die ganzen Pizzen im Warenkorb so kosten.
Genau daran scheitere ich gerade. Ich habe mir gedacht, dass ich eine Map aus Pizza-Name und Preis baue. Leider bin ich aber gerade zu doof die Preise mit der Map zu berechnen. Evtl. funktioniert ja meine Map auch nicht richtig. Leider habe ich dazu nicht so viel gefunden, oder verstehe es nicht so richtig. Kann mir jemand evtl. dabei Helfen?

P.S Das ist natürlich kein kommerziellen Projekt, sondern nur was zum lernen.

Danke schon mal

Content-ID: 304673

Url: https://administrator.de/contentid/304673

Ausgedruckt am: 22.11.2024 um 22:11 Uhr

colinardo
colinardo 16.05.2016 aktualisiert um 19:24:23 Uhr
Goto Top
Hallo tobmes,
hier mal ein "ganz einfaches" Schema wie du das mit Objekten und einem Array machen kannst:
// Array enthält die Artikel
var warenkorb = ;
// Artikel Objekt-Gerüst erstellen
var artikel = function(n,p){return {name:n,preis:p};}
// ein paar Artikel erstellen
var a1 = new artikel('Pizza Funghi',5.90);  
var a2 = new artikel('Pizza Margherita',4.90);  
var a3 = new artikel('Pizza Hawaii',6.90);  
// Artikel dem Warenkorb-Array hinzufügen
warenkorb.push(a1);
warenkorb.push(a2);
warenkorb.push(a3);
// Variable hält die Gesamtsumme
var total = 0;
//Gesamtsumme aller Artikel im Array zur Gesamtsumme addieren
warenkorb.forEach(function(el){
  total += el.preis;
});
// Testweise Gesamtpreis ausgeben
alert('Die Gesamtsumme des Warekorbs beträgt ' + total.toFixed(2) + '€');  
Auch wenn das nur zu deiner Übung dient, im richtigen Leben muss ein Warenkorb immer durch ein anderes serverseitiges Skript auf Validität geprüft werden, denn sonst könnte ein "Wicht" deine Preise einfach nach seinem Gusto manipulieren face-wink

Grüße Uwe
tobmes
tobmes 16.05.2016 um 21:02:40 Uhr
Goto Top
Hi Uwe,

danke für deine schnelle Antwort. Ich glaube ich verstehe da was nicht so ganz.
Frage 1: Kann ich Zeile 6 nicht durch var a1 = new artikel(name,price); ersetzten, wenn ich eine function calc(name,price) um das ganze herum setzte?
Frage 2: In Zeile 4 ist mir nicht ganz klar, was {return {name:n,preis:p};} macht.

Danke schon mal.

Gruß
Arano
Arano 16.05.2016 um 22:35:19 Uhr
Goto Top
Hi

function calc(name,price) { 
    var m = new Map(); 
Wird damit nicht bei jedem Aufruf von "calc()" "m" auf ein leeres Map-Object zurückgesetzt !?
    m[name] = price;
Wenn eine Artikel (der gleiche Artikel !) 2mal, 3mal, 5mal angeklickt wird, wird dann nicht immer einfach der alte Preis durch den Neuen ersetzt (der zudem noch identisch ist)
    var value = m[name]; 
Wenn "value" als Gesamtpreis ausgegeben wird, sollten dann nicht eine mathematische Operation durchgeführt werden z.B. addieren.

  • Gültigkeitsbereiche
  • Mathematik

Ich nehme mal an, das die Funktion "add()" den Warenkorb managed und das "calc()" nur den Gesamtpreis hochrechen soll (und was ist mir runter !?)
<html>
  <head>
    <script type="text/javascript">  
      <!--
        var WKsum = 0;
        function calc( price )
        {
            WKsum += price;
            document.getElementById('wksumme').innerHTML = WKsum + " EUR"; 
        }
      -->
    </script>
  </head>
  <body>
  
  <a href="#" onclick="calc(1)">111111</a><br>  
  <a href="#" onclick="calc(5)">555555</a><br>  
  <a href="#" onclick="calc(1.23)">123123</a><br>  
  <br>
  WKsum = <span id="wksumme">0 EUR</span>  
  
  </body>
</html>


~Arano
colinardo
colinardo 16.05.2016 aktualisiert um 23:26:07 Uhr
Goto Top
Zitat von @tobmes:
Frage 1: Kann ich Zeile 6 nicht durch var a1 = new artikel(name,price); ersetzten, wenn ich eine function calc(name,price) um das ganze herum setzte?
Frage 2: In Zeile 4 ist mir nicht ganz klar, was {return {name:n,preis:p};} macht.
Das Konstrukt erstellt ein Objekt(Name-Wert-Paar) mit dem an die Function übergebenen Parametern von Name und Preis (n und p). Das ganze ist angelehnt an die objektorientierte Programmierung, ähnlich wie mit Klassen. Man könnte es auch als Prototyp bezeichnen, der alle benötigten Bestandteile eines einzelnen Artikels beherbergt.

Das könntest du sinnvollerweise z.B. auch noch durch ein Feld Anzahl ergänzen, in dem du die Anzahl der Artikel festhältst.
var artikel = function(n,p,a){return {name:n,preis:p,anzahl:a};} 

Wie immer gibt es hier diverse Wege um sein Ziel zu erreichen, das ist ein möglicher.
Sheogorath
Sheogorath 16.05.2016 aktualisiert um 23:40:36 Uhr
Goto Top
Moin,

nachdem mein Aufschrei nun alle geweckt hat, wollen wir uns mal ans Verbessern machen :D

Also zunächst mal ein paar Kommentare zu deinem JavaScript-Code allgemein:

@colinardo hat hier schon das Array angesprochen. Wobei ich es nicht so wie er umsetzen würde.

Was du speichern willst sind in diesem Fall ja weniger Objekte, als viel mehr die Preise zu deinen Pizzas. Das machst du am besten über einen Hash oder wie du schon richtig erkannt hast eine Map. Also eine Speicherstruktur die einen Namen mit einem Preis assoziiert.

Allerdings ist die Art und Weise wie du sie deklarierst für JavaScript eher untypisch.

Statt lange
var m = new Map(); 
m[name] = price; 

Zu schreiben und das ganze auch noch in ein eigenes Objekt zu packen, wäre es einfacher die Preise einfach direkt im Objekt zu speichern:
preise['Pizza Funghi'] = 5.90;  
preise['Pizza Margherita'] = 4.90;  
preise['Pizza Hawaii'] = 6.90;  

Du hast dir das ganze Objekt um die Pizza direkt gespart. Die Preise sind auch direkt erreichbar. Das `new`-Statement sollte man allgemein in JavaScript vermeiden, da es meist überflüssig ist und sehr langsam.

Du kannst die Variable `preise` entweder global definieren, wie du es in @Arano gemacht hat, oder du nutzt ein bisschen mehr JavaScript Magie ;)

Hierzu musst du natürlich den Pizzen eine ID im HTML Code verpassen.
// eine Funktion definieren, die man nach dem Laden des HTML Codes aufruft.
function onReady() {
  // Zuerst mal die Variablen definieren
  var price, sum;
  sum = 0;
  // Die Preise mit den Namen assoziieren
  price['Pizza Funghi'] = 5.90;  
  price['Pizza Margherita'] = 4.90;  
  price['Pizza Hawaii'] = 6.90;  

  // eine Funktion defineren, die wir aufrufen, wenn wir etwas zum Warenkorb hinzufügen
  function addToCart(pizza) {
    // einfach mal auf die Summe drauf rechnen, man kann hier auch ein Array nutzen und per push(a1) den Preis hinein pushen. Wie es in einem echten Warenkorb üblich wäre.
    sum += price[pizza];
   // die summe aktualisieren
   document.getElementById("summe").innerHTML = sum;  
  }
  // jetzt definieren fügen wir die onClick funktionen zu den Pizzen hinzu. Wichtig dies hier zu tun, da man sonst keinen zugriff auf prices hat. Dazu muss man allerdings anonyme Funktionen definieren, da man keine Parameter an callback-Funktionen übergeben kann.
    document.getElementById("Funghi'").addEventListener("click", function() {addToCart('Pizza Funghi')});  
    document.getElementById("Margherita'").addEventListener("click", function() {addToCart('Pizza Margherita')});  
    document.getElementById("Hawaii'").addEventListener("click", function() {addToCart('Pizza Hawaii')});  
}
onReady();

So, das sollte die ganze Magie sein :D Wie ich mal wieder feststelle für einen Neueinsteiger vielleicht doch nicht so leicht zu verstehen.

Ich muss anmerken, dass ich den Code gerade grob aus dem Kopf zusammengezimmert habe, vielleicht ist da noch ein Bug drin versteckt, aber Konzeptionell sollte es richtig sein.

Wirklich hart definiert man inzwischen ziemlich ungern onClick Funktionen, da man hierfür global functionen definieren muss. Was eine gute Referenz ist: http://www.w3schools.com/js/js_htmldom_eventlistener.asp

Ansonsten solltest du dir auch mal http://www.w3schools.com/js/js_best_practices.asp lesen.

W3Schools ist als JavaScript Referenz sehr sehr nützlich.

In diesem Sinne viel Spaß bei der Magie ;)

Gruß
Chris
tobmes
tobmes 17.05.2016 aktualisiert um 14:26:27 Uhr
Goto Top
Hi erstmal vielen Dank für eure schnelle und super Hilfe. Ein paar Sachen sind mir jetzt schon etwas klarer geworden. Aber Ihr habt mich auch auf eine Idee gebracht, da fehlt mir aber ein Ansatz dazu.

wie ihr schon teilweise geschrieben habt macht es Sinn den Preis im Warenkorb zu reduzieren, wenn ich eine Pizza wieder raus nehme.

Mittlerweile füge ich eine Pizza so zum Warenkorb hinzu:
function add(name, price) {
    var item = document.getElementById("warenk");  
    var option = document.createElement("option");  
    //var map = new Map();
    //var total = 0;
    
   
   
    option.text = name;
    option.selcted = true;
    item.options[item.length] = option;
    calc(name, price);

}




function calc(name, preis) {
    var sumField = document.getElementById("summe");  
    var artikel = function (n, p) {
        return {name: n, preis: p};
    };
    var art = new artikel(name, preis);
    var total = 0;
    warenkorb.push(art);
    warenkorb.forEach(function (el) {
        total += el.preis;
        sumField.innerHTML = total.toFixed(2);
    });
}

Ja, bestimmt nicht schön, aber naja ... face-smile

Bisher lösche ich ein einzelnes Item aus dem Warenkorb so:
function removeSelectetItem() {
    var x = document.getElementById("warenk");  
   console.log(x.selectedIndex, typeof x); //logt 0, Object
    x.remove(x.selectedIndex);
}

Jetzt müsste ich ja um den Preis zu senken wissen, welches Item ich lösche um den richtigen Preis wieder subtrahieren. Komme ich da so überhaupt dran, oder ist das schon wieder kompletter Müll.

Danke euch schon mal wieder für eure nette Hilfe.
129413
129413 18.05.2016 aktualisiert um 16:27:13 Uhr
Goto Top
var cart = {};
var total = 0;

// Preise
var prices = {
  'Pizza A':5.90,  
  'Pizza B':4.90,  
  'Pizza C':7.90,  
  'Pizza D':9.90  
}

// Pizza hinzufügen
function addPizza(pizza){
  if (cart[pizza] == undefined){
   cart[pizza] = 1;
  }else{
   cart[pizza] += 1;
  }
  calcSum(cart);
}

// Pizza entfernen
function removePizza(pizza){
  if (cart[pizza] > 0){
   cart[pizza] -= 1;
  }else{
   delete cart[pizza];
  }
  calcSum(cart);
}

// Summe berechnen
function calcSum(cart){
  total = 0;
  for(var pizza in cart){
   if (cart.hasOwnProperty(pizza)){
    total += cart[pizza] * prices[pizza]
   }
  }
}

// Beispiele zum Hinzufügen und Entfernen
addPizza('Pizza A');  
addPizza('Pizza B');  
addPizza('Pizza B');  
removePizza('Pizza B');  
addPizza('Pizza C');  

alert(total.toFixed(2));
Gruß skybird