简体   繁体   中英

How to change the value of input dynamically?

I have a dynamic inputs, which I can add and delete a row with inputs, there are inputs of material-ui for timepicker, which having an input with her icon of a clock when I click on it the clock will appear. but the values of this input cannot change with the clock.

My code is :

import { TimePicker } from "material-ui-time-picker";
import {
  Input as Time,
  Dialog as Clock,
  DialogActions,
  Button as ButtonOk
} from "@material-ui/core";
  constructor(props) {
    super(props);
    this.state = {
      isOpenS: false,
      isOpenE: false,
      start: moment().format("HH:MM"),
      end: moment().format("HH:MM"),
      tranches: [
        { start: moment().format("HH:MM"), end: moment().format("HH:MM") }
      ]
    };

    this.ajouterTranche = this.ajouterTranche.bind(this);
    this.supprimerTranche = this.supprimerTranche.bind(this);
    this.handleKeyboardStartChange = this.handleKeyboardStartChange.bind(this);
  }


  openDialogS = () => this.setState({ isOpenS: true });
  closeDialogS = () => this.setState({ isOpenS: false });
  backdropClickS = () => this.setState({ isOpenS: false });
  handleDialogStartChange = (i, newValue) => {
    const hours = newValue
      .getHours()
      .toString()
      .padStart(2, "0");
    const minutes = newValue
      .getMinutes()
      .toString()
      .padStart(2, "0");
    const textValue = hours + ":" + minutes;
    // this.setState({ start: textValue });
    this.state.tranches[i] = Object.assign({}, this.state.tranches[i], {
      start: textValue
    });
    this.setState({
      tranches: this.state.tranches
    });
  };

  handleKeyboardStartChange = (i, event) => {
    const rowDataCopy = this.state.tranches.slice(0);
    rowDataCopy[i] = Object.assign({}, rowDataCopy[i], {
      start: event.target.value
    });
    this.setState({
      tranches: rowDataCopy
    });
  };
  createDateFromTextValue = (i, value) => {
    const splitParts = value.split(":");
    return new Date(1970, 1, 1, splitParts[0], splitParts[1]);
  };

  openDialogE = () => this.setState({ isOpenE: true });
  closeDialogE = () => this.setState({ isOpenE: false });
  handleDialogEndChange = newValue => {
    const hours = newValue
      .getHours()
      .toString()
      .padStart(2, "0");
    const minutes = newValue
      .getMinutes()
      .toString()
      .padStart(2, "0");
    const textValue = hours + ":" + minutes;
    this.setState({ end: textValue });
  };
  handleKeyboardEndChange = (i, event) => {
    // On va copier le tableau de tranches
    const rowDataCopy = this.state.tranches.slice(0);
    // On va jouter cette valeur changée au tableau de tranches
    rowDataCopy[i] = Object.assign({}, rowDataCopy[i], {
      end: event.target.value
    });
    this.setState({
      tranches: rowDataCopy
    });
  };
  createDateFromTextValue = value => {
    const splitParts = value.split(":");
    return new Date(1970, 1, 1, splitParts[0], splitParts[1]);
  };


  ajouterTranche = () => {
    this.setState(prevState => ({
      tranches: [...prevState.tranches, ""]
    }));
  };

  supprimerTranche = idx => () => {
    const rowDataCopy = this.state.tranches.slice(0);
    rowDataCopy.splice(1, 1);
    this.setState({
      tranches: rowDataCopy
    });
  };
render() {

    console.log(this.state.start);
    return (

      <div>
        {this.state.tranches.map((el, i) => (
          <Row key={i}>
            <Col span={12} />
            <Col span={12}>
              <Row>
                <Col span={8}>
                  &nbsp; &nbsp; &nbsp;
                  <label className="pt-label .modifier">
                    <strong>Heure de début</strong>
                  </label>
                  <br />
                  <Time
                    value={el.start}
                    onChange={time => this.handleKeyboardStartChange(i, time)}
                    style={heure}
                    disableUnderline={true}
                    inputComponent={TextMaskCustom}
                    endAdornment={
                      <InputAdornment position="end" style={{ opacity: "0.4" }}>
                        <IconButton onClick={this.openDialogS}>
                          <AccessTime />
                        </IconButton>
                      </InputAdornment>
                    }
                  />
                  <Clock
                    maxWidth="xs"
                    open={this.state.isOpenS}
                    onBackdropClick={this.closeDialogS}
                  >
                    <TimePicker
                      mode="24h"
                      value={this.createDateFromTextValue(this.state.start)}
                      onChange={time => this.handleDialogStartChange(i, time)}
                    />
                    <DialogActions>
                      <ButtonOk onClick={this.closeDialogS} color="primary">
                        Ok
                      </ButtonOk>
                    </DialogActions>
                  </Clock>
                  <br />
                </Col>
                <Col span={8}>
                  &nbsp; &nbsp; &nbsp;
                  <label className="pt-label .modifier">
                    <strong>Heure de fin</strong>
                  </label>
                  <br />
                  <Time
                    value={el.end}
                    onChange={time => this.handleKeyboardEndChange(i, time)}
                    style={heure}
                    disableUnderline={true}
                    inputComponent={TextMaskCustom}
                    endAdornment={
                      <InputAdornment position="end" style={{ opacity: "0.4" }}>
                        <IconButton onClick={this.openDialogS}>
                          <AccessTime />
                        </IconButton>
                      </InputAdornment>
                    }
                  />
                  <Clock
                    maxWidth="xs"
                    open={this.state.isOpenE}
                    onBackdropClick={this.closeDialogE}
                  >
                    <TimePicker
                      mode="24h"
                      value={this.createDateFromTextValue(this.state.end)}
                      onChange={this.handleDialogEndChange}
                    />
                    <DialogActions>
                      <ButtonOk onClick={this.closeDialogE} color="primary">
                        Ok
                      </ButtonOk>
                    </DialogActions>
                  </Clock>
                  <br />
                </Col>
                <Col span={8}>
                  {i === 0 ? (
                    <>
                      <br />
                      &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
                      &nbsp;
                      <Icon
                        type="plus-circle"
                        theme="twoTone"
                        twoToneColor="#52c41a"
                        onClick={this.ajouterTranche}
                      />
                      <br />
                    </>
                  ) : (
                    <>
                      <Icon
                        type="close-circle"
                        theme="twoTone"
                        twoToneColor="red"
                        onClick={this.supprimerTranche(i)}
                      />
                      <Icon
                        type="plus-circle"
                        theme="twoTone"
                        twoToneColor="#52c41a"
                        onClick={this.ajouterTranche}
                      />
                      <br />
                    </>
                  )}
                </Col>
              </Row>
            </Col>
          </Row>
        ))}
      </div>


    );
  }
}

My sandbox code is : https://codesandbox.io/s/182oy5995l

When I put a value on the input and I click on the clock, I get the moment value of the clock and not the value which I put on the input. I want when I change the time from the clock, the input will be change and vice versa.

How can I fix it ?

I'm going to set you on the right track. I think if you get this, you'll be able to quickly fix the rest of the problems. I don't really know what you're trying to do with the start and end though. So what I've done will only work on the timepicker and you can use this to fix the keyboard thing again.

Here is my forked version
https://codesandbox.io/s/2xm39130kn

When you call handleDialogStartChange with multiple objects, you can't just modify one state. Unless they're all supposed to share the same time. That seems pointless.

I modified your timepicker onChange function to onChange={time => this.handleDialogStartChange(i, time)} so you can push the index as well so you know which one you want to work with.

I modified your timepicker value function to value={this.createDateFromTextValue(el.start)} so you're referencing the individual element, not the original state variable.

Then in andleDialogStartChange modify the the state of the tranches where you're storing these times, using that index. You'll get a warning not to modify state like this, but so long as you're using it in conjunction with setState, this.setState({ tranches: this.state.tranches }); , it's a legal operation.

handleDialogStartChange = (i, newValue) => {
    const hours = newValue
      .getHours()
      .toString()
      .padStart(2, "0");
    const minutes = newValue
      .getMinutes()
      .toString()
      .padStart(2, "0");
    const textValue = hours + ":" + minutes;
    this.state.tranches[i].start = textValue;
    this.state.tranches[i].end = textValue;
    this.setState({ tranches: this.state.tranches });
    this.setState({ start: textValue });
  };

为了解决我得到了时钟并选择了小时,但它没有改变,value={el.start}更改为value={this.state.start}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM