1

i have table with data and data populated by knockout js foreach bind. i would like to know how to access specific table row's data when it gets updated.

if i could access table row then could add css class to that tr. my objective is to do bit color animation for a row which will be updated just clicking on button. when any data will be push to table row clicking on "Update Data" button then i want to add a class to that table row and after few minute remove that class too. hence i am new so no logic is coming to my mind to achieve this....any help would be appreciated. thanks

jsfiddle http://jsfiddle.net/62Ls6x9n/157/

full code

<button data-bind="click: AddNewData">Add New Data</button>
<button data-bind="click: UpdateDataByIds">Update Data</button>
<br><br>
      <table class="imagetable">
      <thead>
      <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Price</th> 
        <th>Status</th> 
        <th>Edit</th> 
        <th>Delete</th> 
      </tr>
      </thead>
      <tbody data-bind="foreach: Stocks">
        <tr>
            <td data-bind="text: id"></td>
            <td data-bind="text: name"></td> 
            <td data-bind="text: price"></td> 
            <td data-bind="text: status"></td>
            <td><a href="#" data-bind="click: $parent.UpdateData">edit</a></td>
            <td><a href="#" data-bind="click: $parent.DeleteItem">delete</a></td>
        </tr>
      </tbody>
    </table>

table.imagetable {
    font-family: verdana,arial,sans-serif;
    font-size:11px;
    color:#333333;
    border-width: 1px;
    border-color: #999999;
    border-collapse: collapse;
}
table.imagetable th {
    background:#b5cfd2 url('cell-blue.jpg');
    border-width: 1px;
    padding: 8px;
    border-style: solid;
    border-color: #999999;
}
table.imagetable td {
    background:#dcddc0 url('cell-grey.jpg');
    border-width: 1px;
    padding: 8px;
    border-style: solid;
    border-color: #999999;
}

var StockItem = function(_id, _name, _price, _status){
    var self = this;
    self.id = ko.observable(_id);
    self.name = ko.observable(_name);
    self.price = ko.observable(_price);
    self.status = ko.observable(_status);
};

var data= [ 
new StockItem("12345", "Acme Widget 1", "£25.99", "In Stock"), 
new StockItem("67890", "Acme Widget 2", "£28.99", "In Stock"),                                                               new StockItem("11123","Acme Widget 3","£15.99", "In Stock"), 
 new StockItem("14156", "Acme Widget 4", "£33.99", "In Stock")
];

var NewData = [new StockItem("99999", "HSL Limited", "£78.99", "In Stock")];

var appViewModel = function() 
{
    var self = this;
    self.Stocks = ko.observableArray(data);

    self.AddNewData = function(){
        self.Stocks.push.apply(self.Stocks,NewData);
    };

    self.DeleteItem = function(dataContext){
        var itemToDelete = dataContext;
        self.Stocks.remove(itemToDelete);
    }

    self.UpdateDataByIds = function(){
        var id1 = '11123';
        var id2 = '12345';
        self.UpdateById(id1,null,null,"Out of Stock");
        self.UpdateById(id2,null,"31.45",null);
    };

    self.UpdateById = function(_id, _name, _price, _status){
        var matchedItem = ko.utils.arrayFirst(self.Stocks(),          function(item) {
            return item.id() === _id;
        });

        if (matchedItem != null){
            if (_name != null) matchedItem.name(_name);
            if (_price != null) matchedItem.price(_price);
            if (_status != null) matchedItem.status(_status);
        }
    };

    self.UpdateData = function(dataContext){
        var itemToEdit = dataContext;
        itemToEdit.status("Out of Stock");
    };
};

var vm = new appViewModel();
ko.applyBindings(vm);
Thomas
  • 33,544
  • 126
  • 357
  • 626

1 Answers1

1

You can add a Mutated array to your view-model:

self.Mutated = ko.observableArray();

And upon updating / adding, add the item id to the array:

self.Mutated.push(_id);

Then in your HTML, have a mutated class on each <TR> that is indeed mutated:

<tr data-bind="css: { mutated: $root.Mutated.indexOf(id()) > -1 }">

And the CSS:

table.imagetable tr.mutated td { background-color: red; }

See Fiddle

haim770
  • 48,394
  • 7
  • 105
  • 133
  • do not understand this `$root.Mutated.indexOf(id()) > -1` ? can we add. i also like to remove mutated class after few sec? how to have this feature. – Thomas Jun 07 '15 at 11:53
  • This line simply checks if the row id exists in the `Mutated` array. See http://jsfiddle.net/62Ls6x9n/163/ for removal after few seconds. – haim770 Jun 07 '15 at 12:04
  • can we do the same with different approach? can we access dom element from this view model function `self.AddNewData = function()` ? guide me if it is possible. thanks – Thomas Jun 07 '15 at 12:05
  • 1
    You can also add a `mutated` flag to the item itself. Your view-model cannot access the DOM elements being affected because it will defeat the whole purpose of MVVM and in Knockout, that's the role of the binding-handlers (There are exceptions though, like the `click` handler that *is* passing the element being clicked to the model). – haim770 Jun 07 '15 at 12:09
  • @haim770 Here's a fiddle that uses the mutated flag and a mutated CSS class. http://jsfiddle.net/62Ls6x9n/173/ – Roy J Jun 07 '15 at 14:16
  • see this link http://stackoverflow.com/questions/30692884/how-to-capture-table-row-on-button-click-to-add-css-class-knockout-js/30693113#30693113 i want a color animation like stackoverflow. initially add red color and after 500ms that red color fade to default one....i guess this can not be done by mutating....what is your suggestion. thanks – Thomas Jun 07 '15 at 14:40
  • @haim770 u gave two jsfiddle link. what is the difference between Mutated array and mutated flag ? would u mind to explain. thanks – Thomas Jun 07 '15 at 16:33
  • @Thomas, Whether to store ids of mutated objects in array or mark each item with `mutated` flag is a matter of personal preference in this case. As for the 2 Fiddles: In the second Fiddle I added the code to remove the item id from the `Mutated` array after 1 second (using a timeout registered on `subscribe`). – haim770 Jun 07 '15 at 17:15
  • @haim770 one request. i post a thread whose url is http://stackoverflow.com/questions/30697599/knockoutjs-trying-to-do-color-animation-for-tr-by-custom-binding can u please see this post and answer...........i stuck to do the color animation by custom binding. – Thomas Jun 08 '15 at 06:46
  • i update the jsfiddle link http://jsfiddle.net/tridip/o47suzqo/12/ still fade in effect is not very smooth. so looking for suggestion to have smooth fade in effect. thanks – Thomas Jun 08 '15 at 10:41