Hot Towel SPA – Visual Studio Project Template | John Papa

John Papa

Evangelist on the loose

Hot Towel SPA – Visual Studio Project Template

...

Want to build a SPA but can’t decide where to start? Use Hot Towel and in seconds you’ll have a SPA and all the tools you need to build on it! You can get Hot Towel along with the new RTM version of ASP.NET and Web Tools 2012.2, as announced by Scott Guthrie today.

Download the HotTowel SPA project template for Visual Studio 2012 here or download the HotTowel SPA project template for Visual Studio 2013 here.

Download the VSIX for the Hot Towel SPA template here

Hot Towel: Because you don’t want to go to the SPA without one!

Hot Towel creates a great starting point for building a Single Page Application (SPA) with ASP.NET. Out of the box you it provides a modular structure for your code, view navigation, data binding, rich data management and simple but elegant styling. It provides everything you need to build a SPA, so you can focus on your app, not the plumbing.

Learn more about building a SPA from my videos, tutorials and Pluralsight courses.

Create a New SPA Template Project with Hot Towel

Requirements:

  • Visual Studio 2012 or Visual Studio Express 2012 for Web
  • ASP.NET Web Tools 2012.2 update. You can install the update here.

Start Visual Studio and select New Project from the Start page. Or, from the File menu, select New and then Project.

In the Templates pane, select Installed Templates and expand the Visual C# node. Under Visual C#, select Web. In the list of project templates, select ASP.NET MVC 4 Web Application. Name the project and click OK.
2-18-2013 2-01-45 PM

In the New Project wizard, select Single Page Application.

2-18-2013 2-02-02 PM

Application Structure

Hot Towel SPA provides an App folder which contains the JavaScript and HTML files that define your application.

Inside the App folder:

The App folder contains a collection of modules. These modules encapsulate functionality and declare dependencies on other modules. The views folder contains the HTML for your application and the viewmodels folder contains the presentation logic for the views (a common MVVM pattern). The services folder is ideal for housing any common services that your application may need such as HTTP data retrieval or local storage interaction. It is common for multiple viewmodels to re-use code from the service modules.

ASP.NET MVC Server Side Application Structure

Hot Towel builds on the familiar and powerful ASP.NET MVC structure.

  • App_Start
  • Content
  • Controllers
  • Models
  • Scripts
  • Views

Featured Libraries

  • ASP.NET MVC
  • ASP.NET Web API
  • ASP.NET Web Optimization – bundling and minification
  • Breeze.js – rich data management
  • Durandal.js – navigation, app life cycle and View composition
  • Knockout.js – data bindings
  • Require.js – Modularity with AMD and optimization
  • Toastr.js – pop-up messages
  • Twitter Bootstrap – robust CSS styling

Installing via the Visual Studio 2012 Hot Towel SPA Template

Hot Towel can be installed as a Visual Studio 2012 template. Just click File | New Project and choose ASP.NET MVC 4 Web Application. Then select the Hot Towel Single Page Application template and run!

Installing via the NuGet Package

Hot Towel is also a NuGet package that augments an existing empty ASP.NET MVC project. Just install using Nuget and then run!
hottowel install nuget

How Do I Build On Hot Towel?

Simply start adding code!

  1. Add your own server-side code, preferably Entity Framework and WebAPI (which really shine with Breeze.js)
  2. Add views to the App/views folder
  3. Add viewmodels to the App/viewmodels folder
  4. Add HTML and Knockout data bindings to your new views
  5. Update the navigation routes in shell.js

Walkthrough of the HTML/JavaScript

Views/HotTowel/index.cshtml

index.cshtml is the starting route and view for the MVC application. It contains all the standard meta tags, css links, and JavaScript references you would expect. The body contains a single <div> which is where all of the content (your views) will be placed when they are requested. The @Scripts.Render uses Require.js to run the entrance point for the application’s code, which is contained in the main.js file. A splash screen is provided to demonstrate how to create a splash screen while your app loads.

<body>
    <div id="applicationHost">
        @Html.Partial("_splash")
    </div>

    @Scripts.Render("~/scripts/vendor")
        <script type="text/javascript" 
            src="~/App/durandal/amd/require.js" 
            data-main="@Url.Content("~/App/main")"></script>
</body>

App/main.js

The main.js file contains the code that will run as soon as your app is loaded. This is where you want to define your navigation routes, set your start-up views, and perform any setup/bootstrapping such as priming your application’s data.

The main.js file defines several of durandal’s modules to help the application kick-start. The define statement helps resolve the modules dependencies so they are available for the function. First the debugging messages are enabled, which send messages about what events the application is performing to the console window. The app.start code tells the durandal framework to start the application. The conventions are set so that durandal knows all views and viewmodels are contained in the same named folders, respectively. Finally, the app.setRoot kicks loads the shell using a predefined entrance animation.

define(['durandal/app', 
        'durandal/viewLocator', 
        'durandal/system', 
        'durandal/plugins/router'],
    function (app, viewLocator, system, router) {

    // Enable debug message to show in the console 
    system.debug(true);

    app.start().then(function () {
        router.useConvention();
        viewLocator.useConvention();
        //Show the app by setting the root view 
        // model for our application.
        app.setRoot('viewmodels/shell', 'entrance');
    });
});

Views

Views are found in the App/views folder.

shell.html

The shell.html contains the master layout for your HTML. All of your other views will be composed somewhere in side of your shell view. Hot Towel provides a shell with three such regions: a header, a content area, and a footer. Each of these regions is loaded with contents form other views when requested.

The compose bindings for the header and footer are hard-coded in Hot Towel to point to the nav and footer views, respectively. The compose binding for the section #content is bound to the router module’s active item. In other words, when you click a navigation link its corresponding view is loaded in this area.

<div>
    <header>
        <!--ko compose: {view: 'nav'} --><!--/ko-->
    </header>
     <section id="content" class="main container-fluid">
        <!--ko compose: {model: router.activeItem, 
            afterCompose: router.afterCompose, 
            transition: 'entrance'} -->
        <!--/ko-->
    </section>
    <footer>
        <!--ko compose: {view: 'footer'} --><!--/ko-->
    </footer>
</div>

nav.html

The nav.html contains the navigation links for the SPA. This is where the menu structure can be placed, for example. Often this is data bound (using Knockout) to the router module to display the navigation you defined in the shell.js. Knockout looks for the data-bind attributes and binds those to the shell viewmodel to display the navigation routes and to show a progressbar (using Twitter Bootstrap) if the router module is in the middle of navigating from one view to another (see router.isNavigating).

<nav class="navbar navbar-fixed-top">
    <div class="navbar-inner">
        <a class="brand" href="/">
            <span class="title">Hot Towel SPA</span> 
        </a>
        <div class="btn-group" 
            data-bind="foreach: router.visibleRoutes">
            <a data-bind="css: { active: isActive }, 
                attr: { href: hash }, 
                text: name" 
                class="btn btn-info" href="#"></a>
        </div>
        <div class="loader pull-right" 
            data-bind="css: { active: router.isNavigating }">
            <div class="progress progress-striped 
                        active page-progress-bar">
                <div class="bar" style="width: 100px;"></div>
            </div>
        </div>
    </div>
</nav>

home.html and details.html

These views contain HTML for custom views. When the home link in the nav view’s menu is clicked, the home view will be placed in the content area of the shell view. These views can be augmented or replaced with your own custom views.

footer.html

The footer.html contains HTML that appears in the footer, at the bottom of the shell view.

ViewModels

ViewModels are found in the App/viewmodels folder.

shell.js

The shell viewmodel contains properties and functions that are bound to the shell view. Often this is where the menu navigation bindings are found (see the router.mapNav logic).

define(['durandal/system', 
        'durandal/plugins/router', 
        'services/logger'],
    function (system, router, logger) {
        var shell = {
            activate: activate,
            router: router
        };

        return shell;

        function activate() {
            return boot();
        }

        function boot() {
            router.mapNav('home');
            router.mapNav('details');
            log('Hot Towel SPA Loaded!', null, true);
            return router.activate('home');
        }

        function log(msg, data, showToast) {
            logger.log(msg, 
                data, 
                system.getModuleId(shell), 
                showToast);
        }
    });

home.js and details.js

These viewmodels contain the properties and functions that are bound to the home view. it also contains the presentation logic for the view, and is the glue between the data and the view.

define(['services/logger'], 
function (logger) {
    var vm = {
        activate: activate,
        title: 'Home View'
    };

    return vm;

    function activate() {
        logger.log('Home View Activated', 
            null, 'home', true);
        return true;
    }
});

Services

Services are found in the App/services folder. Ideally your future services such as a dataservice module, that is responsible for getting and posting remote data, could be placed.

logger.js

Hot Towel provides a logger module in the services folder. The logger module is ideal for logging messages to the console and to the user in pop up toasts.

Resources

tags: asp.net hottowel hottowelette SPA visual studio 2012
  • Nik Ivancic

    John your timing could not be better – as I was precisely the guy who looked ad so many different alternatives for SPA that finally I could not decide where to start.

  • Pingback: ASP.NET SPA Templates Released | John Papa

  • Richard B

    Very kool. I’ll grab my hot towel and jump right in :-)

  • Peter

    Does JS Intellisense work out of the box. I’ve been unsuccessful trying to get Intellisense working with a CodeCamper Breeze based project, as RequireJS is a stumbling block.

  • Nik Ivancic

    Is there a way to set the length of time the splash screen is up. I would expect that the current behavior is such that the splash screen goes away when the app is loaded, which on a quick machine and relatively small app looks like a flash, not splash :-)

    • John

      Nik – Hmmm. If you really want to control the first screen, you could do that with Durandal in its boot sequence. Or if you want the splash.html to start and hang around for a set amount of time, you could delay the kick off of durandal using a settimeout. I havent tried it, but that could work.

      • Nik Ivancic

        Thanks, John; I will try that route and will post my findings – in case you want to add such information to http://www.johnpapa.net/hottowel article.

        By the way, I built my first HotTowel app, love the name, love the template and plan to make a SPA prototype of Congral’s Shared Care Space application – see http://www.sharedcareplan.org which is a Patient Portal Component of SCS.

  • l3ny

    Why does everything has be MVC now days. That’s unfair.

    • John

      l3ny – You can use HotTowelette with ASP.NET (non MVC) . Its a NuGet package that is a little sister to HotTowel. Grab HotTowelette here

  • Pingback: The Morning Brew - Chris Alcock » The Morning Brew #1298

  • Markus Zywitza

    I’ve been wondering whether the template also includes authentication and authorization. I’ve been missing that in the Code Camper SPA and the Pluralsight course.

    • John

      Markus – The ASP.NET SPA template has auth built in, definitely check it out!

  • Paul

    Howdy John and thanks for this awesome template. Just wondering…. how would one go about a heiracial NAV using routes?

    router.mapNav(‘home’)
    router.mapNav(‘bedroom’);

    router.mapNav(‘details’);

    • John

      Paul – You can define nested navigation using slashes in the paths.

      • Paul

        Thanks John. I have nested routes working in ‘shell.js’ i.e. router.mapNav(‘admin/dashboard’, null, ‘Dashboard’);
        but I would like the NAV to display sub menus for nested routes i.e.

        Home
        Details
        Admin
        |—Dashboard

        Any thoughts on how to achieve this?

        • John

          Paul,

          You can create custom menus. For example, you could create a sub menu in a dropdown button for an about view (and other additional sub items)

          var routes = [{
              url: 'about',
              moduleId: 'viewmodels/about',
              name: 'About',
              visible: false,
              caption: 'About',
              // Add anything you want to settings
              settings: { admin: true } 
          }];
          
          router.map(routes);
          

          Then you can add buttons with a binding like this (wrapped in a ul with bootstrap):

          < a class="btn btn-info dropdown-toggle" data-toggle="dropdown" rel="nofollow">
              <span>Admin</span> <span class="caret"></span></a>
          <ul class="dropdown-menu pull-right">
              <!-- ko foreach: adminRoutes -->
              <li><a data-bind="attr: { href: hash }, html: caption" rel="nofollow"></a></li>
              <!-- /ko -->
          </ul>
          

          You can find much more in my upcoming Pluralsight course, SPA JumpStart, due out in March 2013

  • http://dirkwatkins.net/ Dirk

    Way to get toastr included!

  • Naze

    Hi John, I been following your SPA work on pluralsight and I’ve been really impressed. Can you recommend a treegrid control that will work with knockout bindings in a SPA application.

  • cipo

    Does anyone has sample app (something simple which includes webapi controller and breeze) which is based on hot towel spa template?

    • John

      cipo – The Breeze SPA template has a web api controller built into it. You can copy that over from the ToDo app.

  • Erikas

    John,

    Will HotTowelSpa.vsix installer support Microsoft Visual Studio Express 2012 for Web? Right now it’s not installing the template:

    19/02/2013 15:00:03 – Searching for applicable products…
    19/02/2013 15:00:03 – Found installed product – Microsoft Visual Studio 2010 Ultimate
    19/02/2013 15:00:03 – Found installed product – Microsoft Visual Studio Express 2012 for Web
    19/02/2013 15:00:03 – Found installed product – Global Location
    19/02/2013 15:00:03 – VSIXInstaller.NoApplicableSKUsException: This extension is not installable on any currently installed products.

    • John

      Erikas – The template doe snot support Web Express today, however this will be changed later this week. Sorry for the delay.

  • Prashanth

    And I am really waiting for your next course on Pluralsight (From scratch – for a JS rookie like me)

  • jomarito

    Hi, a very interesting post.

    I’ve tried but adding hottowel with nuget to a new mvc4 app it doesn’t work. http request for /script/vendor returns 404 error, not loading needed scripts.

    What can be happening?

    Other question, vsix is only availble for visual studio 2012 and not for express edition, is it ok?

    Thanks and regards.

  • Pheenix

    Could you please provide an example for the details.html with a binding in it?
    Probably I don’t understand it completely, but it would help me to.
    I extended the details.js viewmodel(vm) with a something: “something” and I would like to bind it in the details.html as follows: .

    data-bind=”text: something”

    It is also a bit disturbing that throughout changing these html files it is always cached in the browser, and I couldn’t find a good way for having the new contents. I always have to clear cache…

    • John

      Pheenix,

      Sure. The details.js viewmodel already has a simple binding in it for the title.

          var vm = {
              activate: activate,
              title: 'Details View'
          };
      

      So what you did should work just fine. And you could add some more like this with or without observables:

          var vm = {
              activate: activate,
              title: 'Details View',
              something: 'some value',
              foo: ko.observable('hello world')
          };
      

      The way I handle caching is to check the box for disable cache in Chrome. Then keep the developer tools open and every time I browse to a page I refresh first. This keeps it fresh. If you are not sure if your changes applied because of cache, you can always check the sources tab and examine the javascript file to see what is in there.

      Hope this helps.

      • JoeBloke

        In Chrome, when you have the developer tools open, you can also click refresh, but hold it in for a second or two. You’ll see a dropdown menu with nice Reload options.

  • http://www.ericpanorel.net Eric

    After watching and digesting the SPA course on Pluralsight, I had been using the CodeCamper “framework” to build SPA’s. This is an awesome time saver!!!

  • http://kroltech.com Jason

    Hey John, Thanks for this great article and as always your great work in the community!

    Quick question – any ideas why none of the templates are showing up for me after installation? I restarted VS as well as rebooted. I still see the plain stock list of web project templates (MVC3, MVC4, etc). New Project -> Visual C# -> Web -> (same list).

    Thanks!!

    • http://kroltech.com Jason

      Duh ignore me!! I didnt realize I had to select MVC4 project and THEN i see the list of templates.

      Thanks again!!

  • Nat

    Marvellous! John, have you considered doing a Hot Towel specific course for Pluralsight?

  • Mladen Mihajlovic

    Any chance of getting a TypeScript edition at some stage?

  • Clinton Gallagher @virtualCableTV

    I think I need a course in nested braces and semi-colons with a chapter of SPA debugging tips.

  • http://github.com/jpolvora Jone Polvora

    John ! I think I’ve made a kind of “Hot Towel” tutorial before knowing about this excellent VSIX template. Take a look at my video in http://www.youtube.com/watch?feature=player_embedded&v=in1M0vzg4mg . Essentially I created a new solution, and installed Breeze, Durandal and Toastr NuGet packages. But your template is better to start fresh ! Awesome work. Thanks for sharing.

  • http://www.baardmuts.nl Leroy

    John,

    I love the template and I get a better look-and-feel of the spa and Durandal with Breeze

    I do have a question, the splashscreen…. I would like to show this a bit longer any idea where I can adjust this?

    Hope to hear from you! Keep up the good work ;)

    Leroy

    • John

      Leroy – it will take longer on a real web server, not your dev box . but you can always use settimeout

      • http://www.baardmuts.nl Leroy

        John,

        I’m trying to find the right place for the settimeout but it seems like it’s not being recognized or something? Where should I place it?

        Leroy

        • Matt Johnson

          @Leroy – I was able to delay the splash screen by putting a timeout in main.js, wrapping the entire app.start() function block. Not sure if this is the *best* place or not, but it works well.

          You can use setTimeOut if you want. Or what’s even easier, since Q.js is already there for promises, you can write:

          Q.delay(500).then(function() {
          // wrap around the existing app.start block
          });

          • Leroy

            Yes, that worked for me 2 ;)

            thanks!

  • Paul

    John,

    This is great. The Durandal piece is what I have been waiting for to complete the spa framework. If I wanted to retain the flexibility of deploying to a native mobile device (using Cordova), is there any downside to replacing index.cshtml with index.html including the bundles manually? Obviously all WebApi related projects would remain server side but I don’t see anything else on the client side which isn’t pure html5.

    • John

      Paul , sure. Its perfectly fine to just use the client code. Or look for hottowelette, pure asp.net with no mvc

  • Matt Johnson

    I think I’m in love with this.

    Hot Towel? You should have called it Happy Ending!

    Seriously though – is there a TypeScript version in the works?

  • Ken

    Hi John. This is great! Thanks for sharing. I did notice it hangs on the splash view in IE 10. Works fine in FF. Just wanted to give you a heads up.

    • http://www.baardmuts.nl Leroy

      It doesn’t hang here in IE 10! Might wanna check the console?

  • Uros

    +1 on TypeScript version from me too

  • Ken

    Console is clear. All CSS and JS loads successfully (returns 200). Still investigating…

    • http://www.baardmuts.nl Leroy

      I’m using IE10 on windows 8 with 64-bits.

      My console isn’t saying alot eiher, maybe delete cache or use another browser. Because if I use Google Chrome for a while it won’t update, if I then use a different browser it shows the new website while in Google Chrome still shows the old one. I bet on cache or something.

      Please let us know ;)

      • Ken

        Leroy – I’m also using IE10 on windows 8 with 64-bits. Clearing the cache does not fix it. FireFox works fine so it appears to be specific to IE10 on my machine since it works properly for you. I believe it may be a security setting in IE I need to adjust. Will investigate more over the weekend.

  • Petr

    Why is prefered http://www.breezejs.com/ over http://jaydata.org/ for accessing data?

    • John

      Petr – It’s a preference of style and features. Breeze does everything I need.

  • http://www.baardmuts.nl Leroy

    Dear,

    I made a couple of files in TypeScript and rewrote some things. But I wasn’t able to port the shell.js to shel.ts (shell2.ts is a start!)
    http://dl.dropbox.com/u/5117989/Hot%20Towel%20TypeScript.rar

    Gr. LEroy

  • Tony

    John,

    For some reason the template type is not showing up of VS 2012 Ultimate even though I have installed the .vsix ok. Then when I try the nuget package I get the same behaviour as jomarito- I get a 404 of the vendors file. This looks like a tremendous tempate but I can’t get it to work! Any ideas?

    -Tony

    • John

      Tony – can you zip up the solution and make it available to me on dropbox so I can try it?

      • Tony

        When I went to went to reproduce the problem things started working. What I did differently was saving the solution before installing the nuget package and also installing the package from the package manager console. In any event, things are working properly. Thanks again for the help.

  • Matt Johnson

    Any chance of a video featuring Hot Towel? I just watched the one on Durandal on their site, and I think much of it will apply here as well. But I’d love to see an end-to-end demo specifically of Hot Towel. Or perhaps highlighting it in one of your excellent PluralSight courses. Many Thanks!

    • John

      I’ll be putting a short HotTowel video together for the asp.net site very soon (travelling this week). And I’ll have a more comprehensive set of videos in my next pluralsight course, SPA JumpStart.

      • Hoang

        John, do you have a expected date for the next SPA course on pluralsight? Thanks.

        • John

          Hoang – March 10th is my due date to get it all in. So shortly after that.

  • amir hosein

    +1 for typescript version

  • Mladen Mihajlovic

    Found this for the people interested in TypeScript: https://github.com/borisyankov/DefinitelyTyped

  • Russ Hardie

    Can anyone provide some resources on how to make a ‘muilt-page’ spa application? For example, a spa ‘page’ to manage customer’s profiles combined with a spa ‘page’ to manage orders, etc….
    Thanks

  • http://www.biztalk360.com Dhana

    Hi John,
    With this SPA template i am not able to use the koExternalTemplates discussed in your pluralsight courses. Looks like infuser does its job but ko is not updating the rendering. Not sure if the problem is due to the fact that durandal works on one element (applicationHost) compared to your other SPA course uses body element directly? Any help would be appreciated.

    Steps to reproduce:

    Start a new project with HotTowel SPA template (search for this template in google if you dont already have)
    Via NuGet add koExternalTemplate, which will install traffic cop and infiser as well.
    Update BundleConfig.cs to add TrafficCop,infuser and koExternalTemplate
    create a folder names Templates under root of the project add a template file. update main js with infuser configs to point to the Templates and file pattern (if you know bit of koExternalTemplate you know what i am talking about).
    Include the template in home/details html and launch the app.
    Result: you will only see ‘Loading…’ in place of your template and template doesnt get rendered.

    same question here: http://stackoverflow.com/questions/15072983/i-upgraded-to-knockoutjs-2-2-1-and-jquery-1-9-koextenaltemplates-are-broken

    • John

      Dhana – Can you share your project so I can test it?

      Another option is you could skip the koExternalTemplate and use Durandal for this using its compose binding. It pulls in html using require.js on demand.

      • http://www.biztalk360.com Dhana

        John, the project is here http://sdrv.ms/XUqyRs Thanks. Meanwhile i will explore compose binding (which mean more rework :( )

        • John

          Dhana – The best option is to use Durandal’s `compose` binding with that view. Like this:

              <div data-bind="compose: { view: 'templates/_sample.tmpl.html', activate: true }">      
              </div>
          

          And move the templates foler under the views folder (convention).

          • http://www.biztalk360.com Dhana

            That helps.. Thanks John…

  • Emmanuel

    Hello John,

    Template incredible,

    I’m new to SPA, and I think this is the best option for this.

    I have some questions about the template:

    I need to create an application that has a section of widgets, and this section has to work independently of the application, and the footer should have its own functionality while working, so the user can navigate through the modules, and modules must have a communication between them.

    How does widget.js works?
    Can you give an example?

    can I activate more than one view model, so they can work at the same time?

    Best regards,

  • http://lunarmedia.com Vindberg

    First of thanks for this template. Its golden.

    Having created a new empty MVC 4 project, and added the template using nuget its working perfect in debug=true.

    Changing debug=”false” in web.config breaks the website. It stalls (404) at /app/main-built.js. Any ideas?

    Vindberg.

    • John

      Vindberg – There is a comment in the index.cshtml above the main-built.js call to remind you to run the optimizer if you want to create the main-built.js. That file will then contain a bundle of all of your html and javascript for your app, and saves you from having to make multiple network calls. I don;t create it for you because it would be out of date the minute you add anything to the App folder.

      Remember to run the Durandal optimizer.exe to create the main-built.js

  • Brett

    Hi John, great stuff! A bit new to this SPA concept and associated libraries. I am trying to take the binding example a bit further as per your post to Pheenix above. I put some data bound text boxes on the details.html page and have the vm updating the values when the page loads. Since I am making the text box observable in the details.js page, should the ko library fire something to let me know the viewmodel has updated? Here is my code;

    var vm = {
    activate: activate,
    title: ‘Details Plus’,
    firstName: ko.observable(‘Chicken’)
    };

    Nothing seems to fire off (like an update event) that I can see in Fiddler.

    Apologies if this is a n00b question! I have tried to do some of the ko tutorials but they dont seem to work in the context of say details.html (presumably due to the viewmodels .js files).

    Any direction would be great!

    • Brett

      Sorry to clarify the above a bit more – I am expecting Fiddler to show me when I change the contents of a textbox that has a ko.observable against it. Nothing happens when I change the text box. Do I need to do anything else to update the viewmodel on change of a text box (like call a js function)?

    • John

      Brett – Knockout’s observables will notify between the source (object model) and the data bound targets (HTML). There is no Fiddler activity as it all happens in the browser. When you change a value in your HTML, it updates the observable. When you change the observable, it is reflected in the HTML. The default behavior for text boxes is that it will update the observable when the textbox loses focus.

  • Asif

    Hello John,
    Hot Towel Template awesome,
    I’m new to SPA, and I think this is the best option for me.
    I want to use some Asp.Net Native controls + the some thirdparty controls on the home.html and details.html Views. how i can use them

    Thanks

  • Mathew

    Hey John,

    Really digging all of the SPA stuff that your doing, great work. I followed you pluralsight course, now I’m trying to get into this hot towel template and I have one quick question regaurding the “dataservice” aspect. For the Hot Towel, would you recommend creating one dataservice that lives in the dataservice folder, separate dataservices for each entity/viewmodel, or simply just using breeze in the viewmodel. I’m new to the whole breeze thing, trying to get a grip on how to best implement it. Thanks for bestowing all of your js wisdom on us, you are a master.

    Thanks,
    Matt

    • John

      Matthew – I’d start by creating 1 dataservice.js that encapsulates beeeze and the data management logic. You want your viewmodels to look in one place for the data access so they can not duplicate code. Also helps so you can share the data. I’ll have more details in my course in March too. I hope this helps for now!

      • Mathew

        New course! Nice, I’ll be looking out for it. In this new course, do you implement a UoW/Repo pattern with the breeze EFContextProvider wrapper? If so, how do you package that breeze.webapi dll up and place it into your class library? Adding breeze into the mix looks like it will be an amazing help to SPAs

        • John

          Matthew – I don’t spend much time on the server in the beginner course, since I covered a lot of that in the intermediate course that I published last year. You can find a lot of UoW/Repo material there. You could tell Breeze to talk to a UoW and Repo, though you’d still want to surface the EF context to Breeze if you want all the extra goodies that Breeze provides. If you want more details on that, I encourage your to open a question on StackOverflow for Breeze. They are very active up there.

          • http://www.breezejs.com Ward Bell

            Matthew – Excellent question … and as John suggests, it would be great if you could ask it on StackOverflow (tag with “breeze”) so other people can get in on it.

            In brief, while my controller might create and call a ContextProvider (typically the EFContextProvider) in demos, in my real apps I always write a server-side UoW/Repository. The Breeze Spa Template starts down this road. It has a Repository class that inherits from EFContextProvider. In real life, I wouldn’t use inheritance and I’d have multiple projects. But it’s a place to begin. See my discussion here of that example here.

          • Mathew

            Sure thing and thanks again to both Ward and yourself. I posted my question to here to anyone else who comes across this and is curious to learn more – http://stackoverflow.com/q/15113804/1968049

  • Al

    Hi John,

    Thanks again for another great learning resource. I noticed that Hot Towel does not “define” any of the libraries (ko, jquery, toastr, sammy, etc.) like your Code Camper application does in “define3rdPartyModules” in main.js. Hot Towel just grabs them out of the global scope. Why is this the case? Why did Code Camper do it like that?

    I appreciate all of your help,

    Al

    • John

      Al – There are a few schools of thought on this. One way is to use AMD and require.js to load all modules on demand (some shimmed). That is what I did in Code Camper. This is more effort as some must be shimmed and some use AMD. Also, some use AMD but leave the object in the glboal space. Others remove it.

      Another way is to just use AMD loading for your modules. I have been leaning towards this lately as most of the time I want all 3rd party libraries loaded up front anyway. I bundle and minify them and load in advance. Then load I my modules as needed using AMD/require.js since the dependency chain is more complicated for those (and I may not need some of them).

      It is really just a choice and both options work well depending on which pros and cons work for you.

      I hope this helps.

      • Al

        Thanks a lot John for your help. I was getting confused with the library bundles and what seemed like redundant defines while everything was pre-loaded and available globally. It is crystal clear now.

        Al

  • Brett

    Hi John,

    Thanks for the replies above! One more question at this point;

    On details.html I have created a few form fields (as noted above) and want to fire off an event from a button click (like update the view model, which should reflect in the fields). Code below. When I click the button I get an error UpdateVM() is undefined. Is the script getting lost/conflicting in the structure somewhere?;

    function UpdateVM() {
    this.firstName.value = “Bertie”;
    }

    First Name:

    Last Name:

    • Brett

      Sorry HTML tags were cut out. imagine a two fields as textboxes with a data-bind of value: firstName and value: lastName. Data is getting into those fields from details.js, so I know the binding is working.

    • John

      Brett – To use data binding you should use Knockout’s binding syntax. Like this <input data-bind="value: firstName"/>

      The view model would have an observable like this this.firstName - ko.observable('Bertie');

      And you bind the viewmodel to the view using ko.applyBindings(new MyViewModel())

      I recommend checking out Knockout’s syntax first on their web site or I have a course at Pluralsight on Knockout at http://jpapa.me/komvvm

      If I am misunderstanding, please clarify. I hope this helps!

      • Brett

        Hi John,

        Yeah I understand a bit about ko at this point. What I am getting confused about is where I put the viewmodel update javascript code. I have added a button to the form on details.html that has data-bind=”click: updateMe()” on it. Where should the function updateMe() live (details.html, details.js? if latter, where in details.js?) If you could please provide me with an example it will save a lot of head-on-desk contact :). I have tried both locations, but nothing fires. I feel like it should work in either, but not sure about where to place the script …

        Cheers,
        Brett

  • http://www.zarria.co.za Bob

    Thanks for this article, quick, simple and well written!

    SPA makes tedious tasks so much easier.

  • http://jitendra.me Jitendra Singh

    Are you planning to publish a tutorial on pluralsight ?

    • John

      Jitendra – Yes, I will be publishing a beginner course on SPA that is based on HotTowel in March via Pluralsight.

  • Asif

    Hello John,
    I’m new to SPA, and I think this is the best option for me.
    I want to use some Asp.Net Native controls + the some thirdparty controls on the home.html and details.html Views. how i can use them
    Thanks

  • Dung

    http://stackoverflow.com/questions/15131297/how-can-i-use-durandal-mvc-controller-in-viewpath
    Hi John ! I want to use Durandal with Mvc using controller, razor. How can i do it. Thanks. Could you please make some example, the view will be controller/action ?
    Thanks !

  • Dave

    Dear Mr Papa.

    I am using yout hottowel template as the base framework for my app. I would like to use kendo ui treeview control . But its based on mvc and not on mvvm. Can you. Please advise on how to handle this. Is there a way to combine mvc with mvvm or…?

    Greatly appreciate your work and love your pluralsight vids

  • David Stanescu

    +1 on TypeScript version

  • Leroy

    John,

    I’m trying to use this template with TypeScript and so far everything is kinda working out just right, but I won’t succeed implementing BreezeJS in TypeScript in this template. When I’m developing there is no problem but when I try to run the page with the BreezeJS implemented it says JavaScript runtime error: ‘Breeze’ is undefined. Do you have an example or a simple solution on how to deal with this? I checked and breeze.min.js and breeze.debug.js or but loaded in. Could this be something with capitals or….

    Hope to hear from you keep up the good work ;)

    Leroy

    • http://www.breezejs.com Ward Bell

      Not sure what you’re doing but it can’t be a good thing if the message refers to “Breeze” because (a) case matters and (b) it’s lower case “breeze”

      • Leroy

        This is my typescript file

        [code]
        ///
        ///
        ///

        import app = module('durandal/app');
        import logger = module('services/logger');

        export module Services {
        export class Dataservice {
        //serviceName = "api/customer";

        //serviceName: string;

        Manager: Breeze.EntityManager;
        EntityQuery: Breeze.EntityQuery;

        constructor(/*serviceName: string*/) {
        this.Manager = new Breeze.EntityManager("api/customer");
        this.EntityQuery = new Breeze.EntityQuery("Customers");
        }

        getAllCustomers() {
        //var query = this.EntityQuery
        //.from("Customers");
        var query = new Breeze.EntityQuery("Customers");
        //logger.log("fdfds",null,"dasd",true);
        return this.Manager.executeQuery(query);
        }
        }
        }
        [/code]

        • http://www.breezejs.com Ward Bell

          In Durandal world, 3rd party libraries are loaded first and outside of Require.js purview. Their scripts load objects directly into the global namespace (‘window” on a browser) with names of their choosing. Typically they load objects and regular function which, by JS convention, are camelCase. So it is ‘breeze‘, not ‘Breeze’, ‘jquery‘, not ‘Jquery’, etc. TypeScript is JavaScript and does not change that.

  • John

    Hi John, thank you for the great work.

    I do have a question about routing which I’m sure is not specific to HotTowel but maybe to Durandal or Sammy.

    Let’s say that I just want to put a link on the foot to /securityguard/dashboard. I’m using security guard for user management. If I just do this Administration It never takes me there. Instead I get an error about the module returning HTML instead of JS. If add a target=’_blank’, then it works fine, but that’s not what I want.

    It would also be great if I could add the same link to the navigation on top.

    Any suggestions?

    Thanks

  • http://www.durandaljs.com Rob Eisenberg

    That’s a bug in the Durandal router which has been fixed and will go out in the next release. If you want to use the improved version now, you can grab it from the repo.

    • John

      Rob, will I just need the router.js? or do I need everything from it for this fix?

      Thanks

  • John

    Thanks Rob.

    I will get the repo and go from there.

  • João Vitor PBC

    +1 on TypeScript version of this.

  • http://www.linkedin.com/in/oscaragreda Oscar Agreda

    Well played, John, you are always way ahead of the curve, as in the past, software development always follow your discoveries

    Have you considered adding one more punch to you awesome HotTowel Template
    http://addyosmani.github.com/jquery-ui-bootstrap/components.html
    Regards

  • Matt

    Given the whole “One ASP.NET” concept http://www.hanselman.com/blog/ASPNETAndWebTools20122ReleaseCandidate.aspx,
    is there any chance we will see a SPA application built using Web Forms?

    • John

      Matt – My intermediate SPA course at Pluralsight uses a standard HTML page and if you use the HotTowelette NuGet package, you get a SPA with regular ASP.NET.

      • Matt

        I guess what is so hard to get up to speed on in the intermediate course is
        how many abstractions the app has related to the data layers.
        The course seems way more about those issues and design patterns
        then about javascript. The problem, at least for me, is that it also assumes a lot of prior experience on how to implement those patterns in .net.
        I like working in SQL, have no taste for EF Code First, and rely heavily on stored procs, especially for complex cases where I pass multiple parameters and then return multiple recordsets using WebMethod() calls
        in code behind and jquery/knockout on the client. So this is “bad”
        because of lack of separation of concerns. I am searching for instruction
        or examples of how to include a measure of abstraction, but I guess I
        have to yet to come across a tutorial or “how to” that just clicks for me:
        “ah, this is how I would re-write the existing code with a better separation
        of concerns”. My sense is part of this should be really simple, but I lack
        the confidence without first seeing a real example.

        • Mathew

          Hey Matt,
          Yea I had the same problem, except I’m just coming into the stuff (still a student). It sounds like you have a pluralsight account already, so I’d recommend you check out Julie Lerman’s Entity Framework in the Enterprise (Great Course) and maybe her new Getting Started with Entity Framework 5 as well if your new to EF like I was. Entity Framework in the Enterprise, I thought, really helped me get a grasp on how SoC can be effectively implemented using EF. If it doesn’t help, well then you still took an interesting course. Hope that helps

  • Greg Donovan

    Hi John – we are sold on your Hot Towel design :) Our app will requie some rich client-side grids – what grids, if any, do you recommend (Wijmo, Telerik, jqxwidgets…to name a few)?

    Regards,

    Greg

    • John

      Greg – There are several good ones. But I first try to design my sites without a grid and use a template for rows. I only use a grid if I need something I can;t do easily without one. Grids come with a price (overhead and complexity). But if you want a grid, any of the major vendors has a decent grid, just make sure it has a binding handler for Knockout (if you are using KO). Or you can use a more common one like datatables.js

  • Pingback: Hot Towel SPA – Visual Studio Project Template | WebDevStuff | Scoop.it

  • Alex Maiereanu

    Hi,

    Thist of all i want to thank you for all the support you give us for staying in touch with new technologies :).

    Have you given any thought on how do make spa’s searchable by google? I want to apply the spa principle to a web shop project where some of the data should be crawlable by google. I read the google guidline (https://developers.google.com/webmasters/ajax-crawling/docs/html-snapshot ) on how to do this for ajax content. but i can’t figure out how to create a reusable way to make html snapshots. I am thinking to provide custom routes for content that i want to be indexed,showing exactly what i would have otherwise loaded thru ajax.

    Alex

    • Rad

      Alex,
      Do you have some some samples available that try to use searchable SPA design?

      John,
      This would be a very nice addition to SPA.

      Thanks,
      Rad

      • Alex Maiereanu

        Hi,

        I will play around with this feature in the near future for a project i am working on. If it works out alright i will post some example code

        Alex

  • Tiago Reis

    -1 for Typescript in Hot Towel. Although TypeScript can certainly be a good thing, etc, I think developers should really start paying more attention to JavaScript, and to be able to write proper JavaScript. Why abstract (maybe due to lack of knowledge in proper JavaScript?) when one can structure JavaScript in a very powerful way? It’s just my opinion of course.

    • Mike

      @Tiago, TypeScript is a superset of JavaScript. This means you still have to know JavaScript. Here is what I like about TypeScript every time I write code in JavaScript it starts with me doing a search for “JavaScript Module Pattern” so I can remember what the code is for the module pattern.

      So instead of:

      var MODULE = (function (my) {
      my.anotherMethod = function () {
      // added method…
      };

      return my;
      }(MODULE));

      you can just write:

      module Module {
      function anotherMethod() {
      // added method…
      };
      }

      Also the type checking is a huge win. In the above example, if I was passing a variable to anotherMethod like this anotherMethod(url), if I try to pass a number as url, the IDE will light up immediately and tell me that url requires a string. You still have to know JavaScript, as all of the code you put inside anotherMethod is still JavaScript, it just makes your code more readable and saves you from shooting yourself in the foot. This foot saving is much more apparent when dealing with a large code base, but still helpful when dealing with a small code base. In my view it is a productivity tool, it helps me write code faster, the code is more readable, and the type checking lets me catch where I passed the wrong variable or typo’d a variable name write after I type it instead of waiting until I run the code and have to debug why something isn’t working. I think your comment would apply more to something like CoffeeScript where the syntax is completely different. For TypeScript, you still have to write JavaScript and you still have to understand it.

      • Nik Ivancic

        This little jewel on how to use TypeScript in the context of what you do is greatly appreciated.

      • Tiago Reis

        @Mike, I totally get what you are saying. Maybe I’m just a purist when it comes to JavaScript :) but if I was, I wouldn’t like Durandal so much (because I’d try to do everything by myself). Time will say if I’m going to start using it :)

  • Randhir

    John:
    Please suggest me which is best way like (breeze or durandal) using the hot towel template.

    • John

      Randhir – Both. Breeze is for rich data and Durandal is the app lifecycle and view composition Both together are a good combination.

  • LastTribunal

    John,
    I’m trying to figure out how to implement a jquery method inside a hottowel viewmodel.
    Can you provide an example?
    Thanks and my apologies for the stupid question

    var vm = {
    activate: activate,
    title: ‘Applications’
    };

    return vm;

  • LastTribunal

    More specifically, i am trying to implement Dyntree (https://code.google.com/p/dynatree/) inside the viewmodel:
    $(function(){
    $(“#tree”).dynatree({ onActivate: function(node) {
    alert(“You activated ” + node.data.title);
    }, children: [{ title: "Item 1" },
    {
    title: "Folder 2", isFolder: true, key: "folder2", children: [{ title: "Sub-item 2.1" },
    { title: "Sub-item 2.2" }]
    }, { title: “Item 3″ }]
    });
    });

  • Emmanuel Tolentino

    thanks John,

    Excellent course, I just seen your “Single Page Apps JumpStart” course at pluralsight, and is excellent.

    I have solved some doubts that I had.

  • Sathyan

    We have an application with a backend in .net and SQL Server database with front end in Power Builder. The plan is to give it a thin client I.e browser based UI. The application has over 1000 screens divided into 25 modules.

    What would be the best way to create a SPA for it.

    Please advice

  • Joseph

    Hi John,

    Great training, I loved it. I could say enough about your training is going to help me in my upcoming project.

    What we are trying to re-write is huge application. It will require more than one SPA inside web site. How would you advice me to do that. Can we have multiple sub folders under App folder representing each spa? Can you advice me how I go about and achieve this goal?

    Thanks

    Joseph

    • John

      Joseph – Thanks, I am happy you enjoy the material.

      First consider if you need more than 1 SPA. If there are a lot of views, that’s fine. But if you mean to have different apps or areas of apps that act very differently, and all should be hosted in the same MVC app, then that’;s fine too. The key is that the theme and the client state between these apps should be the same. Theme can be done via CSS and state via postback or local storage, to name a few. This will be a topic I hit in a future course.

      • Joseph

        Hi John,

        Thank you for your quick response. I really do appreciate it.

        Our Main web site will have navigation bar on the left side and each item in there will be different application. The MVC app is going to be the same. But client state is going to different most of the time, the themes will the same.

        Thanks again John. Looking forward to your next series.

        Joseph

  • Richard Davison

    John, Love your stuff.
    Trying to make it my own and add authentication.
    I have started with the Durandal sample and added things denoted here
    http://stackoverflow.com/questions/15462746/durandal-mvc-app-authentication-security
    as noted there I have a sample that is 98% working (everything is wired up and appears to be correct, but when I hit the logout button the content in the browser does not change even though success messages are received).
    Also please note that clicking logout twice seems to cause a javascript error.
    Thoughts?
    RD

    • John

      Richard – Provide the sample via SkyDrive or Dropbox please so I might take a look at it.

      • Richard Davison

        https://www.dropbox.com/sh/sfubdmdct8wpz2a/BLkN6epx0V?m
        as promised.
        all you should have to do is connect to a db with the simple membership tables and a known user id and go from there.
        Have not had a chance to impliment register yet…

        Included scripts for simple membership tables as well.
        please see global.asax

        RD

  • http://noneasyetapartfromgravoidstomp-o-tron simon dowdeswell

    John Im new to JS/jQuery. it took me a long time to work out that these breeze js calls are defined by manager = new entityModel.EntityManager(‘api/Customer’); are not portable to any deployment. If i deploy to a virtual directory, say cs2 then my code needs to be:

    manager = new entityModel.EntityManager(‘cs2/api/Customer’);

    in order to work.

    Is there a better way to work out the real path

    • John

      Simon

      These are your Web API calls, and are common in any ajax application. Some common techniques are to create a root string variable such as var rootUrl = 'cs2/api';. Then when you move elsewhere it is an easy change. Generally I have a config.js file for this stuff.

    • http://www.breezejs.com Ward Bell

      @simon – I think when you look a bit closer at BreezeJS you’ll find that the standard thing to do is define a base path (e.g. var serviceName = 'cs2/api/myAppController' ) which routes to a single controller. Put that in configuration. Change it at will. In your repository/UoW/datacontext/whatever-you-call-it, reference that configuration when creating an EntityManager, e.g.: var manager = new breeze.EntityManager(config.serviceName);

      Then you specify resource names in EntityQuery construction:

      var custQuery = new breeze.EntityQuery.from('Customers');
      var prodQuery = new breeze.EntityQuery.from('Products');
      

      You say “but Ward, I don’t want all of my resources in a single controller”. Not a problem. Redefine your service name in config to something like 'cs2/api/' and then define your query resource name with the controller:

      var custQuery = new breeze.EntityQuery
          .from('customers/Customers');
      var prodQuery = new breeze.EntityQuery
          .from('products/Products');
      

      That seems kind of silly to me so I could do some server-side routing to get back to:

      var custQuery = new breeze.EntityQuery.from('customers');
      var prodQuery = new breeze.EntityQuery.from('products');
      

      The routes would channel these requests to appropriate controllers and actions. Not a big deal. Aside: you’ll have to do some server-side custom routing of the EntityManager requests to the appropriate “Metadata” and “SaveChanges” endpoints but that’s pretty trivial. If I’m using a Breeze controller on my server that can handle queryables, I’m not loving this controller-per-type approach because I’m going to end up with a lot of controllers that only have one method. But maybe you don’t want that kind of controller and instead want lots of very specifically named actions. You can do that too:

      var custQuery = new breeze.EntityQuery
          .from('customers');
      var custQuery = new breeze.EntityQuery
          .from('customers/getGoldCustomers');
      var custQuery = new breeze.EntityQuery
          .from('customers/'+42); // get customer with id=42
      var custQuery = new breeze.EntityQuery
          .from('customers/startsWith')
          .withParameters({name: 'b'});
      

      It’s not hard. It just means having server-side endpoints that understand the resolved URLs. More detail is beyond the scope of this comment. My point is … you’re not handcuffed … like you might have thought.

      • http://noneasyetapartfromgravoidstomp-o-tron simon dowdeswell

        Thanks, Ward, John for taking the time to help me out !

        for my config ive gone with working out the base url :

            function processBaseUrl() {
                var baseUrl = window.location.pathname;
                var urlLength = baseUrl.length;
                if (urlLength > 0) {
                    if (baseUrl.charAt(urlLength - 1) !== '/') {
                        return baseUrl + '/';
                    }
                }
                return baseUrl;
            }
        

        These points you raise, Ward are exactly whats on my mind … only 1 controller … too many controllers … I am in favour of more specific requests so that the name can indicate the intention.

        I will be looking into the routing as you indicated.

        one small point – i tried to switch the project over to basic jQuery AJAX and couldnt get it working (gave me 404 even though the path was good) until I commented out the whole HotTowelRouteConfig and put the route in with the standard RouteConfig.RegisterRoutes ie:

                    routes.MapRoute(
                        name: "HotTowelMvc",
                        url: "{controller}/{action}/{id}",
                        defaults: new
                            {
                                controller = "HotTowel",
                                action = "Index",
                                id = UrlParameter.Optional
                            }
                        );
        

        I would have thought the two were equivalent … but obviously not

  • Rody

    I’ve added a new view and viewmodel to a new project. Added an extra router.mapNav() to this view, but the view is not loaded:

    router.mapNav(‘details’);
    router.mapNav(‘subdetails’);

    Whenever I click on the menubar on subdetails the details view gets activated. I think it has something to do with durandal using the url paramter of router.mapNav as regular expression, but I don’t know how I can force the router to use the entire string instead of a regular expression.

    • John

      Rody

      There appears to be a bug in either Sammy or Durandal. I created an issue in Durandal’s github repo for it. In the meantime, you can solve this 2 ways: either put the subdetails first (so its foudn first) or change the name of subdetails.

      https://github.com/BlueSpire/Durandal/issues/104

  • Ronnel

    Hi John,

    how would u do a data driven menu/routes?

    • John

      Ronnel – Pull the menus from a database via an ajax call, then load into the router instead of hard coding.

  • Leroy
  • Mike

    John,
    I installed the vsix file and I’m running VS 2012 Premium but I don’t see the templates when installed when I select ASP.NET MVC 4 Application. Anything else I can try?

    • izmirli

      are you probably selecting VB as language? It appears under C# only for me.

  • Mike

    Forget my last comment. I got it working with the Nuget package. Sorry.

  • Paul Wade

    Hi John,

    Can I get this working with VS2010?

    Regards,

    Paul.

    • John

      Paul – Yes, but not the VSIX (that requires VS 2012). You can use the NuGet packages nuget.org/packages/hottowelette or nuget.org/packages/hottowel

      • Paul Wade

        Hi John,

        Just to let you know…..

        I downloaded the completed exercise files from your PluralSight course and successfully converted it to run with VS2010.

        I followed Adam Storr’s article on how to do the conversion, so a big thank you to Adam http://westdiscgolf.blogspot.co.uk/2012/09/opening-pluralsight-single-page.html

        Also… I need to get my VS2010 HotTowel running with IE8, can this be achieved using Shim and Sham files? Do I have to include them in the BundleConfig?

        Any help appreciated.

        Regards,

        Paul.

  • Pingback: ASP.Net MVC: Single Page Application (SPA) from Scratch; A How To Step by Step « OmegaMan's Musings

  • Pingback: Getting Started with Durandal.js | Developer Chunks

  • http://stackoverflow.com/users/1014822/jcfx JcFx

    +1 for a TypeScript version.

  • Raymond Suelzer

    What is the purpose of widget.js ? It is not included in any documentation that I have seen.

  • Pingback: Developing MVVM style HTML5 applications (part 1)

  • Pingback: John Papa interview on SPA (Single Page Applications) - SSW TV | SSW TV

  • Pingback: I’ll take my Durandal with Intellisense, please | landofjoe

  • https://github.com/anthonychu Anthony Chu

    Here’s what it looks like with TypeScript. I converted the viewmodels and a couple other core JavaScript files to TypeScript.

    https://github.com/anthonychu/HotTowelTS

    One immediate advantage is the fully functional intellisense you gain with TypeScript. That’s huge as Visual Studio’s built-in JavaScript intellisense doesn’t work at all with RequireJS and AMD.

    John: Thanks for the awesome courses on Knockout, TypeScript, and SPA. It’s been a joy to learn about and work with these tools!

  • Daniel

    Hi, is this extension also available for VS 2010?

    • John

      Daniel – the NuGet packages work in VS 2010

  • http://www.cronopiodd.com Agustin Cassani

    Hi John, thanks for this incredible template! I have used it in many projects with ASP.NET 4.5 with no problems at all but I am facing some troubles trying to apply it to older projects done with ASP.NET 4.0 The error message says something related to EF and its dependencies but I am pretty sure that that is a general error and the real one is somewhere else. Could you tell me what do I need to set up in order to use this template with ASP.NET 4.0 or is it impossible? Thanks in advance!

  • ccliu

    Hosting Question: SPA is normally File URI Scheme or hosting on server such as IIS?

    Great video, thanks!

  • Sverre

    Hi John, thanks for the excellent SPA template. I am trying to use it in a real world project with several layers. There is a data layer based on EF in a separate project but I am hesitant to introduce a dependency on Breeze EFContextProvider in this layer. On PluralSight you have a similar scenario in the “Single Page Apps with HTML5, Web API, Knockout and jQuery” course and using dependency injection. How would you recommend using the Breeze EFContextProvider in this situation?

    • John

      Sverre – You can use the UoW and Repo patterns on the server and just have Breeze sit on top of them.

  • Fred

    John, Thanks for this great framework.
    one of my clients requires an app to run on iPad and the web, but when running on the iPad we require offline data. I plan to use phonegap, is hottowel the best framework to do it in ?

    TIA
    Fred

    • John

      Fred – I haven’t taken the exact HotTowel stack to phonegap yet. But the concepts should translate well. Sounds like a great idea for a new course :)

  • CB

    Hi,
    I’m enjoying your SPA pluralsight course… Well, I was, right up to the part after installing the entityframework.sqlservercompact and you say, “Now, we go to our fragments folder and bring in….”
    Where the heck is the “code/fragments” folder? You never say in the video!
    Thanks for any pointers…
    C. Bates

    • John

      CB – Thanks for the feedback. I am glad you are enjoying the course. The example code is available with a Pluralsight Plus subscription.

  • Andre

    I started to follow the videos on `pluralsight` about this template. But I have already a question: Can I use Kendo UI MVVM pattern to do the bindings instead of using knockout? Or need I to use knockout with this kind of template? Sorry if this is a basic question, but I’m starting now in the web development.

    Thanks in advance!

    • John

      Andre – I have not tested Kendo’s MVVM pattern with Hot Towel. But it could certainly work.

  • http://www,kresco.nl Rody van Sambeek

    John, in your pluralsight video it seems you have intellisense using durandal. But I’m not sure, because it shows really fast. When I use the HotTowel template in my own project, I don’t get the correct intellisense from modules I load in using durandal.

    Is this resharper working? Or do you have specific settings to get this working?

    • John

      Rody – Without named modules using AMD, it doesnt work well in VS. I use Resharper and it helps greatly.

  • Pingback: DevIntersection, Angle Brackets og Curly Braces i Las Vegas – BEKK Open

  • Simon

    A HowTo question: I have a view that I want to be reusable – selectCustomer. when i call router.navigateTo(‘selectCustomer’)

    what is a good way to supply a callback, to be used in selectCustomer, to be called when the customer is selected.

    Currently I have an appNavigation service to set a selectCustomer Callback property and then navigate to it, but its kind of global so no stack (the viewModels are all singletons) … a bit cludgy. I would rather call:

    router.navigateTo(‘selectCustomer’, new selectCustomerVm(callback))

    note i am a js noob, so I dont actually know how to expose the selectCustomerVm class and get a new instance with the require injection mechanism

  • Israel Peru Castro

    Hi John. I installed the 2013 template, but doesn’t show up in VS 2013 RC. Any ideas?

  • Bill Ross at Pax EDI

    Assuming I have in place:

    * an EF Database Context
    * an API HTTP Controller on top of that
    * Hot Towel all set up

    Can I only do /route/method/optional id?
    Or can I use linq-like syntax to go crazy with my where clause?
    Or do I have to write a separate method for each grouping of criteria?
    And if so, does my call look like /route/method/param1,param2,param3,param4?

    And where would I read up more about working with databases using the config I posted at the beginning of this post?

    Thanks,

    Bill

  • Andrey

    Hi John,
    New version of Durandal removes durandal folder from App and installs it to scripts instead. Application has stopped working because of this… How do I need to change mapping to the new durandal location?

    • vinneyk

      I’m sure @disqus_Wb0q4UTiH8:disqus has already worked this out but for convenience of someone else who might be dealing with the same issue (as I have been), I found some documentation for upgrading Durandal 1.x to 2.x >> http://durandaljs.com/documentation/Conversion-Guide.html

  • Philippe Da Silva

    Hi John,
    Do you believe we’ll see anytime soon Hot Towel for ASP.NET MVC 5 that comes with Visual Studio 2013 RTM?
    I’m thinking to start a new project and I love the neat features provided by this latest MVC version the ASP.Net team came up with.
    Thanks,
    Regards

    • johnpapa7

      I will be updating the nuget packages in the next few weeks. There were a lot of changes, unfortunately.

      • Philippe Da Silva

        Thanks John. Anything I could do to help you out ?

        • johnpapa7

          I just got off a cruise and I have to assess WHAT exactly is wrong with nuget packaes since the latest Microsoft updates (asp.net, ef, odata, sql ce, etc). Once I know what is wrong, I can fix it. If you know what is wrong and can share, that may expedite this since I have not even looked yet.

          • Philippe Da Silva

            Allright. I created an issue on your github repository: I’ll have a look and post there some more information. Thanks

          • johnpapa7

            Hi folks! Thanks for watching my course! Some of you have let me know that there are some issues with the newest WebApi NuGet packages. Once these are resolved (coordinating with Microsoft and Breeze folks) I will let you all know. In the meantime, here is the workaround which is quite simple:

            For now, the easiest thing to do is install the nuget packages in this order. I am working with the Breeze team and the ASP.NET team to make this easier soon :)

            Install-Package Microsoft.AspNet.WebApi -version 4.0.30506.0

            Install-Package Microsoft.AspNet.WebApi.Odata -version 4.0.30506.0

            Install-Package EntityFramework.SqlServerCompact -version 4.3.6

            install-Package HotTowel.angular -pre

            Install-Package HotTowel.angular.breeze -pre

            The first 3 ask it to use the WebApi 4.0.30506 … which makes it all work. Once I get confirmation from the Breeze team on some changes and check them with the Web Api team, I will update this and let everyone know how to make it work with Web API v2.

          • Philippe Da Silva

            Hi John, any news on the MVC 5 and EF6 support ? ;)

          • Amir Davoodi

            Hi John, thanks a lot for this great work. However, as Philippe asked already, do you have any plan to upgrade Hot Towel to be compatible with MVC 5 anytime soon?

          • Paul

            Hi John. I updated my Hottowel durandal project (VS 2012) to include the latest breeze js, however it seems breeze has come a long way since the last release of your template and as a result has broken my project, looks like other breeze dep packages were updated also :( Can you please let us know of a safe way to upgrade breeze to v 1.4.7 or higher?? I use breeze with EF and it seems the server side of breeze has changed as well. Cheers Paul

  • izmirli

    When I open a new project, I dont see under VB templates but C# has it. Is it only for c#? if yes, why not for VB as well?

  • Fred

    John, I have created an enterprise App with Hot towel SPA, works Superb. I have many viewmodel js files, can we use bundleconfig for optimization or whats the Best Practice for minification of these files?, can you please help.

    • johnpapa7

      Fred – there are many good sways to bundle and minify. If you like ASP.NET Web Optmization, that works great. I also like using node.js with a grunt.js task to minify and bundle.

  • aboomar

    i just install hottowel template change application title and run form VS2012 it’s work fine local but when i publish it to as it’s to Microsoft WindowsAzure Hosted Site it’s bring me this error

    {Uncaught ReferenceError: ko is not defined main.js:17

    (anonymous function)}

    <>

    so is there any farther configurations needed to publish hottowel template ?? please any help

    • aboomar

      geting this error when i’m using [Install-package hottowel ]

      but when i install [HotTowelSpa.2012.vsix] to vs templates it’s work fine in azure site also i try to compare the tow solution i didn’t finde the difference

  • Reg Req

    Hey John, Thanks for such a wonderful template. I’m learning and fixing as per my need. After updating lot of new packages in VS 2013, Progress bar is not coming up. I can simply see a box but no color and no stripes.. It was after updating boostrap.css (id: twitter.bootstrap). Other issue is already mentioned by lot of folks regarding updates of nuget packages giving trouble. Attached is the image of it. Your help would be much appreciable in both the cases.

  • Nazm

    Mr John,

    Can we use SPA Towelette in ASP.NET web forms by using other WEB API ?

  • SiddharthP

    Hi John, I have just tried installing hot towel package for mvc 5 and it fails complaining about web api and ef. Any guidance how to install your package for it in vs 13 ?

  • michel dahdah

    Are there any instructions on how to extract a working sample of HotTowel that could work on unix systems?

  • david weng

    Very nice template, it is great!

    Any hint on why we need the breeze.partial-entities

    .js? why we cannot consume data directly from Breezejs and need those partial thing, Dtos to Entity? please point a direction so I can learn it.
    Thanks!

  • GregJF

    Hi John
    Have an issue with HotTowel in IIS (not Express)
    Could find HotTowel Community site so log issue with StackOverFlow.

    http://stackoverflow.com/questions/22603091/hottowel-spa-uses-incorrect-get-address-for-img-on-firefox-and-chrome

    Can you please have a look

    Regards

    GregJF

  • Ganesh Kumar

    Hi John,

    Thanks for your wonderful video on pluralsight. Is it possible to host the application in sharepoint? if not Can it be made to get compatible with Sharepoint hosting? Thanks in advance.

  • http://www.guilhermemorais.com/ Guilherme Morais

    Hi! Mr. Papa,

    First of all thanks for the video in youtube about SPA and hot Towels, very nice in deed. I was accessing the demo site (http://papademo.azurewebsites.net/) and I have Adblock Plus (Plugin which blocks Adsenes..) and I was unable to open the site, the script (logger.js which is part of durandal) don´t load was blocked. Maybe there a way to warning the user about that?

    I´m wondering if it´s possible to alert they about this type of block, the site wont charge and looks like is stuck…

  • Gouri

    I am calling the Index method of the Spa Controller using an ajax call. I see that the view does not get rendered. But on successful completion of the ajax request, if I try to execute $(“body”).html(response), I see that _LoginPartial and _splash partial views are seen but there are script errors for the next lines in the index.cshtml file when main.js is getting loaded. Any idea on how can I render the view correctly while using an ajax call.

  • Paddymel

    How does the Durandal merge with Angular affect Hot Towel? Are there concerns or a new version on the horizon?

%d bloggers like this: