Jay
Jay

Reputation: 406

KnockoutJS in MVC DataTable Delete Function

I have followed a tutorial that I found at http://www.dotnetcurry.com/aspnet-mvc/933/knockoutjs-aspnet-mvc-tutorial-beginner. The tutorial is great and covers add and update however there are no click handlers included for delete or cancelling the update.

I tried to follow the same pattern the author provided for saving data and I created a function to delete, however this does not work.

function deleteData(currentData) {
    var postUrl = "";
    var submitData = {
        concerns_id: currentData.concerns_id(),
        concerns_description: currentData.concerns_description(),
    };
    if (currentData.concerns_id > 0) {
        postUrl = "/concerns/delete"
    }
    $.ajax({
        type: "POST",
        contentType: "application/json",
        url: postUrl,
        data: JSON.stringify(submitData)
    }).done(function (id) {
        currentData.concerns_id(id);
    }).error(function (ex) {
        alert("ERROR Deleting");
    })
};

This is the table:

<table class="table">
    <tr>
      <th>concerns_id</th>
      <th>concerns_description</th>
      <th></th>
    </tr>
  <tbody data-bind="foreach: ConcernCollection">
     <tr data-bind="template: { name: Mode, data: $data }"></tr>
  </tbody>
</table>

The Templates:

<script type="text/html" id="display">
  <td data-bind="text: concerns_id"></td>
  <td data-bind="text: concerns_description"></td>
  <td>
    <button class="btn btn-success kout-edit">Edit</button>
    <button class="btn btn-danger kout-delete">Delete</button>
  </td>
</script>

<script type="text/html" id="edit">
  <td><input type="text" data-bind="value: concerns_id " /></td>
  <td><input type="text" data-bind="value: concerns_description" /></td>
  <td>
    <button class="btn btn-success kout-update">Update</button>
    <button class="btn btn-danger kout-cancel">Cancel</button>
  </td>
</script>

Full JS without the Delete Function that I tied to add:

$(document).ready(function () {
$.ajax({
    type: "GET",
    url: "/concerns/GetConcerns",
}).done(function (data) {
    $(data).each(function (index, element) {
        var mappedItem =
            {
                concerns_id: ko.observable(element.concerns_id),
                concerns_description: ko.observable(element.concerns_description),
                Mode: ko.observable("display")
            };
        viewModel.ConcernCollection.push(mappedItem);
    });
    ko.applyBindings(viewModel);
}).error(function (ex) {
    alert("Error");
});

$(document).on("click", ".kout-edit", null, function (ev) {
    var current = ko.dataFor(this);
    current.Mode("edit");
});

$(document).on("click", ".kout-update", null, function (ev) {
    var current = ko.dataFor(this);
    saveData(current);
    current.Mode("display");
});



$(document).on("click", "#create", null, function (ev) {
    var current = {
        concerns_id: ko.observable(0),
        concerns_description: ko.observable(),
        Mode: ko.observable("edit")
    }
    viewModel.ConcernCollection.push(current);
});

 function saveData(currentData) {
      var postUrl = "";
      var submitData = {
          concerns_id: currentData.concerns_id(),
          concerns_description: currentData.concerns_description(),
      };
      if (currentData.concerns_id && currentData.concerns_id() > 0) {
          postUrl = "/concerns/Edit"
      }
      else {
          postUrl = "/concerns/Create"
      }
      $.ajax({
          type: "POST",
          contentType: "application/json",
          url: postUrl,
          data: JSON.stringify(submitData)
      }).done(function (id) {
          currentData.concerns_id(id);
      }).error(function (ex) {
          alert("ERROR Saving");
      })
  }
});

Any help or guidance would be apprenticed this is my first time working with Knockout.js

Thanks,

Upvotes: 1

Views: 229

Answers (1)

John Pavek
John Pavek

Reputation: 2665

I'm not gonna lie, your code is a little hard to follow. I really don't think you're getting the full knockout experience. I put together a tiny little demo to show you just how you can use knockout to add/remove items from a list and display them.

Knockout should be used for data-binding. You should honestly never need to use jQuery to attach listeners by class. That is how your code becomes spaghetti.

While your question doesn't ask it, I strongly recommend visiting http://learn.knockoutjs.com/ before continuing your tutorial much further.

I hope this helps!

function ViewModel() {
  var self = this;

  self.Items = ko.observableArray();


  self.DeleteRow = function(row) {
    // Your ajax call here
    self.Items.remove(row);
  }

  self.AddRow = function() {
    self.Items.push("Added Item at " + new Date());
  }

  self.LoadFakeData = function() {
    // Put ajax calls here
    for (i = 0; i < 10; i++) {
      self.Items.push("Item " + i);
    }
  }

  self.Load = function() {
    self.LoadFakeData();
  }

  self.Load();
}

ko.applyBindings(new ViewModel())
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind="foreach: Items">
  <span data-bind="text: $data"></span>
  <span data-bind="click: $parent.DeleteRow">X</span>
  <br>
</div>
<hr>
<span data-bind="click: AddRow">Add Row</span>

Upvotes: 2

Related Questions