при использовании response-datetime, redux-form и пользовательского ввода поле не обновляется.Есть идеи почему? - PullRequest
0 голосов
/ 13 октября 2018

Я пытаюсь визуализировать пользовательское поле ввода, а не использовать поле по умолчанию, так как мне нужны дополнительные элементы, окружающие мой ввод

Это мой компонент, 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 вместе

...