Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Knockoutjs rocks:</p> <pre><code> &lt;script src="http:////cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js" type="text/javascript"&gt;&lt;/script&gt; &lt;script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-min.js" type="text/javascript"&gt;&lt;/script&gt; &lt;script src="http://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js" type="text/javascript"&gt;&lt;/script&gt; &lt;asp:HiddenField ID="hfClientModel" runat="server" /&gt; &lt;script type="text/javascript"&gt; var oViewModel; var iCounter; $(document).ready(function () { var oModel = JSON.parse($('#&lt;%= hfClientModel.ClientID %&gt;').val()); iCounter = oModel.Items.length; oViewModel = ko.mapping.fromJS(oModel); ko.applyBindings(oViewModel); }); function DeleteEmail(iEmailIndex) { oViewModel.Items.remove(function (item) { return item.Index() == iEmailIndex; }); } function AddEmail() { iCounter++; oViewModel.Items.push(ko.mapping.fromJS({ Email: '', Index: iCounter })); } function PersistClientModel() { $('#&lt;%= hfClientModel.ClientID %&gt;').val(ko.toJSON(oViewModel)); } &lt;/script&gt; &lt;table width="900px"&gt; &lt;tr&gt; &lt;td&gt; Email : &lt;/td&gt; &lt;td&gt; &lt;input type="text" data-bind="{value: FirstEmail}" /&gt; &lt;input type="button" value="Add" onclick="AddEmail()" /&gt; &lt;/td&gt; &lt;/tr&gt; &lt;!-- ko foreach: Items --&gt; &lt;tr&gt; &lt;td&gt;&amp;#160;&lt;/td&gt; &lt;td&gt; &lt;input data-bind="{value: Email}" /&gt; &lt;input type="button" value="Delete" data-bind="{click: function() { DeleteEmail($data.Index()); }}" /&gt; &lt;/td&gt; &lt;/tr&gt; &lt;!-- /ko --&gt; &lt;/table&gt; &lt;asp:Button Text="Postback!" ID="btnSave" runat="server" OnClick="btnSave_Click" OnClientClick="PersistClientModel()" /&gt; </code></pre> <p>Server side:</p> <pre><code>[DataContract] public class ViewModel { [DataMember] public string FirstEmail { get; set; } [DataMember] public IList&lt;EmailModel&gt; Items { get; set; } public ViewModel() { Items = new List&lt;EmailModel&gt;(); } } [DataContract] public class EmailModel { [DataMember] public string Email { get; set; } [DataMember] public int Index { get; set; } } public partial class Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { var serializer = new DataContractJsonSerializer(typeof(ViewModel)); using (var stream = new MemoryStream()) { serializer.WriteObject(stream, new ViewModel()); hfClientModel.Value = Encoding.UTF8.GetString(stream.ToArray()); } } } protected void btnSave_Click(object sender, EventArgs e) { var serializer = new DataContractJsonSerializer(typeof(ViewModel)); ViewModel viewModel; using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(hfClientModel.Value), false)) { viewModel = (ViewModel)serializer.ReadObject(stream); } // enjoy viewModel } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload