Announcement

Collapse
No announcement yet.

knockout.js - items aus input-Feld zu Liste hinzufügen und wieder entfernen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • knockout.js - items aus input-Feld zu Liste hinzufügen und wieder entfernen

    Hallo!

    Ich würde gerne erreichen, dass die Werte aus den input-Feldern in die Liste geschrieben werden und nach Klicken auf remove wieder verschwinden. Das Hinzufügen hat schon mal geklappt, aber aus irgendeinem Grund klappts jetzt nicht mehr. Ich hoff, es ist nicht nur ein Tippfehler...
    Und was ich noch gar nicht rausbekommen habe ist, wie man es schafft, Dinge aus der Liste zu entfernen obwohl der button dafür außerhalb der Liste ist. Im Moment würde jedes Mal, wenn ich etwas in die Liste einfüge, ein neuer remove button erstellt.

    Code:
    <html>
    <head>
    <title>
    </title>
    <meta charset='utf-8'/>
    <link rel='stylesheet' href='style.css' />
    </head>
    <body>
    
    <form data-bind="click:addProduct">
    <input data-bind="value:prodname"></input>
    <input data-bind="value:price"></input>
    <button type="submit">add</button>
    </form>
    
    
    	<ul data-bind="foreach:shoppingCart">
    		<li data-bind="text:name"></li>
    		<li data-bind="text:price"></li>
    		<button data-bind="click:$root.removeProduct">remove</button>
    	</ul>
    	
    <script type='text/javascript' src='knockout.js'></script>
    <script type="text/javascript">
    
    function Product(name,price) {
    	var self = this;
    	self.name = ko.observable(name);
    	self.price = ko.observable(price);
    }
    
    function personVM() {
    	var self = this;
    	self.prodname = ko.observable("");
    	self.price = ko.observable("");
    	self.shoppingCart = ko.observableArray("");
    
    	self.addProduct = function() {
    	if(self.prodname() != "" && self.price() != "")
    		self.shoppingCart.push(new Product(self.prodname(),self.price()));
    	};
    
    	self.removeProduct = function(product) {
    		self.shoppingCart.remove(product);
    	};
    }
    var vm = new personVM();
    ko.applyBindings(vm);
    </script>
    </body>
    </html>

  • #2
    Ich habs mal in jsbin gebastelt so wie ich mir das vorstellen würde:

    http://jsbin.com/iwAbAtoB/2/edit
    Zuletzt editiert von fanderlf; 29.01.2014, 14:31. Reason: nochmal angesehen

    Comment


    • #3
      Super, vielen Dank, das Hinzufügen klappt ja jetzt. Aber so ganz sehe ich noch nicht, was ich groß anders gemacht habe? Und das mit dem Löschen: Es müsste doch möglich sein, neue Einträge hinzuzufügen und dann mit einem button außerhalb der Liste in umgekerhter Reihenfolge zu löschen...?

      Hier ist sowas Ähnliches, nur leider nicht mit ner Liste:

      http://knockoutjs.com/examples/betterList.html


      Ich habs jezz hinbekommen, dass der button nicht jedes Mal erzeugt wird, aber ich weiß nicht, wie ich an die Werte komme:

      Code:
      <!DOCTYPE html>
      <html>
      <head>
      <script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/2.2.1/knockout-min.js"></script>
      <meta charset=utf-8 />
      <title>JS Bin</title>
      </head>
      <body>
        <div>
          <input data-bind="value:prodname">
          <input data-bind="value:price">
        </div>
        
        
        <ul data-bind="foreach:shoppingCart">
          <li>
            <div><span data-bind="text:name"></span> <span data-bind="text:price"></span>
            </div>
      	   </li>
        </ul>
      
              <div>
              <button data-bind="click:removeProduct">remove</button>
            </div>
      	  
        <button data-bind="click:addProduct">add</button>
      	    
      	
      <script type='text/javascript' src='knockout.js'></script>
      <script type="text/javascript">
      
      function Product(name,price) {
      	var self = this;
      	self.name = ko.observable(name);
      	self.price = ko.observable(price);
      }
      
      function personVM() {
      	var self = this;
      	self.prodname = ko.observable("");
      	self.price = ko.observable("");
      	self.shoppingCart = ko.observableArray([]);
      
      	self.addProduct = function() {
      	if(self.prodname() !== "" && self.price() !== "")
      		self.shoppingCart.push(new Product(self.prodname(),self.price()));
      	};
      
      	self.removeProduct = function() {
      		self.shoppingCart.remove(this.prodname(),this.price()); // klappt nicht
      	};
      }
      var vm = new personVM();
      ko.applyBindings(vm);
      </script>
      </body>
      </html>

      Comment


      • #4
        Anders gemacht hast Du:
        - Die Inputs waren eine Form und irgendwie haben Textänderungen bei mir auch das click auf der Form ausgelöst. Das click event sollte definitiv auf dem Button und nicht auf der Form sein. Das ist jetzt aber nur mein Gefühl und ich bin auch nicht der absolute KnockoutJS Experte, obwohl ich schon eine Seite mit vielen Eingabemöglichkeiten damit gebaut habe.
        - Eine Form und ein Submit Button. In der Regel werden die Änderungen mit derselben URL an den Server gePOSTed. Ich glaube auch das ist kein gewolltes Verhalten an dieser Stelle. Deswegen habe ich dort die Form rausgenommen.

        Wenn der Button ausserhalb der Liste ist, willst Du ja einfach nur den letzten Datensatz aus dem Array nehmen. Also einfach auf dem Observable Array das letzte Element mit pop() entfernen. Dazu musst Du ja gar nicht wissen welches das letzte Element ist. Ein Array ist bereits sortiert und kennt sein letztes Element. pop() gibt das letzte Element übrigens auch zurück falls Du noch was andres damit machen willst.

        Soll die Seite eigentlich auch ohne JS nutzbar sein?
        Zuletzt editiert von fanderlf; 29.01.2014, 15:21.

        Comment


        • #5
          aaah, an pop() hab ich gar nicht gedacht... herrjeh. Also eigentlich soll die Seite ohne JS nicht laufen. Will ja grad was mit knockout, Jquery und IndexedDB umsetzen. Wieso meinst du?

          Comment


          • #6
            Ne dann ist alles gut, aber ich würde knockoutjs dann am anfang der seite laden, sonst sitzt der benutzer ewig vor einer zerstörten Seite. Darüber sollte man sich übrigens auch noch Gedanken machen. Also wie die Seite aussieht bis denn Knockout usw. mal anfängt zu laufen

            Comment


            • #7
              samma, ich merk grad, dass das Ganze nur funzt, wenn ich knockout, wie du, von nem CDN einbinde... wieso das denn?
              so, wie ich es hier eingebunde habe, klappt es nicht. Aber JQuery klappt so. Und wenn ich das CDN benutze und den knockout-code in den head packe, klappt es auch nicht.

              Code:
              <!DOCTYPE html>
              <html>
              <head>
              <meta charset=utf-8 />
              <title>test</title>
              <script src="knockout-3.0.0.js"></script>
              <script type='text/javascript' src='jquery-1.10.2.min.js'></script>
              
              </head>
              <body>
                <div>
                  <input data-bind="value:prodname">
                  <input data-bind="value:price">
                  
                </div>
                
                
                <ul data-bind="foreach:shoppingCart">
                  <li>
                    <div><span data-bind="text:name"></span> <span data-bind="text:price"></span>
                    </div>
              
                  </li>
                </ul>
              	
              	      <div>
                      <button data-bind="click:removeProduct">remove</button>
                    </div>
              	  <button data-bind="click:addProduct">add</button>
              	 <script type="text/javascript">
              function Product(name,price) {
              	var self = this;
              	self.name = ko.observable(name);
              	self.price = ko.observable(price);
              }
              
              function personVM() {
              	var self = this;
              	self.prodname = ko.observable("");
              	self.price = ko.observable("");
              	self.shoppingCart = ko.observableArray([]);
              
              	self.addProduct = function() {
              	if(self.prodname() !== "" && self.price() !== "")
              		self.shoppingCart.push(new Product(self.prodname(),self.price()));
              	};
              
              	self.removeProduct = function(product) {
              		self.shoppingCart.pop();
              	};
              }
              var vm = new personVM();
              ko.applyBindings(vm);
              </script>
              </body>
              </html>
              Zuletzt editiert von Vokabulator; 30.01.2014, 10:49.

              Comment


              • #8
                Im Script-Tag den typ setzen.....
                Christian

                Comment


                • #9
                  bringt leider auch nix. Und is seit HTML 5 eigentlich aucht nicht mehr obgligatoisch.

                  Comment


                  • #10
                    pff. ich habs... da war was in der knockout-datei falsch. nun funzt es. Vielen Dank fanderlf!

                    Comment


                    • #11
                      Sehr gerne

                      Comment

                      Working...
                      X