Sharing cookies between subdomains

A while ago I wrote about sharing cookies on an old Tumblr blog of mine. I figured it contains some valuable information so I migrated the post here. The reason I wrote it was that I was working on a pitch that would take a user through a series of puzzles. Each puzzle would enable the user to see the next website(subdomain) and I decided I'd save the progress of the user in a cookie.

Normally you'd define a cookie for a domain like www.example.com. When the browser tries to read this cookie, the current domain has to be www.example.com. So sub.example.com wouldn't work and the cookie won't be read. There is, however, a way to get around this security limitation and it's quite easy.

If you only specify .example.com(note the period before example.com) as the host for your cookie, it will be accessible for every subdomain from this host. So both www.example.com and sub.example.com can use this cookie.

An example in code (using the jquery cookie plugin):

$.cookie('foo', 'bar', {path: '/', domain: '.example.com'});

Well, hope it's helpful to some of you out there.

Using Angular UI Bootstrap modals

While working on a personal project I figured I'd use Bootstrap because then I wouldn't have to worry about styling. All was very well and using Angular.js together with Twitter Bootstrap totally made my day. But then I needed to show a modal dialog. I know how to do this but I stumbled upon the Angular UI directives for Bootstrap this seemed great. I mean, that's just awesome. Using the power of Angular's directives should get these modals up and running super fast. Or so I thought..

After skimming the docs and looking at the modal example I figured I'd give it a go. I set up my templates and wrote some code. Clicked on my button and then.. nothing. Just some error message.. My code looked like this, and from the docs I understood that this would be fine.

(function(){
    var app = angular.module('cmsRecipesModule', ['ui.bootstrap']);
    app.controller('cmsRecipesController', [
        '$scope',
        '$rootScope',
        'recipeService',
        '$modal',
        function($scope, $rootScope, recipeService, $modal){
            $scope.recipes = recipeService.recipes;

            $scope.deleteRecipe = function(id) {
                $modal.open({
                    templateUrl: '/templates/modal.html',
                    controller: 'ModalCtrl'
                });
            }
        }
    ]);

    app.controller('ModalCtrl', [
        '$scope',
        '$modalInstance',
        function($scope, $modalInstance){
            console.log('instance');
        }]);
})();
<div class="modal-header">
    <h3 class="modal-title">Weet je zeker dat je dit recept wilt verwijderen?</h3>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
    <button class="btn btn-primary" ng-click="ok()">OK</button>
    <button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>

This was just like the docs told me to do it and should've worked just fine. But it didn't, my code wouldn't find the window and backdrop templates. So I added the template folder from angular-ui to my project but that led to another error telling me my template needed one root. And one root only. This bugged me, I did the same things with my template as the examples did and they worked fine. So then I turned to some more searching online an I found this Github issue. This person was having the same issues I had and the solution was simple. He made a 'beginners mistake' because he forgot to list ui.bootstrap.tpls as dependency for the module that was creating the modal window. After I added this dependency everything was working just fine. So, to everybody getting an error about their templateRoot when trying to use the modals from angular ui's bootstrap directives. Make sure you added ui.bootstrap.tpls.

My final code for the controller ended up like this:

(function(){
    var app = angular.module('cmsRecipesModule', ['ui.bootstrap', 'ui.bootstrap.tpls']);
    app.controller('cmsRecipesController', [
        '$scope',
        '$rootScope',
        'recipeService',
        '$modal',
        function($scope, $rootScope, recipeService, $modal){
            $scope.recipes = recipeService.recipes;

            $scope.deleteRecipe = function(id) {
                $modal.open({
                    templateUrl: '/templates/modal.html',
                    controller: 'ModalCtrl'
                });
            }
        }
    ]);

    app.controller('ModalCtrl', [
        '$scope',
        '$modalInstance',
        function($scope, $modalInstance){
            console.log('instance');
        }]);
})();

Creating a multi step form with Angular.js

Before we start, you might want to check out this example of the form in action.

While I was working with Angular.js to create a nice little recipe / cookbook site for myself, I was creating a form that required me to split it up into multiple parts or steps. I found this surprisingly easy to do actually but I can imagine that not everybody will have the same experience I did. In this short post I will provide you with a good starting point for your html and your javascript.

I'll be using the power of Angular.js directives to hide and show parts of the form. Well, let's dive in then!

First of all, we'll set up a form. It could look a little like this. I'm using bootstrap to style the form in this example. You can just ignore the classes I've used.

<form class="form-vertical" name="myForm" ng-controller="FormController" novalidate>
    <fieldset ng-show="step == 1">
        <legend>Step one</legend>
        <div class="form-group">
           <label for="name">Your name</label>
           <input class="form-control" type="text" id="name" name="name" ng-model="name" />
        </div>
        <button class="btn btn-primary" ng-click="nextStep()">Next step</button>
    </fieldset>
    <fieldset ng-show="step == 2">
        <legend>Step two</legend>
        <div class="form-group">
            <label for="email">Your email</label>
            <input class="form-control" type="email" id="email" name="email" ng-model="email" />
        </div>
        <button class="btn btn-default" ng-click="prevStep()">Previous step</button>
        <button class="btn btn-primary" ng-click="nextStep()">Next step</button>
    </fieldset>
    <fieldset ng-show="step == 3">
        <legend>Step three</legend>
        <div class="form-group">
            <label for="msg">Short message</label>
            <input class="form-control" type="text" id="msg" name="msg" ng-model="msg" />
        </div>
        <button class="btn btn-default" ng-click="prevStep()">Previous step</button>
        <button class="btn btn-primary" ng-click="submitForm()">Submit</button>
    </fieldset>
</form>

So, that's not very bizarre right? It's a regular Angular.js style form with a bunch of fieldsets. The magic happens with the ng-show directives that are set on the fieldsets. These directive will make sure that we will only show a certain fieldset if the step property of our controller is equal to a certain number.

Let's tie this up with some Javascript.

(function(){
    var app = angular.module('myApp', []);
    app.controller('FormController', ['$scope', function($scope){
        $scope.step = 1;

        $scope.nextStep = function() {
            $scope.step++;
        }

        $scope.prevStep = function() {
            $scope.step--;
        }

        $scope.submitForm = function() {
            // submit code goes here
        }
    }]);
})();

If we were to test this out in an actual app we would have a pretty neat form that spans multiple steps. The model data is preserved for each because we're just showing and hiding different parts of a single form!

Source on github