Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Saturday, March 28, 2015

Sample Grunt.js file for your javascript project

Grunt is a well-known javascript task runner. To set up your project for development and production you can use grunt to automating few steps like creating css files from your LESS or SASS module, combining all your javascript files to a single one, compressing your javascript, etc.

In this post I am going to explain a sample gruntfile for javascript project, I am not covering CSS part of the project in this post.

Follow the below steps:


Create a project directory, for example learninggrunt

Navigate to learninggrunt directory in your command prompt/terminal.

Execute the following command:

npm init

The above command will ask you various question, for now just type yes in every option and leave it.

Now you will see a package.json file created in learninggrunt folder/directory.

Execute the following commands:

npm install grunt --save-dev
npm install grunt-contrib-clean --save-dev
npm install grunt-contrib-uglify --save-dev
npm install grunt-contrib-watch --save-dev
If above commands are successfully executed then create a gruntfile.js in learninggrunt directory.

The project folder structure you can create similar to this:



  
  • The 'dist' directory contains the uglified/minified/compressed javascript file along with it's map file.
  • The 'src' directory contains all your javascript source code
  • The 'lib' directory contains any library that  you are using in your current project, for example I am using AngularJS.


The content of gruntfile.js is below: 

module.exports = function(grunt) {
  grunt.initConfig({
    clean: {

      release: ["dist"]
    },
    uglify: {
      dev_target: {
        sources: {
          src: 'src/**/*.js'
        },
        options: {
          sourceMap: true
        },
        files: {
          'dist/main.js': ['lib/angular-1.3.15/angular.js', 'src/**/*.js']
        }
      },
      prod_target: {

        files: {
          'dist/main.js': ['lib/angular-1.3.15/angular.min.js', 'src/**/*.js']
        }
      }
    },
    watch: {
      files: ['<%= uglify.dev_target.sources.src %>'],
      tasks: ['uglify:dev_target']
    }
  });
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.registerTask('build_dev', ['clean', 'uglify:dev_target', 'watch']);
  grunt.registerTask('build_prod', ['clean', 'uglify:prod_target']);
};

Next you can run the build_dev or build_prod task like the below command under the learninggrunt directory:

grunt build_dev(For development release )

grunt build_prod(For production release)


After executing build_dev grunt task you will find main.js and main.js.map files:







The map file helps you to debug the javascript source code in browser.


After executing build_prod grunt task you will find only main.js file, you do not need a debugging feature in production environment.





So you can just send your 'dist' directory to production server or any module that is dependent on the feature you are developing. The main.js file contains all your javascript code which you have developed in 'src' folder along with required libraries.

Tuesday, June 3, 2014

dragging table rows in IE9

This post is regarding the rearranging rows in a table by doing drag and drop( my previous post Rearranging rows by Drag and Drop ). The reason it does not work in IE 9(Internet explorer version 9 ) is  because of  the browser does not support draggable attribute for tr tag. So to make the reordering work by drag and drop  is by adding and 'a' tag as the first column which basically work as an anchor to do drag the row.

As IE9 support draggable attribute on 'a' then the browser can understand and do drag the particular row.
In the help of polyphil we can detect the browser and add draggable attribute to the correct tag:

1: IE9:  a tag (<a draggable="true"></a>)
1: Other browsers(Chrome and Firefox):  tr tag(<tr draggable="true">)

Please check this fiddle to know how to check the browser version and accordingly make the required element draggable.

JSFiddle example

Wednesday, April 16, 2014

An angular table directive having reordering of rows feature by doing drag and drop

 I have created one table directive which has support for row reordering in drag and drop way.
 This table directive named as angTable uses two other directive draggable and droppable directive.

  Checkout the column reordering part

The angTable directive creates one table having column and rows derived from a configuration.This configuration is nothing but an object having two attributes 'head' and 'data'.

head: Array having the column header labels.
data:  Array having objects as rows

To add the drag and drop feature for the columns, draggable and droppable attribute directives have been used with their required parameters.Please check the readme.md file in the below Plunker link.

Note:To give feedback image while dragging occurs there are two other subtable in the directive where one table is on top of the other table using z-index.The top table coloring  scheme is white so that it can hide the table below it, that way the table which is at bottom in the layer having less z-index is hidden from the user but displayed to the browser, so when we drag any column of the actual table the below subtable is actually getting dragged.

http://plnkr.co/iy63pZ

Sunday, February 9, 2014

Introduction to Transclusion of directives in AngularJS

This is an introduction to the transclusion part of directives in AngularJS. In order to make it more simpler, I have created one directive:

http://plnkr.co/edit/T2hh9d?p=preview

which uses couple of key use cases(mentioned below) of transclusion.

ng-transclude:  Rendering transcluded content. 
transcludeFn:   Constructor Function to modify the transcluded content with or without new scope.

By definition transclusion is the inclusion of document or part of the document into another document by reference.(From Wikipedia)

In case of AngularJS transclusion is used in similar fashion but we have more control on the transcluded content. If you are creating a directive which basically acts as an wrapper for it's child contents, and the content can be anything.Then transclusion should be your approach.

 Consider the below directive:
    
<org-v-card>

    <h4>{{firstName}} {{lastName}}</h4>

    <h5>Designation: {{jobtitle}}</h5>

    <h5>Company: {{company}}</h5>

    <h5>Phn no: {{phn}}</h5>

    <h5>Email: {{email}}</h5>

</org-v-card>

In the above example org-v-card is an user defined directive which acts as wrapper for it's child contents(one h4 and four h5 elements ).

Lets look into the template part  of the org-v-card directive.

<div class="vcard">
    Quick Info:<span ng-transclude></span>
</div>

In the above example to access all the child content(In this example one h4 and four h5 elements) and to render  it we are using <span ng-transclude></span>. The directive ng-transclude provided by AngularJS renders the child contents of the parent directive(In this example org-v-card).

Lets look into the controller:

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

theApp.controller('myCtrl', function ($scope) {

  $scope.firstName = "Mike";
  $scope.lastName = "Logan";
  $scope.jobtitle = 'Consultant';
  $scope.company = 'BCA Corp.';
  $scope.phn = '080-22116677';
  $scope.email = 'mlogan@bca.com';
});


theApp.directive('orgVCard', ['$compile',
  function ($compile) {
    return {
      restrict: 'E',
      transclude: true,
      templateUrl: 'vcardtemplate.html',
      replace: true,
      link: function (scope, iele, attr, controller, transcludeFn) {
        /**        
         * Modify the  transcluded content with a new scope and return the cloned content        
       */     


   var modifyTranscludeContent = function (clonedelem, newscope) {

          newscope.firstName = "Jane";
          newscope.lastName = "King";
          newscope.jobtitle = 'Manager';
          newscope.company = 'BCA Corp.';
          newscope.phn = '080-22116678';
          newscope.email = 'jking@bca.com';
          clonedelem.scope = newscope;
          angular.element(clonedelem[0]).css('font-weight', 'bold')
            .css('color', 'red');
        };

        /**         
        * It shows the top most div        
        */        
        console.log(iele);
        /**         
         * Get the modified transcluded content      
         */        
        var transInstance = new transcludeFn(scope.$new(), modifyTranscludeContent;

        iele.append('Reports to:')
        /**         
         *Render the cloned content compiled with new scope values         
        */       
        iele.append(transInstance);


      }

    };

  }
]);

In the above script we are creating following scope variables:
 firstName, lastName, jobtitle, company, phn and email.

In the directive we are giving transclude:true, which means this directive can act as wrapper for it's child elements.

In the link function we are passing transcludeFn as an parameter, this function takes two parameters:

scope.$new: [Optional]A newly generated scope which is applicable only to the transcluded   content not to the directive.
modifyTranscludeContent:  This function(defined in the link function ) as defined above it accepts two parameters , clonedelement and the scope.

clonedelement :   The cloned element of the transcluded  content. Which  also get returned by the transcludeFn.
scope: The scope for the cloned elements.If no values  passed for this then the scope assigned to the directive will be considered as the value.

Inside  modifyTranscludeContent we are assigning different values to properties  of the scope passed to the  function  and assigning that scope to the clonedelement.

Consider the below line:

var transInstance = new transcludeFn(scope.$new(), modifyTranscludeContent);

transInstance is basically the cloned content after assigning the new scope to it. So now all the child content will render values which are assigned inside the transcludeFn.

In  the last line we are appending the cloned contents  to the parent directive.