JSFiddle - React, Tailwind, and code Playground

HTML

<header>
  <div class="content-wrapper">
    <div class="float-left">
      <p class="site-title"><a href="/">Fresh Water Buoys</a></p>
    </div>
    <div class="float-right">
      <!--
                     <section id="login">
                        Hello, <span class="username">SOM\roland.wales</span>!
                     </section>
                         -->
      <nav>
        <ul id="menu">
          <li><a href="/">Home</a></li>
          <li><a href="/Home/About">About</a></li>
          <li><a href="/Home/Contact">Contact</a></li>
        </ul>
      </nav>
    </div>
  </div>
</header>
<div id="body">

  <section class="content-wrapper main-content clear-fix">
    <h2>Your seat reservations (<span data-bind="text: seats().length"></span>)</h2>

    <table>
      <thead>
        <tr>
          <th>Passenger name</th>
          <th>Meal</th>
          <th>Modified name</th>
          <th>Surcharge</th>
          <th></th>
        </tr>
      </thead>
      <tbody data-bind="foreach: seats">
        <tr>
          <td>
            <input data-bind="value: name, click: $root.nameClick" />
          </td>
          <td>
            <select data-bind="options: $root.availableMeals, value: meal, optionsText: 'mealName'"></select>
          </td>
          <td data-bind="text: modifiedName"></td>
          <td data-bind="text: formattedPrice"></td>
          <td><a href="#" data-bind="click: $root.removeSeat">Remove</a></td>
        </tr>
      </tbody>
    </table>

    <button data-bind="click: addSeat, enable: seats().length < 5">Reserve another seat</button>

    <h3 data-bind="visible: totalSurcharge() > 0">
     Total surcharge: $<span data-bind="text: totalSurcharge().toFixed(2)"></span>
 </h3>
  </section>
</div>

JavaScript

// Class to represent a row in the seat reservations grid
function SeatReservation(name, initialMeal) {
  var self = this;
  self.name = ko.observable(name);
  self.meal = ko.observable(initialMeal);

  self.modifiedName = ko.computed(function() {
    var name2 = self.name();
    self.name(name2);
    return name2;
  });

  self.formattedPrice = ko.computed(function() {
    var price = self.meal().price;
    return price ? "$" + price.toFixed(2) : "None";
  });
}


// Overall viewmodel for this screen, along with initial state
function ReservationsViewModel() {
  var self = this;

  // Non-editable catalog data - would come from the server
  self.availableMeals = [{
    mealName: "Standard (sandwich)",
    price: 0
  }, {
    mealName: "Premium (lobster)",
    price: 34.95
  }, {
    mealName: "Ultimate (whole zebra)",
    price: 290
  }];

  // Editable data
  self.seats = ko.observableArray([
    new SeatReservation("Steve", self.availableMeals[0]),
    new SeatReservation("Bert", self.availableMeals[0])
  ]);

  // Computed data
  self.totalSurcharge = ko.computed(function() {
    var total = 0;
    for (var i = 0; i < self.seats().length; i++)
      total += self.seats()[i].meal().price;
    return total;
  });

  // Operations
  self.addSeat = function() {
    self.seats.push(new SeatReservation("", self.availableMeals[0]));
  }
  self.removeSeat = function(seat) {
    self.seats.destroy(seat)
  } /* use destroy instead of remove to set _destroy property */

  /*
   * This updates the name observable to "a new name".
   */
  self.nameClick = function(seat) {
    seat.name("a new name");
    seat.name.valueHasMutated();
  }
}

ko.applyBindings(new ReservationsViewModel());