Wednesday, May 14, 2014

Precedence Order of CSS rules

Learning AngularJS; Guide for beginners:

Every web developer needs to write CSS for making a site beautiful and attractive. CSS is easy but also tricky due to its different behavior on different browsers. The most annoying thing with CSS any developer face is the order of precedence in which CSS rule applied.







Let say there is a div with class and id, and there is css rule define for class, id and tag.

<div class="div-class" id="DivId">
Here is content div...</div>
<style>
d iv{
background-color:red;
width:100px;
height:100px;
}

#DivId{
background-color:green;
width:200px;
height:200px;
}

.div-class{
background-color:yellow;
width:300px;
height:300px;
}
</style>

So, which rule will be applied to div? Any guess! No Lets see demo.

Order of precedence of CSS rule

There is a specific order in which CSS applied to an element. This order can further be divided into two parts.

A. Placement Method of CSS

Style to any HTML element can be applied in three different legal ways.

  1. As inline styles — css style directly applied to an element using style attribute.
<div style="background-color: red; height: 100px; width: 100px;">
</div>
  1. As embedded styles — style applied by writing CSS in style tag in head tag of HTML.
<style>
.div-class:{
  background-color: red; 
  height: 100px; 
  width: 100px;
}
</style>
<div class="div-class">
</div>
  1. In an external stylesheet — in this we put all our code in file with extension .css and include in html page with link tag.
<link href="theme.css" rel="stylesheet" type="text/css"></link> 
<div class="div-class">
</div>
<!-- and a seperate theme.css file contain>
.div-class:{
  background-color: red; 
  height: 100px; 
  width: 100px;
}

CSS declaration overrides the other declaration in the order of precedence we listed above. Its means:
  • Inline styles have highest priority and it overrides all other rules if there is same property describe in other methods.
  • Embedded styles have less priority than inline style but it overrides the same propertied define in external stylesheets.
  • The External style sheet has lowest priority but it is the recommended way, as it separates the CSS from HTML and make it easy to manage CSS in one place. If there is more than one external style sheet than priority decided in the way files included in HTML, first file (top) has lowest priority while the last file included (at bottom) has greater priority.

B. CSS Selector Precedence


Within any of above method precedence is different for the CSS selector used. As we see in the first example in this post. A div having three different rules for different selector will result in only one of three CSS selector.  The order of precedence of the various CSS selectors are:

ID Selector

ID is restrictive attribute, valid HTML page contains only one element with a specific ID. That is the reason ID selector has the highest priority. Which means a CSS rule in external CSS file will override all other CSS rules with the same properties for any element. Similarly the CSS rule define for ID in embedded style will override other rules in embedded style.

#DivId
{
  background-color:red;
}

Attribute Selector

In priority order second selector is attribute selector, in which we define CSS for the element which has a specific attribute value. It also has the same scope for external and embedded styles as for ID.
a[target]
{
  background-color:red;
}

<a href="http://goo.gl/DnIh3A">Angular JS
<a href="http://goo.gl/xk3G5A" target="_blank">c# inconsistency in equality

Class Selector

After attribute selector, class selector has the priority on others selector. Class selector is defined by a dot with class name.

.aClass{
  background-color : yellow;
}

<a class="aClass" href="http://goo.gl/DnIh3A">Angular JS

After class selector the order of precedence is:
  • Child Selector parent > first child of element
    ul > li { }
  • Adjacent Sibling Selector two elements sibling to each other
    #DivId + ul { }
  • Descendant Selector child at any level under parent tag
    ul li { }
  • Type Selector tag name
    li{ }

Order of declaration


Beside above given rules of precedence, CSS follows the descending fashion to apply CSS rule means if there are two different rules for the same class, will result the last rule to be applied
.aClass{
  background-color : yellow;
}
.aClass{
  background-color : red;
}
//this last one will override above ones
.aClass{
  background-color : green;
}
<a class="aClass" href="http://goo.gl/DnIh3A">Angular JS

The !important Rule



There can be a situation when we need to override the CSS in less priority place. Like if there is a width property assigned in inline CSS and we need to override in External Style Sheet or width property set in ID selector and we want to override it in class selector then we use !important with the rule we want to have higher priority.



For example anchor tag with inline CSS:


<a href="http://goo.gl/DnIh3A" style="background-color: #389abe; border: 1px solid red;">Angular JS

and we want to override background color in type selector rule than we use:

a {  
  border:5px dotted green;
  background-color: yellow !important; 
}  
See Demo here

If two different Selectors or CSS styles placement contains the !important than priority will be according to above given conditions.

Learning AngularJS; Guide for beginners:

Saturday, May 10, 2014

Learning AngularJS Part 5: Routing or Views Switching

Here is Previous Part of this series:

So here we are with fifth part of the series, In previous article we see modularity and controller, config, factory of an AngularJS application. In this post we going to see routing or views switching in more details.


Why we need Routing?

First question here is why we need routing as we are working on Single Page Application (SPA). Answer is simple! yes we are working on SPA but user friendly URLs really help in reaching correct page instantly, it also help when your user bookmarks a particular view.

If we have our site http://www.example.com and we are showing the same URLs for all of our page then if user bookmark this URL, on next visit he will again the same URL now your application really not know what user is expected view so application will show home page which is not user friendly way.

Instead this if we show http://www.example.com/aboutus or http://www.example.com/order etc and attach these URL in your application to a particular view templates than it is really helpful and user-friendly.

So routing actually give a logical name to your application's views and bind them to a particular controller.

Routing URL - views and cotrollers
Routing -Views

How to route in AngularJS?

In previous post we have seen a bit of routing using ngRoute, but in this post we will see routing with UiRouter because UI Router is more powerful and is updated with more advanced feature along with basic functionality ngRoute provide, like Nested Views, multiple named view etc.

For setting routing, Firstly we nee uiRouter library you can download it from here or can use CDN hosted library then we need to add directive ng-view to the main (index.html) view.

<html ng-app="myDemoApp">
  <head>
    
    
  </head>
  <body>
     
      Home About Us Contact US
</body> </html>


It work as a placeholder where all the html will be injected on a fly when particular url will be hit. For instance when user navigate to /#AboutUs , the view linked with AboutUs route will be injected to this placeholder, similarly other route will works.


Now we need add routes to config so we can associate views to urls and also while routing to views we pass the controller to the views.

//here we need to inject ui.router as we using it for routing
var myDemoApp = angular.module('myDemoApp', ['ui.router']);

//$stateprovider is the service procided by ui.router
myDemoApp.config(['$stateProvider', function ($stateProvider) {

//create route object
    
    var home= {
        url: '/home',
        templateUrl: 'views/Home.html',
        controller: 'HomeCtrl'
    },
    aboutUs= {
        url: '/aboutus',
        templateUrl: 'views/AboutUs.html',
        controller: 'AboutUsCtrl'
    },
    contactUs= {
        url: '/contactus',
        templateUrl: 'views/ContactUs.html',
        controller: 'ContactUsCtrl'
    };

//Now add these route state privider

    $stateProvider
       .state('home', home)
       .state('aboutus', aboutUs)
       .state('contactUs', contactUs);
}]);


Now we add our views and place them in app/views/ folder also we need to add controllers to application module, if we do not need any controller like we just need to show some view which has nothing to show from controller then we can remove controller from above given object but usually each view has some controller to communicate. we can add controller like we have seen in previous post.

myDemoApp.controller('HomeCtrl', function ($scope) {
    $scope.message = 'Hello! we are on Home Page';
})
.controller('AboutUsCtrl', function ($scope) {
    $scope.message = 'Hello! we are on About Us Page';
})
.controller('ContactUsCtrl', function ($scope) {
    $scope.message = 'Hello! we are on Contact Us Page';
});

Now add three html files in views folder in app directory for each route and add html required in each view.

{{message}}

Now we have added everything we needed, save all files and try accessing url application with above configured urls. It must render particular views on different routes.

Master Pages in AngularJS

Master Page is the concept used in ASP.NET, It  is the base templates where we put all the common functionality which we need to show on all the pages, so instead repeating same code on all page we create a base page where we code required html, and inherit all pages from this base. Now all pages start showing within this template. These common views can be site log, top navigation, sidebar, logged in user information, footer etc.

We can also achieve this Master Page concept in AngularJS. Lets see it with an example:


Here in above example there are four different layers of views:
  1. Main View with Primar Navigation (Nav Link 1, Nav Link 2 ....)
  2. Second Level View with Sub-Navigation (One, Two, Three ...)
  3. Third Level View with Side Navigation (link1, link2, link3)
  4. Most inner View with content

To achieve this we define a hierarchy of routes.

For example:

  • /#NavLink1/One/Link1
  • /#NavLink2/One/Link1
  • /#NavLink1/Two/Link1
  • /#NavLink1/Two/Link2

and similarly for all other pages.


angular.module('demoMasterPage', ['ui.router'])
    .config(['$stateProvider', function ($stateProvider) {

    var NavLink1 = {
        //Name must be in format Parent.Child
        name: 'NavLink1',   
        url: '/Navlink1',
        templateUrl: 'views/Navlink1.html',
        controller: 'homeCtrl'
    },
    NavLink2 = {
        name: 'NavLink2',
        url: '/Navlink2',
        templateUrl: 'views/Navlink2.html',
        controller: 'homeCtrl'
    },
    NavLink3 = {
        name: 'NavLink3',
        url: '/Navlink3',
        templateUrl: 'views/Navlink3.html',
        controller: 'homeCtrl'
    },

    NavLink1One = {
        name: 'NavLink1.One',
        url: '/Navlink1/One',
        templateUrl: 'views/Navlink1/One.html',
        controller: 'homeCtrl'
    },
    NavLink1Two = {
        name: 'NavLink1.Two',
        url: '/Navlink1/Two',
        templateUrl: 'views/Navlink1/Two.html',
        controller: 'homeCtrl'
    },

   // similarly for NavLink1Three,NavLink1Four, NavLink2One, NavLink2Two and so on.

    NavLink1OneLink1 = {
        name: 'NavLink1.One.Link1',
        url: '/Navlink1/One/Link1',
        templateUrl: 'views/Navlink1/One/Link1.html',
        controller: 'homeCtrl'
    },
    NavLink1OneLink2 = {
        name: 'NavLink1.One.Link2',
        url: '/Navlink1/One/Link2',
        templateUrl: 'views/Navlink1/One/Link2.html',
        controller: 'homeCtrl'
    };
    //Similarly define all the combination you want to separate

   //add routes to stateProvider
    $stateProvider.state('NavLink1', NavLink1)
        .state('NavLink2', NavLink2)
        .state('NavLink3', NavLink3)
        .state('NavLink1.One', NavLink1One)
        .state('NavLink1.Two', NavLink1Two)
        .state('NavLink1.One.Link1', NavLink1OneLink1)
        .state('NavLink1.One.Link2', NavLink1OneLink2);
}])
.config(function ($urlRouterProvider) {
    
    //set default page to redirect; if wrong route is given redirect here    
    $urlRouterProvider.otherwise('/NavLink1/One/Link1');
});

Add different html pages for each views, If view contains a child view so we need to ng-view to that view, except level4 which has no further child views. Here is index.html:

<html ng-app="myDemoApp">
  <head>
    
    
  </head>
  <body>
     
     
</body> </html>

NavLink1 will be a template injected in main index.html so we donot need to wrap it in html,body tags, Here is NavLink1:


     

Similarly One will contain navigation and ng-view so it can redirect to child views. Create all the pages and save them in right places and then try your application in browser and see the impact of different routes.

This above example can be optimized in many ways which you will learn as you have more experience in working with AngularJS

So hope now you have clear picture of routing in AngularJS if you have any confusion, question, suggestion or feedback please comment.

Here is Previous Part of this series:

Tuesday, May 6, 2014

Learning AngularJS Part 4: Modular Design of AngularJS Application

Here is Previous Part of this series:

So here I am with the fourth article in the series of Learning AngularJS a guide for beginners. If you have not read the previous articles I recommend you to read in sequence, it will help you in understanding more quickly. In this post we will see the modularity of AngularJS Application.

Before starting the real topic we need to see SPA (Single Page Application).

So what is SPA?

Single Page Application (SPA) or also called Single Page Interface (SPI) is a web application in which we have only one main view which is able to load many small pages on a fly, providing enhanced desktop application like fluid user experience.

Traditional web application gives a blink and load impact when we route from one page to another while in SPA we load a main page on first time then we never post back completely instead we load partial or small HTML pages which make it faster and give it a better user experience.

AngularJS application are Single Page Application, we have a main container page index.html load on first go then we only load the views which we required. To load the view at run-time we need to handle routing which is one of the main SPA concepts.

In the previous post we see the directives, filters and data bindings, so now we will see AngularJS as a complete module and how controller, model views, directives, routes actually fit into this module.

Module (AngularJS Application)


we define module for our application as:


<html ng-app="moduleName" > 

and in JavaScript we create an object for our module as:

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

Defining ng-app on html  tag will create a scope for angular application to the HTML and within this HTML scope angular directives , filters and data bindings will work. Since we are working on SPA application so having ng-app on html tag will scope whole application because when this page gets loaded then we not actually loading another page instead we loading partial views which get renders within this main page.

Now we have define the module for our application now we need to add config, controllers, directive, services to our module. Module in actually a container in which we bundle all of our same functionality.

Different module can also interact with each other. If you noticed the empty array passed to the module function with module name is the dependency injection we discussed in our first post. Here we can inject helping module or the module our application depends on. Like for route management we have many already written module available, we just need to pass the module object to our module and then we can use it within our application. We can define multiple modules:

// Define sub modules with no dependencies
angular.module('AccountApp', []);
angular.module('LoginApp', []);

// define main module and inject all other modules as dependencies
angular.module('MainApp', [
    'AccountApp',
    'LoginApp']);

Firstly we set config to our application module in which we can configure routing (we will see in details later). For this we just need to set config in module object.

//we passed ngRoute is an external module for handling routing
var moduleName = angular.module('moduleName', ['ngRoute']);

moduleName.config(function ($routeProvider) {
  $routeProvider

   // route for the home page
   .when('/', {
    templateUrl: 'pages/home.html',
    controller: 'mainController'
  });

}); 

If you noticed here we also passed the controller to the view previously we declare the controller for a view within the view but that is not a recommended way as we said in Model View Controller view should be independent of controller so it must not be dependent on controller, so better way is to pass controller to view on the fly when we routing to view.

Now View has the controller scope so it can access the scope variables of controller. We also need to add controller to our application module, for this we simple need to add controller to main module object.

 // create the controller and inject Angular's $scope
moduleName.controller('mainController', function ($scope) {
    // create a message to display in our view
    $scope.message = 'Hello friend I am Main Controller';
});
and the view for home page will look like:

<!-- home.html -->
<div class="content">
        <h1>First Application</h1>
    <p>{{ message }}</p>
</div>

Here in this simple application we do not required a service or factory but in application when we interacting with APIs then we need to create factory [or services, provider, value]. These four are for same things with some different features. As we might need to get User data from server using AJAX calls and we may need it in five different controllers so instead of repeating the same code for fetching user's data in controllers we move this to User Service and then call this service from different controllers.

We can define factory to our application using:

moduleName.factory('MyService', function () {

    var factory = {};

    factory.getUser = function () {
        //..
    }

    return factory;
});

So lets review a complete cycle of angular application. Our application is a single module. It has configured routes when a particular URL get hit, it will be routed to specific View and Controller is also passed to the view at routing. Now View has the scope access of particular controller. It will call the controller for data. Controller will hit the service for data and service will send back data to controller fetching it from server. Controller pass that data to View and View render it accordingly.

So It was concept of modularity in AngularJS application. If you have any confusions or feedback or If you want to see any particular topic regarding AngularJS in this series please comment below.

Here is Previous Part of this series:
Life insurance policy, bank loans, software, microsoft, facebook,mortgage,policy,