Реагировать, как перейти к целевой области ввода в форме? - PullRequest
0 голосов
/ 05 ноября 2018

У меня была очень длинная форма, в которой было около 20 различных полей, и я отобразил эту область ввода с помощью функции карты. Я хочу проверить входные данные, когда нажимаю кнопку отправки и перехожу к соответствующему полю ввода.

const ReportFields = [
  {
      title: "Report Title*",
      field: "report_title",
      type: "text",
      required: true
  },
  {
      title: "Submitting Agency*",
      field: "submitting_agency",
      type: "text",
      required: true
  },
  {
      title: "Division*",
      field: "division",
      type: "select",
      required: true
  },
  {
      title: "Committee*",
      field: "committee",
      type: "select",
      required: true
  },
  {
      title: "Assigned Contact*",
      field: "assigned_contact",
      type: "select",
      required: true
  },
  {
      title: "Other Recipients",
      field: "other_recipients",
      type: "text",
      required: false
  }];

class App extends Component {

  state = {
    report: {
    report_title: "",
    submitting_agency: "",
    division: "",
    committee: "",
    assigned_contact: "",
    other_recipients: ""
    },
    errorMessage: "",
    refs: {}
  }

 componentDidMount() {
    this.registerRefs();
 }

 registerRefs = () => {
    const refs = ReportFields.reduce((acc, current) => {
      const ref = React.createRef();
      acc[current.field] = ref;
      return acc;
    }, {});

    this.setState({ refs });
 }

   onSubmit = (e) => {
      e.preventDefault();
      for (let i = 0; i < ReportFields.length; i++) {
      const curt = ReportFields[i];
      if (curt.required && this.state.report[curt.field] === "") {
        this.setState({errorMessage: `${curt.title} cannot be empty!`});
        this.state.refs[curt.field].current.focus();
        break;
      }
    }
  }

   render() {
     const display = ReportFields.map((field, idx) => {
     return (
       <div key={idx}>
         <p>{field.title}</p>
         <input 
            type={field.type}
            onChange={(e) => {
              this.setState({
                 report: {...this.state.report, [field.field]: e.target.value}
            })
        }}
        ref={this.state.refs[field.field]}
        ></input>
      </div>
    );
})

    return (
      <div className="App">
        {display}
        <input type="button" value="submit" onClick={this.onSubmit}/>
      </div>
    );
 }
}

 export default App;

Я пытался использовать ответные ссылки, но это не работает, вы понимаете?

Кроме того, я на самом деле использую это содержимое в реагирующем режиме, это будет одной из причин, почему это не работает?

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

Итерация по всем полям и создание отдельной ссылки для каждого из них. Используйте уникальный идентификатор (в качестве предложения - свойство name), чтобы получить доступ к ссылке позже.

class App extends Component {
  constructor(props) {
    super(props);
    this.focusTextInput = this.focusTextInput.bind(this);

    // Fields
    this.ReportFields = [
      {
        type: "text",
        name: "firstname",
        title: "First Name"
      },
      {
        type: "text",
        name: "lastname",
        title: "Last Name"
      }
    ];

    this.inputRefs = this.ReportFields.reduce((acc, field) => ({
        ...acc,
        [field.name]: React.createRef()
      }), {}); 
  }

  state = {
    a: {
      b: "",
      c: "",
      d: "",
      e: "",
      f: "",
      g: "",
      h: "",
      i: "",
      j: "",
      k: "",
      l: "",
      m: "",
      n: "",
      o: "",
      p: "",
      q: "",
      r: "",
      s: "",
      t: "",
      u: "",
      v: "",
      w: "",
      x: "",
      y: ""
    },
    errorMessage: ""
  };

  focusTextInput() {

    // Focus on the input you wish, in this case "firstname"
    console.log(this.inputRefs["firstname"].current.focus());
  }

  render() {
    const display = this.ReportFields.map((field, idx) => {
      return (
        <div key={idx}>
          <p>{field.title}</p>
          <input
            type={field.type}
            onChange={e => {
              this.setState({
                report: { ...this.state.report, [field.field]: e.target.value }
              });
            }}
            ref={this.inputRefs[field.name]}
          />
        </div>
      );
    });

    return (
      <div className="App">
        {display}
        <input type="button" value="submit" onClick={this.focusTextInput} />
      </div>
    );
  }
}
0 голосов
/ 05 ноября 2018

Хорошо, вот решение, которое я знаю, кто может работать, но я не говорю, что оно лучшее. Рабочий пример здесь https://codesandbox.io/s/94v4r6w7kr. Как вы можете видеть, когда вы нажимаете кнопку Отправить, вы переходите к вводу пароля.

Как это работает? Во-первых, как вы видите, нам нужен способ сохранить все ссылки, которые мы собираемся создать. Я сохраняю это в состоянии ссылки здесь. Это работает как цикл над каждым полем и для каждого я создаю REF и добавляю это к объекту. Я использую этот объект внутри государства. Когда вы захотите использовать его после этого, вы можете позвонить this.state.refs[thenameoftheinput].current.focus().

Это пример, и я позволю вам заставить его работать с вашими собственными данными. Но я надеюсь, что это может дать вам представление:)

const ReportFields = [
  {
    title: "Report Title*",
    field: "report_title",
    type: "text",
    required: true
  },
  {
    title: "Submitting Agency*",
    field: "submitting_agency",
    type: "text",
    required: true
  },
  {
    title: "Division*",
    field: "division",
    type: "select",
    required: true
  },
  {
    title: "Committee*",
    field: "committee",
    type: "select",
    required: true
  },
  {
    title: "Assigned Contact*",
    field: "assigned_contact",
    type: "select",
    required: true
  },
  {
    title: "Other Recipients",
    field: "other_recipients",
    type: "text",
    required: false
  }
];

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      refs: {}
    };
  }

  componentDidMount() {
    this.registerRefs();
  }

  registerRefs = () => {
    const refs = ReportFields.reduce((acc, current) => {
      const ref = React.createRef();
      acc[current.field] = ref;
      return acc;
    }, {});

    this.setState({ refs });
  };

  focusTextInput = () => {
    this.state.refs.division.current.focus();
  };

  render() {
    const inputs = ReportFields.map(el => {
      return <input placeholder={el.title} ref={this.state.refs[el.field]} />;
    });

    return (
      <div>
        <form>
          {inputs}
          <input type="button" value="submit" onClick={this.focusTextInput} />
        </form>
      </div>
    );
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...