Tuesday, February 16, 2016

Grunt: sass, scss, autoprefixer, cssmin, and watch Notes with Sample Files

Example Gruntfile.js

module.exports = function(grunt) {
    'use strict'

    var processdate = (new Date).toString();

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        //Watch objects
        //----------------------------------
        watch: {
            scripts: {
                files: ['scss/**/*.scss'],
                tasks: ['sass','autoprefixer','cssmin'],
                options: {
                    interval: 500,
                    spawn: false
                }
            }
        },

        sass: {
            options: {
                includePaths: require('node-bourbon').includePaths,
                outputStyle: 'nested',  // Values: 'nested', 'compressed'
                precision: 3,
                sourceMap: true, // Without this being true the resulting map file isn't linked at the bottom of the generated .css file
                sourceMapEmbed: false,
                sourceComments: false
            },
            dist: {
                files: {
                    'global.css': ['scss/master.scss']
                }
            }
        },

        //Plugins
        //----------------------------------
        autoprefixer: {
            options: {
                browsers: ['last 2 versions'],
                cascade: false,
                map: {
                    prev: false,
                    inline: false,
                    annotation: false,
                    sourcesContent: false
                }
            },
            multiple_files: {
                src: 'global.css',
                dest: 'global.css'
            }
        },

        cssmin: {
            add_banner: {
                options: {
                    banner: '/* Author: **Your Name\n * Created: 2016-02-16\n * Last Updated: '+processdate+'\n */'
                },
                files: {
                    'global.min.css': ['global.css']
                }
            }
        }

    });


    //Load NPM Tasks
    //----------------------------------
    grunt.loadNpmTasks ('grunt-contrib-watch');
    grunt.loadNpmTasks ('grunt-sass');
    grunt.loadNpmTasks ('grunt-autoprefixer');
    grunt.loadNpmTasks ('grunt-contrib-cssmin');


    grunt.registerTask('default', ['sass','autoprefixer','cssmin']);
    grunt.registerTask('c', ['sass']);  // c=compile
    grunt.registerTask('w', ['watch']);

};


Example package.json:

{
    "name": "grunt",
    "version": "0.1.1",
    "private": true,
    "devDependencies": {
        "grunt": "latest",
        "grunt-autoprefixer": "latest",
        "grunt-contrib-cssmin": "latest",
        "grunt-contrib-watch": "latest",
        "grunt-sass": "latest",
        "node-bourbon": "latest"
    }
}


Example master.scss:

// Manually list all files to be included in specific order, skip .scss extensions
@import "./fonts";
@import "./variables";
@import "./base";
@import "./layout";
@import "./partials";
@import "./global";


And then command line:

$ npm update
$ npm install
$ grunt
$ grunt w



That's it.

Better JS functions than previous attempts at similar functionality

Some code notes for later reference:


A better number formatting function:
            function toDecimal (number) {  // CREDITS: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString
                return number.toLocaleString("en-US",{ style: 'decimal', minimumIntegerDigits: 1, maximumFractionDigits: 2, minimumFractionDigits: 2 });
            };



A better currency format function:
            function toDollar (number) {  // CREDITS: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString
                return number.toLocaleString("en-US",{ style: 'currency', currency: 'USD' });
            };



I've always wanted a good one of these:
            function guid () {  // CREDITS: http://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
                function s4() {
                    return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
                }
                return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
            };


Saturday, January 23, 2016

Native HTML5 Ternary Checkbox - With Labels!

I worked through creating a html ternary checkbox (a checkbox with a tertiary option) this morning - with labels! Woohoo!

Now that we can create a third option we need to tell the user what it means, so we probably need labels.

Here are some images of the results on-screen:





Given a checkbox like this:

<input id="example" name="example" type="checkbox" class="ternaryCheckbox" value="1" />

We can use the default 'Yes', 'No', 'All' options with this HTML:

<input id="example" name="example" type="checkbox" class="ternaryCheckbox" value="1" />
<span class="ternaryLabelsYesNoAll"></span>


OR, use custom labels:

Show Archived: <input id="example" name="example" type="checkbox" class="ternaryCheckbox" value="1" />
<span class="ternary-option checked">Active Only</span>
<span class="ternary-option unchecked">Archived Only</span>
<span class="ternary-option alternate">All Records</span>


We add this JS to attach the handler and the function to run the ternary checkbox:

$(document).ready(function(){
    $(":checkbox.ternaryCheckbox").on("click",ternaryCheckbox);
});

function ternaryCheckbox(e){
    var $t = $(this),
        that = this,
        originalVal = $t.val(),
        checkedVal = originalVal,
        alternateVal = ($t.data("ternary") != undefined ? $t.data("ternary") : 2);
    // This should only be undefined the first time to cache the original value
    if ($t.data("primary") == undefined) {
        $t.data("primary",checkedVal);
    } else {
        checkedVal = $t.data("primary");
    }
    // if 'un-checking', and NOT in tern state, go to tern state, else normal checked or unchecked
    if($t.prop("checked")==false && $t.prop("indeterminate")==false && originalVal!=alternateVal) {
        $t.val(alternateVal);
        $t.prop("checked",true);
        $t.prop("indeterminate",true);
    } else {
        $t.val(checkedVal);
        $t.prop("indeterminate",false);
    }
};


Here is the Raw CSS:

.ternaryCheckbox ~ .ternaryLabelsYesNoAll {
    display: inline-block;
    font-weight: 100;
    margin-right: 21px;
    position: relative;
    width: 1px;
}
.ternaryCheckbox ~ .ternaryLabelsYesNoAll:after {
    content: "No";
    display: inline-block;
}
.ternaryCheckbox:checked ~ .ternaryLabelsYesNoAll:after {
    content: "Yes";
}
.ternaryCheckbox:indeterminate ~ .ternaryLabelsYesNoAll:after {
    content: "All";
}

.ternaryCheckbox ~ .ternary-option {
    display: inline-block;
    font-weight: 100;
    min-width: 22px;
}
.ternaryCheckbox ~ .ternary-option.alternate, .ternaryCheckbox ~ .ternary-option.checked {
    display: none;
}
.ternaryCheckbox:checked ~ .ternary-option.checked {
    display: inline-block;
}
.ternaryCheckbox:indeterminate ~ .ternary-option.checked, .ternaryCheckbox:checked ~ .ternary-option.alternate, .ternaryCheckbox:checked ~ .ternary-option.unchecked {
    display: none;
}
.ternaryCheckbox:indeterminate ~ .ternary-option.alternate {
    display: inline-block;
}



Here is the Sass CSS:

/* Ternary Checkbox and Option Labels */

/* Using default 'No', 'Yes', 'All' default labels:
    <input id="example" name="example" type="checkbox" class="ternaryCheckbox" value="1"<? if (local.example != 0)> checked</?><? if (local.example == 2)> indeterminate</?> />
    <span class="ternaryLabelsYesNoAll"></span>
    // Nothing else is needed, CSS does the rest.
*/
.ternaryCheckbox {
    ~ .ternaryLabelsYesNoAll {
        display: inline-block;
        font-weight: 100;
        margin-right: 21px;
        position: relative;
        width: 1px;
        &:after {
            content: 'No';
            display: inline-block;
        }
    }
    &:checked  {
        ~ .ternaryLabelsYesNoAll:after {
            content: 'Yes';
        }
    }
    &:indeterminate ~ .ternaryLabelsYesNoAll:after {
        content: 'All';
    }
}


/* Using custom ternary labels:
    <input id="example" name="example" type="checkbox" class="ternaryCheckbox" value="1"<? if (local.example != 0)> checked</?><? if (local.example == 2)> indeterminate</?> />
    <span class="ternary-option checked">Checked</span>
    <span class="ternary-option unchecked">Unchecked</span>
    <span class="ternary-option alternate">Alternate</span>
*/
.ternaryCheckbox {
    ~ .ternary-option {
        display: inline-block;
        font-weight: 100;
        min-width: 22px;  /* Override this if longer values are being used, inline style is fine */
        &.checked,
        &.alternate {
            display: none;
        }
    }
    &:checked {
        ~ .ternary-option.checked {
            display: inline-block;
        }
        ~ .ternary-option {
            &.unchecked,
            &.alternate {
                display: none;
            }
        }
        &:indeterminate ~ .ternary-option {
            &.checked {
                display: none;
            }
            &.alternate {
                display: inline-block;
            }
        }
    }
}

-GBuilt

[This solution is completely open source, absolutly free to use without any restriction. Please give creative to this blog post URL.

Saturday, January 9, 2016

Setting up a new NodeJS Server

The following is on Ubuntu, you may have slightly different default location or bash script names to edit on different Linux disros.


Install Node Version Manager (NVM):
First make sure the prerequisites are ready:

$ sudo apt-get update
$ sudo apt-get install build-essential libssl-dev
 
Now for the actual install command:
 $ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.30.1/install.sh | bash 


Then I did some additional moving around. It automatically puts things in the users folder. I wanted them globally:
$ sudo mkdir /etc/nvm
$ sudo mv ~/.nvm/* /etc/nvm/
Then change the initialization so it's for all users:

$ sudo vim /etc/bash.bashrc
Add this to the bottom:
export NVM_DIR="/etc/nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"  # This loads nvm

Then remove/comment-out the old script location in your user bash:

$ vim ~/.bashrc
Remove or comment-out these two lines - should be at the very bottom:
#export NVM_DIR="/home/ubuntu/.nvm"
#[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"  # This loads nvm

2. Logout and log back in again, then test if it's working:

$ nvm  [enter]
That should return a list of possible commands + options for using NVM, like this  [truncated]:


Node Version Manager

Note: refers to any version-like string nvm understands. This includes:
  - full or partial version numbers, starting with an optional "v" (0.10, v0.1.2, v1)
  - default (built-in) aliases: node, stable, unstable, iojs, system
  - custom aliases you define with `nvm alias foo`

Usage:
  nvm help                                  Show this message
  nvm --version                             Print out the latest released version of nvm
  nvm install [-s]                 Download and install a , [-s] from source. Uses .nvmrc if available
...
...
...

3. Now install the latest stable version of node:

$ nvm install stable

Then check the install:

$ nvm ls
That should display something like this:
->       v5.4.0
node -
> stable (-> v5.4.0) (default)
stable -
> 5.4 (-> v5.4.0) (default)
iojs -
> N/A (default)

4. Then set the default engine so it works forever (not sure why this isn't set my default if not set):

$ nvm alias default stable

Check it:

$ nvm ls
That should display something like this:
->       v5.4.0
default -
> stable (-> v5.4.0)
node -
> stable (-> v5.4.0) (default)
stable -
> 5.4 (-> v5.4.0) (default)
iojs -
> N/A (default)



Install Git:

1. Command line with apt-get:

$ sudo apt-get install git

2. Now make the command prompt show the current branch name whenever you are in a git repo directory:

$ sudo vim /etc/profile

Then add the following to the end of the file:

#Show the Current GIT Branch -- if GIT is initialized
function parse_git_branch {
  git branch --no-color 2
> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
function proml {
    local        BLUE="\[\033[0;34m\]"
    local         RED="\[\033[0;31m\]"
    local   LIGHT_RED="\[\033[1;31m\]"
    local       GREEN="\[\033[0;32m\]"
    local LIGHT_GREEN="\[\033[1;32m\]"
    local       WHITE="\[\033[1;37m\]"
    local  LIGHT_GRAY="\[\033[0;37m\]"

    PS1="\u@\h \$(date +%b%d@%I:%M:%S%p) \w$RED\$(parse_git_branch)$GREEN\$ "
    PS2='
> '
    PS4='+ '
}
proml

mesg n



Set up your nodejs website:

1. Make the /var/www/ web directory with proper owners and permissions

$ cd /var
$ sudo mkdir www
$ sudo chown -R [your-username]:[your-username] www

2. Create a folder for each website:

$ mkdir [website-name]
$ cd [website-name]

3. Clone your git repo into the current directory (don't forget the period at the end)

$ git clone .



That's it!