Skip to content

Instantly share code, notes, and snippets.

@smockle
Created March 7, 2014 02:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save smockle/9403781 to your computer and use it in GitHub Desktop.
Save smockle/9403781 to your computer and use it in GitHub Desktop.
AngularJS directives and a controller. Used in a calendar/scheduling app.
/*jshint bitwise: true, curly: true, eqeqeq: true, forin: true, immed: true, indent: 4, latedef: true, newcap: true, noarg: true, noempty: true, nonew: true, quotmark: double, undef: true, strict: true, trailing: true, maxdepth: 4, esnext: true, browser: true, devel: true */
/*global $: true, angular: true, moment: true, $http */
var NG_BIG = angular.module("NG_BIG", []);
NG_BIG.directive("dateformat", function ($parse, $filter) {
return {
require: "ngModel",
link: function (scope, element, attrs, ngModel) {
// Input: What the model has in it.
// Output: What the textbox will display.
ngModel.$formatters.push(
function (value) {
return moment(value).format("MMMM Do");
}
);
// Input: What the textbox has in it on submit.
// Output: What the model will have in it.
ngModel.$formatters.unshift(
function (value) {
return value;
}
);
// Input: What the textbox has in it on typing.
// Output: What the model will have in it.
ngModel.$parsers.unshift(
function (value) {
return moment(value, "MMMM DDo").format("MM/DD/YYYY HH:00:00");
}
);
}
}
});
var size = function () {
// Our app is loaded and the DOM is compiled
var biggest_height = 0;
$(".month").each(function () {
$(this).css("height", "100%");
if ($(this).height() > biggest_height) {
biggest_height = $(this).height();
}
});
$(".month").height(parseInt(biggest_height, 10));
};
NG_BIG.directive("dimensions", ["$timeout", function ($timeout) {
return {
link: function ($scope, element, attrs) {
// FIXME: Update is broadcast for each month. Size iterates through each month. N^2. Bad.
$scope.$on("update", function () {
$timeout(size, 0, false);
})
}
};
}]);
NG_BIG.controller("biggio", ["$scope", "$http", function ($scope, $http) {
"use strict";
function Day(year, month, day) {
// Year.
this.year = year;
// Month.
this.month = month;
// Day.
this.day = day;
// Array of events.
this.events = [];
this.checked = false;
this.check = function () {
this.checked = !this.checked;
$scope.checked.push(this);
};
var i, a, b,
t = moment(this.year + this.month + this.day, "YYYYMMD");
this.getEvents = function () {
this.events = [];
if ($scope.events !== undefined) {
for (i = 0; i < $scope.events.length; i++) {
var dupe = $scope.events[i];
//var dupe = Object.create($scope.events[i]);
dupe.isStart = false;
dupe.isEnd = false;
a = moment(dupe.StartTime);
b = moment(dupe.EndTime);
if ((a.isBefore(t, "day") || a.isSame(t, "day")) && (b.isAfter(t, "day") || b.isSame(t, "day"))) {
if (a.isSame(t, "day")) {
dupe.isStart = true;
}
if (b.isSame(t, "day")) {
dupe.isEnd = true;
}
this.events.push(dupe);
}
}
}
if (this.events[0] == "") { this.events.shift(); }
return this.events;
};
if (this.events.length === 0) {
this.events.push("");
}
}
function Month(year, month) {
// Iterator.
var i;
// Year.
this.year = year;
// Month.
this.month = month;
// Array of day names.
this.week = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
// First day of the month.
this.firstDay = moment(this.year + this.month + "01", "YYYYMMDD").format("dddd");
// Number of blanks until first day of the month.
this.numBlanks = this.week.indexOf(this.firstDay);
// Number of days in the month.
this.numDays = new Date(this.year, this.month, 0).getDate();
// Array of days.
this.days = [];
for (i = 1; i <= this.numDays; i++) {
this.days[this.numBlanks + i - 1] = new Day(this.year, this.month, i);
}
this.days = this.days.concat(new Array(7 - (this.numBlanks + this.numDays % 7)));
}
$scope.date = moment();
$scope.month = new Month($scope.date.format("YYYY"), $scope.date.format("MM"));
$scope.title = function () { return $scope.date.format("MMMM YYYY"); };
$scope.checked = [];
$scope.go = {
previous: function () {
$scope.date.subtract("months", 1);
$scope.month = new Month($scope.date.format("YYYY"), $scope.date.format("MM"));
},
today: function () {
$scope.date = moment();
$scope.month = new Month($scope.date.format("YYYY"), $scope.date.format("MM"));
},
next: function () {
$scope.date.add("months", 1);
$scope.month = new Month($scope.date.format("YYYY"), $scope.date.format("MM"));
}
};
$scope.update_days = function () {
for (var i = 0; i < $scope.month.days.length; i++) {
if ($scope.month.days[i] !== undefined && $scope.month.days[i].hasOwnProperty("events")) {
$scope.month.days[i].getEvents();
}
}
$scope.$broadcast("update");
};
//
// TEST
//
function Test(object) {
object = object || { LocationID: 2, StartTime: $scope.date, Duration: 1, EndTime: $scope.date.add("hours", 1), MaxAttendees: 50, Cost: 0, isProctored: false, StatusID: 1 };
this.ID = object.ID;
this.LocationID = object.LocationID;
this.StartTime = object.StartTime;
this.Duration = object.Duration;
this.EndTime = object.EndTime;
this.MaxAttendees = object.MaxAttendees;
this.Course = object.Course;
this.Section = object.Section;
this.Name = object.Name;
this.Notes = object.Notes;
this.Cost = object.Cost;
this.isProctored = object.isProctored;
this.StatusID = object.StatusID;
}
// Return whether an event exists in the given hour.
Test.prototype.exists = function (hour, id) {
for (var i = 0; i < $scope.events.length; i++) {
if ($scope.events[i].ID == id) { return true; }
}
var es = this.during(hour);
return es.length > 0 && es[0] !== "" && es[0].Course !== "";
};
// Display an add or edit modal.
Test.prototype.add = function (hour, id) {
var firstDay = $scope.checked[0],
lastDay = $scope.checked[$scope.checked.length - 1];
if (id === undefined && (firstDay === undefined || lastDay === undefined)) {
return;
}
// Edit
if (this.exists(hour, id)) {
$scope.event = this;
this.op = "Edit";
// Add
} else {
$scope.event = this;
this.StartTime = moment(firstDay.year + firstDay.month + firstDay.day, "YYYYMMDD");
this.EndTime = moment(lastDay.year + lastDay.month + lastDay.day, "YYYYMMDD");
this.op = "Add";
}
$(".modal#event").modal();
};
// Remove an event from the JSON event list.
Test.prototype.forget = function () {
var i, a;
for (i = 0; i < $scope.events.length; i++) {
a = $scope.events[i].ID;
if (a === this.ID) {
$scope.events.splice(i, 1);
}
}
};
// Add or edit an event.
Test.prototype.update = function () {
var hour = moment(this.StartTime).format("YYYY-MM-DDT");
hour += "07";
hour = moment(hour, "YYYY-MM-DDTHH").format("MM/DD/YYYY HH:00:00");
this.StartTime = hour;
hour = moment(this.EndTime).format("YYYY-MM-DDT");
hour += "19";
hour = moment(hour, "YYYY-MM-DDTHH").format("MM/DD/YYYY HH:00:00");
this.EndTime = hour;
// Add
if (this.op === "Add") {
$http.post("/big/tests/add", this).success(
function (data) {
$(".modal#event").modal("hide");
$scope.events.push($.extend(Test.prototype, data));
$scope.update_days();
}
);
// Edit
} else if (this.op === "Edit") {
$http.post("/big/tests/edit", this).success(
function (data) {
$(".modal#event").modal("hide");
this.forget();
$scope.events.push($.extend(Test.prototype, data));
$scope.update_days();
}.bind(this)
);
}
},
// Delete an event.
Test.prototype.destroy = function () {
if ($scope.events !== undefined) {
$http.post("/big/tests/delete", this).success(
function () {
$(".modal#event").modal("hide");
this.forget();
$scope.update_days();
}.bind(this)
);
}
};
// Set example properties.
Test.prototype.test = function () {
this.Course = "UNIV 4001";
this.Section = "001";
this.Name = "The Auburn Tradition";
this.Cost = 0;
this.isProctored = false;
};
// Return list of events in a given day.
Test.prototype.during = function (day) {
var i, a, es = [],
t = moment($scope.date.format("YYYY-MM-") + day, "YYYY-MM-DTH");
if ($scope.events !== undefined) {
for (i = 0; i < $scope.events.length; i++) {
a = moment($scope.events[i].StartTime);
if (a.isSame(t, "day")) {
es.push($scope.events[i]);
}
}
}
if (es.length === 0) {
es.push("");
}
return es;
};
$scope.event = new Test();
angular.element(document).ready(size);
$(window).on("resize", size);
$scope.testify = function (objects) {
var output = [];
for (var i = 0; i < objects.length; i++) {
output.push(new Test(objects[i]));
}
return output;
}
}]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment