Simple AngularJs Countdown Timer

A Simple AngularJs Countdown Timer has come in handy a few times while making new products and slowly removing the dependency on jQuery. I originally wrote a countdown timer using jQuery, but with AngularJs that isn’t considered best practices. This is what the previous javascript looked like.

OLD WAY:

//Countdown timer starting at 3, then closes current window.
var _startCountdown = function(){
	var count = 3;
	var counter = setInterval(function () {
	count = count - 1;
	if (count <= 0) {
	  clearInterval(counter);
	  $('#timer').hide();
	  $('#success').show();
	  //Wait just a second then close tab.
	  setTimeout(function () {
		$window.close();
	  }, 1000);
	  return;
	}
	$('#timer').text(count);
	}, 900);
}

This worked fine and served its purpose. However, with wanting to removed jQuery from within the angular controller, I decided to find a way to do this solely in AngularJs. It turned out to be quite easy.

NEW WAY:

var _startCountdown = function(){
	var timerCount = 3;

	var countDown = function () {
		if (timerCount < 0) {
		  //Any desired function upon countdown end.
		  $window.close();
		} else {
		  $scope.countDownLeft = timerCount;
		  timerCount--;
		  $timeout(countDown, 1000);
		}
	};
	$scope.countDownLeft = timerCount;
	countDown();
}

Now, within your html you have access to a scope variable called {{ countDownLeft }}. Make sure to pass in $timeout into your controller.

Dynamically Center Div Within Div

Dynamically Center Div Within Div turned out to be a bit harder to accomplish with CSS than I wanted. I had to handle a case with internationalization where a div with text was contained in a div and need to be centered vertically. The catch was that the text could be from one line to multiple lines. This was the solution I found.

Html Code:

<div id="page">
 <div id="content_container">
   <div id="content">
     <p>your contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour contentyour content</p>
   </div>
 </div>
</div>

Css Code:

#content-outer {
 display:table;
 overflow:hidden;
 margin:0px auto; 
 height:100%;
 width:465px;
}

#content-inner {
 display:table-cell;
 vertical-align: middle;
}

html, body {
 height:100%;
}

Jsfiddle Here

If anyone has a better solution for dynamically vertically centering a div within a div I would love to hear it.

JavaScript Regex To Get Parts Of URL

I came across an extremely useful JavaScript Regex To Get Parts Of URL lately that I thought I would document as it took some searching to find. Basically I was trying to find the host of any number of combinations of urls. Meaning, if you have https://www.adamthings.com/ I wanted to then only get adamthings.com back.

The use case for this was I need to ensure the host domains matched. So if I got an input of say http://www.alienwarefxthemes.com/ I wanted to fail it because adamthings.com does not equal alienwarefxthemes.com.

Now I realize this regex may be a bit overkill for this situation but it was one of the few that seem to handle the majority of my cases successfully.

Now, the regex. I’ll be the first to admit I don’t understand everything that is going on as I didn’t write it and regex are not my thing.

var _host_from_url = function (url) {
var clean_url = jq.trim(url);
var match = clean_url.match(/^((http[s]?|ftp):\/\/)?\/?([^\/\.]+\.)*?([^\/\.]+\.[^:\/\s\.]{2,3}(\.[^:\/\s\.]‌​{2,3})?)(:\d+)?($|\/)([^#?\s]+)?(.*?)?(#[\w\-]+)?$/i);

return match[4];
};

Sorry for the wrapping, but I wanted it to all be on the screen without scrolling. So in my case, I was returning the 5th part of the array as it was the host name. Lets look at some outcomes.

Url To Test:
https://www.adamthings.com/post/2014/02/17/hello-world-angularjs/ has 10 groups:

  1. http://
  2. http
  3. www.
  4. adamthings.com
  5. /
  6. post/2014/02/17/hello-world-angularjs/

As you can see there is a lot more information you can gather from this regex. I recommend playing with it and seeing how it works for you. Here are some other examples. (Left out the blanks to conserve space but you can see the url used and what parts it found.

www.adamthings.com has 10 groups:
www.
adamthings.com

http://www.subdomain.adamthings.com has 10 groups:
http://
http
subdomain.
adamthings.com

https://www.adamthings.com has 10 groups:
https://
https
www.
adamthings.com

adamthings.com has 10 groups:
adamthings.com

https://www.adamthings.com has 10 groups:
http://
http
adamthings.com

https://www.adamthings.com has 10 groups:
https://
https
adamthings.com

Hello World With AngularJs

To understand the basic architecture of creating a simple app lets make a Hello World with AngularJs. In the process, we will look at how to declare a new Angular app, create a controller, and create a Hello World directive.

Creating a new Angular module is pretty simple (The name can be whatever you choose):

var app = angular.module('adamsAngularApp', []);

As we have seen before, this will be used to let Angular know this is the app to look for our directives we have declared for upon DOM compilation. For this example we will just throw it up at the top of the page in the tag.

<html ng-app="adamsAngularApp">

Now to make a controller. The nice part about having controllers is to be able to manipulate the parents $scope that Angular provides in each controller or create a child $scope that can be manipulated per controller. Controllers also tend to help keep things readable and separated into nice and abstracted thoughts. Lets look at the declaration statement for a controller.

app.controller('MainController', function ($scope) {
    $scope.name = 'World'; //This is using the parent scope.
});

Angular is pretty neat with its $scope. As you can see above, we just added a name element to the scope that we can now use in our directive. Implementing the controller in part of our app is pretty simple. We could implement it solely on a div surrounding what we are using it for or if you need your whole page to use the controller, we can just throw it on the tag.

<body ng-controller="MainController">
</body>

Now lets put together a simple directive to go in the middle. Let’s take a look at the declaration of the directive we will use.

app.directive('helloWorld', function () {
    return {
        //We Will Fill this soon.
    };
});

Pretty simple. Now lets add some simple arguments in the return statement.

app.directive('helloWorld', function () {
    return {
        replace: true, //replaces new HTML element with template below
        restrict: 'AE', // directive can be used as a new HTML element or an attribute
        template: '<h3>Hello World. {{ name }}</h3>' //Template that will replace
    };
});

All comments are inline in the example. Basically, when this directive gets executed it’s going to replace the html element we created with the template in the directive. Also, take a look at how the $scope.name was used in the template. Upon execution this will be rendered as the value of name which is ‘Welcome.’ Now lets finish it off with the full html front.

<html ng-app="adamsAngularApp">
	<head>
		//Include reference to AngularJs
	</head>
	<body ng-controller="MainController">
		<hello-world />
	</body>
</html>

Simple AngularJs Directive

Let’s take a look at a simple AngularJs directive to start getting an understanding of how directives work and how AngularJs uses them. As discussed in the previous angular post, we have to mark some outer element on the page as ng-app. A little refresher, this tells angular that it needs to run through all of the DOM elements looking for directives. Once it locates all of the directives, they are associated with those DOM elements and will run now.

So what is a directive? In the simplest form, it is essentially just a function that is tied to the DOM and gets run when the DOM gets compiled. There are multiple ways to denote a DOM element with a directive. One of the more common ways it’s done, is just like putting ng-app directive in the body tag. Lets say we have a directive called angularDatePicker; you could mark a element like follows:

 <span angularDatePicker></span>

It is as simple as that, now every time the DOM is compiled, angular will see that directive and execute it on that span each time. Now lets take a look at a data binding and model example. Two built in directives that AngularJS gives us are ng-model and ng-bind. They are more or less just different ways of invoking your own directive. In the follow snippet. You will notice that when you type in the input box, the type is bound and output on in the divs denoted by these 3 different, valid, bind methods.

<body ng-app>
    <input type="text" ng-model="myDirective" placeholder="Type Some Text.." />
    <div ng-bind="myDirective"></div>
    <div ng:bind="myDirective"></div>
    <div ng_bind="myDirective"></div>
</body>

There are two more way to do the same binding but the only difference is they are the only 2 that are HTML5 compliant and should pass HTML5 validators.

<!-- HTML5 Compliant -->
<div x-ng-bind="myDirective"></div>
<div data-ng-bind="myDirective"></div>

All 5 of the methods above are valid ways to invoking a directive.

Here is a working JSFiddle to see it in action.  Click Here

StackOverflow Profile