Skip to content

Instantly share code, notes, and snippets.

@JaimeStill
Last active April 19, 2017 13:15
Show Gist options
  • Save JaimeStill/8e6094727b768c7fb47fce720e587cdd to your computer and use it in GitHub Desktop.
Save JaimeStill/8e6094727b768c7fb47fce720e587cdd to your computer and use it in GitHub Desktop.
Snippet notes related to JavaScript and JavaScript-based technologies

JavaScript

Contents

Back to Top

Importing 3rd Party Library as Variable

Make sure to install the libarary as a dependency, and if available, the typings:

npm install --save jquery @types/jquery

In the TypeScript component that will be using the library, import it as follows:

import * as $ from 'jquery';

back to top

Array.filter(function (x) { return x.selected === true; });

Polyfill

if (!Array.prototype.filter) {
    Array.prototype.filter = function (fun/*, thisArg*/) {
        'use strict';
        
        if (this === void 0 || this === null) {
            throw new TypeError();
        }
        
        var t = Object(this);
        var len = t.length >>> 0;
        if (typeof fun !== 'function') {
            throw new TypeError();
        }
        
        var res = [];
        var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
        for (var i = 0; i < len; i++) {
            if (i in t) {
                var val = t[i];
                
                if (fun.call(thisArg, val, i, t)) {
                    res.push(val);
                }
            }
        }
        
        return res;
    };
}

back to top

Module Registration

app.js

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

Directives

File Select Directive

fileSelect.js

(function () {
  var fileUpload = function () {
    return {
      restrict: 'EA',
      replace: true,
      templateUrl: 'file-select.html',
      scope: {
        selectOptions: '=',
        fileModel: '='
      },
      link: function (scope, element) {
        function updateFiles(files) {
          scope.fileModel.files = files;
        }
        
        var fileInput = element.find('input')[0];
        var fileSelect = element.find('input')[1];
        
        fileInput.addEventListener('change', function (e) {
          scope.$evalAsync(updateFiles(e.target.files));
        });
        
        fileSelect.addEventListener('click', function (e) {
          if (fileInput) {
            fileInput.click();
          }
          
          e.preventDefault();
        }, false);
        
        scope.$watch(function () { return scope.fileModel.files.length; },
          function (newValue, oldValue) {
            if (newValue !== oldValue) {
              if (newValue === 0) {
                angular.element(fileInput).val(null);
              }
            }
          });
      }
    };
  };
  
  app.directive('fileSelect', fileSelect);
}());

file-select.html

<div>
  <input type="file" multiple accept="{{selectOptions.accept}}" style="display: none" />
  <div class="input-group">
    <div class="input-group-addon">Select Files</div>
    <div class="input-group-btn">
      <input type="button" class="btn btn-primary" value="{{selectOptions.fileSelectText" />
    </div>
  </div>
</div>
Example Usage

See Web API Backend Here

demoSvc.js

(function () {
  var demoSvc = function ($http, $q) {
    var addFiles = function (files) {
      var deferred = $q.defer();
      
      $http({
        url: '/api/demo/addFiles',
        method: 'PUT',
        headers: { 'Content-Type': undefined },
        data: files,
        transformRequest: function (data) {
          var formData = new FormData();
          
          for (var i = 0; i < data.files.length; i++) {
            formData.append("file_" + i, data.files[i]);
          }
          
          return formData;
        }
      }).success(function () {
        deferred.resolve();
      }).error(function (err) {
        console.log(err);
        deferred.reject(err);
      });
      
      return deferred.promise;
    };
    
    return {
      addFiles: addFiles
    };
  };
  
  demoSvc.$inject = ['$http', '$q'];
  app.factory('demoSvc', demoSvc);
}());

demo.js

(function () {
  var demo = function (demoSvc) {
    return {
      restrict: 'EA',
      replace: true,
      templateUrl: 'demo.html',
      link: function (scope) {
        scope.fileModel = function () {
          var files = [];
          
          return {
            files: files
          }
        };
        
        scope.addFiles = function () {
          logSvc.addFiles(scope.fileModel.files).then(function () {
            scope.fileModel.files = [];
          });
        };
        
        scope.selectOptions = {
          accept: '*/*',
          fileSelectText: "Browse..."
        };
      }
    };
  };
  
  demo.$inject = ['demoSvc'];
  app.directive('demo', demo);
}());

demo.html

<div>
  <h2>File Select Directive Demo</h2>
  <hr />
  <file-select select-options="selectOptions" file-model="fileModel"></file-select>
  <h4>Pending Files</h4>
  <table class="table table-striped">
    <thead>
      <tr>
        <th>Name</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="file in fileModel.files">
        <td ng-bind="file.name"></td>
      </tr>
    </tbody>
  </table>
  <button class="btn btn-success" ng-click="addFiles()">Add Files</button>
</div>

Services

Service Pattern

(function () {
    var someSvc = function ($http, $q) {
        var
            someModel = {},
            someFunction = function (someData) {
                var deferred = $q.defer();
                
                $http({
                    url: '/api/someApiUrl',
                    method: 'POST',
                    data: someData
                }).success(function (data) {
                    someModel = data;
                    deferred.resolve(data);
                }).error(function (data) {
                    deferred.reject(data);
                });
                
                return deferred.promise;
            };
            
        return {
            someModel: someModel,
            someFunction: someFunction
        };
    };
    
    someSvc.$inject = ['$http', '$q'];
    someApp.factory('someSvc', someSvc);
}());

// Example Implementation
var someCtrl = function ($scope, someSvc) {
    $scope.model = someSvc.someModel;
    someSvc.someFunction().then(function (data) {
        // Promise succeeded
    }).catch(function (data) {
        // Promise failed
    }).finally(function (data) {
        // Do regardless of succeed or fail
    });
};

someCtrl.$inject = ['$scope', 'someSvc'];

Filters

dashify

AngularJS Filter that converts spaces into dashes for href and id attributes

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

(function () {
    var dashify = function () {
        return function (value) {
            return (!value) ? '' : value.replace(/ /g, '-');
        }
    };
    
    app.filter('dashify', dashify);
}());
<div id={{model.name | dashify}}></div>
<span>{{1288323623006 | date:'yyy-MM-dd HH:mm:ssZ' : '-0700'}}</span>

date-time-picker directive

Built around the Bootstrap Datepicker and Moment.js

dateTimePicker.js

(function () {
    var dateTimePicker = function () {
        return {
            restrict: 'EA',
            replace: true,
            templateUrl: '/Content/templates/core/date-time-picker.html',
            scope: {
                dateLabel: '@',
                dateValue: '='
            },
            link: function (scope, element) {
                var picker = $(element[0]).datetimepicker();
                
                var data = picker.data("DateTimePicker");
                
                scope.$watch('dateValue', setDisplayDate);
                
                function setDisplayDate() {
                    data.date(new Date(scope.dateValue)).format("MMM DD, YYYY HH:mm");
                }
                
                picker.on('dp.change', function (e) {
                    scope.$evalAsync(function () {
                        if (data.date()) {
                            scope.dateValue = data.date().format("MMM DD, YYYY HH:mm");
                        } else {
                            scope.dateValue = null;
                        }
                    })
                });
            }
        };
    };
    
    app.directive('dateTimePicker', dateTimePicker);
}());

date-time-picker.html

<div class="input-group-date">
    <span class="input-group-addon" ng-bind="dateLabel"></span>
    <input class="form-control" ng-model="dateValue" />
    <span class="input-group-addon">
        <span class="glyphicon glyphicon-calendar"></span>
    </span>
</div>

linked-date-time-picker directive

Built around the Bootstrap Datepicker and Moment.js

linkedDateTimePicker.js

(function () {
    var linkedDateTimePicker = function () {
        return {
            restrict: 'EA',
            replace: true,
            templateUrl: '/Content/templates/core/linked-date-time-picker.html',
            scope: {
                startDate: '=',
                endDate: '=',
                startLabel: '@',
                endLabel: '@',
                isSmall: '='
            },
            link: function (scope, element) {
                var start = $(element[0].children[0].children[0]).datetimepicker();
                var end = $(element[0].children[1].children[0]).datetimepicker({
                    useCurrent: false
                });
                
                var startDate = start.data("DateTimePicker");
                var endData = end.data("DateTimePicker");
                
                scope.$watch('startDate', setStartDisplay);
                scope.$watch('endDate', setEndDisplay);
                
                function setStartDisplay() {
                    startData.date(new Date(scope.startDate)).format("MMM DD, YYYY HH:mm");
                }
                
                function setEndDisplay() {
                    endData.date(new Date(scope.endDate)).format("MMM DD, YYYY HH:mm");
                }
                
                start.on('dp.change', function (e) {
                    endData.minDate(e.date);
                    
                    scope.$evalAsync(function () {
                        if (startData.date()) {
                            scope.startDate = startData.date().format("MMM DD, YYYY HH:mm");
                        } else {
                            scope.startDate = null;
                        }
                    });
                });
                
                end.on('dp.change', function (e) {
                    startData.maxDate(e.date);
                    
                    scope.$evalAsync(function () {
                        if (endData.date()) {
                            scope.endDate = endData.date().format("MMM DD, YYYY HH:mm");
                        } else {
                            scope.endData = null;
                        }
                    });
                });
            }
        };
    };
    
    app.directive('linkedDateTimePicker', linkedDateTimePicker);
}());

linked-date-time-picker.html

<div class="row">
    <div class="col-sm-6">
        <div class="input-group date" ng-class="{'input-group-sm': isSmall}">
            <span class="input-group-addon" ng-bind="startLabel"></span>
            <input type="text" class="form-control" ng-model="startDate" />
            <span class="input-group-addon">
                <span class="glyphicon glyphicon-calendar"></span>
            </span>
        </div>
    </div>
    <div class="col-sm-6">
        <div class="input-group date" ng-class="{'input-group-sm': isSmall}">
            <span class="input-group-addon" ng-bind="endLabel"></span>
            <input type="text" class="form-control" ng-model="endDate" />
            <span class="input-group-addon">
                <span class="glyphicon glyphicon-calendar"></span>
            </span>
        </div>
    </div>
</div>

Edit Modal Pattern

editModal.js

(function () {
    var editModal = function (someSvc) {
        return {
            restrict: 'EA',
            replace: true,
            templateUrl: '/Content/templates/edit-modal.html',
            scope: {
                modalOptions: '=',
                model: '=model'
            },
            link: function (scope) {
                scope.options = someSvc.model;
            }
        };
    };
    
    editModal.$inject = ['someSvc'];
    app.directive('editModal', editModal);
}());

edit-modal.html

<div class="modal fade" tabindex="-1" id="edit-modal" role="dialog">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <button ng-click="modalOptions.cancel()" class="close" data-dismiss="modal">
                    <span>&times;</span>
                </button>
                <h4 class="modal-title">Edit Entity</h4>
            </div>
            <div class="modal-body">
                <div class="row">
                    <div class="col-md-6">
                        <div class="input-group input-group-sm">
                            <div class="input-group-addon">Name</div>
                            <input type="text" class="form-control" ng-model="model.name" />
                        </div>
                    </div>
                    <div class="col-md-6">
                        <div class="input-group input-group-sm">
                            <div class="input-group-addon">Dependency</div>
                            <select ng-model="model.dependency" class="form-control" ng-options="dep.name for dep in options.data track by dep.id"></select>
                        </div>
                    </div>
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn btn-default" ng-click="modalOptions.cancel()" data-dismiss="modal">Cancel</button>
                <button class="btn btn-success" ng-click="modalOptions.ok()" data-dismiss="modal">Update</button>
            </div>
        </div>
    </div>
</div>

Usage in directive JavaScript

link: function (scope) {
    someSvc.getOptions();
    scope.editModalOptions = {
        ok: function () {
            scope.editEntity();
        },
        cancel: function () {
            scope.clearEditingEntity();
        }
    }
    
    scope.setEditingEntity = function (entity) {
        scope.editing = {
            name: entity.name,
            dependency: entity.dependency
        };
    }
    
    scope.clearEditingEntity = function () {
        scope.editing = {};
    }
    
    scope.editEntity = function () {
        if (validate(scope.editing)) {
            someSvc.updateEntity(scope.editing).then(function () {
                someSvc.getEntities();
            });
        }
    }
}

Usage in directive HTML

<edit-modal modal-options="editModalOptions" model="editing"></edit-modal>
<table class="table table-condensed table-striped">
    <thead>
        <tr>
            <th>Entity</th>
            <th>Dependency</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="entity in entities.data">
            <td ng-bind="entity.name"></td>
            <td ng-bind="entity.dependency.name"></td>
            <td>
                <a class="btn btn-success btn-sm" data-toggle="modal" data-target="#edit-modal" ng-click="setEditingEntity(entity)" href="">Edit</a>
            </td>
        </tr>
    </tbody>
</table>

Confirm Modal Pattern

confirm-modal.js

(function () {
    var confirmModal = function () {
        return {
            restrict: 'EA',
            replace: true,
            templateUrl: '/Content/templates/core/confirm-modal.html',
            scope: {
                modalOptions: '='
            }
        };
    };
    
    app.directive('confirmModal', confirmModal);
}());

confirm-modal.html

<div class="modal fade" tabindex="-1" id="{{modalOptions.modalId}}" role="dialog">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button ng-click="modalOptions.cancel()" class="close" data-dismiss="modal">
                    <span>&times;</span>
                </button>
            </div>
            <div class="modal-body">
                <p>{{modalOptions.bodyText}}</p>
            </div>
            <div class="modal-footer">
                <div class="btn btn-toolbar">
                    <div class="btn-group">
                        <button class="btn btn-default" ng-click="modalOptions.cancel()" data-dismiss="modal">{{modalOptions.closeButtonText}}</button>
                    </div>
                    <div class="btn-group" ng-switch="modalOptions.actionClass">
                        <button class="btn btn-success" ng-click="modalOptions.ok()" data-dismiss="modal" ng-switch-when="success">{{modalOptions.actionButtonText}}</button>
                        <button class="btn btn-danger" ng-click="modalOptions.ok()" data-dismiss="modal" ng-switch-when="danger">{{modalOptions.actionButtonText}}</button>
                        <button class="btn btn-warning" ng-click="modalOptions.ok()" data-dismiss="modal" ng-switch-when="warning">{{modalOptions.actionButtonText}}</button>
                        <button class="btn btn-info" ng-click="modalOptions.ok()" data-dismiss="modal" ng-switch-when="info">{{modalOptions.actionButtonText}}</button>
                        <button class="btn btn-primary" ng-click="modalOptions.ok()" data-dismiss="modal" ng-switch-default>{{modalOptions.actionButtonText}}</button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

Usage in directive JavaScript

link: function (scope) {
    scope.modalOptions = {
        modalId: 'delete-modal',
        headerText: 'Delete Entity',
        bodyText: 'Are you sure you want to delete this entity?',
        closeButtonText: 'Cancel',
        actionButtonText: 'Delete',
        actionClass: 'danger',
        ok: function () {
            scope.deleteEntity(scope.deleteId);
        },
        cancel: function () {
            scope.clearDeleteId();
        }
    }
    
    scope.setDeleteId = function (id) {
        scope.deleteId = id;
    }
    
    scope.clearDeleteId = function () {
        scope.deleteId = 0;
    }
    
    scope.deleteEntity = function (id) {
        someSvc.toggleDelete(id).then(function () {
            someSvc.getEntities();
        });
    }
}

Usage in directive HTML

<confirm-modal modal-options="modalOptions"></confirm-modal>
<table class="table table-striped table-condensed">
    <thead>
        <tr>
            <th>Entity</th>
            <th>Dependency</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="entity in entities.data">
            <td ng-bind="entity.name"></td>
            <td ng-bind="entity.dependency.name"></td>
            <td>
                <a class="btn btn-danger" data-toggle="modal" data-target="#{{modalOptions.modalId}}" ng-click="setDeleteId(entity.id)" href="">Delete</a>
            </td>
        </tr>
    </tbody>
</table>

nav-pills Hosting Directives

tableManager.js

(function () {
    var tableManager = function () {
        return {
            restrict: 'EA',
            replace: true,
            templateUrl: '/Content/templates/admin/table-manager.html',
            scope: {},
            link: function (scope) {
                scope.entitiesInitialized = false;
                
                scope.initializeEntities = function () {
                    if (!(scope.entitiesInitialized)) {
                        scope.$broadcast('initialize-entities');
                        scope.entitiesInitialized = true;
                    }
                }
            }
        };
    };
    
    app.directive('tableManager', tableManager);
}());

table-manager.html

<div>
    <h2>Data Management</h2>
    <hr />
    <ul class="nav nav-pills nav-justified">
        <li role="presentation" class="active">
            <a href="#some" role="tab" data-toggle="tab">Some</a>
        </li>
        <li role="presentation">
            <a href="#entity" role="tab" data-toggle="tab" ng-click="initializeEntities()">Entity</a>
        </li>
        <li role="presentation">
            <a href="#another" role="tab" data-toggle="tab" ng-click="initializeAnother()">Another</a>
        </li>
    </ul>
    <div class="tab-content">
        <div role="tabpanel" class="tab-pane active" id="some">
            <some-manager></some-manager>
        </div>
        <div role="tabpanel" class="tab-pane" id="entity">
            <entity-manager></entity-manager>
        </div>
        <div role="tabpanel" class="tab-pane" id="another">
            <another-manager></another-manager>
        </div>
    </div>
</div>

Initializing in directive JavaScript

link: function (scope) {
    scope.$on('initialize-entities', function () {
        scope.initialize();
    }
    
    scope.initialize = function () {
        initializeEntity();
        scope.entities = someSvc.entities;
        someSvc.getEntities();
    }
}

nav-pills Set Render Object by Id

<ul class="nav nav-pills">
    <li ng-repeat="object in activeObjects.data" ng-class="{'active': object.id == model.object.id}">
        <a ng-click="getObject(object.id)" href="">{{object.name}}</a>
    </li>
</ul>
link: function (scope) {
    scope.activeObjects = someSvc.activeObjects;
    scope.model = someSvc.objectModel;
    
    someSvc.getActiveObjects().then(function () {
        if (scope.activeObjects.data.length > 0) {
            someSvc.getObject(scope.activeObjects.data[0].id);
        }
    });
    
    scope.getObject = function (id) {
        someSvc.getObject(id);
    }
}

nav-pills Set Render Object with Metadata

<ul class="nav nav-pills nav-justified">
    <li ng-class="{'active': category === 'Supervisor'}">
        <a ng-click="setObject('Supervisor')" href="">Supervisor Interview</a>
    </li>
    <li ng-class="{'active': category === 'Candidate'}">
        <a ng-click="setObject('Candidate')" href="">Candidate Interview</a>
    </li>
</ul>
<div ng-repeat="question in activeObject.questions">
    <div ng-switch="question.questionFormat.format">
        <text-question ng-switch-when="Text" question="question"></text-question>
        <textarea-question ng-switch-when="Text - Large" question="question"></textarea-question>
        <bool-question ng-switch-when="Yes / No" question="question"></bool-question>
        <label-question ng-switch-default question="question"></label-question>
    </div>
</div>
link: function (scope) {
    scope.category = 'Supervisor';
    scope.model = someSvc.model;
    
    someSvc.getObjects().then(function () {
        scope.activeOjbect = scope.model.data.supervisorObject;
    });
    
    scope.setObject = function (category) {
        if (category === "Supervisor") {
            scope.category = 'Supervisor';
            scope.activeObject = scope.model.data.supervisorObject;
        } else {
            scope.category = 'Candidate';
            scope.activeObject = scope.model.data.candidateObject;
        }
    }
}

back to top

Node Template

Implement a simple node project via CLI and open in Visual Studio Code

md {project-dir}
cd {project-dir}
npm init
npm install --save-dev {modules}
code .

List Node Module Details

List all globally installed npm modules without dependencies

npm -g ls --depth=0

Output Node Module Details

Output a listing of globally installed npm modules to a .json file

npm -g -l ls --depth=0 --json > {directory}\npm-modules.json

package.json scripts

"scripts": {
  "start": "node ./bin/www",
  "server1": "set PORT=3001 & node ./bin/www"
}

To run the start script, {dir}>npm start. To run the server1 script, {dir}>npm run server1.

back to top

Specify multiple file extensions for a gulp task

var gulp = require('gulp');

gulp.task('images', function () {
  return gulp
    .src('images/*.{png,jpg}')
    .pipe(gulp.dest('dist/images'));
});

Back to Top

npm install -g webpack
mkdir webpack-demo && cd webpack-demo
npm init -y
npm install --save-dev webpack
npm install --save lodash
mkdir app
code .

app/index.js

import _ from 'lodash';

function component () {
    var element = document.createElement('div');
    
    element.innerText = _.join(['Hello', 'webpack'], ' ');
    
    return element;
}

document.body.appendChild(component());

index.html

<html>
    <head>
        <title>webpack 2 demo</title>
    </head>
    <body>
        <script src="dist/bundle.js"></script>
    </body>
</html>

webpack.config.js

var path = require('path');

module.exports = {
    entry: './app/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    }
};

Execute the webpack command to build the dist/bundle.js file

./node_modules/.bin/webpack

back to top

Resources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment