Я пытаюсь визуализировать пользовательское поле ввода, а не использовать поле по умолчанию, так как мне нужны дополнительные элементы, окружающие мой ввод
Это мой компонент, PetalkInvitationModal
.Другие 2 являются примерами компонентов, которые я пытаюсь собрать вместе для рендеринга фактического поля ввода.Сначала я пытался использовать RenderInputField
, но затем я начал собирать RenderInputModalField
, чтобы иметь возможность вручную управлять реквизитом
import React from 'react'
import {GenericActionOrCancelModal} from "../GenericActionOrCancelModal";
import {reduxForm, Field} from "redux-form";
import Datetime from 'react-datetime';
import WarningAlert from "./components/alerts";
export class PetalkInvitationModal extends GenericActionOrCancelModal {
this.renderDateInputOutsideForm = this.renderDateInputOutsideForm.bind(this);
this.renderDateInputField = this.renderDateInputField.bind(this);
this.renderDateInputAsFormField = this.renderDateInputAsFormField.bind(this);
}
renderDateInputOutsideForm(options) {
return <Datetime
closeOnSelect={true}
renderInput={this.renderDateInputField(options)}/>;
}
/**
* @param {{id}, {label}, {name}, {required}} options
*/
renderDateInputField(options) {
return (props, openCalendar, closeCalendar)=> {
return (
<div className="form-group">
<div className="form-label-group">
<input
className="form-control"
{...props}/>
<label htmlFor={options.id} onClick={openCalendar}>{options.label}</label>
</div>
</div>
)
}
}
renderDateInputAsFormField(props) {
const {input, inputProps, meta: {touched, error}} = props;
// I'm trying to pass all the callbacks that I get, down to my component
// I tried calling the callbacks from props2, and from olderInput
const RenderInputModalWrapper = (
(props2) => <RenderInputModalField olderInput={input} {...props2}/>
);
return <Datetime {...input} {...inputProps} renderInput={RenderInputModalWrapper}/>
}
renderFields() {
return (
<div>
{/*this doesn't work, sadly :( */}
<Field
name="option1"
type="text"
component={this.renderDateInputAsFormField}
inputProps={{
closeOnSelect: true
}}
/>
{/*this works...but it's not controlled by redux-form */}
{this.renderDateInputOutsideForm({
label: 'Erste Option (erforderlich)',
name: 'option1',
})}
</div>
)
}
}
function validate(values) {
//...
}
export function RenderInputField(field) {
const {input, meta: {touched, error, valid}} = field;
const error_message = touched && !valid ? error : "";
return (
<div className="form-group">
<label htmlFor={field.htmlFor}>{field.label}</label>
<input {...field.input}
id={field.htmlFor}
className={field.className}
type={field.type ? field.type : "text"}
autoFocus={field.autoFocus}
placeholder={field.placeholder}
readOnly={field.readOnly ? field.readOnly : false}
/>
</div>
)
}
export function RenderInputModalField(props) {
let extras = {};
let {onChange, onBlur, onFocus, onDragStart, onDrop} = props;
if(props.olderInput){
// this is not good at all field doesn't respond to clicks now
// onChange = (evt) => (props.olderInput.onChange(evt), onChange(evt))
// onBlur = (evt) => (props.olderInput.onBlur(evt), onBlur(evt))
// onFocus = (evt) => (props.olderInput.onFocus(evt), onFocus(evt))
// onDragStart = (evt) => (props.olderInput.onDragStart(evt), onDragStart(evt))
// onDrop = (evt) => (props.olderInput.onDrop(evt), onDrop(evt))
// this is not good; does something on the second click. only changes the
// field value the first time
// onChange = (evt) => (onChange(evt), props.olderInput.onChange(evt))
// onBlur = (evt) => (onBlur(evt), props.olderInput.onBlur(evt))
// onFocus = (evt) => (onFocus(evt), props.olderInput.onFocus(evt))
// onDragStart = (evt) => (onDragStart(evt), props.olderInput.onDragStart(evt))
// onDrop = (evt) => (onDrop(evt), props.olderInput.onDrop(evt))
// this also responds to open only on the second click.
// it also updates the value only the first time
// onChange = (evt) => onChange(evt)
// onBlur = (evt) => (onBlur(evt))
// onFocus = (evt) => (onFocus(evt))
// onDragStart = (evt) => (onDragStart(evt))
// onDrop = (evt) => (onDrop(evt))
// this doesn't respond to the first click, and doesn't update anything
// onChange = (evt) => ( props.olderInput.onChange(evt))
// onBlur = (evt) => (props.olderInput.onBlur(evt))
// onFocus = (evt) => (props.olderInput.onFocus(evt))
// onDragStart = (evt) => (props.olderInput.onDragStart(evt))
// onDrop = (evt) => (props.olderInput.onDrop(evt))
}
extras = {onChange, onBlur, onFocus, onDragStart, onDrop};
return (
<div className="form-group">
<label htmlFor={props.htmlFor}>{props.label}</label>
<input {...props}
{...extras}
id={props.htmlFor}
className={props.className}
type={props.type ? props.type : "text"}
autoFocus={props.autoFocus}
placeholder={props.placeholder}
readOnly={!!props.readOnly}
/>
</div>
)
}
export default reduxForm({
validate,
form: 'PetalkInvitationModalForm'
})(PetalkInvitationModal)
Итак, как вы можете видеть, я попытался позвонить и передать всеобратные вызовы я мог, но, очевидно, я что-то упустил, и я уже потратил много времени на это.
Любые идеи приветствуются
[EDIT] Также, Я должен отметить, что я нашел этот пост https://github.com/YouCanBookMe/react-datetime/issues/552#issuecomment-392226610, поэтому я знаю, как визуализировать Datetime
компонент внутри Field
.
<Field
name="arrivalDate"
component={CustomDatetimePicker}
inputProps={{
timeFormat: false,
closeOnSelect: true,
dateFormat: 'DD/MM/YYYY',
}}
/>
const CustomDatetimePicker = props => {
const {
input,
inputProps,
meta: { touched, error }
} = props;
return (
<Datetime {...input} {...inputProps} />
);
};
Я также прочитал документациюreact-datetime
, где мне показывают, как визуализировать настраиваемое поле ввода внутри Datetime
компонента: https://github.com/YouCanBookMe/react-datetime#customize-the-input-appearance
var MyDTPicker = React.createClass({
render: function(){
return <Datetime renderInput={ this.renderInput } />;
},
renderInput: function( props, openCalendar, closeCalendar ){
function clear(){
props.onChange({target: {value: ''}});
}
return (
<div>
<input {...props} />
<button onClick={openCalendar}>open calendar</button>
<button onClick={closeCalendar}>close calendar</button>
<button onClick={clear}>clear</button>
</div>
);
},
});
Я просто слишком нюх на реакцию, чтобы иметь возможность собрать эти 2 вместе