Skip to content

Commit b6f2dd9

Browse files
Dan Forstersimeg
authored andcommitted
Tidy up input rendering, add test & docs for renderInput
1 parent b8a9a7f commit b6f2dd9

File tree

4 files changed

+69
-23
lines changed

4 files changed

+69
-23
lines changed

DateTime.js

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -416,26 +416,19 @@ var Datetime = createClass({
416416
children = [];
417417

418418
if ( this.props.input ) {
419+
var finalInputProps = assign({
420+
type: 'text',
421+
className: 'form-control',
422+
onClick: this.openCalendar,
423+
onFocus: this.openCalendar,
424+
onChange: this.onInputChange,
425+
onKeyDown: this.onInputKey,
426+
value: this.state.inputValue,
427+
}, this.props.inputProps);
419428
if ( this.props.renderInput ) {
420-
children = children.concat( this.props.renderInput({
421-
onClick: this.openCalendar,
422-
onFocus: this.openCalendar,
423-
onChange: this.onInputChange,
424-
onKeyDown: this.onInputKey,
425-
value: this.state.inputValue,
426-
openCalendar: this.openCalendar,
427-
}) );
429+
children = [ React.createElement('div', { key: 'i' }, this.props.renderInput( finalInputProps, this.openCalendar )) ];
428430
} else {
429-
children = [ DOM.input( assign({
430-
key: 'i',
431-
type: 'text',
432-
className: 'form-control',
433-
onClick: this.openCalendar,
434-
onFocus: this.openCalendar,
435-
onChange: this.onInputChange,
436-
onKeyDown: this.onInputKey,
437-
value: this.state.inputValue
438-
}, this.props.inputProps ))];
431+
children = [ React.createElement('input', assign({ key: 'i' }, finalInputProps ))];
439432
}
440433
} else {
441434
className += ' rdtStatic';

README.md

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,12 @@ render: function() {
5555
| **onViewModeChange** | `function` | empty function | Callback trigger when the view mode changes. The callback receives the selected view mode string (`years`, `months`, `days` or `time`) as only parameter.|
5656
| **viewMode** | `string` or `number` | `'days'` | The default view to display when the picker is shown (`'years'`, `'months'`, `'days'`, `'time'`). |
5757
| **className** | `string` or `string array` | `''` | Extra class name for the outermost markup element. |
58-
| **inputProps** | `object` | `undefined` | Defines additional attributes for the input element of the component. For example: `onClick`, `placeholder`, `disabled`, `required`, `name` and `className` (`className` *sets* the class attribute for the input element). |
58+
| **inputProps** | `object` | `undefined` | Defines additional attributes for the input element of the component. For example: `onClick`, `placeholder`, `disabled`, `required`, `name` and `className` (`className` *sets* the class attribute for the input element). See [Customize the Input Appearance](#customize-the-input-appearance). |
59+
| **renderInput** | `function` | `undefined` | Replace the rendering of the input element. The accepted function has `openCalendar` (a function which opens the calendar) and the default calculated `props` for the input. Must return a React component or `null`. See [Customize the Input Appearance](#customize-the-input-appearance). |
5960
| **isValidDate** | `function` | `() => true` | Define the dates that can be selected. The function receives `(currentDate, selectedDate)` and shall return a `true` or `false` whether the `currentDate` is valid or not. See [selectable dates](#selectable-dates).|
60-
| **renderDay** | `function` | `DOM.td(day)` | Customize the way that the days are shown in the daypicker. The accepted function has the `selectedDate`, the current date and the default calculated `props` for the cell, and must return a React component. See [appearance customization](#customize-the-appearance). |
61-
| **renderMonth** | `function` | `DOM.td(month)` | Customize the way that the months are shown in the monthpicker. The accepted function has the `selectedDate`, the current date and the default calculated `props` for the cell, the `month` and the `year` to be shown, and must return a React component. See [appearance customization](#customize-the-appearance). |
62-
| **renderYear** | `function` | `DOM.td(year)` | Customize the way that the years are shown in the year picker. The accepted function has the `selectedDate`, the current date and the default calculated `props` for the cell, the `year` to be shown, and must return a React component. See [appearance customization](#customize-the-appearance). |
61+
| **renderDay** | `function` | `DOM.td(day)` | Customize the way that the days are shown in the daypicker. The accepted function has the `selectedDate`, the current date and the default calculated `props` for the cell, and must return a React component. See [Customize the Datepicker Appearance](#customize-the-datepicker-appearance). |
62+
| **renderMonth** | `function` | `DOM.td(month)` | Customize the way that the months are shown in the monthpicker. The accepted function has the `selectedDate`, the current date and the default calculated `props` for the cell, the `month` and the `year` to be shown, and must return a React component. See [Customize the Datepicker Appearance](#customize-the-datepicker-appearance). |
63+
| **renderYear** | `function` | `DOM.td(year)` | Customize the way that the years are shown in the year picker. The accepted function has the `selectedDate`, the current date and the default calculated `props` for the cell, the `year` to be shown, and must return a React component. See [Customize the Datepicker Appearance](#customize-the-datepicker-appearance). |
6364
| **strictParsing** | `boolean` | `false` | Whether to use Moment.js's [strict parsing](http://momentjs.com/docs/#/parsing/string-format/) when parsing input.
6465
| **closeOnSelect** | `boolean` | `false` | When `true`, once the day has been selected, the datepicker will be automatically closed.
6566
| **closeOnTab** | `boolean` | `true` | When `true` and the input is focused, pressing the `tab` key will close the datepicker.
@@ -82,7 +83,36 @@ If there are multiple locales loaded, you can use the prop `locale` to define wh
8283
```
8384
[Here you can see the i18n example working](http://codepen.io/simeg/pen/yVVjdJ).
8485

85-
## Customize the Appearance
86+
## Customize the Input Appearance
87+
It is possible to customize the way that the input is displayed. The simplest is to supply `inputProps` which get assigned to the default `<input />` element within the component.
88+
89+
```js
90+
<DateTime inputProps={{ placeholder: 'N/A', disabled: true }}>
91+
```
92+
93+
Alternatively, if you need to render different content than an `<input />` element, you may supply a `renderInput` function which is called instead.
94+
95+
```js
96+
var MyDTPicker = React.createClass({
97+
render: function(){
98+
return <Datetime renderInput={ this.renderInput } />;
99+
},
100+
renderInput: function( props, openCalendar ){
101+
function clear(){
102+
props.onChange({target: {value: ''}});
103+
}
104+
return (
105+
<div>
106+
<input {...props} />
107+
<button onClick={openCalendar}>open calendar</button>
108+
<button onClick={clear}>clear</button>
109+
</div>
110+
);
111+
},
112+
});
113+
```
114+
115+
## Customize the Datepicker Appearance
86116
It is possible to customize the way that the datepicker display the days, months and years in the calendar. To adapt the calendar for every need it is possible to use the props `renderDay(props, currentDate, selectedDate)`, `renderMonth(props, month, year, selectedDate)` and `renderYear(props, year, selectedDate)` to customize the output of each rendering method.
87117

88118
```js

react-datetime.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ declare module ReactDatetime {
8686
Defines additional attributes for the input element of the component.
8787
*/
8888
inputProps?: Object;
89+
/*
90+
Replace the rendering of the input element. The accepted function has openCalendar
91+
(a function which opens the calendar) and the default calculated props for the input.
92+
Must return a React component or null.
93+
*/
94+
renderInput?: (props: Object, openCalendar: Function) => React.Component<any, any>;
8995
/*
9096
Define the dates that can be selected. The function receives (currentDate, selectedDate)
9197
and should return a true or false whether the currentDate is valid or not. See selectable dates.

test/tests.spec.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,23 @@ describe('Datetime', () => {
382382
expect(component.find('input').getDOMNode().placeholder).toEqual('custom-placeholder');
383383
});
384384

385+
it('renderInput', () => {
386+
const renderInput = (props, openCalendar) => {
387+
return (
388+
<div>
389+
<input {...props} />
390+
<button className="custom-open" onClick={openCalendar}>open calendar</button>
391+
</div>
392+
);
393+
};
394+
const component = utils.createDatetime({ renderInput });
395+
396+
expect(component.find('button.custom-open').length).toEqual(1);
397+
expect(utils.isOpen(component)).toBeFalsy();
398+
utils.clickOnElement(component.find('button.custom-open'));
399+
expect(utils.isOpen(component)).toBeTruthy();
400+
});
401+
385402
it('renderDay', () => {
386403
let props = {},
387404
currentDate = '',

0 commit comments

Comments
 (0)