Skip to content

Commit

Permalink
Open source Android date and time pickers
Browse files Browse the repository at this point in the history
Reviewed By: bestander

Differential Revision: D2856486

fb-gh-sync-id: 0bb81136289e2f121387649765ba682103e4701b
  • Loading branch information
Martin Konicek authored and facebook-github-bot-8 committed Jan 26, 2016
1 parent 5f0ef12 commit 9a0539d
Show file tree
Hide file tree
Showing 29 changed files with 1,275 additions and 41 deletions.
117 changes: 117 additions & 0 deletions Examples/UIExplorer/DatePickerAndroidExample.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/**
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
* Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
'use strict';

var React = require('react-native');
var {
DatePickerAndroid,
StyleSheet,
Text,
TouchableWithoutFeedback,
} = React;

var UIExplorerBlock = require('./UIExplorerBlock');
var UIExplorerPage = require('./UIExplorerPage');

var DatePickerAndroidExample = React.createClass({

statics: {
title: 'DatePickerAndroid',
description: 'Standard Android date picker dialog',
},

getInitialState() {
return {
presetDate: new Date(2020, 4, 5),
allDate: new Date(2020, 4, 5),
simpleText: 'pick a date',
minText: 'pick a date, no earlier than today',
maxText: 'pick a date, no later than today',
presetText: 'pick a date, preset to 2020/5/5',
allText: 'pick a date between 2020/5/1 and 2020/5/10',
};
},

async showPicker(stateKey, options) {
try {
var newState = {};
const {action, year, month, day} = await DatePickerAndroid.open(options);
if (action === DatePickerAndroid.dismissedAction) {
newState[stateKey + 'Text'] = 'dismissed';
} else {
var date = new Date(year, month, day);
newState[stateKey + 'Text'] = date.toLocaleDateString();
newState[stateKey + 'Date'] = date;
}
this.setState(newState);
} catch ({code, message}) {
console.warn(`Error in example '${stateKey}': `, message);
}
},

render() {
return (
<UIExplorerPage title="DatePickerAndroid">
<UIExplorerBlock title="Simple date picker">
<TouchableWithoutFeedback
onPress={this.showPicker.bind(this, 'simple', {date: this.state.simpleDate})}>
<Text style={styles.text}>{this.state.simpleText}</Text>
</TouchableWithoutFeedback>
</UIExplorerBlock>
<UIExplorerBlock title="Date picker with pre-set date">
<TouchableWithoutFeedback
onPress={this.showPicker.bind(this, 'preset', {date: this.state.presetDate})}>
<Text style={styles.text}>{this.state.presetText}</Text>
</TouchableWithoutFeedback>
</UIExplorerBlock>
<UIExplorerBlock title="Date picker with minDate">
<TouchableWithoutFeedback
onPress={this.showPicker.bind(this, 'min', {
date: this.state.minDate,
minDate: new Date(),
})}>
<Text style={styles.text}>{this.state.minText}</Text>
</TouchableWithoutFeedback>
</UIExplorerBlock>
<UIExplorerBlock title="Date picker with maxDate">
<TouchableWithoutFeedback
onPress={this.showPicker.bind(this, 'max', {
date: this.state.maxDate,
maxDate: new Date(),
})}>
<Text style={styles.text}>{this.state.maxText}</Text>
</TouchableWithoutFeedback>
</UIExplorerBlock>
<UIExplorerBlock title="Date picker with all options">
<TouchableWithoutFeedback
onPress={this.showPicker.bind(this, 'all', {
date: this.state.allDate,
minDate: new Date(2020, 4, 1),
maxDate: new Date(2020, 4, 10),
})}>
<Text style={styles.text}>{this.state.allText}</Text>
</TouchableWithoutFeedback>
</UIExplorerBlock>
</UIExplorerPage>
);
},
});

var styles = StyleSheet.create({
text: {
color: 'black',
},
});

module.exports = DatePickerAndroidExample;
4 changes: 2 additions & 2 deletions Examples/UIExplorer/ListViewExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ var UIExplorerPage = require('./UIExplorerPage');

var ListViewSimpleExample = React.createClass({
statics: {
title: '<ListView> - Simple',
title: '<ListView>',
description: 'Performant, scrollable list of data.'
},

Expand All @@ -50,7 +50,7 @@ var ListViewSimpleExample = React.createClass({
render: function() {
return (
<UIExplorerPage
title={this.props.navigator ? null : '<ListView> - Simple'}
title={this.props.navigator ? null : '<ListView>'}
noSpacer={true}
noScroll={true}>
<ListView
Expand Down
18 changes: 8 additions & 10 deletions Examples/UIExplorer/PickerAndroidExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ const {
const Item = PickerAndroid.Item;

const PickerAndroidExample = React.createClass({

statics: {
title: '<PickerAndroid>',
description: 'Provides multiple options to choose from, using either a dropdown menu or a dialog.',
},

getInitialState: function() {
return {
selected1: 'key1',
Expand Down Expand Up @@ -124,19 +130,11 @@ const PickerAndroidExample = React.createClass({
this.setState({mode: newMode});
},

onSelect: function(key, value) {
onSelect: function(key: string, value: string) {
const newState = {};
newState[key] = value;
this.setState(newState);
},
});

exports.title = '<PickerAndroid>';
exports.displayName = 'PickerAndroidExample';
exports.description = 'The Android Picker component provides multiple options to choose from';
exports.examples = [
{
title: 'PickerAndroidExample',
render(): ReactElement { return <PickerAndroidExample />; }
},
];
module.exports = PickerAndroidExample;
4 changes: 2 additions & 2 deletions Examples/UIExplorer/RefreshControlExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const RefreshControlExample = React.createClass({
isRefreshing: false,
loaded: 0,
rowData: Array.from(new Array(20)).map(
(val, i) => ({text: 'Initial row' + i, clicks: 0})),
(val, i) => ({text: 'Initial row ' + i, clicks: 0})),
};
},

Expand Down Expand Up @@ -108,7 +108,7 @@ const RefreshControlExample = React.createClass({
// prepend 10 items
const rowData = Array.from(new Array(10))
.map((val, i) => ({
text: 'Loaded row' + (+this.state.loaded + i),
text: 'Loaded row ' + (+this.state.loaded + i),
clicks: 0,
}))
.concat(this.state.rowData);
Expand Down
112 changes: 112 additions & 0 deletions Examples/UIExplorer/TimePickerAndroidExample.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/**
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
* Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
'use strict';

var React = require('react-native');
var {
TimePickerAndroid,
StyleSheet,
Text,
TouchableWithoutFeedback,
} = React;

var UIExplorerBlock = require('./UIExplorerBlock');
var UIExplorerPage = require('./UIExplorerPage');

var TimePickerAndroidExample = React.createClass({

statics: {
title: 'TimePickerAndroid',
description: 'Standard Android time picker dialog',
},

getInitialState() {
// *Text, *Hour and *Minute are set by successCallback -- this updates the text with the time
// picked by the user and makes it so the next time they open it the hour and minute they picked
// before is displayed.
return {
isoFormatText: 'pick a time (24-hour format)',
presetHour: 4,
presetMinute: 4,
presetText: 'pick a time, default: 4:04AM',
simpleText: 'pick a time',
};
},

async showPicker(stateKey, options) {
try {
const {action, minute, hour} = await TimePickerAndroid.open(options);
var newState = {};
if (action === TimePickerAndroid.timeSetAction) {
newState[stateKey + 'Text'] = _formatTime(hour, minute);
newState[stateKey + 'Hour'] = hour;
newState[stateKey + 'Minute'] = minute;
} else if (action === TimePickerAndroid.dismissedAction) {
newState[stateKey + 'Text'] = 'dismissed';
}
this.setState(newState);
} catch ({code, message}) {
console.warn(`Error in example '${stateKey}': `, message);
}
},

render() {
return (
<UIExplorerPage title="TimePickerAndroid">
<UIExplorerBlock title="Simple time picker">
<TouchableWithoutFeedback
onPress={this.showPicker.bind(this, 'simple')}>
<Text style={styles.text}>{this.state.simpleText}</Text>
</TouchableWithoutFeedback>
</UIExplorerBlock>
<UIExplorerBlock title="Time picker with pre-set time">
<TouchableWithoutFeedback
onPress={this.showPicker.bind(this, 'preset', {
hour: this.state.presetHour,
minute: this.state.presetMinute,
})}>
<Text style={styles.text}>{this.state.presetText}</Text>
</TouchableWithoutFeedback>
</UIExplorerBlock>

<UIExplorerBlock title="Time picker with 24-hour time format">
<TouchableWithoutFeedback
onPress={this.showPicker.bind(this, 'isoFormat', {
hour: this.state.isoFormatHour,
minute: this.state.isoFormatMinute,
is24Hour: true,
})}>
<Text style={styles.text}>{this.state.isoFormatText}</Text>
</TouchableWithoutFeedback>
</UIExplorerBlock>
</UIExplorerPage>
);
},
});

/**
* Returns e.g. '3:05'.
*/
function _formatTime(hour, minute) {
return hour + ':' + (minute < 10 ? '0' + minute : minute);
}

var styles = StyleSheet.create({
text: {
color: 'black',
},
});

module.exports = TimePickerAndroidExample;

2 changes: 2 additions & 0 deletions Examples/UIExplorer/UIExplorerList.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,15 @@ var APIS = [
require('./BorderExample'),
require('./CameraRollExample'),
require('./ClipboardExample'),
require('./DatePickerAndroidExample'),
require('./GeolocationExample'),
require('./IntentAndroidExample.android'),
require('./LayoutEventsExample'),
require('./LayoutExample'),
require('./NetInfoExample'),
require('./PanResponderExample'),
require('./PointerEventsExample'),
require('./TimePickerAndroidExample'),
require('./TimerExample'),
require('./ToastAndroidExample.android'),
require('./XHRExample'),
Expand Down
10 changes: 5 additions & 5 deletions Libraries/Components/Clipboard/Clipboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ module.exports = {
*/
getString() {
if (arguments.length > 0) {
let callback = arguments[0];
console.warn('Clipboard.getString(callback) is deprecated. Use the returned Promise instead');
Clipboard.getString().then(callback);
return;
let callback = arguments[0];
console.warn('Clipboard.getString(callback) is deprecated. Use the returned Promise instead');
Clipboard.getString().then(callback);
return;
}
return Clipboard.getString();
},
Expand All @@ -40,7 +40,7 @@ module.exports = {
* Clipboard.setString('hello world');
* }
* ```
* @param this parameter is content that will be set into clipboard.
* @param the content to be stored in the clipboard.
*/
setString(content) {
Clipboard.setString(content);
Expand Down
Loading

5 comments on commit 9a0539d

@satya164
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

@chandu0101
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@xitaoque
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I compile the example in UIExplorer and the DatePickerAndroid and TimePickerAndroid do work.
But when I write it in my code, it doesn't work. DatePickerAndroid and TimePickerAndroid is undefined.
I noticed that under "myProject"/node_modules/react-native/Libraries/Components there are no DatePickerAndroid and TimePickerAndroid folders, so I copy them form RN source and put them there.
But still, It do not work.
What should I add to my project in order to make DatePickerAndroid and TimePickerAndroid to work?

@xu6148152
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xitaoque
Update your RN to 0.20

@pickhardt
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @mkonicek quick question - DatePickerAndroid isn't in the docs, but it looks like it's been available here for about a month. Is this something we can rely on using?

Please sign in to comment.