Anh Trinh JavaScript Developer

Stop Whining About New JS Frameworks

I think there’s a lot of misplaced irritation regarding the abundance of new JavaScript frameworks. It seems like many developers just want someone to tell them how to build web apps. The number of options is overwhelming, and they just want to make something. I can completely understand how it can be frustrating to choose something and get started.

Here’s my advice:

Abandon the notion that there’s a “right framework,” and just choose one and get hacking. It’s likely that any framework you choose won’t be actively maintained in a year. It’s likely that any framework you choose will anticipate 95% of the things you want to do, but handle the rest a bit less gracefully. There is no clear winner for absolutely all use cases, and there will likely never be.

Don’t “learn Backbone.js.” For that matter, don’t “learn” any other framework. Learn the philosophy behind it. The architecture is much more important than the API. Learn how the framework makes you more productive. Many of these frameworks are conceptually similar, but maybe add a new feature or account for some specific use case. Some have strong opinions, some don’t. Use and read about as many different frameworks as you can. Figure out what their opinions are, and form your own. Write about your experiences.

The web development scene is going through a seriously awesome renaissance. We finally have bigger, more reliable building blocks to make things. There are lots of smart people with interesting and vastly different ideas on ways to group these pieces together to make yet larger blocks. Enjoy and appreciate this renaissance. Better yet, participate in it.

Source: BrianFord

Add Select Box feature to Twitter Bootstrap Dropdown

Twitter Bootstrap comes with a very nice Javascript Plugin for Dropdown. What you just need to do is mark up the HTML, include the bootstrap.js and you’ll have a nicely dropdown working.

I guess a lot of you had ever wanted that Dropdown acts like a selectbox, which means when you click to a menu item, that item will be selected, and the dropdown will be updated with that value.

There is already a great plugin outthere:bootstrap select, which has a full featured set of what a Modern Selectbox should do. It also support you to search the options by passing data-live-search="true" to the markup.

This plugin convert a selectbox into a dropdown, which leads to these that you might not like:

  • In an application where the HTML are rendered before the scripts running, user will first see the default selectbox when openning the page

  • It is hard for us to customize the output of a selectbox. What if we want to achive this kind of button? http://getbootstrap.com/components/#btn-dropdowns-split It is just a different markdown for bootstrap’s dropdown.

I want something work similar, but simpler. So i decided to extend the existing bootstrap dropdown plugins to add the select box behavior:

(function ($) {

    var Dropdown = $.fn.dropdown.Constructor;
    var toggle   = '[data-toggle="dropdown"]';

    var getParent = function ($this) {
        return $this.parent();
    };

    var select = function(e) {
        if (event.type === 'keydown' && !/13/.test(e.which)) return;

        var $this = $(this);

        e.preventDefault();
        e.stopPropagation();

        if ($this.is('.disabled, :disabled')) return;

        var $parent  = getParent($this);
        var isActive = $parent.hasClass('open');

        var desc = ' li:not(.divider):visible a';
        var $items = $parent.find('[data-select="true"]' + desc);

        if (!$items.length) return;

        var index = $items.index(e.target);

        var $selected = $items.eq(index);
            selectedText = $items.eq(index).text();

        //previous selected
        var $previousSelect = $this.find('.selected');

        if (!$selected.hasClass('selected')) {
            $selected.parent('li').addClass('selected');
            $parent.find('.btn').first().text(selectedText);

            $previousSelect.removeClass('selected');
        }

        //focus to the selectbox after select
        $parent.find(toggle).dropdown('toggle').trigger('focus');

        //trigger the event
        $parent.trigger(e = $.Event('selected.bs.dropdown', {relatedTarget : this}));
    };

    $.extend(true, Dropdown.prototype, {select: select});

    $(document)
        .on('keydown.bs.dropdown.data-api', '[data-select="true"]', Dropdown.prototype.select)
        .on('click.bs.dropdown.data-api', '[data-select="true"]', Dropdown.prototype.select);

})(jQuery);

What does the code do?

  • First it introduce a new data attribute: data-select="true" on the .dropdown-menu list

  • It bind a special handler called select to the keydown & click event on the [data-select="true"]

  • This way, the original plugin will be kept untouched. Also its behavior. You only add the new functionality when you wanted

Usage & Contribution

I’ve created a Github repository for it. Please come and have a look. If you have any idea to improve it, don’t hesitate to fork it.

Cheers.

Bootstrap 3 Tips and Tricks

##Optionally Remove the Gutter Padding from Columns

Bootstrap lets you customize and compile your own build based on your needs. This is anything from colors, container sizes, and to gutter padding size. However, sometimes you’ll come across an instance where you just want a single row with no padding. Most cases you’ll just individually select the column and kill off the padding with CSS. However, you can build your own utility class helper to do this on the fly. This utility class will cover all column sizes and still supports full responsiveness. Here’s the CSS snippet:

.no-gutter > [class*='col-'] {
    padding-right:0;
    padding-left:0;
}

And here’s how you can use it in your HTML:

<div class="row no-gutter">
    <div class="col-md-4">
        ...
    </div>
    <div class="col-md-4">
        ...
    </div>
    <div class="col-md-4">
        ...
    </div>
</div>

##Custom Container Sizes

Like it or not, sometimes you’ll be working on a design that doesn’t follow a grid system or a designer who likes to push the boundaries farther and use different grid column sizes on different rows throughout a page and / or site. Bootstrap columns automatically fill to it’s parent container. So if you need a smaller container or a larger container, you can easily extend the Bootstrap core and make your own container classes. Here’s an example:


@media (min-width: 768px) {
    .container-small {
        width: 300px;
    }
    .container-large {
        width: 970px;
    }
}
@media (min-width: 992px) {
    .container-small {
        width: 500px;
    }
    .container-large {
        width: 1170px;
    }
}
@media (min-width: 1200px) {
    .container-small {
        width: 700px;
    }
    .container-large {
        width: 1500px;
    }
}

Now the only thing you need to worry about is overflow issues if say a container you made is larger then the device window. For example with the .container-large class, if a user has a browser window of 1200px, it will create this nasty overflow issue. Here’s the fix for that.

.container-small, .container-large {
    max-width: 100%;
}

##Use Heading Classes to Save Time and Stay Semantic

A design sometimes will have elements that don’t always match best practice for having semantic markup. What I mean by this is usually your h1 tag is followed by an h2 and so on. This isn’t necessarily a bad thing when this happens, it’s just something to watch out for because at the end of the day, one of the most important things to make sure of is that your markup is structured in a way that is friendly to read for Google and other Bots.

You can swap out Headings styles with different classes. Take a look at the example code below to see it in action:

<h1 class="h2">Heading 1 that looks like Heading 2</h1>
<h2 class="h4">Heading 2 that looks like Heading 4</h2>
<h3 class="h1">Heading 3 that looks like Heading 1</h3>

##Responsive Video Embeds that Maintain Aspect Ratio When Bootstrap 3.2 came out, it came out with an additional helper class to make it easier to make iframes (like YouTube embeds) responsive while maintaining a certain aspect ratio. It’s extremely easy to use these, just add the following code to your markup:

<!-- 16:9 aspect ratio -->
<div class="embed-responsive embed-responsive-16by9">
    <iframe class="embed-responsive-item" src="//www.youtube.com/embed/ePbKGoIGAXY"></iframe>
</div>

<!-- 4:3 aspect ratio -->
<div class="embed-responsive embed-responsive-4by3">
    <iframe class="embed-responsive-item" src="//www.youtube.com/embed/ePbKGoIGAXY"></iframe>
</div>

Notice how the iframe doesn’t include frameborder=”0”. This is because Bootstrap will actually normalize any ugly outlines for you with this helper class.

##Responsive Utility Classes Need a Display Property

With Bootstrap 3.2 being released, they updated the way responsive utility classes work. Normally you would just assign .visible-xs, .visible-sm, .visible-md, and .visible-lg to hide or show certain elements at different device widths. Now, you actually have to specify a “state” as well of either block, inline, or inline-block. This maximizes your control, but if you’re confused on which on to use, just use block. Here’s some examples:

/* With * being xs, sm, md, or lg */
.visible-*-block {}
.visible-*-inline {}
.visible-*-inline-block {}

##Extend the Class, Don’t Override It I often see front-end code where developers completely override Bootstrap styles to customize buttons and other elements rather than extending the existing classes. This gets messy real fast. It’s much easier to maintain if you just extend the existing classes. For example, let’s make a completely flat and yellow button called .btn-yellow to demo the principle.

.btn-yellow {
  background: rgb(250, 255, 140);
  color: #574500;
  border: none;
  -moz-box-shadow: none !important;
  -webkit-box-shadow: none !important;
  box-shadow: none !important; /* !important tags aren't necessarily always bad */
}
.btn-yellow:hover, .btn-yellow:focus {
  background: rgb(252, 255, 179);
}
.btn-yellow:active {
  background: rgb(247, 255, 71);
}

This way you can still use things like .btn-lg or .btn-block to customize your buttons. Now, I’ll also make a class called .btn-xxl:

.btn-xxl {
  padding: 20px 26px;
  font-size: 35px;
  border-radius: 8px;
}

Building a base CSS by extending the classes can prove to be extremely helpful in the long run and can really speed up your front-end development.

##* { box-sizing: border-box; } My favorite thing about Bootstrap 3 versus 2 is that it adopted the new box-sizing: border-box property for all elements and pseudo-elements (:before and :after). This might be more obvious to some, but what this does is changes the way the CSS box-model works. When this is enabled the width and height properties include the padding and border, but not the margin. In laymen terms, if you add padding, your element isn’t going to grow in size. Instead, the element’s contents gets pushed closer and closer towards the center of the box.

Bootstrap 2 didn’t use this method, and I imagine people people who recently switch will be thrown off by this since it goes against how most people are taught CSS in the first-place. After you get used to it though, it starts to make responsive web development a lot easier and will probably be your new default even without Bootstrap. I think the idea to do it this way was first introduced by Paul Irish from this post.

##Your Respond.js include might be all wrong

Respond.js is is an excellent polyfill for bringing media queries to legacy browsers (for this case, getting Bootstrap 3 to work with IE8). Making sure that respond.js is even actually working will make your cross-browser tests much easier. I learned that Respond.js can fail based on two things:

  1. Where it is located in the document
  2. If you’re loading your styles from a CDN

###Load respond.js after your CSS If for whatever reason you are loading respond.js before your styles, this will cause the polyfill to fail. You need to load respond.js after your styles. If you have inline styles, respond.js should technically be loaded after that as well.

###A CDN can create cross-domain errors Respond.js works by requesting a copy of your CSS via AJAX. If you have your CSS on a different domain, such as a CDN, per security settings of browsers, it won’t be able to load the CSS assets. It’s recommended that you create a proxy-page to enable cross-domain communication. You can read about doing that at their official docs. The quickest and easiest solution though is to just host the Bootstrap 3 assets and the Respond.js assets yourself (don’t use a CDN). This is a quick an easy fix that would work for most people. You should evaluate the pros and cons of ditching the CDN for your specific project since using the CDN has obvious performance benefits.

Source: scotch.io

My favourite Modules Pattern & JQuery Plugin boilerplates

###The Reavealing Module Pattern

    //define your app's namespace
    var app = app || {};
    
    //your module inside 'app' namespace
    var app.myModule = (function ($) {

        // 'this' refers to global window

        //private variable
        var secret = {
        	message: 'I am pretty awesome'
        };
        
        //private function
        var _tellTheSecret = function() {
        	return secret.message;
        }
        
        //public function
        function init() {
        	//init the module base on the present of the element on the page
            
            if ($('#some-element').length) {
            
            	//your initialize code here
                //...
            }
        }
		
        // variables and functions private unless attached to API below
        // define the public API
        var API = {};
        API.init = init;

        return API;
    }(jQuery));

###JQuery Plugin Boilerplate

    ;(function($) {
        // wrap code within anonymous function: a private namespace

        // replace 'MyPlugin' and 'myplugin' below in your own plugin...

        // constructor function for the logical object bound to a
        // single DOM element
        function MyPlugin(elem, options) {

            // remember this object as self
            var self = this;
            // remember the DOM element that this object is bound to
            self.$elem = $(elem);

            // default options
            var defaults = {
                msg: "You clicked me!"
            };
            // mix in the passed-in options with the default options
            self.options = $.extend({}, defaults, options);

            // just some private data
            self.count = 1;

            init();

            // initialize this plugin
            function init() {

                // set click handler
                self.$elem.click(click_handler);
            }

            // private click handler
            function click_handler(event) {
                alert(self.options.msg + " " + self.count);
                self.count += 1;
            }

            // public method to change msg
            function change_msg(msg) {
                self.options.msg = msg;
            }

            // define the public API
            var API = {};
            API.change_msg = change_msg;
            return API;
        }

        // attach the plugin to jquery namespace
        $.fn.myplugin = function(options) {
            return this.each(function() {
                // prevent multiple instantiation
                if (!$(this).data('myplugin'))
                    $(this).data('myplugin', new MyPlugin(this, options));
            });
        };
    })(jQuery);

AngularJS - Differences between the service(), factory(), and provide() methods

In Angular, services are singleton objects that are created when necessary and are never cleaned up until the end of the application life-cycle (when the browser is closed). Controllers are destroyed and cleaned up when they are no longer needed.

This is why we can’t dependably use controllers to share data across our application, especially when using routing

Services are designed to be the glue between controllers, the minions of data, the slaves of functionality, the worker-bees of our application.

###3 ways to creat a service in AngularJS

###factory() The factory() method allows us to define a service by returning an object that contains service functions and service data. The service definition function is where we place our injectable services, such as $http and $q.

  angular.module('myApp.services')
  	.factory('User', function($http) { // injectables go here
        var backendUrl = "http://localhost:3000";
        var service = {
          // our factory definition
          user: {},
          setName: function(newName) { 
          service.user['name'] = newName; 
          },
       	  setEmail: function(newEmail) {
            service.user['email'] = newEmail;
          },
          save: function() {
            return $http.post(backendUrl + '/users', {
            	user: service.user
          	});
          }
        };
        return service;
});

####Using the factory() in our app It’s easy to use the factory in our application as we can simply inject it where we need it at run-time

    angular.module('myApp')
    .controller('MainCtrl', function($scope, User) {
      $scope.saveUser = User.save;
    });

####When to use the factory() method The factory() method is a great choice to use to build a factory when we just need a collection of methods and data and don’t need to do anything especially complex with our service.

We cannot use the factory() method when we need to configure our service from the .config() function.

###service() The service() method, on the other hand allows us to create a service by defining a constructor function. We can use a prototypical object to define our service, instead of a raw javascript object.

	angular.module('myApp.services')
    .service('User', function($http) { // injectables go here
      var self = this; // Save reference
      this.user = {};
      this.backendUrl = "http://localhost:3000";
      this.setName = function(newName) {
        self.user['name'] = newName;
      }
      this.setEmail = function(newEmail) {
        self.user['email'] = newEmail;
      }
      this.save = function() {
        return $http.post(self.backendUrl + '/users', {
          user: self.user
        })
      }
    });

####Using the factory() in our app It’s easy to use the factory in our application as we can simply inject it where we need it at run-time

    angular.module('myApp')
    .controller('MainCtrl', function($scope, User) {
      $scope.saveUser = User.save;
    }); 

####When to use the service() method The service() method is great for creating services where we need a bit more control over the functionality required by our service. It’s also mostly guided by preference to use this instead of referring to the service

We cannot use the service() method when we need to configure our service from the .config() function.

###provide() The lowest level way to create a service is by using the provide() method. This is the only way to create a service that we can configure using the .config() function.

Unlike the previous to methods, we’ll set the injectables in a defined this.$get() function definition.

    angular.module('myApp.services')
    .provider('User', function() {
      this.backendUrl = "http://localhost:3000";
      this.setBackendUrl = function(newUrl) {
        if (url) this.backendUrl = newUrl;
      }
      this.$get = function($http) { // injectables go here
        var self = this;
        var service = {
          user: {},
          setName: function(newName) {
            service.user['name'] = newName;
          },
          setEmail: function(newEmail) {
            service.user['email'] = newEmail;
          },
          save: function() {
            return $http.post(self.backendUrl + '/users', {
              user: service.user
            })
          }
        };
        return service;
      }
    });

####Using the provider() in our app In order to configure our service, we can inject the provider into our .config() function.

    angular.module('myApp')
    .config(function(UserProvider) {
    UserProvider.setBackendUrl("http://myApiBackend.com/api");
    })

We can use the service in our app just like any other service now

    angular.module('myApp')
    .controller('MainCtrl', function($scope, User) {
      $scope.saveUser = User.save;
    });

####When to use the provider() method

The provider() method is required when we want to configure our service before the app runs. For instance, if we need to configure our services to use a different back-end based upon different deployment environments (development, staging, and production).

It’s the preferred method for writing services that we intend on distributing open-source as well as it allows us to configure services without needing to hard-code configuration data.

Source: ng-newsletter