Show / hide elements dynamically using knockout

I have a table with four columns, namely code, name, quantity and price. From this I want to dynamically change the content / element of the Count column. Usually it should show the item with the quantity displayed in it, and when the user clicks on the item, I want to show the item so that the user can edit the quantity. I am trying to implement according to "Example 2" on this link for knockout documentation .

Below is my code:

Page view model

function OrderVM (vm) {
    var self = this;
    self.OrderNo= ko.observable(vm.OrderNo());   
    .....
    .....
    self.OrderedProducts = ko.observableArray([]);
    for (i = 0; i < vm.OrderedProducts().length; i++) {
        var p = new ProductVM(vm.OrderedProducts()[i]);
        self.OrderedProducts.push(p);
    }
    .....
}

function ProductVM(vm) {
    var self = this;

    self.Code = ko.observable(vm.Code());
    self.Name = ko.observable(vm.Name());
    self.Quantity = ko.observable(vm.Quantity());
    self.Price = ko.observable(vm.Price());
    self.IsEditing = ko.observable(false);

    this.edit = function () {
        self.IsEditing(true);
    }
}

      

In my Razor view , I have the following code:

<tbody data-bind="foreach:OrderedProducts">
<tr>
    <td class="lalign"><span data-bind="text:Code"/></td>
    <td class="lalign"><span data-bind="text:Name" /></td>
    <td class="ralign" style="padding:1px!important;">
        <span data-bind="visible: !IsEditing(), text: Quantity, click: edit"
            style="width:100%;float:left;text-align:right;padding-right:10px;" />
        <input data-bind="value: Quantity,visible:IsEditing,hasfocus:IsEditing"
               style="width:100%;text-align:right;padding-right:10px;" />
    </td>
    <td class="ralign rightbordernone" style="padding-right:20px!important;"><span data-bind="text:Price"/></td>
</tr>

      

With the above code, when I click the span element in the "Count" column of the table, the "edit" function is called and the "IsEditing" value is true, but I cannot see the input element visible in my cell. After clicking on the span element, if I look at the html using "Inspect Element", I still only see the element, but not on the screen, in my opinion I can see neither the range nor the input element.

This is very simple logic and it performs as expected, but the end result on the view is not as expected. Can anyone help me discover what is wrong with the above code?

+3


source to share


1 answer


The problem is complex. It lies in the fact that span

it is not a self-closing element. This will work:

<td>
    <span data-bind="visible: !IsEditing(), text: Quantity, click: edit"></span>
    <input data-bind="value: Quantity, visible: IsEditing, hasfocus: IsEditing" />
</td>

      

Here's the full demo:



function ProductVM(vm) {
    var self = this;

    self.Code = ko.observable(vm.Code());
    self.Name = ko.observable(vm.Name());
    self.Quantity = ko.observable(vm.Quantity());
    self.Price = ko.observable(vm.Price());
    self.IsEditing = ko.observable(false);

    this.edit = function () {
        self.IsEditing(true);
    }
}

ko.applyBindings({ OrderedProducts: [new ProductVM({
    Code: function() { return 1; },
    Name: function() { return "Apples"; },
    Quantity: function() { return 10; },
    Price: function() { return 12.50; }
})]})
      

span { padding: 5px; background: pink; }
      

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

(Click "10" e.g. the Quantity for demo.)
<table>
  <tbody data-bind="foreach: OrderedProducts">
    <tr>
      <td><span data-bind="text:Code"></span></td>
      <td><span data-bind="text:Name"></span></td>
      <td>
        <span data-bind="visible: !IsEditing(), text: Quantity, click: edit"></span>
        <input data-bind="value: Quantity, visible: IsEditing, hasfocus: IsEditing" />
      </td>
      <td><span data-bind="text:Price"></span></td>
    </tr>
  </tbody>
</table>
      

Run codeHide result


Remember that the same applies to elementsdiv

, don't use them in a self-closing manner, or Knockout will fool you when you least expect it.

+5


source







All Articles