Permalink
Browse files

boosh!

  • Loading branch information...
0 parents commit 4683e5f4d0acc0d6fabbf5ec2acb1d43b213c646 @ded committed Nov 2, 2011
Showing with 357 additions and 0 deletions.
  1. +1 −0 .gitignore
  2. +2 −0 Makefile
  3. +25 −0 Makefile.js
  4. +26 −0 README.md
  5. +59 −0 calender.css
  6. +181 −0 calender.js
  7. +6 −0 calender.min.js
  8. +34 −0 demo.html
  9. +23 −0 package.json
1 .gitignore
@@ -0,0 +1 @@
+node_modules
2 Makefile
@@ -0,0 +1,2 @@
+boosh:
+ node Makefile.js
25 Makefile.js
@@ -0,0 +1,25 @@
+require('smoosh').config({
+ "JAVASCRIPT": {
+ "DIST_DIR": "./",
+ "calender": [
+ "./calender.js"
+ ]
+ },
+ "JSHINT_OPTS": {
+ "boss": true
+ , "forin": false
+ , "curly": false
+ , "debug": false
+ , "devel": false
+ , "evil": true
+ , "regexp": false
+ , "undef": false
+ , "sub": true
+ , "white": false
+ , "indent": 2
+ , "whitespace": true
+ , "asi": true
+ , "laxbreak": true
+ , "plusplus": false
+ }
+}).run().build().analyze()
26 README.md
@@ -0,0 +1,26 @@
+# CalEnder
+A basic, themeable calendar datepicker for [Ender](http://ender.no.de)
+
+![calender](http://dustindiaz.com/basement/img/calender.png)
+
+Currently, this depends on Enders minimal starter pack [The Jeesh](https://github.com/ender-js/jeesh)
+
+Use it like this:
+
+```html
+<link rel="stylesheet" type="text/css" href="calender.css">
+<script src="http://ender-js.s3.amazonaws.com/jeesh.min.js"></script>
+<script src="calender.js"></script>
+<script>
+ $('input.my-date').calender()
+</script>
+```
+
+If you're already using ender, you can add it to your existing instance
+
+ $ ender add calender
+
+# Features
+There's currently no features other than it being a datepicker. More will come. Thanks.
+
+Enjoy!
59 calender.css
@@ -0,0 +1,59 @@
+.date {
+ width: 200px;
+ font-size: 12px;
+ font-family: lucida grande, lucida;
+ display: none;
+ position: absolute;
+ user-select: none;
+ -webkit-user-select: none;
+ z-index: 999999999;
+}
+.date.active {
+ display: block;
+}
+.date table {
+ width: 100%;
+ background-color: #222;
+ border-radius: 5px;
+ border-collapse: collapse;
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
+ cursor: default;
+}
+.date table tr.date-header th {
+ text-align: center;
+}
+.date table th.date-month-year {
+ color: yellow;
+}
+.date table tr.date-daysofweek th {
+ color: #aaa;
+}
+.date table tbody tr:hover,
+.date table tbody td.hover {
+ background-color: #333;
+}
+.date table td,
+.date table th {
+ color: #fff;
+ font-weight: bold;
+ text-align: right;
+ border: 0;
+ padding: 5px;
+}
+.date table tbody td,
+.date tr.date-daysofweek th {
+ border-right: 2px groove #444;
+}
+.date table tbody td:last-child,
+.date table tr.date-daysofweek th:last-child {
+ border-right-width: 0;
+}
+.date table td.today {
+ color: yellow;
+}
+.date table .inactive {
+ color: #555;
+}
+.date-month-previous {
+ -webkit-transform: rotate(180deg);
+}
181 calender.js
@@ -0,0 +1,181 @@
+/**
+ * CalEnder: A Datepicker for Ender
+ * copyright Dustin Diaz @ded 2011 | License MIT
+ * https://github.com/ded/calEnder
+ */
+!function ($) {
+
+ var template = "" +
+ "<div class='date'>" +
+ " <table>" +
+ " <thead>" +
+ " <tr class='date-header'>" +
+ " <th class='date-nav date-month-previous'>&#8227;</th>" +
+ " <th colspan='5' class='date-month-year'>" +
+ " <span class='date-current-month'></span>" +
+ " <span class='date-current-year'></span></th>" +
+ " <th class='date-nav date-month-next'>&#8227;</th>" +
+ " </tr>" +
+ " <tr class='date-daysofweek'>" +
+ " <th>S</th>" +
+ " <th>M</th>" +
+ " <th>T</th>" +
+ " <th>W</th>" +
+ " <th>R</th>" +
+ " <th>F</th>" +
+ " <th>S</th>" +
+ " </tr>" +
+ " </thead>" +
+ " <tbody class='date-days'></tbody>" +
+ " </table>" +
+ "</div>"
+
+
+ var months = [
+ 'January', 'February', 'March', 'April'
+ , 'May', 'June', 'July', 'August'
+ , 'September', 'October', 'November', 'December'
+ ]
+
+ function isLeapYear(year) {
+ return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0))
+ }
+ function getDaysInMonth(year, month) {
+ return [31, (isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]
+ }
+
+ function getMonthNumberFromName(name) {
+ return months.indexOf(name) + 1
+ }
+
+
+ function Calendar (el, options) {
+ var self = this
+ this.options = options || {}
+ this.$input = $(el).first()
+ this.$calendar = $(template).appendTo('body')
+ this.$calendar.delegate('tbody td', 'mouseover', function () {
+ $(this).closest('tbody').find('td:nth-child(' + (this.cellIndex + 1) + ')').addClass('hover')
+ })
+
+ $(document).bind('click', function (e) {
+ self.$calendar.removeClass('active')
+ })
+
+ this.$calendar.bind('mousedown click', function (e) {
+ e.stopPropagation()
+ e.preventDefault()
+ })
+
+ this.$calendar.delegate('tbody td', 'mouseout', function () {
+ $(this).closest('tbody').find('td:nth-child(' + (this.cellIndex + 1) + ')').removeClass('hover')
+ })
+ this.$calendar.delegate('tbody td:not(.inactive)', 'click.day', function (e) {
+ var day = $(this).html()
+ self.$input.val([
+ getMonthNumberFromName(self.$calendar.find('.date-current-month').html())
+ , day
+ , self.$calendar.find('.date-current-year').html()].join('-')
+ )
+ self.$calendar.removeClass('active')
+ })
+
+ this.$calendar.delegate('.date-month-previous', 'click', function (e) {
+ var y = parseFloat(self.$calendar.find('.date-current-year').html())
+ , m = getMonthNumberFromName(self.$calendar.find('.date-current-month').html()) - 1
+ if (--m == -1) --y && (m = 11)
+ self.setDate(months[m] + ' 1,' + y)
+ })
+
+ this.$calendar.delegate('.date-month-next', 'click', function (e) {
+ var y = parseFloat(self.$calendar.find('.date-current-year').html())
+ , m = getMonthNumberFromName($('.date-current-month').html())
+ if ((m == 12)) ++y && (m = 0)
+ self.setDate(months[m] + ' 1,' + y)
+ })
+
+ this.setDate((this.options.date || new Date()).toDateString())
+ }
+
+ Calendar.prototype.setDate = function (date) {
+ var d = new Date(date)
+ , monthStart = (new Date(d.getFullYear(), d.getMonth(), 1).getDay())
+ , daysInPreviousMonth = getDaysInMonth(
+ d.getMonth() ? d.getFullYear() : d.getFullYear() - 1
+ , d.getMonth() ? d.getMonth() - 1 : d.getMonth()
+ )
+ , html = []
+ , firstWeek = 1
+ , theDay = 0
+ , dateBegin = daysInPreviousMonth - monthStart
+ , daysInMonth = getDaysInMonth(d.getYear(), d.getMonth())
+ , remainingWeeks = Math.floor((daysInMonth + monthStart - 7) / 7)
+ , i = 0
+
+ this.$calendar.find('.date-current-year,.date-current-month,tbody.date-days').empty()
+ this.$calendar.find('.date-current-year').html(d.getFullYear())
+ this.$calendar.find('.date-current-month').html(months[d.getMonth()])
+
+ html.push('<tr>')
+ while (dateBegin < daysInPreviousMonth) {
+ html.push('<td class="inactive">' + (++dateBegin) + '</td>')
+ }
+ while (monthStart < 7) {
+ html.push('<td>' + (++theDay) + '</td>')
+ monthStart++
+ }
+ html.push('</tr>')
+ for (; i < remainingWeeks; i++) {
+ html.push('<tr>')
+ var j = 0
+ while (j < 7) {
+ html.push('<td>' + (++theDay) + '</td>')
+ j++
+ }
+ html.push('</tr>')
+ }
+ if (theDay < daysInMonth) {
+ html.push('<tr>')
+ i = 0
+ var finalDays = theDay + 7
+ , newDays = 0
+ while (i < 7) {
+ if (theDay < daysInMonth) {
+ html.push('<td>' + (++theDay) + '</td>')
+ } else {
+ html.push('<td class="inactive">' + (++newDays) + '</td>')
+ }
+ i++
+ }
+ html.push('</tr>')
+ }
+ this.$calendar.find('tbody.date-days').append(html.join(''))
+
+ var now = new Date()
+ if (d.getMonth() == now.getMonth() && d.getFullYear() == now.getFullYear()) {
+ this.$calendar.find('.date tbody.date-days td').each(function (el) {
+ if (el.innerHTML == now.getDate() && !$(el).hasClass('inactive')) $(el).addClass('today')
+ })
+ }
+ }
+
+ $.ender({
+ calender: function (options) {
+ $(this).forEach(function (el) {
+ var $el = $(el)
+ , offset = $el.offset()
+ , calendar = new Calendar(el, options)
+ $el
+ .bind('focus click', function (e) {
+ e.stopPropagation()
+ calendar.$calendar.css({ left: offset.left, top: offset.top + offset.height}).addClass('active')
+ })
+ .bind('keydown', function (e) {
+ if (e.keyCode == 9) {
+ calendar.$calendar.removeClass('active')
+ }
+ })
+ })
+ }
+ }, true)
+}(ender);
6 calender.min.js
@@ -0,0 +1,6 @@
+/**
+ * CalEnder: A Datepicker for Ender
+ * copyright Dustin Diaz @ded 2011 | License MIT
+ * https://github.com/ded/calEnder
+ */
+!function(a){function d(a){return a%4===0&&a%100!==0||a%400===0}function e(a,b){return[31,d(a)?29:28,31,30,31,30,31,31,30,31,30,31][b]}function f(a){return c.indexOf(a)+1}function g(d,e){var g=this;this.options=e||{},this.$input=a(d).first(),this.$calendar=a(b).appendTo("body"),this.$calendar.delegate("tbody td","mouseover",function(){a(this).closest("tbody").find("td:nth-child("+(this.cellIndex+1)+")").addClass("hover")}),a(document).bind("click",function(a){g.$calendar.removeClass("active")}),this.$calendar.bind("mousedown click",function(a){a.stopPropagation(),a.preventDefault()}),this.$calendar.delegate("tbody td","mouseout",function(){a(this).closest("tbody").find("td:nth-child("+(this.cellIndex+1)+")").removeClass("hover")}),this.$calendar.delegate("tbody td:not(.inactive)","click.day",function(b){var c=a(this).html();g.$input.val([f(g.$calendar.find(".date-current-month").html()),c,g.$calendar.find(".date-current-year").html()].join("-")),g.$calendar.removeClass("active")}),this.$calendar.delegate(".date-month-previous","click",function(a){var b=parseFloat(g.$calendar.find(".date-current-year").html()),d=f(g.$calendar.find(".date-current-month").html())-1;--d==-1&&--b&&(d=11),g.setDate(c[d]+" 1,"+b)}),this.$calendar.delegate(".date-month-next","click",function(b){var d=parseFloat(g.$calendar.find(".date-current-year").html()),e=f(a(".date-current-month").html());e==12&&++d&&(e=0),g.setDate(c[e]+" 1,"+d)}),this.setDate((this.options.date||new Date).toDateString())}var b="<div class='date'> <table> <thead> <tr class='date-header'> <th class='date-nav date-month-previous'>&#8227;</th> <th colspan='5' class='date-month-year'> <span class='date-current-month'></span> <span class='date-current-year'></span></th> <th class='date-nav date-month-next'>&#8227;</th> </tr> <tr class='date-daysofweek'> <th>S</th> <th>M</th> <th>T</th> <th>W</th> <th>R</th> <th>F</th> <th>S</th> </tr> </thead> <tbody class='date-days'></tbody> </table></div>",c=["January","February","March","April","May","June","July","August","September","October","November","December"];g.prototype.setDate=function(b){var d=new Date(b),f=(new Date(d.getFullYear(),d.getMonth(),1)).getDay(),g=e(d.getMonth()?d.getFullYear():d.getFullYear()-1,d.getMonth()?d.getMonth()-1:d.getMonth()),h=[],i=1,j=0,k=g-f,l=e(d.getYear(),d.getMonth()),m=Math.floor((l+f-7)/7),n=0;this.$calendar.find(".date-current-year,.date-current-month,tbody.date-days").empty(),this.$calendar.find(".date-current-year").html(d.getFullYear()),this.$calendar.find(".date-current-month").html(c[d.getMonth()]),h.push("<tr>");while(k<g)h.push('<td class="inactive">'+ ++k+"</td>");while(f<7)h.push("<td>"+ ++j+"</td>"),f++;h.push("</tr>");for(;n<m;n++){h.push("<tr>");var o=0;while(o<7)h.push("<td>"+ ++j+"</td>"),o++;h.push("</tr>")}if(j<l){h.push("<tr>"),n=0;var p=j+7,q=0;while(n<7)j<l?h.push("<td>"+ ++j+"</td>"):h.push('<td class="inactive">'+ ++q+"</td>"),n++;h.push("</tr>")}this.$calendar.find("tbody.date-days").append(h.join(""));var r=new Date;d.getMonth()==r.getMonth()&&d.getFullYear()==r.getFullYear()&&this.$calendar.find(".date tbody.date-days td").each(function(b){b.innerHTML==r.getDate()&&!a(b).hasClass("inactive")&&a(b).addClass("today")})},a.ender({calender:function(b){a(this).forEach(function(c){var d=a(c),e=d.offset(),f=new g(c,b);d.bind("focus click",function(a){a.stopPropagation(),f.$calendar.css({left:e.left,top:e.top+e.height}).addClass("active")}).bind("keydown",function(a){a.keyCode==9&&f.$calendar.removeClass("active")})})}},!0)}(ender)
34 demo.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html lang="en-us">
+ <head>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+ <title>CalEnder Demo</title>
+ <style type="text/css" media="screen">
+ body {
+ width: 600px;
+ margin: 0 auto;
+ }
+ h1 {
+ font: 100 46px/1.4 "lucida grande", lucida;
+ color: #555;
+ }
+ input {
+ font: 36px lucida grande, lucida, helvetica, arial;
+ padding: 10px;
+ border: 1px solid #999;
+ }
+ </style>
+ <link rel="stylesheet" href="./calender.css" type="text/css">
+ <script src="http://ender-js.s3.amazonaws.com/jeesh.min.js"></script>
+ <script src="./calender.min.js"></script>
+ <script>
+ $(document).ready(function () {
+ $('input').calender()
+ })
+ </script>
+ </head>
+ <body>
+ <h1>pick a date</h1>
+ <p><input type="text" name="some_date" value="" id="some_date"></p>
+ </body>
+</html>
23 package.json
@@ -0,0 +1,23 @@
+{
+ "name": "bonzo"
+ , "description": "Simple, themable, Datepicker for Ender"
+ , "version": "0.0.1"
+ , "homepage": "https://github.com/ded/calEnder"
+ , "author": "Dustin Diaz <dustin@dustindiaz.com> (http://dustindiaz.com)"
+ , "keywords": ["ender", "calendar", "date", "datepicker", "datechooser", ""]
+ , "main": "./datepicker.js"
@edds
edds Nov 3, 2011

I think this needs to be "./calender.js".

@ded
ded Nov 6, 2011

yep. apparently missed that

+ , "ender": "noop"
+ , "repository": {
+ "type": "git"
+ , "url": "https://github.com/ded/calEnder.git"
+ }
+ , "dependencies": {
+ "jeesh": "*"
+ }
+ , "scripts": {
+ "build": "node Makefile.js"
+ }
+ , "devDependencies": {
+ "smoosh": "*"
+ }
+}

0 comments on commit 4683e5f

Please sign in to comment.