Fix calendar always resetting to today instead of date entered in input

(by making the component fully controlled)
master
Vitaliy Filippov 2018-10-09 19:01:34 +03:00
parent 2281fa2e25
commit af25b26fe8
3 changed files with 24 additions and 30 deletions

View File

@ -3,7 +3,7 @@
* Creates a calendar widget which can be used to select the date more easily than using just a text box
*
* Modified: http://yourcmc.ru/git/vitalif-js/calendar
* Version: 2018-07-01
* Version: 2018-10-09
* License: MIT-like, http://www.openjs.com/license.php
*
* Example:
@ -33,28 +33,12 @@ export class Calendar extends preact.Component
start: 'days',
}
componentWillMount()
{
if (!this.state.mode)
this.setState({ mode: this.props.start });
if (!this.state.year)
this.setState({ year: this.props.selected.getFullYear() });
if (!this.state.month)
this.setState({ month: this.props.selected.getMonth() });
}
componentWillReceiveProps(nextProps, nextState)
{
if (this.props.mode != nextProps.mode)
this.setState({ mode: nextProps.mode });
}
render(props, state)
{
return (<div class="calendar-box" style={{display: "block"}}>
{this.state.mode == 'months' ? this.renderMonths(props, state) : null}
{this.state.mode == 'years' ? this.renderYears(props, state) : null}
{this.state.mode == 'days' ? this.renderDays(props, state) : null}
{props.mode == 'months' ? this.renderMonths(props) : null}
{props.mode == 'years' ? this.renderYears(props) : null}
{props.mode == 'days' ? this.renderDays(props) : null}
<a class="calendar-cancel" onclick={() => Calendar.hideCalendar()}>{props.close_label}</a>
</div>);
}
@ -115,21 +99,22 @@ export class Calendar extends preact.Component
showMonths(year)
{
this.setState({ year, mode: 'months' });
this.props.onChangeProps({ year, mode: 'months' });
}
showYears(year)
{
this.setState({ year, mode: 'years' });
this.props.onChangeProps({ year, mode: 'years' });
}
showDays(year, month)
{
this.setState({ year, month, mode: 'days' });
this.props.onChangeProps({ year, month, mode: 'days' });
}
renderMonths(props, { year })
renderMonths(props)
{
var year = props.year;
var cur_y = props.today.getFullYear();
var cur_m = props.today.getMonth();
var sel_m = props.selected.getFullYear() == year ? props.selected.getMonth() : -1;
@ -155,7 +140,7 @@ export class Calendar extends preact.Component
</table>);
}
renderYears({ selected, today }, { year })
renderYears({ selected, today, year })
{
var beg = year & ~15;
var cur_y = today.getFullYear();
@ -190,9 +175,9 @@ export class Calendar extends preact.Component
}
/// Creates a calendar with the date given in the argument as the selected date.
renderDays(props, { year, month })
renderDays(props)
{
var { selected, selectboxes, sunday, today, month_names } = props;
var { year, month, selected, selectboxes, sunday, today, month_names } = props;
// Display the table
var next_month = month+1;
@ -291,7 +276,7 @@ export class Calendar extends preact.Component
static showCalendar(input, options)
{
// Show the calendar with the date in the input as the selected date
var props = { ...options };
var props = { ...Calendar.defaultProps, ...options };
props.selected = new Date();
var date_in_input = input.value.replace(/\s+.*$/, ''); // Remove time
if (date_in_input)
@ -322,7 +307,15 @@ export class Calendar extends preact.Component
}
}
props.today = new Date();
props.year = props.selected.getFullYear();
props.month = props.selected.getMonth();
props.mode = props.start;
props.input = input;
props.onChangeProps = (h) =>
{
props = { ...props, ...h };
preact.render(<Calendar {...props} />, Calendar.box.parentNode, Calendar.box);
};
Calendar.init();
Calendar.box.style.display = "block";
preact.render(<Calendar {...props} />, Calendar.box.parentNode, Calendar.box);
@ -351,6 +344,7 @@ export class Calendar extends preact.Component
{
Calendar.showCalendar(input_or_id, options);
});
// FIXME: Add change listener to enable interactive date selection in calendar while typing
}
// Will be called once when the first input is set.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long