From f9153a9f86e083cbaad6bbf19adfa02f0ebaeb21 Mon Sep 17 00:00:00 2001 From: Erick Torres Date: Thu, 7 Jan 2016 18:09:09 -0500 Subject: [PATCH 1/3] Select all days of the selected header day --- build/kalendae.css | 11 +++++- readme.md | 14 ++++--- src/main.js | 96 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 111 insertions(+), 10 deletions(-) diff --git a/build/kalendae.css b/build/kalendae.css index 8b36473..91476f8 100644 --- a/build/kalendae.css +++ b/build/kalendae.css @@ -156,6 +156,11 @@ color:#666; } +.kalendae .k-header.k-active span { + cursor: pointer; + border-radius:3px; +} + .kalendae .k-days span { text-align:right; width:20px; @@ -193,7 +198,8 @@ } /** Selected day, when inside the selectable area **/ -.kalendae .k-days span.k-selected.k-active { +.kalendae .k-days span.k-selected.k-active, +.kalendae .k-header.k-active span.k-selected { background:#7EA0E2; color:white; } @@ -212,7 +218,8 @@ } /** Selectable day, hovered **/ -.kalendae .k-days span.k-active:hover { +.kalendae .k-days span.k-active:hover, +.kalendae .k-days span.k-active.k-day-hover-active { border-color:#666; } diff --git a/readme.md b/readme.md index 5ec37cc..82624ad 100644 --- a/readme.md +++ b/readme.md @@ -15,13 +15,13 @@ Kalendae is an attempt to do something that nobody has yet been able to do: make ##Screenshots -Default calendar, no options defined. +Default calendar, no options defined. ![screenshot](http://i.imgur.com/Ig52z.png) -Two month calendar attached to an input element. +Two month calendar attached to an input element. ![screenshot](http://i.imgur.com/GIR3g.png) -Two month, range selection, future dates only, with weekends blacked out: +Two month, range selection, future dates only, with weekends blacked out: ![screenshot](http://i.imgur.com/JzBc7.png) ###[View The Demo Page](http://chipersoft.github.com/Kalendae/) @@ -72,12 +72,12 @@ To ease date handling processes, Kalendae bundles the [moment.js](http://www.mom The following options are available for configuration. -- `attachTo`: The element that the calendar div will be appended to. +- `attachTo`: The element that the calendar div will be appended to. - In `Kalendae` this defaults to the first argument on the constructor. - In `Kalendae.Input` this defaults to the document body. - Can be an Element or an element's string ID. -- `format`: The format mask used when parsing date strings. +- `format`: The format mask used when parsing date strings. - Uses moment.js notation (see http://momentjs.com/docs/#/display/format ) - If left undefined, will attempt to parse the date automatically. - Default is `null`. @@ -122,6 +122,8 @@ The following options are available for configuration. - `dayOutOfMonthClickable`: Allow clicks on days that fall outside of the currently focused month. Default is `false`. +- `dayHeaderClickable`: Allow click on header days to select all instances of the selected day name. It only works in "multiple" mode. Default is `false`. + - `useYearNav`: Include the double-arrow year navigation. Default is `true`. - `side`: Chooses the side on which to display the picker. Default is `bottom`. @@ -140,7 +142,7 @@ The following settings alter the internal behavior of Kalendae and should only b - `dayNumberFormat`: Format string for individual day numbers. - Default is `"D"` -- `dayAttributeFormat`: Format string for the `data-date` attribute set on every span +- `dayAttributeFormat`: Format string for the `data-date` attribute set on every span - Default is `"YYYY-MM-DD"` - `parseSplitDelimiter`: RegExp used when splitting multiple dates from a passed string diff --git a/src/main.js b/src/main.js index 0045381..3c16838 100644 --- a/src/main.js +++ b/src/main.js @@ -121,10 +121,31 @@ var Kalendae = function (targetElement, options) { $caption = util.make('span', {'class':classes.caption}, $title); //title caption //column headers - $header = util.make('div', {'class':classes.header}, $cal); + $header = util.make('div', {'class':classes.header + ' ' + (opts.dayHeaderClickable == true ? classes.dayActive : '')}, $cal); i = 0; do { - $span = util.make('span', {}, $header); + $span = util.make('span', {'data-day':i}, $header); + + if (opts.dayHeaderClickable == true && opts.mode == 'multiple') { + $span.addEventListener("mouseover", function(e){ + var daysContainer = e.target.parentNode.nextSibling; + daysToHover = daysContainer.getElementsByClassName('k-day-week-' + e.target.getAttribute('data-day')); + if (daysToHover.length > 0) { + for (var i = 0; i < daysToHover.length; i++) { + if (util.hasClassName(daysToHover[i], classes.dayActive)) util.addClassName(daysToHover[i], 'k-day-hover-active'); + } + } + }); + $span.addEventListener("mouseleave", function(e){ + var daysContainer = e.target.parentNode.nextSibling; + daysToHover = daysContainer.getElementsByClassName('k-day-week-' + e.target.getAttribute('data-day')); + if (daysToHover.length > 0) { + for (var i = 0; i < daysToHover.length; i++) { + if (util.hasClassName(daysToHover[i], classes.dayActive)) util.removeClassName(daysToHover[i], 'k-day-hover-active'); + } + } + }); + } $span.innerHTML = columnHeaders[i]; } while (++i < 7); @@ -146,6 +167,7 @@ var Kalendae = function (targetElement, options) { //store each calendar view for easy redrawing calendars.push({ + header:$header, caption:$caption, days:dayNodes }); @@ -223,6 +245,20 @@ var Kalendae = function (targetElement, options) { } } return false; + + } else if (util.hasClassName(target.parentNode, classes.header)) { + if (opts.mode == 'multiple' && opts.dayHeaderClickable == true) { + var parentSelected = util.hasClassName(target, classes.daySelected), + month = target.parentNode.parentNode.getAttribute('data-datestart'), + dayToSelect = target.getAttribute('data-day'); + + if (parentSelected == true) { + self.monthDaySelected(month, dayToSelect, true); + } else { + self.monthDaySelected(month, dayToSelect, false); + } + } + return false; } return false; @@ -247,6 +283,7 @@ Kalendae.prototype = { selected :null, /* dates already selected. can be string, date, or array of strings or dates. */ mode :'single', /* single, multiple, range */ dayOutOfMonthClickable:false, + dayHeaderClickable :false, format :null, /* string used for parsing dates. */ subscribe :null, /* object containing events to subscribe to */ @@ -444,6 +481,23 @@ Kalendae.prototype = { this.draw(); }, + monthDaySelected: function(month, daynumber, unselected) { + var days = moment(month).startOf('month').weekday(daynumber), + endMonth = moment(month).endOf('month'); + selected = []; + + while(days <= endMonth) { + if (days >= moment(month).startOf('month') && !this.direction(days)) { + if (unselected) { + this.removeSelected(moment(days).hours(12)); + } else { + this.addSelected(moment(days).hours(12)); + } + } + days.add(7, 'd'); + } + }, + makeSelectedDateVisible: function (date) { outOfViewMonth = moment(date).date('1').diff(this.viewStartDate,'months'); @@ -479,8 +533,10 @@ Kalendae.prototype = { klass, i=0, c, j=0, k, + t=0, z, w, s, + headers, dateString, opts = this.settings, diff; @@ -493,9 +549,19 @@ Kalendae.prototype = { //if the first day of the month is less than our week start, back up a week cal = this.calendars[i]; + + cal.header.parentNode.setAttribute('data-datestart', month.format(this.settings.dayAttributeFormat)); + cal.caption.innerHTML = month.format(this.settings.titleFormat); j = 0; w = 0; + t = 0; + headers = []; + for (var z = 0; z < 7; z++) { + util.removeClassName(cal.header.children[z], classes.daySelected); + headers[z] = 0; + } + do { if (opts.mode == 'week') { if (((j % 7) === 0) && (j !== 0)) { @@ -512,6 +578,13 @@ Kalendae.prototype = { if (s) klass.push(({'-1':classes.dayInRange,'1':classes.daySelected, 'true':classes.daySelected})[s]); + if (opts.dayHeaderClickable == true && opts.mode == 'multiple') { + klass.push('k-day-week-' + day.weekday()); + if ((s == true || s == 1) && !this.direction(day) && month.format('M') == day.format('M')) { + headers[day.weekday()] = headers[day.weekday()] + 1; + } + } + if (day.month() != month.month()) klass.push(classes.dayOutOfMonth); else klass.push(classes.dayInMonth); @@ -529,6 +602,25 @@ Kalendae.prototype = { day.add(1, 'days'); } while (++j < 42); + z = 0; + if (headers.length > 0) { + do { + if (headers[z] > 0) { + var firstDay = Kalendae.moment(month).startOf('month').weekday(z), + startMonth = Kalendae.moment(month).startOf('month'); + endMonth = Kalendae.moment(month).endOf('month'); + t = 0; + do { + if (firstDay >= startMonth && !this.direction(firstDay)) t++; + firstDay.add(7, 'd'); + } while(firstDay <= endMonth) + + if (t == headers[z]) util.addClassName(cal.header.children[z], classes.daySelected); + else util.removeClassName(cal.header.children[z], classes.daySelected); + } + } while(++z < headers.length) + } + month.add(1, 'months'); } while (++i < c); From 2af6b41cdb66df94a045322f43d7a3ca74ab0ce8 Mon Sep 17 00:00:00 2001 From: Erick Torres Date: Thu, 7 Jan 2016 18:11:04 -0500 Subject: [PATCH 2/3] Add demo --- index.html | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 9b681ee..50b8751 100644 --- a/index.html +++ b/index.html @@ -83,7 +83,31 @@

Kalendae

selected:[Kalendae.moment().subtract({M:1}), Kalendae.moment().add({M:1})] }); + +

Month header day select (Multi-select)

+

Week Select

@@ -173,7 +197,7 @@

Kalendae


So is the one on this input. - +
Scroll down and left to find an input. From 915c0b272d61618da8adcf909693aa390e9fe580 Mon Sep 17 00:00:00 2001 From: Erick Torres Date: Fri, 8 Jan 2016 17:45:34 -0500 Subject: [PATCH 3/3] Add the trailing spaces back into the readme --- readme.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/readme.md b/readme.md index 82624ad..b227120 100644 --- a/readme.md +++ b/readme.md @@ -15,13 +15,13 @@ Kalendae is an attempt to do something that nobody has yet been able to do: make ##Screenshots -Default calendar, no options defined. +Default calendar, no options defined. ![screenshot](http://i.imgur.com/Ig52z.png) -Two month calendar attached to an input element. +Two month calendar attached to an input element. ![screenshot](http://i.imgur.com/GIR3g.png) -Two month, range selection, future dates only, with weekends blacked out: +Two month, range selection, future dates only, with weekends blacked out: ![screenshot](http://i.imgur.com/JzBc7.png) ###[View The Demo Page](http://chipersoft.github.com/Kalendae/) @@ -72,12 +72,12 @@ To ease date handling processes, Kalendae bundles the [moment.js](http://www.mom The following options are available for configuration. -- `attachTo`: The element that the calendar div will be appended to. +- `attachTo`: The element that the calendar div will be appended to. - In `Kalendae` this defaults to the first argument on the constructor. - In `Kalendae.Input` this defaults to the document body. - Can be an Element or an element's string ID. -- `format`: The format mask used when parsing date strings. +- `format`: The format mask used when parsing date strings. - Uses moment.js notation (see http://momentjs.com/docs/#/display/format ) - If left undefined, will attempt to parse the date automatically. - Default is `null`. @@ -142,7 +142,7 @@ The following settings alter the internal behavior of Kalendae and should only b - `dayNumberFormat`: Format string for individual day numbers. - Default is `"D"` -- `dayAttributeFormat`: Format string for the `data-date` attribute set on every span +- `dayAttributeFormat`: Format string for the `data-date` attribute set on every span - Default is `"YYYY-MM-DD"` - `parseSplitDelimiter`: RegExp used when splitting multiple dates from a passed string @@ -250,4 +250,3 @@ To create a minified version, run `make minified`. If the minified file is blan ##License Kalendae is released under an MIT license and is freely distributable. -