Gift list
Description
Live example
You have asked for gift(s)
Saved at
Model
public class GiftListModel
{
public List<GiftModel> Gifts { get; set; }
public string ServerTime { get; set; }
public void AddGift()
{
Gifts.Add(new GiftModel());
}
public void RemoveGift(int index)
{
Gifts.RemoveAt(index);
}
public void Save()
{
ServerTime = DateTime.Now.ToString();
}
}
public class GiftModel
{
public string Title { get; set; }
public double Price { get; set; }
}
Razor
@using PerpetuumSoft.Knockout
@model KnockoutMvcDemo.Models.GiftListModel
@{
var ko = Html.CreateKnockoutContext();
}
<p>You have asked for @ko.Html.Span(m => m.Gifts.Count) gift(s)</p>
<form id="myform">
<table>
<tbody>
@using (var items = ko.Foreach(m => m.Gifts))
{
<tr>
<td>Gift name:@items.Html.TextBox(item => item.Title, new { @class = "required" }).UniqueName()</td>
<td>Price: $@items.Html.TextBox(item => item.Price, new { @class = "required number" }).UniqueName()</td>
<td>@ko.Html.Button("Delete", "RemoveGift", "GiftList", new { index = items.GetIndex() })</td>
</tr>
}
</tbody>
</table>
@ko.Html.Button("Add", "AddGift", "GiftList")
<button @ko.Bind.Enable(m => m.Gifts.Count > 0) type="submit">Save</button>
</form>
@using (ko.If(m => m.ServerTime.Length > 0))
{
<p>Saved at @ko.Html.Span(m => m.ServerTime)</p>
}
<script type="text/javascript">
$("#myform").ajaxForm();
$("#myform").validate({ submitHandler: function () { @ko.ServerAction("Save", "GiftList"); } });
</script>
<style scoped="scoped">
input.error {
border: 1px solid red;
background-color: #FDC;
}
label.error {
display: block;
color: Red;
font-size: 0.8em;
}
</style>
@ko.Apply(Model)
Controller
public class GiftListController : BaseController
{
public ActionResult Index()
{
InitializeViewBag("Gift list");
var model = new GiftListModel
{
Gifts = new List<GiftModel>
{
new GiftModel {Title = "Tall Hat", Price = 49.95},
new GiftModel {Title = "Long Cloak", Price = 78.25}
}
};
return View(model);
}
public ActionResult AddGift(GiftListModel model)
{
model.AddGift();
return Json(model);
}
public ActionResult RemoveGift(GiftListModel model, int index)
{
model.RemoveGift(index);
return Json(model);
}
public ActionResult Save(GiftListModel model)
{
model.Save();
return Json(model);
}
}
Html (autogenerated)
<p>You have asked for <span data-bind="text : Gifts().length"></span> gift(s)</p>
<form id="myform">
<table>
<tbody>
<!-- ko foreach: Gifts -->
<tr>
<td>Gift name:<input class="required" data-bind="value : $data.Title,uniqueName : true" name="Title" type="text" /></td>
<td>Price: $<input class="required number" data-bind="value : $data.Price,uniqueName : true" type="text" /></td>
<td><button data-bind="click : function() {executeOnServer(viewModel, '/GiftList/RemoveGift?index='+$index()+'');}">Delete</button></td>
</tr>
<!-- /ko -->
</tbody>
</table>
<button data-bind="click : function() {executeOnServer(viewModel, '/GiftList/AddGift');}">Add</button>
<button data-bind="enable : (Gifts().length > 0)" type="submit">Save</button>
</form>
<!-- ko if: (ServerTime().length > 0) -->
<p>Saved at <span data-bind="text : ServerTime"></span></p>
<!-- /ko -->
<script type="text/javascript">
$("#myform").ajaxForm();
$("#myform").validate({ submitHandler: function () { executeOnServer(viewModel, '/GiftList/Save'); } });
</script>
<style scoped="scoped">
input.error {
border: 1px solid red;
background-color: #FDC;
}
label.error {
display: block;
color: Red;
font-size: 0.8em;
}
</style>
<script type="text/javascript">
var viewModelJs = {"Gifts":[{"Title":"Tall Hat","Price":49.95},{"Title":"Long Cloak","Price":78.25}],"ServerTime":""};
var viewModel = ko.mapping.fromJS(viewModelJs);
ko.applyBindings(viewModel);
</script>