├── .gitignore
├── LICENSE
├── README.md
├── bower.json
├── example
├── developer.html
└── index.html
├── gulpfile.coffee
├── gulpfile.js
├── package.json
└── src
├── build
├── datepicker.css
└── datepicker.min.js
├── css
└── datepicker.styl
└── js
├── ui
├── datepicker
│ ├── DatePicker.jsx
│ ├── DatePickerInput.jsx
│ ├── Day.jsx
│ └── DayPicker.jsx
└── numberpicker
│ └── NumberPicker.jsx
└── utils
└── DateUtils.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .idea/
3 | bower_components/
4 | node_modules/
5 | tmp/
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 misino
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #react-datepicker
2 |
3 | Datepicker component for applications based on Facebook React library.
4 |
5 | ##Usage
6 | Standalone datepicker element. It can perform action if date is selected. Parameters are optional.
7 | For best functionality, *DatePicker* needs to be wrapped in component which sets new date on *onChangeDate* event. An example of such wrapper component could be *DatepickerInput*.
8 |
9 | ```
10 | var callback = function(date) {
11 | alert('new selected date is: '+date);
12 | }
13 |
14 |
15 | ```
16 |
17 | This library contains own datepicker integration with input element.
18 | All parameters are optional.
19 | Parameter *beforeUpdate* has to be function which returns string. This string will be set as value of input field before date change.
20 |
21 | ```
22 | var returnDate = function(date) {return date}; // this callback will be called before input field update. You can use it for example for date formatting as is shown in example/index.html
23 |
24 | ```
25 |
26 | minified javascript and css are located in directory `src/build`
27 |
28 | ###Development
29 | If you want to make changes in code and use benefits of compiling code, you need to have gulp and bower installed.
30 |
31 | ```
32 | npm install -g gulp
33 | npm install -g bower
34 | ```
35 |
36 | before running gulp for the first time, install dependencies and download other stuff via bower
37 |
38 | ```
39 | cd react-datepicker
40 | npm install
41 | bower install
42 | ```
43 |
44 | Compile code via command `gulp build` or `gulp`
45 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-datepicker",
3 | "version": "0.2.0",
4 | "private": true,
5 | "dependencies": {
6 | "este-library": "git://github.com/steida/este-library.git"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/example/developer.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Datepicker Example - unminified files
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
Standalone datepicker
15 |
16 |
17 |
18 |
Input element which is customized to get date from datepicker
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
50 |
51 |
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Datepicker Example
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
Standalone datepicker
13 |
14 |
15 |
16 |
Input element which is customized to get date from datepicker
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
48 |
49 |
--------------------------------------------------------------------------------
/gulpfile.coffee:
--------------------------------------------------------------------------------
1 | gulp = require 'gulp'
2 |
3 | GulpEste = require 'gulp-este'
4 | runSequence = require 'run-sequence'
5 |
6 | este = new GulpEste __dirname, true, '../../../..'
7 |
8 | paths =
9 | stylus: [
10 | 'src/css/datepicker.styl'
11 | ]
12 | coffee: [
13 | 'bower_components/este-library/este/**/*.coffee'
14 | 'src/**/*.coffee'
15 | ]
16 | jsx: [
17 | 'src/**/*.jsx'
18 | ]
19 | js: [
20 | 'bower_components/closure-library/**/*.js'
21 | 'bower_components/este-library/este/**/*.js'
22 | 'src/**/*.js'
23 | 'tmp/**/*.js'
24 | '!**/build/**'
25 | ]
26 | compiler: 'bower_components/closure-compiler/compiler.jar'
27 | externs: [
28 | 'bower_components/react-externs/externs.js'
29 | ]
30 | thirdParty:
31 | development: [
32 | # 'bower_components/react/react.js'
33 | ]
34 | production: [
35 | # 'bower_components/react/react.min.js'
36 | ]
37 |
38 | dirs =
39 | googBaseJs: 'bower_components/closure-library/closure/goog'
40 | watch: ['src']
41 |
42 | gulp.task 'stylus', ->
43 | este.stylus paths.stylus
44 |
45 | gulp.task 'coffee', ->
46 | este.coffee paths.coffee
47 |
48 | gulp.task 'jsx', ->
49 | este.jsx paths.jsx
50 |
51 | gulp.task 'transpile', (done) ->
52 | runSequence 'stylus', 'coffee', 'jsx', done
53 |
54 | gulp.task 'deps', ->
55 | este.deps paths.js
56 |
57 | gulp.task 'concat-deps', ->
58 | este.concatDeps()
59 |
60 | gulp.task 'compile-datepicker', ->
61 | este.compile paths.js, 'src/build',
62 | fileName: 'datepicker.min.js'
63 | compilerPath: paths.compiler
64 | compilerFlags:
65 | closure_entry_point: 'misino.ui.datepicker.DatePickerInput'
66 | externs: paths.externs
67 | warning_level: 'VERBOSE'
68 | compilation_level: 'ADVANCED_OPTIMIZATIONS'
69 |
70 | gulp.task 'concat-all', ->
71 | este.concatAll
72 | 'src/build/react-datepicker-thirdparty.js': paths.thirdParty
73 |
74 |
75 | gulp.task 'js', (done) ->
76 | runSequence [
77 | 'deps' if este.shouldCreateDeps()
78 | 'concat-deps'
79 | 'compile-datepicker'
80 | 'concat-all'
81 | done
82 | ].filter((task) -> task)...
83 |
84 | gulp.task 'build', (done) ->
85 | runSequence 'transpile', 'js', done
86 |
87 | gulp.task 'watch', ->
88 | este.watch dirs.watch,
89 | coffee: 'coffee'
90 | js: 'js'
91 | jsx: 'jsx'
92 | styl: 'stylus'
93 | , (task) -> gulp.start task
94 |
95 | gulp.task 'run', (done) ->
96 | runSequence [
97 | 'watch'
98 | done
99 | ].filter((task) -> task)...
100 |
101 | gulp.task 'default', (done) ->
102 | runSequence 'build', 'run', done
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | // Generated by CoffeeScript 1.7.0
2 | (function() {
3 | var GulpEste, dirs, este, gulp, paths, runSequence;
4 |
5 | gulp = require('gulp');
6 |
7 | GulpEste = require('gulp-este');
8 |
9 | runSequence = require('run-sequence');
10 |
11 | este = new GulpEste(__dirname, true, '../../../..');
12 |
13 | paths = {
14 | stylus: ['src/css/datepicker.styl'],
15 | coffee: ['bower_components/este-library/este/**/*.coffee', 'src/**/*.coffee'],
16 | jsx: ['src/**/*.jsx'],
17 | js: ['bower_components/closure-library/**/*.js', 'bower_components/este-library/este/**/*.js', 'src/**/*.js', 'tmp/**/*.js', '!**/build/**'],
18 | compiler: 'bower_components/closure-compiler/compiler.jar',
19 | externs: ['bower_components/react-externs/externs.js'],
20 | thirdParty: {
21 | development: [],
22 | production: []
23 | }
24 | };
25 |
26 | dirs = {
27 | googBaseJs: 'bower_components/closure-library/closure/goog',
28 | watch: ['src']
29 | };
30 |
31 | gulp.task('stylus', function() {
32 | return este.stylus(paths.stylus);
33 | });
34 |
35 | gulp.task('coffee', function() {
36 | return este.coffee(paths.coffee);
37 | });
38 |
39 | gulp.task('jsx', function() {
40 | return este.jsx(paths.jsx);
41 | });
42 |
43 | gulp.task('transpile', function(done) {
44 | return runSequence('stylus', 'coffee', 'jsx', done);
45 | });
46 |
47 | gulp.task('deps', function() {
48 | return este.deps(paths.js);
49 | });
50 |
51 | gulp.task('concat-deps', function() {
52 | return este.concatDeps();
53 | });
54 |
55 | gulp.task('compile-datepicker', function() {
56 | return este.compile(paths.js, 'src/build', {
57 | fileName: 'datepicker.min.js',
58 | compilerPath: paths.compiler,
59 | compilerFlags: {
60 | closure_entry_point: 'misino.ui.datepicker.DatePickerInput',
61 | externs: paths.externs,
62 | warning_level: 'VERBOSE',
63 | compilation_level: 'ADVANCED_OPTIMIZATIONS'
64 | }
65 | });
66 | });
67 |
68 | gulp.task('concat-all', function() {
69 | return este.concatAll({
70 | 'src/build/react-datepicker-thirdparty.js': paths.thirdParty
71 | });
72 | });
73 |
74 | gulp.task('js', function(done) {
75 | return runSequence.apply(null, [este.shouldCreateDeps() ? 'deps' : void 0, 'concat-deps', 'compile-datepicker', 'concat-all', done].filter(function(task) {
76 | return task;
77 | }));
78 | });
79 |
80 | gulp.task('build', function(done) {
81 | return runSequence('transpile', 'js', done);
82 | });
83 |
84 | gulp.task('watch', function() {
85 | return este.watch(dirs.watch, {
86 | coffee: 'coffee',
87 | js: 'js',
88 | jsx: 'jsx',
89 | styl: 'stylus'
90 | }, function(task) {
91 | return gulp.start(task);
92 | });
93 | });
94 |
95 | gulp.task('run', function(done) {
96 | return runSequence.apply(null, ['watch', done].filter(function(task) {
97 | return task;
98 | }));
99 | });
100 |
101 | gulp.task('default', function(done) {
102 | return runSequence('build', 'run', done);
103 | });
104 |
105 | }).call(this);
106 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-datepicker",
3 | "version": "0.2.1",
4 | "description": "",
5 | "author": "Michal Biros ",
6 | "keywords": [
7 | "React",
8 | "Datepicker"
9 | ],
10 | "private": true,
11 | "repository": {
12 | "type": "git",
13 | "url": "https://github.com/misino/react-datepicker.git"
14 | },
15 | "dependencies": {
16 | "react": "^0.10.0",
17 | "gulp": "^3.6.0"
18 | },
19 | "devDependencies": {
20 | "gulp-este": "^0.5.2",
21 | "run-sequence": "^0.3.6"
22 | },
23 | "scripts": {
24 | "test": "gulp build"
25 | },
26 | "license": "MIT",
27 | "subdomain": "react-datepicker"
28 | }
29 |
--------------------------------------------------------------------------------
/src/build/datepicker.css:
--------------------------------------------------------------------------------
1 | div.datepicker-dates{position:relative;width:156px;height:100%;margin-top:.5em}div.datepicker-dates div.day{position:absolute}.dayInWeek-1{left:0}.dayInWeek-2{left:22px}.dayInWeek-3{left:44px}.dayInWeek-4{left:66px}.dayInWeek-5{left:88px}.dayInWeek-6{left:110px}.dayInWeek-0{left:132px}.week-1{top:0}.week-2{top:24px}.week-3{top:48px}.week-4{top:72px}.week-5{top:96px}.week-6{top:120px}.datepicker{position:relative;height:220px;width:170px;z-index:10}.datepicker .day a{width:20px;display:block;text-align:center;color:#222;text-decoration:none;padding:2px}.datepicker .day a:hover{background-color:#eaeaea}.datepicker .out .day a{color:#bcbcbc}.datepicker .numberpicker{margin:.2em;text-align:center}.datepicker .day.selected{background-color:#c9c9c9}.datepicker-container{position:relative;border:1px solid #979797;padding:.5em;background-color:#fff;height:220px}.datepicker-wrapper{position:absolute}
--------------------------------------------------------------------------------
/src/build/datepicker.min.js:
--------------------------------------------------------------------------------
1 | (function(){var g=this;function h(a,b){var d=a.split("."),c=g;d[0]in c||!c.execScript||c.execScript("var "+d[0]);for(var e;d.length&&(e=d.shift());)d.length||void 0===b?c=c[e]?c[e]:c[e]={}:c[e]=b};function k(a,b){for(var d=[],c=a;c<=b;c++)d.push(c);return d}function l(a,b){var d=new Date;d.setTime(b);d.setDate(a);return d}function m(a,b,d){var c=new Date;c.setTime(d);c.setMonth(b);c.setDate(a);return c};var n=React.createClass({f:"Day",q:function(a){a.preventDefault();this.props.e(this.props.d)},getDefaultProps:function(){return{selected:!1}},render:function(){var a="day week-"+this.props.k+" dayInWeek-"+this.props.d.getDay(),a=a+(this.props.selected?" selected":"");return React.DOM.div({className:a},React.DOM.a({href:"#",onClick:this.q},this.props.d.getDate()))}});var p=React.createClass({f:"DayPicker",h:function(a){this.props.w(a)},render:function(){var a=this.props.d,b=(new Date(a.getFullYear(),a.getMonth()-1+1,0)).getDate(),d=l(1,a.getTime()),c=(0===d.getDay()?7:d.getDay())-1,b=k(b-c+1,b),e=b.map(function(b){b=m(b,a.getMonth()-1,a.getTime());return n({d:b,k:1,e:this.h})}.bind(this)),b=k(1,(new Date(a.getFullYear(),a.getMonth()+1,0)).getDate()),f=b.map(function(b){var d=l(b,a.getTime()),e=Math.ceil((b+c)/7),f=!1;a.getMonth()==this.props.j.getMonth()&&a.getFullYear()==
2 | this.props.j.getFullYear()&&(f=b==this.props.j.getDate());return n({selected:f,d:d,k:e,e:this.h})}.bind(this)),b=k(1,42-e.length-f.length),b=b.map(function(b){var c=m(b,a.getMonth()+1,a.getTime());return n({d:c,k:Math.ceil((e.length+f.length+b)/7),e:this.h})}.bind(this));return React.DOM.div({className:"datepicker-dates"},React.DOM.div({className:"out"},e),React.DOM.div(null,f),React.DOM.div({className:"out"},b))}});var q=React.createClass({f:"NumberPicker",getDefaultProps:function(){return{number:0}},l:function(a){this.props.m(a.target.getAttribute("data-number"))},render:function(){return React.DOM.div({className:"numberpicker"},React.DOM.a({onClick:this.l,"data-number":this.props.number-1,className:"btn btn-xs btn-default"},"<<"),React.DOM.span({className:"btn btn-xs"},this.props.number),React.DOM.a({onClick:this.l,"data-number":this.props.number+1,className:"btn btn-xs btn-default"},">>"))}});var r=React.createClass({f:"DatePicker",v:function(a){this.setState({c:a})},t:function(a){this.setState({c:a});this.props.onChangeDate(a)},getDefaultProps:function(){return{date:new Date,show:!0,onChangeDate:function(a){console.log("You have selected new date"+a)}}},getInitialState:function(){var a=new Date;a.setTime(this.props.date.getTime());return{c:a}},o:function(a){var b=new Date;b.setTime(this.state.c.getTime());b.setFullYear(a);this.setState({c:b})},n:function(a){var b=new Date;b.setTime(this.state.c.getTime());
3 | b.setMonth(a-1);this.setState({c:b})},render:function(){return React.DOM.div({className:"datepicker",style:{display:this.props.show?"block":"none"}},React.DOM.div({className:"datepicker-container"},q({number:this.state.c.getFullYear(),m:this.o}),q({number:this.state.c.getMonth()+1,m:this.n}),p({d:this.state.c,j:this.props.date,e:this.v,w:this.t})))}});h("DatePicker",r);var s=React.createClass({f:"DatePickerInput",getDefaultProps:function(){return{date:new Date,beforeUpdate:function(a){return a}}},getInitialState:function(){return{show:!1}},A:function(){this.setState({show:!0})},r:function(){this.setState({show:!1})},s:function(a){this.props.date=a;this.setState({show:!1})},render:function(){return React.DOM.div(null,React.DOM.div({style:{position:"fixed",top:0,left:0,width:"100%",height:"100%",display:this.state.show?"block":"none"},onClick:this.r}),React.DOM.div({className:"datepicker-wrapper"},
4 | r({date:this.props.date,show:this.state.show,onChangeDate:this.s})),React.DOM.input({type:"text",onFocus:this.A,value:this.props.beforeUpdate(this.props.date)}))}});h("DatePickerInput",s);})();
5 |
--------------------------------------------------------------------------------
/src/css/datepicker.styl:
--------------------------------------------------------------------------------
1 | div.datepicker-dates {
2 | position: relative;
3 | width: 156px;
4 | height: 100%;
5 | margin-top: 0.5em;
6 | div.day {
7 | position:absolute;
8 | }
9 | }
10 |
11 | .dayInWeek-1 {
12 | left:0;
13 | }
14 | .dayInWeek-2 {
15 | left:22px;
16 | }
17 | .dayInWeek-3 {
18 | left:44px;
19 | }
20 | .dayInWeek-4 {
21 | left:66px;
22 | }
23 | .dayInWeek-5 {
24 | left:88px;
25 | }
26 | .dayInWeek-6 {
27 | left:110px;
28 | }
29 | .dayInWeek-0 {
30 | left:132px;
31 | }
32 | .week-1 {
33 | top:0;
34 | }
35 | .week-2 {
36 | top:24px;
37 | }
38 | .week-3 {
39 | top:48px;
40 | }
41 | .week-4 {
42 | top:72px;
43 | }
44 | .week-5 {
45 | top:96px;
46 | }
47 | .week-6 {
48 | top:120px;
49 | }
50 | .datepicker {
51 | position:relative;
52 | height: 220px;
53 | width: 170px;
54 | z-index: 10;
55 | .day {
56 | a {
57 | width:20px;
58 | display: block;
59 | text-align: center;
60 | color: #222;
61 | text-decoration:none;
62 | padding: 2px;
63 | }
64 | a:hover {
65 | background-color: #eaeaea;
66 | }
67 | }
68 | .out .day a {
69 | color: #bcbcbc;
70 | }
71 | .numberpicker {
72 | margin:0.2em;
73 | text-align: center;
74 | }
75 | .day.selected {
76 | background-color: #c9c9c9;
77 | }
78 | }
79 | .datepicker-container {
80 | position:relative;
81 | border:1px solid #979797;
82 | padding:0.5em;
83 | background-color: #fff;
84 | height: 220px;
85 | }
86 | .datepicker-wrapper {
87 | position:absolute;
88 | }
--------------------------------------------------------------------------------
/src/js/ui/datepicker/DatePicker.jsx:
--------------------------------------------------------------------------------
1 | /** @jsx React.DOM */
2 |
3 | goog.provide('misino.ui.datepicker.DatePicker');
4 | goog.require('misino.ui.numberpicker.NumberPicker');
5 | goog.require('misino.ui.datepicker.DayPicker');
6 |
7 | var DatePicker = React.createClass(/** @lends {React.ReactComponent.prototype} */{
8 | /**
9 | *
10 | * @param {Date} date
11 | */
12 | onChangeVisibleDate: function(date) {
13 | this.setState({visibleDate:date});
14 | },
15 | /**
16 | *
17 | * @param {Date} date
18 | */
19 | onChangeSelectedDate: function(date) {
20 | this.setState({visibleDate:date});
21 | this.props['onChangeDate'](date);
22 | },
23 | /**
24 | *
25 | * @returns {{date: Date, show: boolean, onChangeDate: Function}}
26 | */
27 | getDefaultProps: function() {
28 | return({'date':new Date(), 'show':true, 'onChangeDate': function(date) {
29 | console.log('You have selected new date' + date);
30 | }});
31 | },
32 | /**
33 | *
34 | * @returns {{visibleDate: Date}}
35 | */
36 | getInitialState: function() {
37 | var date = new Date();
38 | date.setTime(this.props['date'].getTime());
39 | return({visibleDate:date});
40 | },
41 | /**
42 | *
43 | * @param {number} year
44 | */
45 | changeYear: function(year) {
46 | var date = new Date();
47 | date.setTime(this.state.visibleDate.getTime());
48 | date.setFullYear(year);
49 | this.setState({visibleDate:date});
50 | },
51 | /**
52 | *
53 | * @param {number} month
54 | */
55 | changeMonth: function(month) {
56 | var date = new Date();
57 | date.setTime(this.state.visibleDate.getTime());
58 | date.setMonth(month-1);
59 | this.setState({visibleDate:date});
60 | },
61 | render: function () {
62 | var style = {display:(this.props['show']?'block':'none')};
63 | return (
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | );
73 | }
74 | });
75 |
76 | goog.exportSymbol('DatePicker', DatePicker);
--------------------------------------------------------------------------------
/src/js/ui/datepicker/DatePickerInput.jsx:
--------------------------------------------------------------------------------
1 | /** @jsx React.DOM */
2 |
3 | goog.provide('misino.ui.datepicker.DatePickerInput');
4 | goog.require('misino.ui.datepicker.DatePicker');
5 |
6 | var DatePickerInput = React.createClass(/** @lends {React.ReactComponent.prototype} */{
7 | /**
8 | *
9 | * @returns {{date: Date}}
10 | */
11 | getDefaultProps: function() {
12 | return({'date':new Date(), 'beforeUpdate': function(date) {
13 | return date;
14 | }});
15 | },
16 | /**
17 | *
18 | * @returns {{show: boolean}}
19 | */
20 | getInitialState: function() {
21 | return {show:false};
22 | },
23 | showDatePicker: function() {
24 | this.setState({show:true});
25 | },
26 | hideDatePicker: function() {
27 | this.setState({show:false});
28 | },
29 | /**
30 | *
31 | * @param {Date} date
32 | */
33 | onChangeDate: function(date) {
34 | this.props['date'] = date;
35 | this.setState({show:false});
36 | },
37 | render: function() {
38 | var style={position:'fixed', top:0,left:0, width:'100%', height:'100%', display:(this.state.show?'block':'none')};
39 | // DatePicker is not defined as JSX because of closure compiler
40 | return (
41 |
42 |
43 |
44 | {DatePicker( {'date':this.props['date'], 'show':this.state.show, 'onChangeDate':this.onChangeDate})}
45 |
46 |
47 |
48 | );
49 | }
50 | });
51 |
52 | goog.exportSymbol('DatePickerInput', DatePickerInput);
--------------------------------------------------------------------------------
/src/js/ui/datepicker/Day.jsx:
--------------------------------------------------------------------------------
1 | /** @jsx React.DOM */
2 |
3 | goog.provide('misino.ui.datepicker.Day');
4 |
5 | var Day = React.createClass(/** @lends {React.ReactComponent.prototype} */{
6 | /**
7 | *
8 | * @param e
9 | */
10 | handleClick: function(e) {
11 | e.preventDefault();
12 | this.props.changeDate(this.props.date);
13 | },
14 | /**
15 | *
16 | * @returns {{selected: boolean}}
17 | */
18 | getDefaultProps: function() {
19 | return {selected:false};
20 | },
21 | render: function() {
22 | var className="day week-"+this.props.week+" dayInWeek-"+this.props.date.getDay();
23 | className += (this.props.selected?' selected':'');
24 | return (
25 |
28 | );
29 | }
30 | });
--------------------------------------------------------------------------------
/src/js/ui/datepicker/DayPicker.jsx:
--------------------------------------------------------------------------------
1 | /** @jsx React.DOM */
2 |
3 | goog.provide('misino.ui.datepicker.DayPicker');
4 | goog.require('misino.utils.DateUtils');
5 | goog.require('misino.ui.datepicker.Day');
6 |
7 | var DayPicker = React.createClass(/** @lends {React.ReactComponent.prototype} */{
8 | /**
9 | *
10 | * @param {Date} date
11 | */
12 | selectDay: function(date) {
13 | this.props.selectDate(date);
14 | },
15 | render: function (){
16 | var date=this.props.date,
17 | beforeDaysCount = DateUtils.daysInMonthCount((date.getMonth()-1), date.getFullYear()),
18 | firstDay = DateUtils.createNewDay(1, date.getTime()),
19 | offset = (firstDay.getDay()===0?7:firstDay.getDay())- 1,
20 | daysArray = DateUtils.getArrayByBoundary(beforeDaysCount-offset+1, beforeDaysCount);
21 |
22 | var previousMonthDays = daysArray.map(function(day){
23 | var thisDate = DateUtils.createNewDayMonth(day, date.getMonth()-1, date.getTime());
24 | return
25 | }.bind(this));
26 |
27 | daysArray = DateUtils.getArrayByBoundary(1, DateUtils.daysInMonthCount(date.getMonth(), date.getFullYear()));
28 | var actualMonthDays = daysArray.map(function(day) {
29 | var thisDate = DateUtils.createNewDay(day, date.getTime()),
30 | weekNumber = Math.ceil((day+offset) / 7),
31 | selected = false;
32 |
33 | if(date.getMonth()==this.props.selectedDate.getMonth() && date.getFullYear()==this.props.selectedDate.getFullYear()) {
34 | selected = (day==this.props.selectedDate.getDate());
35 | }
36 | return
37 | }.bind(this));
38 |
39 | daysArray = DateUtils.getArrayByBoundary(1, 42- previousMonthDays.length - actualMonthDays.length);
40 | var nextMonthDays = daysArray.map(function(day){
41 | var thisDate = DateUtils.createNewDayMonth(day, date.getMonth()+1, date.getTime()),
42 | weekNumber = Math.ceil((previousMonthDays.length + actualMonthDays.length + day) / 7);
43 | return
44 | }.bind(this));
45 |
46 | return (
47 |
48 |
49 | {previousMonthDays}
50 |
51 |
52 | {actualMonthDays}
53 |
54 |
55 | {nextMonthDays}
56 |
57 |
58 | );
59 | }
60 | });
--------------------------------------------------------------------------------
/src/js/ui/numberpicker/NumberPicker.jsx:
--------------------------------------------------------------------------------
1 | /** @jsx React.DOM */
2 |
3 | goog.provide('misino.ui.numberpicker.NumberPicker');
4 |
5 | var NumberPicker = React.createClass(/** @lends {React.ReactComponent.prototype} */{
6 | getDefaultProps: function() {
7 | return {number:0};
8 | },
9 | changeNumber: function(e) {
10 | this.props.onChangeNumber(e.target.getAttribute('data-number'));
11 | },
12 |
13 | render: function() {
14 | return (
15 |
16 |
<<
17 |
{this.props.number}
18 |
>>
19 |
20 | )
21 | }
22 | });
--------------------------------------------------------------------------------
/src/js/utils/DateUtils.js:
--------------------------------------------------------------------------------
1 | goog.provide('misino.utils.DateUtils');
2 |
3 | var DateUtils = {
4 | /**
5 | * Gets count of days in current month.
6 | * @param {number} month January has number 1. February 2, ... and so on
7 | * @param {number} year
8 | * @returns {number}
9 | */
10 | daysInMonthCount: function(month, year) {
11 | var d =new Date(year, month+1, 0);
12 | return d.getDate();
13 | },
14 | /**
15 | * Gets array of numbers starting from start to end
16 | * @param {number} start
17 | * @param {number} end
18 | * @returns {Array} array of numbers
19 | */
20 | getArrayByBoundary: function(start, end) {
21 | var out = [];
22 | for(var i= start; i<=end; i++) {
23 | out.push(i);
24 | }
25 | return out;
26 | },
27 | /**
28 | * Creates new Date() instance.
29 | * @param {number} date day in month
30 | * @param {number} time
31 | * @returns {Date}
32 | */
33 | createNewDay: function(date, time) {
34 | var newDate = new Date();
35 | newDate.setTime(time);
36 | newDate.setDate(date);
37 | return newDate;
38 | },
39 | /**
40 | * Creates new Date() instance.
41 | * @param {number} date day in month
42 | * @param {number} month
43 | * @param {number} time
44 | * @returns {Date}
45 | */
46 | createNewDayMonth: function(date, month, time) {
47 | var newDate = new Date();
48 | newDate.setTime(time);
49 | newDate.setMonth(month);
50 | newDate.setDate(date);
51 | return newDate;
52 | }
53 | }
--------------------------------------------------------------------------------