{"id":13459121,"url":"https://github.com/bevacqua/rome","last_synced_at":"2025-05-14T08:06:26.076Z","repository":{"id":18769210,"uuid":"21982076","full_name":"bevacqua/rome","owner":"bevacqua","description":":calendar: Customizable date (and time) picker. Opt-in UI, no jQuery!","archived":false,"fork":false,"pushed_at":"2024-03-16T02:20:16.000Z","size":7568,"stargazers_count":2915,"open_issues_count":86,"forks_count":224,"subscribers_count":71,"default_branch":"master","last_synced_at":"2025-05-10T10:38:03.647Z","etag":null,"topics":["calendar","component","front-end","javascript","vanilla"],"latest_commit_sha":null,"homepage":"https://bevacqua.github.io/rome","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bevacqua.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-07-18T13:57:29.000Z","updated_at":"2025-03-23T14:41:44.000Z","dependencies_parsed_at":"2024-06-18T15:23:43.055Z","dependency_job_id":"0df23425-63bf-4c09-b6a6-896e2d700039","html_url":"https://github.com/bevacqua/rome","commit_stats":{"total_commits":297,"total_committers":14,"mean_commits":"21.214285714285715","dds":0.06397306397306401,"last_synced_commit":"7a7c21288003c814ba24f3dead16bc39a2ba06bf"},"previous_names":[],"tags_count":95,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bevacqua%2Frome","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bevacqua%2Frome/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bevacqua%2Frome/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bevacqua%2Frome/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bevacqua","download_url":"https://codeload.github.com/bevacqua/rome/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254101615,"owners_count":22014909,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["calendar","component","front-end","javascript","vanilla"],"created_at":"2024-07-31T09:01:05.103Z","updated_at":"2025-05-14T08:06:21.061Z","avatar_url":"https://github.com/bevacqua.png","language":"JavaScript","readme":"# rome\n\n\u003e Customizable date _(and time)_ picker. Opt-in UI, no jQuery!\n\nRome wasn't built in a day. Browser support includes every sane browser and **IE7+**.\n\n#### Demo!\n\nYou can [see a live demo here][3].\n\n[![screenshot.png][4]][3]\n\nOh, `rome` synchronizes in real-time with inputs, never steals focus, and its CSS is entirely customizable!\n\n\u003csub\u003eRome depends on [`moment`][6]. It doesn't depend on jQuery or other weird frameworks, though.\n\n## Install\n\nFrom npm or Bower.\n\n```shell\nnpm install --save @bevacqua/rome\n```\n\n```shell\nbower install --save @bevacqua/rome\n```\n\nNote that if you're using the standalone version, the API is published under the `rome` global. If you're using CJS, then you'll have to `require('@bevacqua/rome')`.\n\n### Setup\n\nYou can use your own distribution of [`moment`][6], using `rome.standalone.js`.\n\n```html\n\u003cscript src='moment.js'\u003e\u003c/script\u003e\n\u003cscript src='rome.standalone.js'\u003e\u003c/script\u003e\n```\n\nYou could just use the bundled `rome.js` distribution, which comes with [`moment`][6] in it.\n\n```html\n\u003cscript src='rome.js'\u003e\u003c/script\u003e\n```\n\nIf you need to do anything regarding internationalization, [refer to `moment` for that][5]. Ideally, make those changes before starting to create Rome calendar components.\n\n## API\n\nThe API in `rome` exposes a few properties.\n\n### `rome.find(elem)`\n\nIf a calendar is associated to the provided `elem`, then that calendar is returned, otherwise returns `null`. DOM elements can only have one associated calendar.\n\n### `rome(elem, options={})`\n\nThis method creates a calendar instance and associates it to the provided `elem`. This association can't be undone even by `.destroy()`ing the `rome` instance, because it can be `.restore()`d later. Subsequent calls to `rome(elem)` will return the associated calendar, instead of creating a new one _\u003csub\u003e(see `rome.find(elem)`)\u003c/sub\u003e_. Think of this as a _\"caching feature\"_.\n\nCreating a calendar has a ton of options. These have reasonable defaults that are easy to adjust, too. The options are listed below.\n\nOption             | Description\n-------------------|--------------------------------------------------------------------------------------------------\n`appendTo`         | DOM element where the calendar will be appended to. Takes `'parent'` as the parent element\n`autoClose`        | When set to `true`, the calendar is auto-closed when picking a day _(or a time if `time: true` and `date: false`). A value of `'time'` will only auto-close the calendar when a time is picked.\n`autoHideOnBlur`   | Hides the calendar when focusing something other than the input field\n`autoHideOnClick`  | Hides the calendar when clicking away\n`date`             | The calendar shows days and allows you to navigate between months\n`dateValidator`    | Function to validate that a given date is considered valid. Receives a native `Date` parameter.\n`dayFormat`        | Format string used to display days on the calendar\n`initialValue`     | Value used to initialize calendar. Takes `string`, `Date`, or `moment`\n`inputFormat`      | Format string used for the input field as well as the results of `rome`\n`invalidate`       | Ensures the date is valid when the field is blurred\n`strictParse`      | Compares input strictly against `inputFormat`, and partial matches are discarded\n`max`              | Disallow dates past `max`. Takes `string`, `Date`, or `moment`\n`min`              | Disallow dates before `min`. Takes `string`, `Date`, or `moment`\n`monthFormat`      | Format string used by the calendar to display months and their year\n`monthsInCalendar` | How many months get rendered in the calendar\n`required`         | Is the field required or do you allow empty values?\n`styles`           | CSS classes applied to elements on the calendar\n`time`             | The calendar shows the current time and allows you to change it using a dropdown\n`timeFormat`       | Format string used to display the time on the calendar\n`timeInterval`     | Seconds between each option in the time dropdown\n`timeValidator`    | Function to validate that a given time is considered valid. Receives a native `Date` parameter.\n`weekdayFormat`    | Format used to display weekdays. Takes `min` _(Mo)_, `short` _(Mon)_, `long` _(Monday)_, or an array with seven strings of your choosing.\n`weekStart`        | Day considered the first of the week. Range: Sunday `0` - Saturday `6`\n\nNote that in the case of input fields, when `initialValue` isn't provided the initial value is inferred from `elem.value` instead. In the case of inline calendars, `new Date()` will be used as a default if none is provided.\n\n#### Inlining the Calendar\n\nIf you pass in an element other than an input tag, then this method behaves slightly differently. The difference is that `appendTo` becomes the provided `elem`, and the calendar won't attach itself to an input element. The options listed below will be ignored.\n\n- `autoHideOnBlur`, because there is no input field that can be tracked for `blur` events\n- `invalidate`, because there is no input field to keep consistent with the calendar component\n- `required`, because you can easily do that on an input field\n- `styles.positioned`, because the calendar will be considered inlined\n\nAll of the other options still apply, and identical behavior should be expected.\n\n#### Default Options\n\nIf you don't set an option, the default will be used. You can [look up the defaults here][1], or below.\n\n```json\n{\n  \"appendTo\": document.body,\n  \"autoClose\": true,\n  \"autoHideOnBlur\": true,\n  \"autoHideOnClick\": true,\n  \"date\": true,\n  \"dateValidator\": Function.prototype,\n  \"dayFormat\": \"DD\",\n  \"initialValue\": null,\n  \"inputFormat\": \"YYYY-MM-DD HH:mm\",\n  \"invalidate\": true,\n  \"max\": null,\n  \"min\": null,\n  \"monthFormat\": \"MMMM YYYY\",\n  \"monthsInCalendar\": 1,\n  \"required\": false,\n  \"strictParse\": false,\n  \"styles\": {\n    \"back\": \"rd-back\",\n    \"container\": \"rd-container\",\n    \"date\": \"rd-date\",\n    \"dayBody\": \"rd-days-body\",\n    \"dayBodyElem\": \"rd-day-body\",\n    \"dayConcealed\": \"rd-day-concealed\",\n    \"dayDisabled\": \"rd-day-disabled\",\n    \"dayHead\": \"rd-days-head\",\n    \"dayHeadElem\": \"rd-day-head\",\n    \"dayRow\": \"rd-days-row\",\n    \"dayTable\": \"rd-days\",\n    \"month\": \"rd-month\",\n    \"next\": \"rd-next\",\n    \"positioned\": \"rd-container-attachment\",\n    \"selectedDay\": \"rd-day-selected\",\n    \"selectedTime\": \"rd-time-selected\",\n    \"time\": \"rd-time\",\n    \"timeList\": \"rd-time-list\",\n    \"timeOption\": \"rd-time-option\"\n  },\n  \"time\": true,\n  \"timeFormat\": \"HH:mm\",\n  \"timeInterval\": 1800,\n  \"timeValidator\": Function.prototype,\n  \"weekdayFormat\": \"min\",\n  \"weekStart\": moment().weekday(0).day()\n}\n```\n\n#### Rome API\n\nWhen you create a calendar with `rome(elem)`, you'll get a `cal` instance back. This has a few API methods. Most of these methods return the calendar instance whenever possible, allowing for method chaining.\n\n##### `.show()`\n\nShows the calendar. If associated with an input, the calendar gets absolutely position right below the input field.\n\n##### `.hide()`\n\nHides the calendar.\n\n##### `.id`\n\nAuto-generated unique identifier assigned to this instance of Rome.\n\n##### `.container`\n\nThe DOM element that contains the calendar.\n\n##### `.associated`\n\nThe associated DOM element assigned to this calendar instance. This is the input field or parent element that you used to create the calendar.\n\n##### `.getDate()`\n\nReturns the current date, as defined by the calendar, in a native `Date` object. If `required: false` you'll get `null` when the input field is empty.\n\n##### `.getDateString(format?)`\n\nReturns the current date, as defined by the calendar, using the provided `options.inputFormat` format string or a format of your choosing. If `required: false` you'll get `null` when the input field is empty.\n\n##### `.getMoment()`\n\nReturns a copy of the `moment` object underlying the current date in the calendar. If `required: false` you'll get `null` when the input field is empty.\n\n##### `.destroy()`\n\nRemoves the calendar from the DOM and all of its associated DOM event listeners. The only responsive API method becomes the `.restore` method described below, the rest of the API becomes no-op methods. After emitting the `destroyed` event, all event listeners are removed from the instance.\n\n##### `.destroyed`\n\nReturns `true` when the calendar is in a destroyed state and `false` otherwise.\n\n##### `.restore(options?)`\n\nRestores the calendar, using the provided options (or the default options). The associated DOM element can't be changed. The API methods are restored to their original functionality.\n\n##### `.options(options?)`\n\nIf an options object is provided, it destroys the calendar and initializes it with the provided options. Effectively the same as calling `.restore(options)` immediately after calling `.destroy()`.\n\nIf no options object is provided, a copy of the current options is returned.\n\n##### `.options.reset()`\n\nResets the options to the factory defaults. Effectively the same as calling `.options({})` while preserving the `appendTo` option.\n\n##### `.emitValues()`\n\nEmits all of the data events listed below. Mostly used internally, **should be avoided** in consumer-land.\n\n##### `.setValue(value)`\n\nSets the current date to the provided `value`, but only if that value is valid according to the rules defined by the calendar. Takes `string`, `Date`, or `moment`. Mostly used internally, and it doesn't emit any events.\n\n##### `.refresh()`\n\nForces a refresh of the calendar. This method will redraw the month and update the dates that can be selected in accordance with `dateValidator` and `timeValidator`.\n\n##### `.back()`\n\nSteps the calendar display back by one month. Equivalent to clicking the 'back' button.\nReturns `undefined`.\n\n##### `.next()`\n\nSteps the calendar display forward by one month. Equivalent to clicking the 'next' button.\nReturns `undefined`.\n\n#### Events\n\nRome calendars also provide a few events you can subscribe to. These events are published through an event emitter created using [`contra`][2]. These events are listed below.\n\nEvent       | Arguments   | Description\n------------|-------------|------------\n`ready`     | `[options]` | The calendar has been `.restore`d\n`destroyed` | `[]`        | The calendar has been `.destroy`ed\n`data`      | `[value]`   | The date may have been updated by the calendar. Value of `.getDateString()` is provided\n`year`      | `[year]`    | The year may have been updated by the calendar. Value of `moment.year()` is provided\n`month`     | `[month]`   | The month may have been updated by the calendar. Value of `moment.month()` is provided\n`day`       | `[day]`     | The day may have been updated by the calendar. Value of `moment.date()` is provided\n`time`      | `[time]`    | The time may have been updated by the calendar. Formatted time string is provided\n`show`      | `[]`        | The calendar has been displayed\n`hide`      | `[]`        | The calendar has been hidden\n`back`      | `[month]`   | The calendar view has been moved back a month to the value `moment.month()`\n`next`      | `[month]`   | The calendar view has been moved forward a month to the value `moment.month()`\n\n#### Date and Time Validator\n\nPlease note that `dateValidator` and `timeValidator` both receive a native `Date` object as a parameter. These methods are expected to return `undefined` or `true` if the date is deemed valid, and `false` in case the date is invalid. If `dateValidator` returns `false`, the validation process will try to find a valid date near the desired date.\n\nIf `dateValidator` passes for a given date, the `timeValidator` will attempt to validate that date as well. If the time is invalid, the day will be probed for a valid time. This validation starts at the desired time, and grows in `timeInterval` increments. When the end of the day is reached, validation resumes at the start of the day instead of leaping to the next day.\n\n### `rome.val`\n\nThere are a few default validator factories provided by Rome to make your life easier.\n\nThese methods take a `moment`, a `Date`, a `string` that can be parsed into a `moment` using `inputFormat`, or a DOM element that Rome could use to look up another Rome instance.\n\nIf you passed in a DOM element, the validator will look up the associated Rome instance and validate using its value. The first time the validator is executed on any inline calendar, the `'data'` event for that calendar will be hooked to refresh the related calendar.\n\nFor usage examples you can [refer to the demos][3].\n\n#### `rome.val.afterEq(value)`\n\nReturns whether the date is after the provided value. The comparison uses `\u003e=`, meaning it's inclusive.\n\n#### `rome.val.after(value)`\n\nReturns whether the date is after the provided value. The comparison uses `\u003e`, meaning it's exclusive.\n\n#### `rome.val.beforeEq(value)`\n\nReturns whether the date is before the provided value. The comparison uses `\u003c=`, meaning it's inclusive.\n\n#### `rome.val.before(value)`\n\nReturns whether the date is before the provided value. The comparison uses `\u003c`, meaning it's exclusive.\n\n#### `rome.val.except(left, right)`\n\nReturns whether the date is any date except the provided value. You can provide a wide variety of input values. Keep in mind `Date`, `string`, `moment`, and the DOM element used to find another calendar are all valid input types.\n\n##### Providing `left` only means **\"any date except this one\"**\n\nIf you use `rome.val.except('2014-08-09')`, then `'2014-08-09'` is invalid.\n\n##### Providing `left` and `right` means **\"any date that's not in this range\"**\n\nIf you use `rome.val.except('2014-08-09', '2014-09-01')`, then anything between `'2014-08-09'` and `'2014-09-01'` is invalid.\n\n##### If `left` is an array, each element in the array is treated as the simple case described above\n\nIn this case, `right` is completely ignored. Every item in the array is treated as follows.\n\n###### If the item is single, then a rule is built on that single date\n\nUsing `rome.val.except(['2014-08-09', '2014-09-01'])` means that `'2014-08-09'` and `'2014-09-01'` are both invalid dates.\n\n###### If the item is an array, the first two items are used to determine a date range\n\nUsing `rome.val.except([['2014-08-09', '2014-09-01']])` means anything between `'2014-08-09'` and `'2014-09-01'` is invalid.\n\nThese two types of entries can be combined in any way you like. Each entry will exclude additional dates.\n\nFor instance, `[['2014-04-05', '2014-04-15'], ['2014-04-25', '2014-04-30'], '2014-05-05']` means that April 05 to 15, and April 25 to 30, along with May 05 are all invalid dates.\n\n#### `rome.val.only(left, right)`\n\nIdentical behavior to `rome.val.except`, except for the fact that the selected dates become **the only valid dates**, rather than the **only invalid dates**.\n\n### `rome.moment`\n\nExposes the [`moment`][6] instance used by Rome. To change the `moment` instance, refer to `rome.use(moment)`.\n\n### `rome.use(moment)`\n\nSets the instance of `moment` used by Rome.\n\n## Development\n\nStart by installing any dependencies.\n\n```shell\nnpm install\n```\n\nThen run the Gulp `watch` task.\n\n```shell\ngulp watch\n```\n\nLastly open the page and any changes you make just need a browser refresh.\n\n```shell\nopen index.html\n```\n\n## License\n\nMIT\n\n[1]: https://github.com/bevacqua/rome/blob/master/src/defaults.js\n[2]: https://github.com/bevacqua/contra\n[3]: https://bevacqua.github.io/rome\n[4]: https://cloud.githubusercontent.com/assets/934293/3803583/387125ea-1c1c-11e4-974e-467984e4d1f0.png\n[5]: http://momentjs.com/docs/#/i18n/\n[6]: http://momentjs.com\n","funding_links":[],"categories":["JavaScript","Javascript","Form Widgets","Form Widgets [🔝](#readme)","UI","Uncategorized","表单组件"],"sub_categories":["Calendar","日历","Uncategorized"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbevacqua%2Frome","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbevacqua%2Frome","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbevacqua%2Frome/lists"}