<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ivan Zlatev &#187; jQuery</title>
	<atom:link href="http://ivanz.com/tag/jquery/feed/" rel="self" type="application/rss+xml" />
	<link>http://ivanz.com</link>
	<description></description>
	<lastBuildDate>Mon, 16 Jan 2012 16:11:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Editing Variable Length Reorderable Collections in ASP.NET MVC &#8211; Part 3: Knockout JS</title>
		<link>http://ivanz.com/2011/06/29/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-3/</link>
		<comments>http://ivanz.com/2011/06/29/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-3/#comments</comments>
		<pubDate>Wed, 29 Jun 2011 16:48:27 +0000</pubDate>
		<dc:creator>Ivan Zlatev</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[KnockoutJS]]></category>

		<guid isPermaLink="false">http://ivanz.com/?p=844</guid>
		<description><![CDATA[<a href="http://ivanz.com/2011/06/29/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-3/" title="Editing Variable Length Reorderable Collections in ASP.NET MVC - Part 3: Knockout JS"></a>In Part 1 of this series I discussed the problems that we face when implementing an editor for a variable length, reorderable collection and reuse our server-side ASP.NET MVC views, model binding and validation. In Part 2 of this series &#8230;<p class="read-more"><a href="http://ivanz.com/2011/06/29/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-3/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://ivanz.com/2011/06/29/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-3/" title="Editing Variable Length Reorderable Collections in ASP.NET MVC - Part 3: Knockout JS"></a><p><a title="Editing Variable Length Reorderable Collections in ASP.NET MVC – Part 1" href="http://ivanz.com/2011/06/16/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-1/">In Part 1 of this series</a> I discussed the problems that we face when implementing an editor for a variable length, reorderable collection and reuse our server-side ASP.NET MVC views, model binding and validation.</p>
<p><a title="Editing Variable Length Reorderable Collections in ASP.NET MVC – Part 2" href="http://ivanz.com/2011/06/20/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-2/">In Part 2 of this series</a> I began moving some aspects of the collection editing to the client-side with jQuery Templates, but we realized that it&#8217;s not good enough, because instead of dealing with data we are juggling with our ASP.NET MVC views generated HTML.</p>
<p>In this final Part 3 of the series I want to move the collection editing completely to the client-side using the <a href="http://knockoutjs.com/">Knockout JS library</a> JavaScript library. I will look at:</p>
<ul>
<li>Knockout JS data-binding and tempalting</li>
<li>JSON Form (data really &#8211; no form) submission</li>
<li>jQuery Client-Side Validation </li>
</ul>
<p>I will re-implement our sample collection editor and it is going to look exactly the same as it did before. Before I begin just a reminder that <a href="http://github.com/ivanz/ASP.NET-MVC-Collection-Editing">all of the source code is available on GitHub as a Visual Studio solution</a>.</p>
<h4>What is Knockout JS?</h4>
<p>I am going to quote its creator (Steven Sanderson) from his introductory post, where he provides <a href="http://blog.stevensanderson.com/2010/07/05/introducing-knockout-a-ui-library-for-javascript/">a very good overview</a>:</p>
<blockquote><p>Knockout is a JavaScript library that makes it easier to create rich, desktop-like user interfaces with JavaScript and HTML, using <em>observers </em>to make your UI automatically stay in sync with an underlying data model. It works particularly well with the MVVM pattern, offering <em>declarative bindings </em>somewhat like Silverlight but without the browser plugin.</p></blockquote>
<p>I suggest you read the above linked post or checkout the Knockout JS web site to learn more about it, but to quickly summarize how it works:</p>
<ul>
<li>A JavaScipt view model is defined that holds all the data. All the data properties are initialized as (or wrapped in) observable values and arrays.</li>
<li>HTML elements can be data-bound to a property (similar to WinForms/XAML(WPF/Silverlight)) from the view model using the <em>data-bind </em>attribute syntax. We can bind an input&#8217;s value, a span&#8217;s text, etc. to a view model property.</li>
<li>Whenever a value/or array changes the data-binding kicks in and the HTML element are automatically updated.</li>
<li>Knockout uses jQuery and supports templating via jQuery Templates.</li>
</ul>
<h4>Our Sample</h4>
<p>To understand this lets jump straight into our sample app.</p>
<p>I have added a third edit option to our sample:</p>
<p><a href="http://ivanz.com/wp-content/uploads/2011/06/knockout-edit.png" rel="shadowbox[sbpost-844];player=img;"><img class="aligncenter size-full wp-image-856" title="knockout-edit" src="http://ivanz.com/wp-content/uploads/2011/06/knockout-edit.png" alt="" width="304" height="223" /></a></p>
<p>which surprise, surprise looks exactly the same as in the previous iteration. Apart from one extra feature &#8211; the favourite movies counter I&#8217;ve added to give you a hint of the power of Knockout JS:</p>
<p><a href="http://ivanz.com/wp-content/uploads/2011/06/knockout-edit-screen.png" rel="shadowbox[sbpost-844];player=img;"><img class="aligncenter size-full wp-image-857" title="knockout-edit-screen" src="http://ivanz.com/wp-content/uploads/2011/06/knockout-edit-screen.png" alt="" width="571" height="383" /></a></p>
<h4>View and ViewModel</h4>
<p>Let&#8217;s firstly look at the first iteration of our view model implementation:</p>
<pre class="brush: xml; title: ; notranslate">&lt;script type=&quot;text/javascript&quot;&gt;
var viewModel = {
    Id: ko.observable(@Model.Id),
    Name: ko.observable(&quot;@Model.Name&quot;),
    FavouriteMovies: ko.observableArray(@Html.Json(@Model.FavouriteMovies) || []),

    maxMovies: 10,

    addMovie: function() {
        viewModel.FavouriteMovies.push(@Html.Json(new Movie()));
    },

    removeMovie: function(movie) {
        ko.utils.arrayRemoveItem(viewModel.FavouriteMovies, movie);
    }
};

$(function () {
    ko.applyBindings(viewModel);
});
&lt;/script&gt;</pre>
<p>We:</p>
<ul>
<li>Serialize our ASP.NET MVC <em>User</em> Model to JSON (<em>Id</em>, <em>Name</em>, <em>FavouriteMovies</em>). <em>Html.Json</em> is a custom Html helper that simply wraps a JSON serializer &#8211; you can <a href="https://github.com/ivanz/ASP.NET-MVC-Collection-Editing/blob/master/CollectionEditing/Infrastructure/JsonHtmlExtensions.cs">see it in the source code</a>.</li>
<li>Wrap its values in Knockout observables and then once the page is loaded we initialize Knockout JS with our model</li>
<li>Define some add/remove movie methods to edit the FavouriteMovies collection</li>
</ul>
<p><strong>What&#8217;s crucial here is that we are not dealing with nor manipulating HTML markup</strong>, which is something that we were doing heavily in the previous parts.</p>
<p>When processed server-side the above view model will look like roughly like this in the browser:</p>
<pre class="brush: xml; title: ; notranslate">var viewModel = {
        Id: ko.observable(1),
        Name: ko.observable(&quot;Ivan Zlatev&quot;),
        FavouriteMovies: ko.observableArray([{&quot;Title&quot;:&quot;Movie 1&quot;,&quot;Rating&quot;:5},
                                                           {&quot;Title&quot;:&quot;Movie 2&quot;,&quot;Rating&quot;:10},
                                                           {&quot;Title&quot;:&quot;Movie 3&quot;,&quot;Rating&quot;:12}] || []),

        maxMovies: 10,

        addMovie: function() {
            viewModel.FavouriteMovies.push({&quot;Title&quot;:null,&quot;Rating&quot;:0});
        },

        removeMovie: function(movie) {
            ko.utils.arrayRemoveItem(viewModel.FavouriteMovies, movie);
        }
}</pre>
<p>Let&#8217;s look at the first iteration of our edit view (<em>EditKnockoutJS.cshtml</em>) to better understand how does Knockout help us:</p>
<pre class="brush: xml; title: ; notranslate">@model CollectionEditing.Models.User
@{ ViewBag.Title = &quot;Edit My Account With Knockout JS&quot;; }

&lt;script src=&quot;@Url.Content(&quot;~/Scripts/jquery.validate.min.js&quot;)&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;@Url.Content(&quot;~/Scripts/jQuery.tmpl.min.js&quot;)&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;@Url.Content(&quot;~/Scripts/knockout-1.2.1.debug.js&quot;)&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;@Url.Content(&quot;~/Scripts/knockout.jQueryUI-sortable.js&quot;)&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;

&lt;h2&gt;Edit&lt;/h2&gt;

@using (Html.BeginForm(&quot;EditKnockoutJS&quot;, &quot;User&quot;, FormMethod.Post, new { id = &quot;profileEditorForm&quot; })) {
    @Html.ValidationSummary(false)
    &lt;fieldset&gt;
        &lt;legend&gt;My Details&lt;/legend&gt;

        &lt;input name=&quot;userId&quot; type=&quot;hidden&quot; data-bind=&quot;value: Id&quot;/&gt;

        &lt;label for=&quot;name&quot;&gt;Name:&lt;/label&gt;
        &lt;input type=&quot;text&quot; id=&quot;name&quot; name=&quot;name&quot; data-bind=&quot;value: Name&quot; /&gt;
    &lt;/fieldset&gt;

    &lt;fieldset&gt;
        &lt;legend&gt;My Favourite Movies&lt;/legend&gt;

        &lt;ul id=&quot;moviesEditor&quot; style=&quot;list-style-type: none&quot;
            data-bind=&quot;template: { name: 'moviesTemplate', data: FavouriteMovies },
                       sortableList: viewModel.FavouriteMovies&quot; &gt;
        &lt;/ul&gt;
        &lt;p&gt;You have &lt;span data-bind=&quot;text: FavouriteMovies().length&quot;&gt;&lt;/span&gt; favourite movies.&lt;/p&gt;

        &lt;script id=&quot;moviesTemplate&quot; type=&quot;text/x-jquery-template&quot;&gt;
            {{each(i, movie) $data}}
                &lt;li data-bind=&quot;sortableItem: movie&quot;&gt;
                    &lt;div data-bind=&quot;template: { name: 'movieTemplate', data: movie }&quot;&gt;&lt;/div&gt;
                &lt;/li&gt;
            {{/each}}
        &lt;/script&gt;

        &lt;script id=&quot;movieTemplate&quot; type=&quot;text/x-jquery-template&quot;&gt;
            &lt;img src=&quot;@Url.Content(&quot;~/Content/images/draggable-icon.png&quot;)&quot; style=&quot;cursor: move&quot; alt=&quot;&quot;/&gt;

            &lt;label&gt;Title:&lt;/label&gt;
            &lt;input type=&quot;text&quot; data-bind=&quot;value: Title&quot;/&gt;

            &lt;label&gt;Rating:&lt;/label&gt;
            &lt;input type=&quot;text&quot; data-bind=&quot;value: Rating&quot;/&gt;

            &lt;a href=&quot;#&quot; data-bind=&quot;click: function() { viewModel.removeMovie(this); }&quot;&gt;Delete&lt;/a&gt;
        &lt;/script&gt;

        &lt;button data-bind=&quot;click: addMovie, enable: FavouriteMovies().length &lt; maxMovies&quot;&gt;Add another&lt;/button&gt;
    &lt;/fieldset&gt;

    &lt;p&gt;
        &lt;input type=&quot;submit&quot; value=&quot;Save&quot; /&gt;
        &lt;a href=&quot;/&quot;&gt;Cancel&lt;/a&gt;
    &lt;/p&gt;
}</pre>
<p>In our view we use Knockout JS to data-bind our HTML input fields to the data in the viewModel (notice the &#8220;<em>data-bind</em>&#8221; attributes).</p>
<p>For the collection editor:</p>
<ul>
<li>Similar to Part 2, we have a movie jQuery template, which defines the HTML fields of a movie, but this time we don&#8217;t use any ASP.NET MVC helpers.</li>
<li>We make the HTML list reorderable via Drag and Drop with the two special <em>sortableList</em> and <em>sortableItem</em> bindings.This is a custom Knockout JS binding I&#8217;ve created and hosted on <a href="https://github.com/ivanz/knockout.jQueryUI-sortable.js/blob/master/knockout.jQueryUI-sortable.js">GitHub here</a>. Behind the scenes it magically creates a JQuery UI Sortable keeps our <em>viewModel.FavouriteMovies</em> collection in sync when the widget changes.</li>
<li>We limit the number of favourite movies a user can add via the &#8220;Add Another&#8221; button to ten by using a &#8220;<em>enabled</em>&#8221; binding with a boolean expression. Behind the scenes Knockout JS will manage the state of the button and toggle between enabled/disabled depending on the evaluated value of the expression.</li>
<li>Finally we data-bind a <em>span</em> element to display the current number of favourite movies the user has added. Again, this is something that Knockout will keep up to date for us.</li>
</ul>
<p>Right now with this viewModel and that view we have a working drag and drop add/remove favourite movies editor. What we are still missing however is:</p>
<ul>
<li>Form submission and server-side handling</li>
<li>Form validation</li>
</ul>
<h4>Form Submission and Handling</h4>
<p>Let&#8217;s add some more code to our view model and view to handle form submission.</p>
<p>Firstly we are going to implement a save function in our view model. Because we are no longer using ASP.NET model views, we can&#8217;t simply submit the form as is &#8211; the &#8220;standard&#8221; form values based ASP.NET MVC model binding won&#8217;t work properly and especially so for the collection editing part. </p>
<p>Thankfully starting from version 3 ASP.NET MVC supports out of the box JSON model binding. It kicks in if the HTTP request Content-Type is set to &#8220;application/json&#8221;. So instead of using form submission we are going to post our view model data via an AJAX post request to our MVC action, containing the data in JSON serialized form:</p>
<pre class="brush: jscript; title: ; notranslate"> var viewModel = {
       ... snip ...

        saveFailed: ko.observable(false),

        // Returns true if successful
        save: function()
        {
            var saveSuccess = false;
            viewModel.saveFailed(false);

            // Executed synchronously for simplicity
            jQuery.ajax({
                type: &quot;POST&quot;,
                url: &quot;@Url.Action(&quot;EditKnockoutJS&quot;, &quot;User&quot;)&quot;,
                data: ko.toJSON(viewModel),
                dataType: &quot;json&quot;,
                contentType: &quot;application/json&quot;,
                success: function(returnedData) {
                    saveSuccess = returnedData.Success || false;
                    viewModel.saveFailed(!saveSuccess);
                },
                async: false
            });

            return saveSuccess;
        }
};</pre>
<p>Then we will suppress the default form submission behaviour and replace it with our own:</p>
<pre class="brush: xml; title: ; notranslate">&lt;p&gt;
    &lt;input type=&quot;submit&quot; value=&quot;Save&quot;
             data-bind=&quot;click: function() { viewModel.save(); return false; }&quot;/&gt;
    &lt;a href=&quot;/&quot;&gt;Cancel&lt;/a&gt;
&lt;/p&gt;

&lt;p data-bind=&quot;visible: saveFailed&quot; class=&quot;error&quot;&gt;A problem occurred saving the data.&lt;/p&gt;</pre>
<p>Note that I have added a new &#8220;<em>saveFailed</em>&#8221; property in the viewModel which is set by <em>save()</em>. I have also used a &#8220;<em>visible</em>&#8221; data binding on the value of that property to display the error message paragraph only if the save operation has failed.</p>
<p>Now let&#8217;s also look at the MVC action to handle the form submission:</p>
<pre class="brush: csharp; title: ; notranslate">
[HttpPost]
public ActionResult EditKnockoutJS(User user)
{
    FormResponseData responseData = new FormResponseData() {
        Success = false
    };

    if (this.ModelState.IsValid) {
        CurrentUser = user;
        responseData.Success = true;
    }

    return Json(responseData);
}

class FormResponseData {
    public bool Success { get; set; }
}</pre>
<p>Pretty simple action, which just validates the Model using our validation rules/data annotations and returns a <em>FormReponseData</em> object serialized to JSON, which contains a Success flag expected by the client side.</p>
<p>We can now persist our view model and also use our server-side model validation to prevent the client from doing nasty things:</p>
<p><a href="http://ivanz.com/wp-content/uploads/2011/06/knockout-edit-server-validation.png" rel="shadowbox[sbpost-844];player=img;"><img src="http://ivanz.com/wp-content/uploads/2011/06/knockout-edit-server-validation.png" alt="" title="knockout-edit-server-validation" width="558" height="207" class="aligncenter size-full wp-image-905" /></a></p>
<p>We are not done just yet. Because we no longer use the ASP.NET html helpers we no longer pull the server-side validation error messages and are currently left with the generic &#8220;Something went wrong.&#8221; error message. This isn&#8217;t exactly nice nor user friendly. We can solve this by the use of client-side JavaScript based validation. Remember that we should never ever rely solely on the client-side (and we don&#8217;t in our case).</p>
<h4>Client-Side Validation</h4>
<p>Unfortunately at the time of writing I couldn&#8217;t find anything that validates against the Knockout JS viewModel instead of the HTML markup, so I had to resort to <a href="http://docs.jquery.com/Plugins/validation">jQuery Validation</a> for the client-side validation. The problem with that is that we need to ensure that we have set proper unique &#8220;name&#8221; attributes on our form fields and especially so for our collection editor elements.</p>
<p>Fortunately Knockout JS already has a binding for that called the &#8220;<em>uniqueName</em> binding&#8221;, so all we have to do is add that to our favourite movie collection editor fields like I&#8217;ve showed below and don&#8217;t worry about generating them ourselves. This is great, because as you saw in Part 2 injecting a unique name during jQuery template evaluation is relatively tricky.</p>
<pre class="brush: xml; title: ; notranslate">&lt;script id=&quot;movieTemplate&quot; type=&quot;text/x-jquery-template&quot;&gt;
    &lt;img src=&quot;@Url.Content(&quot;~/Content/images/draggable-icon.png&quot;)&quot; style=&quot;cursor: move&quot; alt=&quot;&quot;/&gt;

    &lt;label&gt;Title:&lt;/label&gt;
    &lt;input type=&quot;text&quot; data-bind=&quot;value: Title, uniqueName: true&quot; class=&quot;required&quot;/&gt;

    &lt;label&gt;Rating:&lt;/label&gt;
    &lt;input type=&quot;text&quot; data-bind=&quot;value: Rating, uniqueName: true&quot; class=&quot;required&quot;/&gt;

    &lt;a href=&quot;#&quot; data-bind=&quot;click: function() { viewModel.removeMovie(this); }&quot;&gt;Delete&lt;/a&gt;
&lt;/script&gt;</pre>
<p>There are multiple ways we can use jQuery Validation and I have decided to go for the simplest declarative one, where we decorate our fields with extra attributes to describe the value constraints that we want to enforce. Let&#8217;s update the above fields to make the <em>Title</em> and <em>Rating</em> required:</p>
<pre class="brush: xml; title: ; notranslate">&lt;label&gt;Title:&lt;/label&gt;
&lt;input type=&quot;text&quot; data-bind=&quot;value: Title, uniqueName: true&quot; class=&quot;required&quot;/&gt;

&lt;label&gt;Rating:&lt;/label&gt;
&lt;input type=&quot;text&quot; data-bind=&quot;value: Rating, uniqueName: true&quot; class=&quot;required&quot;/&gt;</pre>
<p>Finally let&#8217;s plug-in jQuery Validation. To do that we will remove the previous submit button handler and use jQuery Validation instead:</p>
<pre class="brush: xml; title: ; notranslate">
... snip... 

        &lt;input type=&quot;submit&quot; value=&quot;Save&quot;/&gt;

... snip... 

&lt;script type=&quot;text/javascript&quot;&gt;
    $(function () {
        ko.applyBindings(viewModel);

        $(&quot;#profileEditorForm&quot;).validate({
            submitHandler: function(form) {
                if(viewModel.save())
                    window.location.href = &quot;/&quot;;

                return false;
            }
        });
    });
&lt;/script&gt;</pre>
<p>Which gives us nice per-field validation error messages as we type:</p>
<p><a href="http://ivanz.com/wp-content/uploads/2011/06/knockout-edit-client-validation.png" rel="shadowbox[sbpost-844];player=img;"><img src="http://ivanz.com/wp-content/uploads/2011/06/knockout-edit-client-validation.png" alt="" title="knockout-edit-client-validation" width="676" height="276" class="aligncenter size-full wp-image-909" /></a></p>
<h4>Wrapping up</h4>
<p><a href="http://github.com/ivanz/ASP.NET-MVC-Collection-Editing">Download all of the source code from GitHub as a Visual Studio solution.</a></p>
<p>In this part we looked at Knockout JS and how great it is in terms of helping us avoid manipulation of HTML markup among many other things. This is generally something that can get really messy quickly and become hard to maintain and track. We also looked at how it helps us neatly solve our collection editing problem without having to worry about practically anything. In the expense of the sacrifice of our Html helpers and partial views, etc we get a lot of flexibility on the client side to add more interactivity in a neat and clean way.</p>
<h4>Final Words</h4>
<p>If you have a simple collection editing scenario and you are heavily reliant on your ASP.NET MVC views, partial views, editors and displays the approach documented in <a href="http://ivanz.com/2011/06/16/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-1/">Part 1</a> should be sufficient. And if pulling in new entries/rows via AJAX is not an option (e.g. for speed, performance or any other reasons) you can pull in <a href="http://ivanz.com/2011/06/20/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-2/">Part 2</a>. However IMHO the better solution most of the time is to use Knockout JS and what I have described in this part as it opens the doors for more complex client-side interactions in a neat and clean way.</p>
<p>Thank you for reading the series. I will appreciate your feedback in the comments!</p>
 <img src="http://ivanz.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=844" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://ivanz.com/2011/06/29/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-3/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Custom Knockout JS binding for jQuery UI Sortable</title>
		<link>http://ivanz.com/2011/06/27/custom-knockout-js-binding-for-jquery-ui-sortable/</link>
		<comments>http://ivanz.com/2011/06/27/custom-knockout-js-binding-for-jquery-ui-sortable/#comments</comments>
		<pubDate>Mon, 27 Jun 2011 20:23:24 +0000</pubDate>
		<dc:creator>Ivan Zlatev</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[KnockoutJS]]></category>

		<guid isPermaLink="false">http://ivanz.com/?p=865</guid>
		<description><![CDATA[<a href="http://ivanz.com/2011/06/27/custom-knockout-js-binding-for-jquery-ui-sortable/" title="Custom Knockout JS binding for jQuery UI Sortable"></a>For the work in progress Part 3 of my Editing Variable Length Reorderable Collections in ASP.NET MVC blog series I have created a custom Knockout JS binding that keeps a Knockout JS observable array in sync with a jQuery UI &#8230;<p class="read-more"><a href="http://ivanz.com/2011/06/27/custom-knockout-js-binding-for-jquery-ui-sortable/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://ivanz.com/2011/06/27/custom-knockout-js-binding-for-jquery-ui-sortable/" title="Custom Knockout JS binding for jQuery UI Sortable"></a><p>For the work in progress Part 3 of my <a href="http://ivanz.com/2011/06/16/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-1/">Editing Variable Length Reorderable Collections in ASP.NET MVC</a> blog series I have created a custom Knockout JS binding that keeps a Knockout JS observable array in sync with a jQuery UI sortable.</p>
<p>It&#8217;s available here:</p>
<p>Basic usage is to use a <em>sortableList</em> binding on the <em>ul</em> which you  want to make a jQuery Sortable and then a <em>sortableItem</em> binding for each sortable item (<em>li</em>) in the list like that: </p>
<pre class="brush: xml; title: ; notranslate">&lt;ul data-bind=&quot;sortableList: yourObservableArray&quot; &gt;
    {{each(i, arrayItem) yourObservableArray}}
        &lt;li data-bind=&quot;sortableItem: arrayItem&quot;&gt;&lt;/li&gt;
    {{/each}}
&lt;/ul&gt;</pre>
<p>Live example (if you are reading this in a feed reader you will need to open the blog post properly to see this):</p>

<!-- powered by Iframe plugin ver.2.1 (wordpress.org/extend/plugins/iframe/) -->
<iframe src="http://ivanz.github.com/knockout.jQueryUI-sortable.js/example.html" width="100%" height="400" scrolling="no" class="iframe-class" frameborder="0"></iframe>
 <img src="http://ivanz.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=865" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://ivanz.com/2011/06/27/custom-knockout-js-binding-for-jquery-ui-sortable/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Editing Variable Length Reorderable Collections in ASP.NET MVC – Part 2: jQuery Templates</title>
		<link>http://ivanz.com/2011/06/20/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-2/</link>
		<comments>http://ivanz.com/2011/06/20/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-2/#comments</comments>
		<pubDate>Mon, 20 Jun 2011 19:21:44 +0000</pubDate>
		<dc:creator>Ivan Zlatev</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://ivanz.com/?p=796</guid>
		<description><![CDATA[<a href="http://ivanz.com/2011/06/20/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-2/" title="Editing Variable Length Reorderable Collections in ASP.NET MVC – Part 2: jQuery Templates"></a>In Part 1 of this series I discussed the problems that we face when implementing an editor for a variable length, reorderable collection and reuse our server-side ASP.NET MVC views, model binding and validation. And while the solution provided in Part &#8230;<p class="read-more"><a href="http://ivanz.com/2011/06/20/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-2/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://ivanz.com/2011/06/20/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-2/" title="Editing Variable Length Reorderable Collections in ASP.NET MVC – Part 2: jQuery Templates"></a><p><a title="Editing Variable Length Reorderable Collections in ASP.NET MVC – Part 1" href="http://ivanz.com/2011/06/16/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-1/">In Part 1 of this series</a> I discussed the problems that we face when implementing an editor for a variable length, reorderable collection and reuse our server-side ASP.NET MVC views, model binding and validation. And while the solution provided in Part 1 is nice and clean (and I personally use it in a few projects) one field for improvement in true Agile Blogging fashion is to find a way to remove the AJAX request we use for fetching new editor rows.</p>
<p>One way to bring this completely to the client side is by the use of <a href="http://api.jquery.com/category/plugins/templates/">jQuery Template</a> (or any other JavaScript templating engine/library).</p>
<p>A reminder of what our editor looks like before I begin and a second remind that the source code is available on <a href="http://github.com/ivanz/ASP.NET-MVC-Collection-Editing">GitHub</a>:</p>
<p><a href="http://ivanz.com/wp-content/uploads/2011/06/image3.png" rel="shadowbox[sbpost-796];player=img;"><img class="size-full wp-image-780 aligncenter" title="Sample Editor" src="http://ivanz.com/wp-content/uploads/2011/06/image3.png" alt="" width="550" height="435" /></a></p>
<p>To start with I have added a second link to our sample&#8217;s home page titled &#8220;Edit with jQuery templates&#8221;:</p>
<p><a href="http://ivanz.com/wp-content/uploads/2011/06/home-jquery.png" rel="shadowbox[sbpost-796];player=img;"><img class="aligncenter size-full wp-image-803" title="Home Page of the sample" src="http://ivanz.com/wp-content/uploads/2011/06/home-jquery.png" alt="" width="298" height="202" /></a></p>
<p>Corresponding controller actions:</p>
<pre class="brush: csharp; title: ; notranslate">
public ActionResult EditJQueryTemplate()
{
    return View(CurrentUser);
}

[HttpPost]
public ActionResult EditJQueryTemplate(User user)
{
    if (!this.ModelState.IsValid)
        return View(user);

    CurrentUser = user;
    return RedirectToAction(&quot;Display&quot;);
}</pre>
<p>And a new editor view (<em>EditJQueryTemplate.cshtml</em>) which is exactly the same as the one from Part 1 apart from the core editor bit:</p>
<pre class="brush: xml; highlight: [16,26]; title: ; notranslate">&lt;legend&gt;My Favourite Movies&lt;/legend&gt;

@if (Model.FavouriteMovies == null || Model.FavouriteMovies.Count == 0) {
    &lt;p&gt;None.&lt;/p&gt;
}
&lt;ul id=&quot;moviesEditor&quot; style=&quot;list-style-type: none&quot;&gt;
    @if (Model.FavouriteMovies != null) {
        foreach (Movie movie in Model.FavouriteMovies) {
            Html.RenderPartial(&quot;MovieEntryEditor&quot;, movie);
        }
    }
&lt;/ul&gt;
&lt;script src=&quot;@Url.Content(&quot;~/Scripts/jQuery.tmpl.min.js&quot;)&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;

&lt;script type=&quot;text/x-jquery-tmpl&quot; id=&quot;movieTemplate&quot;&gt;
    @Html.CollectionItemJQueryTemplate(&quot;MovieEntryEditor&quot;, new Movie())
&lt;/script&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
    $(function () {
        $(&quot;#moviesEditor&quot;).sortable();
    });

    var viewModel = {
        addNew: function () {
            $(&quot;#moviesEditor&quot;).append($(&quot;#movieTemplate&quot;).tmpl({ index: viewModel._generateGuid() }));
        },

        _generateGuid: function () {
            // Source: http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/105074#105074
            return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
                var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r &amp; 0x3 | 0x8);
                return v.toString(16);
            });
        }
    };
&lt;/script&gt;

&lt;a id=&quot;addAnother&quot; href=&quot;#&quot; onclick=&quot;viewModel.addNew();&quot;&gt;Add another&lt;/a&gt;</pre>
<p>Note the new <em>@Html.CollectionItemJQueryTemplate</em> helper, which takes a collection item instance with default values and the unchanged partial view <em>MovieEntryEditor</em> from Part 1:</p>
<pre class="brush: xml; title: ; notranslate">@model CollectionEditing.Models.Movie

&lt;li style=&quot;padding-bottom:15px&quot;&gt;
    @using (Html.BeginCollectionItem(&quot;FavouriteMovies&quot;)) {
        &lt;img src=&quot;@Url.Content(&quot;~/Content/images/draggable-icon.png&quot;)&quot; style=&quot;cursor: move&quot; alt=&quot;&quot;/&gt;

        @Html.LabelFor(model =&gt; model.Title)
        @Html.EditorFor(model =&gt; model.Title)
        @Html.ValidationMessageFor(model =&gt; model.Title)

        @Html.LabelFor(model =&gt; model.Rating)
        @Html.EditorFor(model =&gt; model.Rating)
        @Html.ValidationMessageFor(model =&gt; model.Rating)

        &lt;a href=&quot;#&quot; onclick=&quot;$(this).parent().remove();&quot;&gt;Delete&lt;/a&gt;
    }
&lt;/li&gt;
</pre>
<p>Basically the helper renders the partial with an ${$index} jQuery template placeholder for which we supply a GUID at run-time on the client-side when we render the template. The output of the helper looks like this:</p>
<pre class="brush: xml; title: ; notranslate">&lt;script type=&quot;text/x-jquery-tmpl&quot; id=&quot;movieTemplate&quot;&gt;
&lt;li style=&quot;padding-bottom:15px&quot;&gt;

    &lt;input autocomplete=&quot;off&quot; name=&quot;FavouriteMovies.Index&quot; type=&quot;hidden&quot; value=&quot;${index}&quot; /&gt;

    &lt;img src=&quot;/Content/images/draggable-icon.png&quot; style=&quot;cursor: move&quot; alt=&quot;&quot;/&gt;

    &lt;label&gt;Title&lt;/label&gt;
    &lt;input name=&quot;FavouriteMovies[${index}].Title&quot; type=&quot;text&quot; value=&quot;&quot; /&gt;

    &lt;label&gt;Rating&lt;/label&gt;
    &lt;input name=&quot;FavouriteMovies[${index}].Rating&quot; type=&quot;text&quot; value=&quot;0&quot; /&gt;

    &lt;a href=&quot;#&quot; onclick=&quot;$(this).parent().remove();&quot;&gt;Delete&lt;/a&gt;
&lt;/li&gt;
&lt;/script&gt;</pre>
<p>Everytime the &#8220;Add another&#8221; button is pressed this template is rendered using a new GUID index value supplied by the <em>viewModel</em> class.</p>
<p>Here is the code of the <em>@Html.CollectionItemJQueryTemplate</em> helper:</p>
<pre class="brush: csharp; title: ; notranslate">public static MvcHtmlString CollectionItemJQueryTemplate&lt;TModel, TCollectionItem&gt;(this HtmlHelper&lt;TModel&gt; html,
                                                                                    string partialViewName,
                                                                                    TCollectionItem modelDefaultValues)
{
    ViewDataDictionary&lt;TCollectionItem&gt; viewData = new ViewDataDictionary&lt;TCollectionItem&gt;(modelDefaultValues);
    viewData.Add(JQueryTemplatingEnabledKey, true);
    return html.Partial(partialViewName, modelDefaultValues, viewData);
}</pre>
<p>It renders the supplied partial view, but before that it sets a flag on the ViewContext&#8217;s ViewData dictionary to indicate that the view is to be rendered as jQuery collection item template. This is then handled by the <em>@Html.BeginCollectionItem</em> by generating an index template placeholder based .Index hidden field for model binding instead of one with an actual GUID value:</p>
<pre class="brush: csharp; title: ; notranslate">public static IDisposable BeginCollectionItem&lt;TModel&gt;(this HtmlHelper&lt;TModel&gt; html, string collectionName)
{
    string collectionIndexFieldName = String.Format(&quot;{0}.Index&quot;, collectionName);

    string itemIndex = null;
    if (html.ViewData.ContainsKey(JQueryTemplatingEnabledKey)) {
        itemIndex = &quot;${index}&quot;;
    } else {
        itemIndex = GetCollectionItemIndex(collectionIndexFieldName);
    }

    string collectionItemName = String.Format(&quot;{0}[{1}]&quot;, collectionName, itemIndex);

    TagBuilder indexField = new TagBuilder(&quot;input&quot;);
    indexField.MergeAttributes(new Dictionary&lt;string, string&gt;() {
        { &quot;name&quot;, collectionIndexFieldName },
        { &quot;value&quot;, itemIndex },
        { &quot;type&quot;, &quot;hidden&quot; },
        { &quot;autocomplete&quot;, &quot;off&quot; }
    });
// snip---</pre>
<p>That&#8217;s it! We are still reusing our ASP.NET views, model binding and validation, but no longer require an AJAX request to fetch a new editor row!.</p>
<p>In Part 3 I will look at Knockout JS templating, data binding and moving variable length reorderable collection editing completely on the client side with the MVVM pattern and using JavaScript form serialization and JSON data submission and model binding.</p>
<p><strong>Next: <a href="http://ivanz.com/2011/06/29/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-3/">Part 3 and Knockout JS client-side collection editing, JSON model binding and client-side validation.</a></strong></p>
 <img src="http://ivanz.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=796" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://ivanz.com/2011/06/20/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-2/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Visual Studio 2008 jQuery IntelliSense Fix</title>
		<link>http://ivanz.com/2009/07/01/visual-studio-2008-jquery-intellisense-fix/</link>
		<comments>http://ivanz.com/2009/07/01/visual-studio-2008-jquery-intellisense-fix/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 21:25:16 +0000</pubDate>
		<dc:creator>Ivan Zlatev</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Bugs]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://i-nz.net/?p=592</guid>
		<description><![CDATA[<a href="http://ivanz.com/2009/07/01/visual-studio-2008-jquery-intellisense-fix/" title="Visual Studio 2008 jQuery IntelliSense Fix"></a>I am tinkering with ASP.NET MVC and jQuery and making my first baby steps in a whole new horrible world of web development. I found out that the JavaScript IntelliSense in Visual Studio 2008 is broken out of the box. &#8230;<p class="read-more"><a href="http://ivanz.com/2009/07/01/visual-studio-2008-jquery-intellisense-fix/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://ivanz.com/2009/07/01/visual-studio-2008-jquery-intellisense-fix/" title="Visual Studio 2008 jQuery IntelliSense Fix"></a><p>I am tinkering with ASP.NET MVC and jQuery and making my first baby steps in a whole new horrible world of web development. I found out that the JavaScript IntelliSense in Visual Studio 2008 is broken out of the box. The error is:</p>
<pre>Warning    2    Error updating JScript IntelliSense: jquery-1.3.2.js:
   Object doesn't support this property or method @ 2173:1</pre>
<p>The fix for Visual Studio 2008 SP1 by Microsoft can be found here:</p>
<p><a href="http://code.msdn.microsoft.com/KB958502">KB958502 &#8211; JScript Editor support for “-vsdoc.js” IntelliSense doc. files</a></p>
 <img src="http://ivanz.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=592" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://ivanz.com/2009/07/01/visual-studio-2008-jquery-intellisense-fix/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

