0

我正在尝试呈现自定义输入字段,而不是使用默认输入字段,因为我需要一些围绕我的输入的额外元素

这是我的组件,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)

如您所见,我尝试调用并传递所有可能的回调,但显然我遗漏了一些东西,而且我已经花了很多时间在这上面。

欢迎任何想法

[编辑] 另外,我需要提一下,我确实找到了这篇文章https://github.com/YouCanBookMe/react-datetime/issues/552#issuecomment-392226610 ,所以我知道如何DatetimeField.

<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内呈现自定义输入字段的文档: https ://github.com/YouCanBookMe/react-datetime#customize-the-input-appearanceDatetime

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>
        );
    },
});

我只是太菜鸟了,无法将这两个放在一起

4

0 回答 0