Merged PR 737859: Support Input.Time
Support Input.Time
This commit is contained in:
Родитель
0f2a21c2ca
Коммит
dfdee71720
|
@ -0,0 +1,85 @@
|
|||
import * as React from 'react';
|
||||
import { DatePickerIOS, Platform, TimePickerAndroid } from 'react-native';
|
||||
import { StyleManager } from '../../Styles/StyleManager';
|
||||
import { TimeUtils } from '../../Utils/TimeUtils';
|
||||
import { ButtonGroup } from '../Containers/ButtonGroup';
|
||||
import { Card } from '../Containers/Card';
|
||||
import { ModalBox } from '../Containers/ModalBox';
|
||||
import { Button } from './Button';
|
||||
export class TimePanel extends React.Component {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.onCancel = () => {
|
||||
if (this.props.onCancel) {
|
||||
this.props.onCancel();
|
||||
}
|
||||
};
|
||||
this.onSave = () => {
|
||||
if (this.props.onSave) {
|
||||
this.props.onSave();
|
||||
}
|
||||
};
|
||||
this.onTimeChangeIos = (date) => {
|
||||
if (this.props.onValueChange) {
|
||||
this.props.onValueChange(TimeUtils.getTimeString(date));
|
||||
}
|
||||
};
|
||||
this.onTimeChange = (hour, minute) => {
|
||||
if (this.props.onValueChange) {
|
||||
this.props.onValueChange(TimeUtils.composeTimeString(hour, minute));
|
||||
}
|
||||
};
|
||||
}
|
||||
componentDidUpdate(prevProps) {
|
||||
if (Platform.OS === 'android' && this.props.show && !prevProps.show) {
|
||||
this.showPickerAndroid();
|
||||
}
|
||||
}
|
||||
render() {
|
||||
if (Platform.OS === 'ios') {
|
||||
return (React.createElement(ModalBox, { show: this.show },
|
||||
React.createElement(Card, { flex: 0, fit: 'content' },
|
||||
React.createElement(DatePickerIOS, { date: TimeUtils.extractTime(this.props.value), mode: 'time', onDateChange: this.onTimeChangeIos }),
|
||||
React.createElement(ButtonGroup, null,
|
||||
this.renderCancelButton(),
|
||||
this.renderSaveButton()))));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
renderCancelButton() {
|
||||
return (React.createElement(Button, { flex: 1, title: 'Cancel', color: StyleManager.getColor('accent', 'default', false), fontSize: StyleManager.getFontSize('default'), fontWeight: StyleManager.getFontWeight('bolder'), backgroundColor: StyleManager.getBackgroundColor('default'), textHorizontalAlign: 'center', textVerticalAlign: 'center', paddingTop: 6, paddingBottom: 6, paddingLeft: 16, paddingRight: 16, onPress: this.onCancel }));
|
||||
}
|
||||
renderSaveButton() {
|
||||
return (React.createElement(Button, { flex: 1, title: 'Save', color: StyleManager.getColor('accent', 'default', false), fontSize: StyleManager.getFontSize('default'), fontWeight: StyleManager.getFontWeight('bolder'), backgroundColor: StyleManager.getBackgroundColor('default'), textHorizontalAlign: 'center', textVerticalAlign: 'center', paddingTop: 6, paddingBottom: 6, paddingLeft: 16, paddingRight: 16, onPress: this.onSave, style: {
|
||||
borderLeftWidth: 1,
|
||||
borderLeftColor: StyleManager.separatorColor,
|
||||
} }));
|
||||
}
|
||||
async showPickerAndroid() {
|
||||
if (Platform.OS === 'android') {
|
||||
const now = TimeUtils.extractTime(this.props.value);
|
||||
try {
|
||||
const { action, hour, minute } = await TimePickerAndroid.open({
|
||||
hour: now.getHours(),
|
||||
minute: now.getMinutes(),
|
||||
is24Hour: true
|
||||
});
|
||||
if (action === TimePickerAndroid.timeSetAction) {
|
||||
this.onTimeChange(hour, minute);
|
||||
this.onSave();
|
||||
}
|
||||
if (action === TimePickerAndroid.dismissedAction) {
|
||||
this.setState({
|
||||
showTimePicker: false
|
||||
}, this.onCancel);
|
||||
}
|
||||
}
|
||||
catch ({ code, message }) {
|
||||
console.warn('Cannot open time picker', message);
|
||||
}
|
||||
}
|
||||
}
|
||||
get show() {
|
||||
return this.props.show && Platform.OS === 'ios';
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ import { ImageSetView } from '../Containers/ImageSet';
|
|||
import { DateInputView } from '../Inputs/DateInput';
|
||||
import { NumberInputView } from '../Inputs/NumberInput';
|
||||
import { TextInputView } from '../Inputs/TextInput';
|
||||
import { TimeInputView } from '../Inputs/TimeInput';
|
||||
export class ContentFactory {
|
||||
static createView(element, index, theme) {
|
||||
if (element) {
|
||||
|
@ -58,6 +59,8 @@ export class ContentFactory {
|
|||
return (React.createElement(NumberInputView, { key: 'NumberInput' + index, element: element, index: index, theme: theme }));
|
||||
case ContentElementType.DateInput:
|
||||
return (React.createElement(DateInputView, { key: 'DateInputView' + index, element: element, index: index, theme: theme }));
|
||||
case ContentElementType.TimeInput:
|
||||
return (React.createElement(TimeInputView, { key: 'TimeInputView' + index, element: element, index: index, theme: theme }));
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
import * as React from 'react';
|
||||
import { Button } from '../../Components/Inputs/Button';
|
||||
import { TimePanel } from '../../Components/Inputs/TimePanel';
|
||||
import { FormContext } from '../../Contexts/FormContext';
|
||||
import { StyleManager } from '../../Styles/StyleManager';
|
||||
import { DebugOutputFactory } from '../Factories/DebugOutputFactory';
|
||||
export class TimeInputView extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.tempValue = '';
|
||||
this.onValueChange = (value) => {
|
||||
this.tempValue = value;
|
||||
};
|
||||
this.onCancel = () => {
|
||||
this.setState({
|
||||
focused: false,
|
||||
}, () => {
|
||||
this.tempValue = this.state.value;
|
||||
});
|
||||
};
|
||||
this.onSave = () => {
|
||||
this.setState({
|
||||
value: this.tempValue,
|
||||
focused: false,
|
||||
}, () => {
|
||||
this.updateStore();
|
||||
});
|
||||
};
|
||||
this.validateInput = (input) => {
|
||||
if (this.props.element) {
|
||||
return this.props.element.validate(input);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
this.onPress = () => {
|
||||
this.setState({
|
||||
focused: !this.state.focused,
|
||||
});
|
||||
console.log('on press');
|
||||
};
|
||||
const { element } = this.props;
|
||||
if (element && element.isValid) {
|
||||
this.state = {
|
||||
focused: false,
|
||||
value: element.value
|
||||
};
|
||||
}
|
||||
}
|
||||
render() {
|
||||
const { element, index, theme } = this.props;
|
||||
if (!element || !element.isValid) {
|
||||
return DebugOutputFactory.createDebugOutputBanner(element.type + '>>' + element.id + ' is not valid', theme, 'error');
|
||||
}
|
||||
return ([
|
||||
React.createElement(Button, { key: 'TimeInputButton' + index, title: this.state.value, color: this.color, backgroundColor: this.backgroundColor, borderColor: this.borderColor, borderRadius: 4, borderWidth: 1, height: this.height, fontSize: this.fontSize, fontWeight: this.fontWeight, textHorizontalAlign: 'center', textVerticalAlign: 'center', marginTop: this.spacing, paddingLeft: this.paddingHorizontal, paddingRight: this.paddingHorizontal, paddingTop: this.paddingVertical, paddingBottom: this.paddingVertical, onPress: this.onPress }),
|
||||
React.createElement(TimePanel, { key: 'TimePanel' + index, value: this.state.value, show: this.state.focused, onValueChange: this.onValueChange, onSave: this.onSave, onCancel: this.onCancel })
|
||||
]);
|
||||
}
|
||||
updateStore() {
|
||||
FormContext.getInstance().updateField(this.props.element.id, this.state.value, this.validateInput(this.state.value));
|
||||
}
|
||||
get fontSize() {
|
||||
return StyleManager.getFontSize('default');
|
||||
}
|
||||
get fontWeight() {
|
||||
return StyleManager.getFontWeight('default');
|
||||
}
|
||||
get paddingVertical() {
|
||||
return 12;
|
||||
}
|
||||
get paddingHorizontal() {
|
||||
return 12;
|
||||
}
|
||||
get numberOfLine() {
|
||||
return 1;
|
||||
}
|
||||
get height() {
|
||||
return this.fontSize * this.numberOfLine + this.paddingVertical * 2;
|
||||
}
|
||||
get color() {
|
||||
if (this.state.focused) {
|
||||
return StyleManager.getInputFocusColor(this.props.theme);
|
||||
}
|
||||
else {
|
||||
return StyleManager.getInputColor(this.props.theme);
|
||||
}
|
||||
}
|
||||
get backgroundColor() {
|
||||
if (this.state.focused) {
|
||||
return StyleManager.getInputFocusBackgroundColor(this.props.theme);
|
||||
}
|
||||
else {
|
||||
return StyleManager.getInputBackgroundColor(this.props.theme);
|
||||
}
|
||||
}
|
||||
get borderColor() {
|
||||
if (this.state.focused) {
|
||||
return StyleManager.getInputFocusBorderColor(this.props.theme);
|
||||
}
|
||||
else {
|
||||
return StyleManager.getInputBorderColor(this.props.theme);
|
||||
}
|
||||
}
|
||||
get spacing() {
|
||||
if (this.props.index !== undefined && this.props.index > 0) {
|
||||
return StyleManager.getSpacing(this.props.element.spacing);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
import * as React from 'react';
|
||||
import { DatePickerIOS, Platform, TimePickerAndroid } from 'react-native';
|
||||
import { StyleManager } from '../../Styles/StyleManager';
|
||||
import { TimeUtils } from '../../Utils/TimeUtils';
|
||||
import { ButtonGroup } from '../Containers/ButtonGroup';
|
||||
import { Card } from '../Containers/Card';
|
||||
import { ModalBox } from '../Containers/ModalBox';
|
||||
import { Button } from './Button';
|
||||
export class TimePanel extends React.Component {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.onCancel = () => {
|
||||
if (this.props.onCancel) {
|
||||
this.props.onCancel();
|
||||
}
|
||||
};
|
||||
this.onSave = () => {
|
||||
if (this.props.onSave) {
|
||||
this.props.onSave();
|
||||
}
|
||||
};
|
||||
this.onTimeChangeIos = (date) => {
|
||||
if (this.props.onValueChange) {
|
||||
this.props.onValueChange(TimeUtils.getTimeString(date));
|
||||
}
|
||||
};
|
||||
this.onTimeChange = (hour, minute) => {
|
||||
if (this.props.onValueChange) {
|
||||
this.props.onValueChange(TimeUtils.composeTimeString(hour, minute));
|
||||
}
|
||||
};
|
||||
}
|
||||
componentDidUpdate(prevProps) {
|
||||
if (Platform.OS === 'android' && this.props.show && !prevProps.show) {
|
||||
this.showPickerAndroid();
|
||||
}
|
||||
}
|
||||
render() {
|
||||
if (Platform.OS === 'ios') {
|
||||
return (React.createElement(ModalBox, { show: this.show },
|
||||
React.createElement(Card, { flex: 0, fit: 'content' },
|
||||
React.createElement(DatePickerIOS, { date: TimeUtils.extractTime(this.props.value), mode: 'time', onDateChange: this.onTimeChangeIos }),
|
||||
React.createElement(ButtonGroup, null,
|
||||
this.renderCancelButton(),
|
||||
this.renderSaveButton()))));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
renderCancelButton() {
|
||||
return (React.createElement(Button, { flex: 1, title: 'Cancel', color: StyleManager.getColor('accent', 'default', false), fontSize: StyleManager.getFontSize('default'), fontWeight: StyleManager.getFontWeight('bolder'), backgroundColor: StyleManager.getBackgroundColor('default'), textHorizontalAlign: 'center', textVerticalAlign: 'center', paddingTop: 6, paddingBottom: 6, paddingLeft: 16, paddingRight: 16, onPress: this.onCancel }));
|
||||
}
|
||||
renderSaveButton() {
|
||||
return (React.createElement(Button, { flex: 1, title: 'Save', color: StyleManager.getColor('accent', 'default', false), fontSize: StyleManager.getFontSize('default'), fontWeight: StyleManager.getFontWeight('bolder'), backgroundColor: StyleManager.getBackgroundColor('default'), textHorizontalAlign: 'center', textVerticalAlign: 'center', paddingTop: 6, paddingBottom: 6, paddingLeft: 16, paddingRight: 16, onPress: this.onSave, style: {
|
||||
borderLeftWidth: 1,
|
||||
borderLeftColor: StyleManager.separatorColor,
|
||||
} }));
|
||||
}
|
||||
async showPickerAndroid() {
|
||||
if (Platform.OS === 'android') {
|
||||
const now = TimeUtils.extractTime(this.props.value);
|
||||
try {
|
||||
const { action, hour, minute } = await TimePickerAndroid.open({
|
||||
hour: now.getHours(),
|
||||
minute: now.getMinutes(),
|
||||
is24Hour: true
|
||||
});
|
||||
if (action === TimePickerAndroid.timeSetAction) {
|
||||
this.onTimeChange(hour, minute);
|
||||
this.onSave();
|
||||
}
|
||||
if (action === TimePickerAndroid.dismissedAction) {
|
||||
this.setState({
|
||||
showTimePicker: false
|
||||
}, this.onCancel);
|
||||
}
|
||||
}
|
||||
catch ({ code, message }) {
|
||||
console.warn('Cannot open time picker', message);
|
||||
}
|
||||
}
|
||||
}
|
||||
get show() {
|
||||
return this.props.show && Platform.OS === 'ios';
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ import { ImageSetView } from '../Containers/ImageSet';
|
|||
import { DateInputView } from '../Inputs/DateInput';
|
||||
import { NumberInputView } from '../Inputs/NumberInput';
|
||||
import { TextInputView } from '../Inputs/TextInput';
|
||||
import { TimeInputView } from '../Inputs/TimeInput';
|
||||
export class ContentFactory {
|
||||
static createView(element, index, theme) {
|
||||
if (element) {
|
||||
|
@ -58,6 +59,8 @@ export class ContentFactory {
|
|||
return (React.createElement(NumberInputView, { key: 'NumberInput' + index, element: element, index: index, theme: theme }));
|
||||
case ContentElementType.DateInput:
|
||||
return (React.createElement(DateInputView, { key: 'DateInputView' + index, element: element, index: index, theme: theme }));
|
||||
case ContentElementType.TimeInput:
|
||||
return (React.createElement(TimeInputView, { key: 'TimeInputView' + index, element: element, index: index, theme: theme }));
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
import * as React from 'react';
|
||||
import { Button } from '../../Components/Inputs/Button';
|
||||
import { TimePanel } from '../../Components/Inputs/TimePanel';
|
||||
import { FormContext } from '../../Contexts/FormContext';
|
||||
import { StyleManager } from '../../Styles/StyleManager';
|
||||
import { DebugOutputFactory } from '../Factories/DebugOutputFactory';
|
||||
export class TimeInputView extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.tempValue = '';
|
||||
this.onValueChange = (value) => {
|
||||
this.tempValue = value;
|
||||
};
|
||||
this.onCancel = () => {
|
||||
this.setState({
|
||||
focused: false,
|
||||
}, () => {
|
||||
this.tempValue = this.state.value;
|
||||
});
|
||||
};
|
||||
this.onSave = () => {
|
||||
this.setState({
|
||||
value: this.tempValue,
|
||||
focused: false,
|
||||
}, () => {
|
||||
this.updateStore();
|
||||
});
|
||||
};
|
||||
this.validateInput = (input) => {
|
||||
if (this.props.element) {
|
||||
return this.props.element.validate(input);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
this.onPress = () => {
|
||||
this.setState({
|
||||
focused: !this.state.focused,
|
||||
});
|
||||
console.log('on press');
|
||||
};
|
||||
const { element } = this.props;
|
||||
if (element && element.isValid) {
|
||||
this.state = {
|
||||
focused: false,
|
||||
value: element.value
|
||||
};
|
||||
}
|
||||
}
|
||||
render() {
|
||||
const { element, index, theme } = this.props;
|
||||
if (!element || !element.isValid) {
|
||||
return DebugOutputFactory.createDebugOutputBanner(element.type + '>>' + element.id + ' is not valid', theme, 'error');
|
||||
}
|
||||
return ([
|
||||
React.createElement(Button, { key: 'TimeInputButton' + index, title: this.state.value, color: this.color, backgroundColor: this.backgroundColor, borderColor: this.borderColor, borderRadius: 4, borderWidth: 1, height: this.height, fontSize: this.fontSize, fontWeight: this.fontWeight, textHorizontalAlign: 'center', textVerticalAlign: 'center', marginTop: this.spacing, paddingLeft: this.paddingHorizontal, paddingRight: this.paddingHorizontal, paddingTop: this.paddingVertical, paddingBottom: this.paddingVertical, onPress: this.onPress }),
|
||||
React.createElement(TimePanel, { key: 'TimePanel' + index, value: this.state.value, show: this.state.focused, onValueChange: this.onValueChange, onSave: this.onSave, onCancel: this.onCancel })
|
||||
]);
|
||||
}
|
||||
updateStore() {
|
||||
FormContext.getInstance().updateField(this.props.element.id, this.state.value, this.validateInput(this.state.value));
|
||||
}
|
||||
get fontSize() {
|
||||
return StyleManager.getFontSize('default');
|
||||
}
|
||||
get fontWeight() {
|
||||
return StyleManager.getFontWeight('default');
|
||||
}
|
||||
get paddingVertical() {
|
||||
return 12;
|
||||
}
|
||||
get paddingHorizontal() {
|
||||
return 12;
|
||||
}
|
||||
get numberOfLine() {
|
||||
return 1;
|
||||
}
|
||||
get height() {
|
||||
return this.fontSize * this.numberOfLine + this.paddingVertical * 2;
|
||||
}
|
||||
get color() {
|
||||
if (this.state.focused) {
|
||||
return StyleManager.getInputFocusColor(this.props.theme);
|
||||
}
|
||||
else {
|
||||
return StyleManager.getInputColor(this.props.theme);
|
||||
}
|
||||
}
|
||||
get backgroundColor() {
|
||||
if (this.state.focused) {
|
||||
return StyleManager.getInputFocusBackgroundColor(this.props.theme);
|
||||
}
|
||||
else {
|
||||
return StyleManager.getInputBackgroundColor(this.props.theme);
|
||||
}
|
||||
}
|
||||
get borderColor() {
|
||||
if (this.state.focused) {
|
||||
return StyleManager.getInputFocusBorderColor(this.props.theme);
|
||||
}
|
||||
else {
|
||||
return StyleManager.getInputBorderColor(this.props.theme);
|
||||
}
|
||||
}
|
||||
get spacing() {
|
||||
if (this.props.index !== undefined && this.props.index > 0) {
|
||||
return StyleManager.getSpacing(this.props.element.spacing);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
import * as React from 'react';
|
||||
|
||||
import { DatePickerIOS, Platform, TimePickerAndroid } from 'react-native';
|
||||
import { StyleManager } from '../../Styles/StyleManager';
|
||||
import { TimeUtils } from '../../Utils/TimeUtils';
|
||||
import { ButtonGroup } from '../Containers/ButtonGroup';
|
||||
import { Card } from '../Containers/Card';
|
||||
import { ModalBox } from '../Containers/ModalBox';
|
||||
import { Button } from './Button';
|
||||
|
||||
interface IProps {
|
||||
value: string;
|
||||
show: boolean;
|
||||
onValueChange: (value: string) => void;
|
||||
onSave: () => void;
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
export class TimePanel extends React.Component<IProps> {
|
||||
public componentDidUpdate(prevProps: IProps) {
|
||||
if (Platform.OS === 'android' && this.props.show && !prevProps.show) {
|
||||
this.showPickerAndroid();
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
if (Platform.OS === 'ios') {
|
||||
return (
|
||||
<ModalBox
|
||||
show={this.show}
|
||||
>
|
||||
<Card
|
||||
flex={0}
|
||||
fit='content'
|
||||
>
|
||||
<DatePickerIOS
|
||||
date={TimeUtils.extractTime(this.props.value)}
|
||||
mode='time'
|
||||
onDateChange={this.onTimeChangeIos}
|
||||
/>
|
||||
<ButtonGroup>
|
||||
{this.renderCancelButton()}
|
||||
{this.renderSaveButton()}
|
||||
</ButtonGroup>
|
||||
</Card>
|
||||
</ModalBox>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private renderCancelButton() {
|
||||
return (
|
||||
<Button
|
||||
flex={1}
|
||||
title='Cancel'
|
||||
color={StyleManager.getColor('accent', 'default', false)}
|
||||
fontSize={StyleManager.getFontSize('default')}
|
||||
fontWeight={StyleManager.getFontWeight('bolder')}
|
||||
backgroundColor={StyleManager.getBackgroundColor('default')}
|
||||
textHorizontalAlign='center'
|
||||
textVerticalAlign='center'
|
||||
paddingTop={6}
|
||||
paddingBottom={6}
|
||||
paddingLeft={16}
|
||||
paddingRight={16}
|
||||
onPress={this.onCancel}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
private renderSaveButton() {
|
||||
return (
|
||||
<Button
|
||||
flex={1}
|
||||
title='Save'
|
||||
color={StyleManager.getColor('accent', 'default', false)}
|
||||
fontSize={StyleManager.getFontSize('default')}
|
||||
fontWeight={StyleManager.getFontWeight('bolder')}
|
||||
backgroundColor={StyleManager.getBackgroundColor('default')}
|
||||
textHorizontalAlign='center'
|
||||
textVerticalAlign='center'
|
||||
paddingTop={6}
|
||||
paddingBottom={6}
|
||||
paddingLeft={16}
|
||||
paddingRight={16}
|
||||
onPress={this.onSave}
|
||||
style={{
|
||||
borderLeftWidth: 1,
|
||||
borderLeftColor: StyleManager.separatorColor,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
private async showPickerAndroid() {
|
||||
if (Platform.OS === 'android') {
|
||||
const now = TimeUtils.extractTime(this.props.value);
|
||||
try {
|
||||
const { action, hour, minute } = await TimePickerAndroid.open({
|
||||
hour: now.getHours(),
|
||||
minute: now.getMinutes(),
|
||||
is24Hour: true
|
||||
});
|
||||
if (action === TimePickerAndroid.timeSetAction) {
|
||||
this.onTimeChange(hour, minute);
|
||||
this.onSave();
|
||||
}
|
||||
if (action === TimePickerAndroid.dismissedAction) {
|
||||
this.setState({
|
||||
showTimePicker: false
|
||||
}, this.onCancel);
|
||||
}
|
||||
} catch ({ code, message }) {
|
||||
console.warn('Cannot open time picker', message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private onCancel = () => {
|
||||
if (this.props.onCancel) {
|
||||
this.props.onCancel();
|
||||
}
|
||||
}
|
||||
|
||||
private onSave = () => {
|
||||
if (this.props.onSave) {
|
||||
this.props.onSave();
|
||||
}
|
||||
}
|
||||
|
||||
private onTimeChangeIos = (date: Date) => {
|
||||
if (this.props.onValueChange) {
|
||||
this.props.onValueChange(TimeUtils.getTimeString(date));
|
||||
}
|
||||
}
|
||||
|
||||
private onTimeChange = (hour: number, minute: number) => {
|
||||
if (this.props.onValueChange) {
|
||||
this.props.onValueChange(TimeUtils.composeTimeString(hour, minute));
|
||||
}
|
||||
}
|
||||
|
||||
private get show() {
|
||||
return this.props.show && Platform.OS === 'ios';
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ import { ImageSetElement } from '../../Schema/Containers/ImageSet';
|
|||
import { DateInputElement } from '../../Schema/Inputs/DateInput';
|
||||
import { NumberInputElement } from '../../Schema/Inputs/NumberInput';
|
||||
import { TextInputElement } from '../../Schema/Inputs/TextInput';
|
||||
import { TimeInputElement } from '../../Schema/Inputs/TimeInput';
|
||||
import { ImageView } from '../CardElements/Image';
|
||||
import { TextBlockView } from '../CardElements/TextBlock';
|
||||
import { AdaptiveCardView } from '../Cards/AdaptiveCard';
|
||||
|
@ -22,6 +23,7 @@ import { ImageSetView } from '../Containers/ImageSet';
|
|||
import { DateInputView } from '../Inputs/DateInput';
|
||||
import { NumberInputView } from '../Inputs/NumberInput';
|
||||
import { TextInputView } from '../Inputs/TextInput';
|
||||
import { TimeInputView } from '../Inputs/TimeInput';
|
||||
|
||||
export class ContentFactory {
|
||||
public static createView(element: ContentElement, index: number, theme: 'default' | 'emphasis'): JSX.Element[] {
|
||||
|
@ -149,6 +151,15 @@ export class ContentFactory {
|
|||
theme={theme}
|
||||
/>
|
||||
);
|
||||
case ContentElementType.TimeInput:
|
||||
return (
|
||||
<TimeInputView
|
||||
key={'TimeInputView' + index}
|
||||
element={element as TimeInputElement}
|
||||
index={index}
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,173 @@
|
|||
import * as React from 'react';
|
||||
import { Button } from '../../Components/Inputs/Button';
|
||||
import { TimePanel } from '../../Components/Inputs/TimePanel';
|
||||
import { FormContext } from '../../Contexts/FormContext';
|
||||
import { TimeInputElement } from '../../Schema/Inputs/TimeInput';
|
||||
import { StyleManager } from '../../Styles/StyleManager';
|
||||
import { DebugOutputFactory } from '../Factories/DebugOutputFactory';
|
||||
|
||||
interface IProps {
|
||||
index: number;
|
||||
element: TimeInputElement;
|
||||
theme: 'default' | 'emphasis';
|
||||
}
|
||||
|
||||
interface IState {
|
||||
value: string;
|
||||
focused: boolean;
|
||||
}
|
||||
|
||||
export class TimeInputView extends React.Component<IProps, IState> {
|
||||
private tempValue = '';
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
const { element } = this.props;
|
||||
|
||||
if (element && element.isValid) {
|
||||
this.state = {
|
||||
focused: false,
|
||||
value: element.value
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { element, index, theme } = this.props;
|
||||
|
||||
if (!element || !element.isValid) {
|
||||
return DebugOutputFactory.createDebugOutputBanner(element.type + '>>' + element.id + ' is not valid', theme, 'error');
|
||||
}
|
||||
|
||||
return (
|
||||
[
|
||||
<Button
|
||||
key={'TimeInputButton' + index}
|
||||
title={this.state.value}
|
||||
color={this.color}
|
||||
backgroundColor={this.backgroundColor}
|
||||
borderColor={this.borderColor}
|
||||
borderRadius={4}
|
||||
borderWidth={1}
|
||||
height={this.height}
|
||||
fontSize={this.fontSize}
|
||||
fontWeight={this.fontWeight}
|
||||
textHorizontalAlign='center'
|
||||
textVerticalAlign='center'
|
||||
marginTop={this.spacing}
|
||||
paddingLeft={this.paddingHorizontal}
|
||||
paddingRight={this.paddingHorizontal}
|
||||
paddingTop={this.paddingVertical}
|
||||
paddingBottom={this.paddingVertical}
|
||||
onPress={this.onPress}
|
||||
/>,
|
||||
<TimePanel
|
||||
key={'TimePanel' + index}
|
||||
value={this.state.value}
|
||||
show={this.state.focused}
|
||||
onValueChange={this.onValueChange}
|
||||
onSave={this.onSave}
|
||||
onCancel={this.onCancel}
|
||||
/>
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private onValueChange = (value: string) => {
|
||||
this.tempValue = value;
|
||||
}
|
||||
|
||||
private onCancel = () => {
|
||||
this.setState({
|
||||
focused: false,
|
||||
}, () => {
|
||||
this.tempValue = this.state.value;
|
||||
});
|
||||
}
|
||||
|
||||
private onSave = () => {
|
||||
this.setState({
|
||||
value: this.tempValue,
|
||||
focused: false,
|
||||
}, () => {
|
||||
this.updateStore();
|
||||
});
|
||||
}
|
||||
|
||||
private validateInput = (input: string) => {
|
||||
if (this.props.element) {
|
||||
return this.props.element.validate(input);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private updateStore() {
|
||||
FormContext.getInstance().updateField(
|
||||
this.props.element.id,
|
||||
this.state.value,
|
||||
this.validateInput(this.state.value)
|
||||
);
|
||||
}
|
||||
|
||||
private onPress = () => {
|
||||
this.setState({
|
||||
focused: !this.state.focused,
|
||||
});
|
||||
console.log('on press');
|
||||
}
|
||||
|
||||
private get fontSize() {
|
||||
return StyleManager.getFontSize('default');
|
||||
}
|
||||
|
||||
private get fontWeight() {
|
||||
return StyleManager.getFontWeight('default');
|
||||
}
|
||||
|
||||
private get paddingVertical() {
|
||||
return 12;
|
||||
}
|
||||
|
||||
private get paddingHorizontal() {
|
||||
return 12;
|
||||
}
|
||||
|
||||
private get numberOfLine() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
private get height() {
|
||||
return this.fontSize * this.numberOfLine + this.paddingVertical * 2;
|
||||
}
|
||||
|
||||
private get color() {
|
||||
if (this.state.focused) {
|
||||
return StyleManager.getInputFocusColor(this.props.theme);
|
||||
} else {
|
||||
return StyleManager.getInputColor(this.props.theme);
|
||||
}
|
||||
}
|
||||
|
||||
private get backgroundColor() {
|
||||
if (this.state.focused) {
|
||||
return StyleManager.getInputFocusBackgroundColor(this.props.theme);
|
||||
} else {
|
||||
return StyleManager.getInputBackgroundColor(this.props.theme);
|
||||
}
|
||||
}
|
||||
|
||||
private get borderColor() {
|
||||
if (this.state.focused) {
|
||||
return StyleManager.getInputFocusBorderColor(this.props.theme);
|
||||
} else {
|
||||
return StyleManager.getInputBorderColor(this.props.theme);
|
||||
}
|
||||
}
|
||||
|
||||
private get spacing() {
|
||||
if (this.props.index !== undefined && this.props.index > 0) {
|
||||
return StyleManager.getSpacing(this.props.element.spacing);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче