JSFiddle - React, Tailwind, and code Playground

by rwaldin

HTML

<!-- ignore this stuff, it's just here to allow us to jsfiddle wsi stuff --><script>WSI = {isEnabled: function(){return false;},offsiteRequests:[]};</script><script src='http://www.williams-sonoma.com/wsimgs/ab/images/s/201207/0011/js/dojo/wsgc/wsgc.js'></script><script>WSI.utils = new wsgc.js.Utils('','');</script><!-- end ignore -->

<!-- templates for calendar -->
<script type="text/html" id="calendarWidget_dayTemplate"><td><a title="[%=date.toDateString()%]" data-date="[%=date.toDateString()%]" class="day day[%=day%] day[%=dayAbbr%] [%=whichMonth%]Month [%=isSelectedDay?'selectedDay':''%]" [%=inDateRange?'href="#"':''%]>[%=day%]</a></td></script>

<script type="text/html" id="calendarWidget_weekTemplate"><tr class="week">[%=days.join('')%]</tr></script>

<script type="text/html" id="calendarWidget_dayOfWeekTemplate"><th title="[%=dayName%]" class="dayOfWeek day[%=dayAbbr%]">[%=dayAbbr%]</th></script>

<script type="text/html" id="calendarWidget_monthTemplate">
    <table class="calendarWidgetTable">
        <thead class="head">
            <tr class="controls">
                <th class="month" colspan="4"><a class="last" href="#">&larr;</a><input class="label" value="[%=monthName%]"/><a class="next" href="#">&rarr;</a></th>
                <th class="year" colspan="3"><a class="last" href="#">&larr;</a><input class="label" value="[%=year%]"/><a class="next" href="#">&rarr;</a></th>
            </tr>
            <tr class="dayAbbrs">[%=dayAbbrs.join('')%]</tr>
        </thead>
        <tbody class="body">[%=weeks.join('')%]</tbody>
    </table>
</script>
<!-- end templates -->




<label for="myDateInput">Event Date </label>

<input id="myDateInput" type="text" class="dateInput" data-dateInput="{}"></input>

<a href="#" class="calendarWidgetTrigger" data-calendarWidget="{target:'myDateInput',endDate:new Date()}"></a>

<label for="myDateInput" class="hint"> mm/dd/yyyy</label>

<div id="myCalendarWidget"></div>

CSS

#myCalendarWidget {
    margin: 10px;
}

.calendarWidgetTable {
    border: 2px solid black;
}

.calendarWidgetTable td, th {
   border: 1px solid #777;
}

.calendarWidgetTable .day, .calendarWidgetTable th {
    width: 36px;
    height: 36px;
    line-height: 38px;
    text-align: center;
}

.calendarWidgetTable .day[href]:hover {
    background-color: #EEF;
    cursor: pointer;
}

.calendarWidgetTable .controls a {
    padding: 0 5px;
    text-decoration: none;
    color: #999;
}

.calendarWidgetTable .controls a[href] {
    font-weight: bold;
    color: #000;
}

.calendarWidgetTable .controls .label {
    display: inline-block;
    text-align: center;
}

.calendarWidgetTable .controls .month {
    border-right-width: 0;
}

.calendarWidgetTable .controls .year {
    border-left-width: 0;
}

.calendarWidgetTable .controls .month .label {
    width: 80px;
}

.calendarWidgetTable .controls .year .label {
    width: 50px;
}

.calendarWidgetTable .controls input {
    border: 0;
    font-size: 14px;
    font-weight: bold;
    border: 1px solid white;
}

.calendarWidgetTable .controls input:hover {
    border: 1px solid #999;
}

.calendarWidgetTable .day {
    color: #000;
    display: inline-block;
    text-decoration: none;
}

.calendarWidgetTable .day[href] {
    text-decoration: underline;
}

.calendarWidgetTable .day.lastMonth, .calendarWidgetTable .day.nextMonth {
    color: #999;
}

.calendarWidgetTable .daySat, .daySun {
    background-color: #EEE;
}

.calendarWidgetTable .selectedDay {
    cursor: pointer;
    background-color: #EEF;
    font-weight: bold;
}

.calendarWidgetTable .dayOfWeek {
    font-weight: bold;
    font-size: 13px;
    border-width: 0px;
    border-bottom-width: 2px; 
    border-color: black;
}

label {
    font-size: 14px;
}

.hint {
    color: #AAA;
    font-style: italic;
}    

.dateInput {
    margin: 4px;
    height: 14px;
    padding-right: 18px;
    width: 80px;
}

.calendarWidgetTrigger {
    display:inline-block;
    position:...

JavaScript

dojo.provide('wsgc.js.CalendarWidget');
dojo.require('wsgc.js.Utils');

dojo.provide('wsgc.js.CalendarWidget');
dojo.require('wsgc.js.Dataset');
dojo.require('wsgc.js.Utils');

dojo.provide('wsgc.js.CalendarWidget');
dojo.require('wsgc.js.Dataset');
dojo.require('wsgc.js.Utils');

dojo.provide('wsgc.js.CalendarWidget');
dojo.require('wsgc.js.Dataset');
dojo.require('wsgc.js.Utils');

(function() {
    var templates = {},
        MIN_DATE  = new Date(1000,0),       // constrain date range to four digit years to 
        MAX_DATE  = new Date(9999,11,31);   // simplify layout and sizing of year labels

    dojo.forEach(["day", "week", "month", "dayOfWeek"], function(name) {
        templates[name] = WSI.utils.template(dojo.byId('calendarWidget_' + name + 'Template').innerHTML);
    });
        
    dojo.declare('wsgc.js.CalendarWidget', [], {
        constructor: function(/*DOMNode*/ elem, /*optional Date*/ date, /*optional Object*/ options) {
            this.elem = elem;
            if(!options && date && date.constructor !== Date) {
                // date not specified, options object found in its place
                options = date;
                date    = new Date();
            }
            this.opts           = options || {};
            this.opts.startDate = fixDate(this.opts.startDate, MIN_DATE);
            this.opts.endDate   = fixDate(this.opts.endDate, MAX_DATE);
            if(this.opts.endDate < this.opts.startDate) {
                throw new Error("end date before start date");
            }
            this.setSelectedDate(date);
        },

        setSelectedDate: function(date) {
            date = fixDate(date, new Date());
            if(this.opts.startDate > date) {
                throw new Error("date before start date");
            } else if(this.opts.endDate < date) {
                throw new Error("date after end date");
            }
            this.selectedDate = date;
            this.viewMonth(date.getMonth(),...