├── .editorconfig ├── .github └── workflows │ └── comment-issue.yml ├── .gitignore ├── .jshintrc ├── .travis.yml ├── .versions ├── LICENSE ├── README.md ├── autoform-bs-datetimepicker.html ├── autoform-bs-datetimepicker.js └── package.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | indent_style = space 7 | indent_size = 2 8 | trim_trailing_whitespace = true 9 | charset = utf-8 10 | 11 | [*.js] 12 | max_line_length = 80 13 | indent_brace_style = 1TBS 14 | spaces_around_operators = true 15 | quote_type = auto -------------------------------------------------------------------------------- /.github/workflows/comment-issue.yml: -------------------------------------------------------------------------------- 1 | name: Add immediate comment on new issues 2 | 3 | on: 4 | issues: 5 | types: [opened] 6 | 7 | jobs: 8 | createComment: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Create Comment 12 | uses: peter-evans/create-or-update-comment@v1.4.2 13 | with: 14 | issue-number: ${{ github.event.issue.number }} 15 | body: | 16 | Thank you for submitting this issue! 17 | 18 | We, the Members of Meteor Community Packages take every issue seriously. 19 | Our goal is to provide long-term lifecycles for packages and keep up 20 | with the newest changes in Meteor and the overall NodeJs/JavaScript ecosystem. 21 | 22 | However, we contribute to these packages mostly in our free time. 23 | Therefore, we can't guarantee your issues to be solved within certain time. 24 | 25 | If you think this issue is trivial to solve, don't hesitate to submit 26 | a pull request, too! We will accompany you in the process with reviews and hints 27 | on how to get development set up. 28 | 29 | Please also consider sponsoring the maintainers of the package. 30 | If you don't know who is currently maintaining this package, just leave a comment 31 | and we'll let you know 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .build* 3 | .npm* 4 | .meteor* 5 | smart.lock 6 | nbproject* 7 | /packages/ 8 | .idea/ 9 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "maxerr" : 50, 3 | "bitwise" : true, 4 | "camelcase" : true, 5 | "curly" : true, 6 | "eqeqeq" : true, 7 | "forin" : true, 8 | "immed" : false, 9 | "indent" : 2, 10 | "latedef" : false, 11 | "newcap" : false, 12 | "noarg" : true, 13 | "noempty" : true, 14 | "nonew" : false, 15 | "plusplus" : false, 16 | "quotmark" : false, 17 | "undef" : false, 18 | "unused" : true, 19 | "strict" : false, 20 | "trailing" : true, 21 | "maxparams" : false, 22 | "maxdepth" : false, 23 | "maxstatements" : false, 24 | "maxcomplexity" : false, 25 | "asi" : false, 26 | "boss" : false, 27 | "debug" : false, 28 | "eqnull" : false, 29 | "es5" : false, 30 | "esnext" : false, 31 | "moz" : false, 32 | "evil" : false, 33 | "expr" : false, 34 | "funcscope" : false, 35 | "globalstrict" : true, 36 | "iterator" : false, 37 | "lastsemic" : false, 38 | "laxbreak" : false, 39 | "laxcomma" : false, 40 | "loopfunc" : false, 41 | "multistr" : false, 42 | "proto" : false, 43 | "scripturl" : false, 44 | "smarttabs" : false, 45 | "shadow" : false, 46 | "sub" : false, 47 | "supernew" : false, 48 | "validthis" : false, 49 | "browser" : true, 50 | "couch" : false, 51 | "devel" : true, 52 | "dojo" : false, 53 | "jquery" : false, 54 | "mootools" : false, 55 | "node" : false, 56 | "nonstandard" : false, 57 | "prototypejs" : false, 58 | "rhino" : false, 59 | "worker" : false, 60 | "wsh" : false, 61 | "yui" : false, 62 | "nomen" : false, 63 | "onevar" : false, 64 | "passfail" : false, 65 | "white" : false, 66 | "predef" : [ 67 | "Meteor", 68 | "Accounts", 69 | "Session", 70 | "Template", 71 | "check", 72 | "Match", 73 | "Tracker", 74 | "EJSON", 75 | "Email", 76 | "Package", 77 | "Tinytest", 78 | "Npm", 79 | "Assets", 80 | "Packages", 81 | "process", 82 | "LocalCollection", 83 | "_", 84 | "Random", 85 | "HTTP" 86 | ] 87 | } 88 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | before_install: 5 | - "curl -L http://git.io/ejPSng | /bin/sh" -------------------------------------------------------------------------------- /.versions: -------------------------------------------------------------------------------- 1 | aldeed:autoform@4.0.0 2 | aldeed:autoform-bs-datetimepicker@1.0.7 3 | aldeed:simple-schema@1.1.0 4 | base64@1.0.3 5 | blaze@2.1.2 6 | blaze-tools@1.0.3 7 | callback-hook@1.0.3 8 | check@1.0.5 9 | ddp@1.1.0 10 | deps@1.0.7 11 | ejson@1.0.6 12 | geojson-utils@1.0.3 13 | html-tools@1.0.4 14 | htmljs@1.0.4 15 | id-map@1.0.3 16 | jquery@1.11.3_2 17 | json@1.0.3 18 | livedata@1.0.13 19 | logging@1.0.7 20 | meteor@1.1.6 21 | minifiers@1.1.5 22 | minimongo@1.0.8 23 | mrt:moment@2.6.0 24 | observe-sequence@1.0.6 25 | ordered-dict@1.0.3 26 | random@1.0.3 27 | reactive-var@1.0.5 28 | retry@1.0.3 29 | spacebars-compiler@1.0.6 30 | templating@1.1.1 31 | tracker@1.0.7 32 | ui@1.0.6 33 | underscore@1.0.3 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2017 Eric Dobbertin 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 | aldeed:autoform-bs-datetimepicker 2 | ========================= 3 | 4 | IMPORTANT: This repo is no longer maintained (but may still work for you). You can find forks and other alternatives that work better on [Atmosphere](https://atmospherejs.com/?q=autoform). 5 | 6 | An add-on Meteor package for [aldeed:autoform](https://github.com/aldeed/meteor-autoform). Provides a single custom input type, "bootstrap-datetimepicker", which renders an input using the [bootstrap-datetimepicker](http://eonasdan.github.io/bootstrap-datetimepicker/) plugin. 7 | 8 | ## Prerequisites 9 | 10 | Bootstrap and the plugin library must be installed separately. 11 | 12 | In a Meteor app directory, enter: 13 | 14 | ```bash 15 | $ meteor add twbs:bootstrap 16 | $ meteor add tsega:bootstrap3-datetimepicker@=3.1.3_3 17 | $ meteor add aldeed:autoform 18 | ``` 19 | 20 | If you need to use the `timezoneId` attribute to get the Date in some timezone other than the local client timezone, you must also add `moment-timezone`: 21 | 22 | ```bash 23 | $ meteor add risul:moment-timezone 24 | ``` 25 | 26 | Or install and import the NPM package. 27 | 28 | ## Installation 29 | 30 | In a Meteor app directory, enter: 31 | 32 | ```bash 33 | $ meteor add aldeed:autoform-bs-datetimepicker 34 | ``` 35 | 36 | ## Usage 37 | 38 | Specify "bootstrap-datetimepicker" for the `type` attribute of any input. This can be done in a number of ways: 39 | 40 | In the schema, which will then work with a `quickForm` or `afQuickFields`: 41 | 42 | ```js 43 | { 44 | date: { 45 | type: Date, 46 | autoform: { 47 | afFieldInput: { 48 | type: "bootstrap-datetimepicker", 49 | dateTimePickerOptions: {} 50 | } 51 | } 52 | } 53 | } 54 | ``` 55 | 56 | Or on the `afFieldInput` component or any component that passes along attributes to `afFieldInput`: 57 | 58 | ```js 59 | {{> afQuickField name="typeTest" type="bootstrap-datetimepicker"}} 60 | 61 | {{> afFormGroup name="typeTest" type="bootstrap-datetimepicker"}} 62 | 63 | {{> afFieldInput name="typeTest" type="bootstrap-datetimepicker"}} 64 | ``` 65 | 66 | ## Choosing a Timezone 67 | 68 | By default, the field's value will be a `Date` object representing the selected date and time in the browser's timezone (i.e., based on the user's computer time settings). In most cases, you probably want the `Date` object relative to some other timezone that you have previously stored. For example, if the form is setting the start date of an event, you want the date to be relative to the event venue's timezone. You can specify a different IANA timezone ID by adding a `timezoneId` attribute. 69 | 70 | ```js 71 | { 72 | date: { 73 | type: Date, 74 | autoform: { 75 | afFieldInput: { 76 | type: "bootstrap-datetimepicker", 77 | timezoneId: "America/New_York" 78 | } 79 | } 80 | } 81 | } 82 | ``` 83 | 84 | Or: 85 | 86 | ```js 87 | {{> afFieldInput name="typeTest" type="bootstrap-datetimepicker" timezoneId="America/New_York"}} 88 | ``` 89 | 90 | ## Automatic Type Conversions 91 | 92 | This input type is intended to be used with `type: Date` schema keys, but it also works with other schema types. Here's a list: 93 | 94 | * `Date`: Value is stored as a `Date` object representing the selected date and time in the timezone you specified with the `timezoneId` attribute. By default, the timezone is that of the browser (i.e., the user's computer time settings). 95 | * `String`: Value is stored as a string representation of the selected date in ISO format, e.g., "2014-11-25T00:00:00". 96 | * `Number`: Value is stored as the result of calling `getTime()` on the `Date` object (representing the selected date and time in the timezone you specified). 97 | * `Array`: If the schema expects an array of `Date` or `String` or `Number`, the value is converted to a one-item array and stored. 98 | 99 | To provide bootstrap-datetimepicker options, set a `dateTimePickerOptions` attribute equal to a helper that returns the options object. 100 | 101 | ## Customizing Appearance 102 | 103 | If you want to customize the appearance of the input, for example to use an input group with date/time icons, use the [aldeed:template-extension](https://atmospherejs.com/aldeed/template-extension) package to replace the "afBootstrapDateTimePicker" template, like this: 104 | 105 | ```html 106 | 114 | ``` 115 | 116 | ```js 117 | Template.dpReplacement.replaces("afBootstrapDateTimePicker"); 118 | ``` 119 | 120 | ## Contributing 121 | 122 | Anyone is welcome to contribute. Fork, make your changes, and then submit a pull request. 123 | -------------------------------------------------------------------------------- /autoform-bs-datetimepicker.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /autoform-bs-datetimepicker.js: -------------------------------------------------------------------------------- 1 | AutoForm.addInputType("bootstrap-datetimepicker", { 2 | template: "afBootstrapDateTimePicker", 3 | valueIn: function (val, atts) { 4 | // datetimepicker expects the date to represent local time, 5 | // so we need to adjust it if there's a timezoneId specified 6 | var timezoneId = atts.timezoneId; 7 | if (typeof timezoneId === "string") { 8 | if (typeof moment.tz !== "function") { 9 | throw new Error("If you specify a timezoneId, make sure that you've added a moment-timezone package to your app"); 10 | } 11 | if (val instanceof Date) { 12 | return moment(AutoForm.Utility.dateToNormalizedLocalDateAndTimeString(val, timezoneId), "YYYY-MM-DD[T]HH:mm:ss.SSS").toDate(); 13 | } 14 | } 15 | 16 | return val; 17 | }, 18 | valueOut: function () { 19 | var m = this.data("DateTimePicker").date(); 20 | 21 | if (!m) { 22 | return m; 23 | } 24 | 25 | var timezoneId = this.attr("data-timezone-id"); 26 | // default is local, but if there's a timezoneId, we use that 27 | if (typeof timezoneId === "string") { 28 | if (typeof moment.tz !== "function") { 29 | throw new Error("If you specify a timezoneId, make sure that you've added a moment-timezone package to your app"); 30 | } 31 | m = moment.tz(AutoForm.Utility.dateToNormalizedLocalDateAndTimeString(m.toDate()), timezoneId); 32 | } 33 | return m.toDate(); 34 | }, 35 | valueConverters: { 36 | "string": function (val) { 37 | return (val instanceof Date) ? val.toString() : val; 38 | }, 39 | "stringArray": function (val) { 40 | if (val instanceof Date) { 41 | return [val.toString()]; 42 | } 43 | return val; 44 | }, 45 | "number": function (val) { 46 | return (val instanceof Date) ? val.getTime() : val; 47 | }, 48 | "numberArray": function (val) { 49 | if (val instanceof Date) { 50 | return [val.getTime()]; 51 | } 52 | return val; 53 | }, 54 | "dateArray": function (val) { 55 | if (val instanceof Date) { 56 | return [val]; 57 | } 58 | return val; 59 | } 60 | }, 61 | contextAdjust: function (context) { 62 | if (context.atts.timezoneId) { 63 | context.atts["data-timezone-id"] = context.atts.timezoneId; 64 | } 65 | delete context.atts.timezoneId; 66 | return context; 67 | } 68 | }); 69 | 70 | Template.afBootstrapDateTimePicker.helpers({ 71 | atts: function addFormControlAtts() { 72 | var atts = _.clone(this.atts); 73 | // Add bootstrap class 74 | atts = AutoForm.Utility.addClass(atts, "form-control"); 75 | delete atts.dateTimePickerOptions; 76 | return atts; 77 | } 78 | }); 79 | 80 | Template.afBootstrapDateTimePicker.rendered = function () { 81 | var $input = this.$('input'); 82 | var data = this.data; 83 | var opts = data.atts.dateTimePickerOptions || {}; 84 | 85 | // To be able to properly detect a cleared field, the defaultDate, 86 | // which is "" by default, must be null instead. Otherwise we get 87 | // the current datetime when we call getDate() on an empty field. 88 | if (!opts.defaultDate || opts.defaultDate === "") { 89 | opts.defaultDate = null; 90 | } 91 | 92 | // instanciate datetimepicker 93 | $input.datetimepicker(opts); 94 | 95 | // set and reactively update values 96 | this.autorun(function () { 97 | var data = Template.currentData(); 98 | var dtp = $input.data("DateTimePicker"); 99 | // set field value 100 | if (data.value instanceof Date) { 101 | dtp.date(data.value); 102 | } else { 103 | dtp.date(); // clear 104 | } 105 | 106 | // set start date if there's a min in the schema 107 | if (data.min instanceof Date) { 108 | dtp.setMinDate(data.min); 109 | } 110 | 111 | // set end date if there's a max in the schema 112 | if (data.max instanceof Date) { 113 | dtp.setMaxDate(data.max); 114 | } 115 | }); 116 | 117 | }; 118 | 119 | Template.afBootstrapDateTimePicker.destroyed = function () { 120 | var dtp = this.$('input').data("DateTimePicker"); 121 | if (dtp) { 122 | dtp.destroy(); 123 | } 124 | }; 125 | -------------------------------------------------------------------------------- /package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'aldeed:autoform-bs-datetimepicker', 3 | summary: 'Custom bootstrap-datetimepicker input type with timezone support for AutoForm', 4 | version: '1.0.7', 5 | git: 'https://github.com/aldeed/meteor-autoform-bs-datetimepicker.git' 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.use('templating@1.0.0'); 10 | api.use('blaze@2.0.0'); 11 | api.use('aldeed:autoform@4.0.0 || 5.0.0 || 6.0.0'); 12 | 13 | // Ensure momentjs packages load before this one if used 14 | api.use('momentjs:moment@2.8.4', 'client', {weak: true}); 15 | api.use('mrt:moment-timezone@0.2.1', 'client', {weak: true}); 16 | 17 | api.addFiles([ 18 | 'autoform-bs-datetimepicker.html', 19 | 'autoform-bs-datetimepicker.js' 20 | ], 'client'); 21 | }); 22 | --------------------------------------------------------------------------------