Blog

  • FOREACH  BINDING

    The foreach link is copied as a significant part of each entry in the array and is linked with each copy of the corresponding matrix element item. This is especially useful for rendering lists or tables.

    Assuming that the matrix is an observable matrix, each time you add, remove, or rearrange an entry in an array, you can effectively link the update user interface to match: insert or remove a tag or reorder multiple copies of an existing DOM element Does not affect any DOM element. This is much faster than regenerating the entire foreach every time you change the matrix.

    Of course, you can arbitrarily nest any foreach any number of other control links to links, and like.

    Exampe 1: how to iterate over an array

    <table>
        <thead>
            <tr><th>First name</th><th>Last name</th></tr>
        </thead>
        <tbody data-bind="foreach: people">
            <tr>
                <td data-bind="text: firstName"></td>
                <td data-bind="text: lastName"></td>
            </tr>
        </tbody>
    </table>
     
    <script type="text/javascript">
        ko.applyBindings({
            people: [
                { firstName: 'Jackson', lastName: 'Anderson },
                { firstName: 'Aiden', lastName: 'Beckett' },
                { firstName: 'Liam', lastName: 'Brady' }
            ]
        });
    </script>

     

    Example 2: Live example with add and remove options

     

    HTML CODE

    <!DOCTYPE html>
    <html>
    <head>
        <script type='text/javascript' src='knockout-3.4.0.js'></script>
        <script type='text/javascript' src='work3.js'></script>
        <link rel="stylesheet" href="work3.css">
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    </head>

    <body>
    <div class='Example'> 
        
        <form action='/someServerSideHandler'>
            <p>You have asked for <span data-bind='text: gifts().length'>&nbsp;</span> gift(s)</p>
            <table data-bind='visible: gifts().length > 0'>
                <thead>
                    <tr>
                        <th>Gift name</th>
                        <th>Price</th>
                        <th />
                    </tr>
                </thead>
                <tbody data-bind='foreach: gifts'>
                    <tr>
                        <td><input class='required' data-bind='value: name, uniqueName: true' /></td>
                        <td><input class='required number' data-bind='value: price, uniqueName: true' /></td>
                        <td><a href='#' data-bind='click: $root.removeGift'>Delete</a></td>
                    </tr>
                </tbody>
            </table>
         
            <button data-bind='click: addGift'>Add Gift</button>
            <button data-bind='enable: gifts().length > 0' type='submit'>Submit</button>
        </form>
        
    </div>
    </body> 
      <script>
            ko.applyBindings(viewModel);
            $("form").validate({ submitHandler: viewModel.save });
        </script>

    </html>

     

    CSS CODE

    body {
      font-family: arial;
      font-size: 14px;
    }

    .Example {
      padding: 1em;
      background-color: #EEEEDD;
      border: 1px solid #CCC;
      max-width: 655px;
    }

    .Example input {
      font-family: Arial;
    }

    .Example b {
      font-weight: bold;
    }

    .Example p {
      margin-top: 0.9em;
      margin-bottom: 0.9em;
    }

    .Example select[multiple] {
      width: 100%;
      height: 8em;
    }

    .Example h2 {
      margin-top: 0.4em;
      font-weight: bold;
      font-size: 1.2em;
    }

    .Example th {
      text-align: left;
      font-weight: bold;
    }

    .Example .price {
      text-align: right;
      padding-right: 2em;
    }

    .Example .grandTotal {
      border-top: 1px solid silver;
      padding-top: 0.5em;
      font-size: 1.2em;
    }

    .Example .grandTotal SPAN {
      font-weight: bold;
    }

    .Example table, .Example td, .Example th {
      padding: 0.2em;
      border-width: 0;
      margin: 0;
      vertical-align: top;
    }

    .Example td input, .Example td select {
      width: 8em;
    }

    .Example td.quantity input {
      width: 4em;
    }

    .Example td select {
      height: 1.8em;
      white-space: nowrap;
    }

    li {
      list-style-type: disc;
      margin-left: 20px;
    }

    JS CODE

     

    var GiftModel = function(gifts) {
        var self = this;
        self.gifts = ko.observableArray(gifts);
     
        self.addGift = function() {
            self.gifts.push({
                name: "",
                price: ""
            });
        };
     
        self.removeGift = function(gift) {
            self.gifts.remove(gift);
        };
     
        self.save = function(form) {
            alert("Could now transmit to server: " + ko.utils.stringifyJson(self.gifts));
            // To actually transmit to server as a regular form post, write this: ko.utils.postJson($("form")[0], self.gifts);
        };
    };
     
    var viewModel = new GiftModel([
        { name: "Tall Hat", price: "39.95"},
        { name: "Long Cloak", price: "120.00"}
    ]);

     

    OUTPUT

     

    You have asked for 2 gift(s)

    Gift name Price  
    Delete
    Delete

     

     

Tags: Knockoutjs