Skip to content

Commit a7dbbde

Browse files
authored
Merge pull request react-dates#1525 from nkinser/nk--couple-dates-change-with-focus-change
Move the call to onDatesChange before the call to onFocusChange
2 parents e66ae14 + 95ee636 commit a7dbbde

File tree

2 files changed

+139
-4
lines changed

2 files changed

+139
-4
lines changed

src/components/DayPickerRangeController.jsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,8 @@ export default class DayPickerRangeController extends React.PureComponent {
495495
return;
496496
}
497497

498+
onDatesChange({ startDate, endDate });
499+
498500
if (!keepOpenOnDateSelect) {
499501
onFocusChange(null);
500502
onClose({ startDate, endDate });
@@ -512,6 +514,8 @@ export default class DayPickerRangeController extends React.PureComponent {
512514
}
513515
}
514516

517+
onDatesChange({ startDate, endDate });
518+
515519
if (isEndDateDisabled && !isStartDateAfterEndDate) {
516520
onFocusChange(null);
517521
onClose({ startDate, endDate });
@@ -523,20 +527,26 @@ export default class DayPickerRangeController extends React.PureComponent {
523527

524528
if (!startDate) {
525529
endDate = day;
530+
onDatesChange({ startDate, endDate });
526531
onFocusChange(START_DATE);
527532
} else if (isInclusivelyAfterDay(day, firstAllowedEndDate)) {
528533
endDate = day;
534+
onDatesChange({ startDate, endDate });
529535
if (!keepOpenOnDateSelect) {
530536
onFocusChange(null);
531537
onClose({ startDate, endDate });
532538
}
533539
} else if (disabled !== START_DATE) {
534540
startDate = day;
535541
endDate = null;
542+
onDatesChange({ startDate, endDate });
543+
} else {
544+
onDatesChange({ startDate, endDate });
536545
}
546+
} else {
547+
onDatesChange({ startDate, endDate });
537548
}
538549

539-
onDatesChange({ startDate, endDate });
540550
onBlur();
541551
}
542552

test/components/DayPickerRangeController_spec.jsx

Lines changed: 128 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1623,6 +1623,133 @@ describe('DayPickerRangeController', () => {
16231623
});
16241624
});
16251625

1626+
describe('props.onDatesChange only called once in onDayClick', () => {
1627+
it('calls props.onDatesChange once when focusedInput === START_DATE', () => {
1628+
const clickDate = moment(today);
1629+
const onDatesChangeStub = sinon.stub();
1630+
const wrapper = shallow((
1631+
<DayPickerRangeController
1632+
onDatesChange={onDatesChangeStub}
1633+
focusedInput={START_DATE}
1634+
endDate={null}
1635+
/>
1636+
));
1637+
wrapper.instance().onDayClick(clickDate);
1638+
expect(onDatesChangeStub).to.have.property('callCount', 1);
1639+
const args = onDatesChangeStub.getCall(0).args[0];
1640+
expect(args.startDate.format()).to.equal(clickDate.clone().format());
1641+
expect(args.endDate).to.equal(null);
1642+
});
1643+
1644+
it('calls props.onDatesChange once when focusedInput === END_DATE and there is no startDate', () => {
1645+
const clickDate = moment(today);
1646+
const onDatesChangeStub = sinon.stub();
1647+
const wrapper = shallow((
1648+
<DayPickerRangeController
1649+
onDatesChange={onDatesChangeStub}
1650+
focusedInput={END_DATE}
1651+
startDate={null}
1652+
/>
1653+
));
1654+
wrapper.instance().onDayClick(clickDate);
1655+
expect(onDatesChangeStub).to.have.property('callCount', 1);
1656+
const args = onDatesChangeStub.getCall(0).args[0];
1657+
expect(args.startDate).to.equal(null);
1658+
expect(args.endDate.format()).to.equal(clickDate.clone().format());
1659+
});
1660+
1661+
it('calls props.onDatesChange once when focusedInput === END_DATE and the day is a valid endDate', () => {
1662+
const clickDate = moment(today);
1663+
const startDate = clickDate.clone().subtract(2, 'days');
1664+
const onDatesChangeStub = sinon.stub();
1665+
const wrapper = shallow((
1666+
<DayPickerRangeController
1667+
onDatesChange={onDatesChangeStub}
1668+
focusedInput={END_DATE}
1669+
minimumNights={2}
1670+
startDate={startDate}
1671+
/>
1672+
));
1673+
wrapper.instance().onDayClick(clickDate);
1674+
expect(onDatesChangeStub).to.have.property('callCount', 1);
1675+
const args = onDatesChangeStub.getCall(0).args[0];
1676+
expect(args.startDate.format()).to.equal(startDate.clone().format());
1677+
expect(args.endDate.format()).to.equal(clickDate.clone().format());
1678+
});
1679+
1680+
it('calls props.onDatesChange once when focusedInput === END_DATE, the day is an invalid endDate, and disabled !== START_DATE', () => {
1681+
const clickDate = moment(today);
1682+
const onDatesChangeStub = sinon.stub();
1683+
const wrapper = shallow((
1684+
<DayPickerRangeController
1685+
onDatesChange={onDatesChangeStub}
1686+
focusedInput={END_DATE}
1687+
minimumNights={2}
1688+
startDate={clickDate.clone().add(1, 'days')}
1689+
endDate={null}
1690+
/>
1691+
));
1692+
wrapper.instance().onDayClick(clickDate);
1693+
expect(onDatesChangeStub).to.have.property('callCount', 1);
1694+
const args = onDatesChangeStub.getCall(0).args[0];
1695+
expect(args.startDate.format()).to.equal(clickDate.clone().format());
1696+
expect(args.endDate).to.equal(null);
1697+
});
1698+
1699+
it('calls props.onDatesChange once when focusedInput === END_DATE and the day is an invalid endDate', () => {
1700+
const clickDate = moment(today);
1701+
const startDate = clickDate.clone().add(1, 'days');
1702+
const onDatesChangeStub = sinon.stub();
1703+
const wrapper = shallow((
1704+
<DayPickerRangeController
1705+
onDatesChange={onDatesChangeStub}
1706+
focusedInput={END_DATE}
1707+
disabled={START_DATE}
1708+
minimumNights={2}
1709+
startDate={startDate}
1710+
endDate={null}
1711+
/>
1712+
));
1713+
wrapper.instance().onDayClick(clickDate);
1714+
expect(onDatesChangeStub).to.have.property('callCount', 1);
1715+
const args = onDatesChangeStub.getCall(0).args[0];
1716+
expect(args.startDate.format()).to.equal(startDate.clone().format());
1717+
expect(args.endDate).to.equal(null);
1718+
});
1719+
1720+
it('calls props.onDatesChange once when there is a startDateOffset', () => {
1721+
const clickDate = moment(today);
1722+
const onDatesChangeStub = sinon.stub();
1723+
const wrapper = shallow((
1724+
<DayPickerRangeController
1725+
onDatesChange={onDatesChangeStub}
1726+
startDateOffset={day => day.subtract(2, 'days')}
1727+
/>
1728+
));
1729+
wrapper.instance().onDayClick(clickDate);
1730+
expect(onDatesChangeStub).to.have.property('callCount', 1);
1731+
const args = onDatesChangeStub.getCall(0).args[0];
1732+
expect(args.startDate.format()).to.equal(clickDate.clone().subtract(2, 'days').format());
1733+
expect(args.endDate.format()).to.equal(clickDate.clone().format());
1734+
});
1735+
1736+
it('calls props.onDatesChange once when there is a endDateOffset', () => {
1737+
const clickDate = moment(today);
1738+
const onDatesChangeStub = sinon.stub();
1739+
const wrapper = shallow((
1740+
<DayPickerRangeController
1741+
onDatesChange={onDatesChangeStub}
1742+
endDateOffset={day => day.add(4, 'days')}
1743+
/>
1744+
));
1745+
wrapper.instance().onDayClick(clickDate);
1746+
expect(onDatesChangeStub).to.have.property('callCount', 1);
1747+
const args = onDatesChangeStub.getCall(0).args[0];
1748+
expect(args.startDate.format()).to.equal(clickDate.clone().format());
1749+
expect(args.endDate.format()).to.equal(clickDate.clone().add(4, 'days').format());
1750+
});
1751+
});
1752+
16261753
describe('logic in props.onDatesChange affects props.onFocusChange', () => {
16271754
let preventFocusChange;
16281755
let focusedInput;
@@ -1652,10 +1779,8 @@ describe('DayPickerRangeController', () => {
16521779
focusedInput={START_DATE}
16531780
/>
16541781
));
1655-
// The first day click sets preventFocusChange to true, but it doesn't take effect until the
1656-
// second day click because onFocusChange is called before onDatesChange
16571782
wrapper.instance().onDayClick(clickDate);
1658-
expect(focusedInput).to.equal(END_DATE);
1783+
expect(focusedInput).to.equal(START_DATE);
16591784
wrapper.instance().onDayClick(clickDate.clone().add(1, 'days'));
16601785
expect(focusedInput).to.equal(END_DATE);
16611786
});

0 commit comments

Comments
 (0)