【问题标题】:display button upon typing input react键入输入时显示按钮反应
【发布时间】:2021-10-21 02:23:06
【问题描述】:

我希望能够在我的输入字段中输入内容,然后在输入内容时在其旁边显示一个按钮,显示提交编辑。现在,我有一个始终存在的按钮,但我希​​望它只在输入时显示。顺便说一句,这都是反应。到目前为止,我已经尝试过jquery,但是 react 不喜欢它。

这是整个页面,以避免混淆我在做什么以及我的东西在哪里。

 import React, { Component } from "react";
import axios from "axios";
import "../styles/TourPage.css";

class TourPage extends Component {
  constructor(props) {
    super(props);
    this.state = {
      myData: [],
      isLoading: true,
    };
  }

  componentDidMount() {
    axios
      .get("/getResults")
      .then((res) => {
        this.setState({
          myData: res.data
        });
      })
      .catch((error) => {
        // Handle the errors here
        console.log(error);
      })
      .finally(() => {
        this.setState({
          isLoading: false
        });
      });
  }

  deleteById = (id) => {

    console.log(id)
    axios
      .post(`/deleteDoc`, {id: id} )
      .then(() => {
        console.log(id, " worked")
        window.location = "/tour"
      })
      .catch((error) => {
        // Handle the errors here
        console.log(error);

  })
}

editById = (id, siteLocation, Services, cnum) => {

  console.log(id, siteLocation, Services, cnum)
  axios
    .post(`/editDoc`, JSON.stringify({id: id, location: siteLocation, Services: Services, cnum: cnum}),{
      headers: {
        "Content-Type": "Application/json"
      }
    } )
    .then(() => {
      console.log(id, " worked")
      window.location = "/tour"
    })
    .catch((error) => {
      // Handle the errors here
      console.log(error);

})
}
  render() {
    // You can handle the loader part here with isLoading flag. In this case No data found will be shown initially and then the actual data
    let { myData, isLoading } = this.state;
    return (
      <table id="customers">
        <tr>
          <th>siteLocation</th>
          <th>Services</th>
          <th>cnum</th>
        </tr>
        {myData.length > 0
          ? myData.map(({ location, Services, cnum, _id }, index) => (
              <tr key={index}>
                <td><input type="text" placeholder={location} name="location" id="location" /> </td>
                <td><input type="text" placeholder={Services} name="Services" id="Services" /> </td>
                <td><input type="text" placeholder={cnum} name="cnumhide" id="cnumhide" /> </td>
                <td><input type="hidden" placeholder={cnum} name="cnum" id="cnum" /> </td>
                <button
                  onClick={(e) => {
                    e.preventDefault();

                    this.deleteById(_id);
                  }}
                  disabled={isLoading}
                >
                  Delete
                </button>
                <button
                 onClick={(e) => {
                  e.preventDefault();
                  var siteLocation = document.getElementById('location').value
                  var Services = document.getElementById('Services').value
                  var cnum = document.getElementById('cnum').value
                  this.editById(_id, siteLocation, Services, cnum)
                }}
                >
                  Submit Edit
                </button>
              </tr>
            ))
          : "No Data Found"}
      </table>
    );
  }
}

const script = document. createElement("script"); $('input').keyup(function(){
  if($.trim(this.value).length > 0)
      $('#location').show()
   else
      $('#location').hide()
});

export default TourPage;

提前感谢4的帮助。

【问题讨论】:

  • 显然,文本是否存在的检查发生在他们开始输入文本之后。显然,在这种情况下,按钮将始终可见。此外,您正在尝试获取$('#location') 的按钮,但没有此 ID 的按钮
  • 使用 onChange() onfocus() onfocusout() 方法来维护负责提交按钮的变量的状态
  • @subrahmanyabhat 你能告诉我怎么做吗?
  • @developerg1000 可以使用功能组件吗?
  • 你不需要 jquery 来实现你想要的。

标签: javascript html jquery reactjs


【解决方案1】:

您可以在文本元素中使用onfocus()。如果要隐藏按钮,请使用onfocusout(),或者如果您只想在输入更改后进行跟踪,请使用onchange() event

    ...
    //class function
    onTyping =()=>{
        this.setState({
            showSubmit:true
        })
    }

    ...
    //render part
    render(){

    ...
    //input which you want to track typing
    <input type="text" onfocus={()=>this.onTyping()} placeholder={location} name="location" id="location" />
    ...
    //element submit button
    {this.state.showSubmit &&  <button
                 onClick={(e) => {
                  e.preventDefault();
                  var siteLocation = document.getElementById('location').value
                  var Services = document.getElementById('Services').value
                  var cnum = document.getElementById('cnum').value
                  this.editById(_id, siteLocation, Services, cnum)
                }}
                >
                  Submit Edit
                </button>}
    ...
    

【讨论】:

    【解决方案2】:

    这是一个可以帮助你的例子,

    const {
      useState
    } = React;
    const Test = () => {
      const [show, setShow] = useState(false);
      const handleChange = (event) => {
        if (event.target.value.length > 0)
          setShow(true);
        else
          setShow(false)
      }
      return ( <div>
        <input type = "text"
        onChange = {
          (event) => handleChange(event)
        }/>
        {show && < button > Submit changes now! </button>} 
        </div>
      )
    }
    ReactDOM.render( < Test / > ,
      document.getElementById('root')
    )
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
    <div id="root"></div>

    【讨论】:

      【解决方案3】:

      有一种方法可以避免使用 jquery 并继续使用您的 react 类组件来实现这一点。

      映射state.myData 以使用输入和按钮呈现每个项目。

      将数组索引与输入的onChange 事件回调一起使用,将inputValue 添加到状态内正确的数组项的对象中。

      将数组索引与按钮的onClick 事件回调一起使用,以在将项目发送到服务器之前从state.myData 获取项目。

      如果项目有inputValue,则可以有条件地呈现按钮。

      import React, { Component } from "react";
      import axios from "axios";
      
      class TourPage extends Component {
        constructor(props) {
          super(props);
          this.state = {
            myData: [],
            isLoading: true
          };
        }
      
        componentDidMount() {
          axios
            .get("https://rickandmortyapi.com/api/character")
            .then((res) => {
              this.setState({
                myData: res.data.results
              });
            })
            .finally(() => {
              this.setState({
                isLoading: false
              });
            });
        }
      
        handleChangeInput = ({ target }, index) => {
          const newData = [...this.state.myData];
          newData[index].inputValue = target.value;
          this.setState({
            myData: newData
          });
        };
      
        handleSubmitEdit = (index) => {
          const item = this.state.myData[index];
          // submit the edit to the api
          console.log(
            `Clicked on 'submit edit' for ${item.name} with value ${item.inputValue}`
          );
        };
      
        render() {
          let { myData, isLoading } = this.state;
          if (isLoading) {
            return "loading...";
          }
          return (
            <div>
              {myData.map(({ name, status, species, inputValue }, index) => {
                return (
                  <div key={index}>
                    <p>{`${name} - ${species} - ${status}`}</p>
                    <input
                      type="text"
                      onChange={(e) => this.handleChangeInput(e, index)}
                      value={inputValue || ""}
                    />
                    {inputValue && (
                      <button onClick={() => this.handleSubmitEdit(index)}>
                        Submit Edit
                      </button>
                    )}
                  </div>
                );
              })}
            </div>
          );
        }
      }
      
      export default TourPage;
      


      如果您希望每行中的每个字段都有一个输入,您可以进行一些小的更改并将您的编辑保存到嵌套对象中的项目状态。

      然后您可以检查该行的编辑对象内是否有任何内容,以有条件地显示每行的提交按钮。

      import React, { Component } from "react";
      import axios from "axios";
      import isEmpty from "lodash.isempty";
      import pick from "lodash.pick";
      
      class TourPage extends Component {
        constructor(props) {
          super(props);
          this.state = {
            myData: [],
            isLoading: true
          };
        }
      
        componentDidMount() {
          axios
            .get("https://rickandmortyapi.com/api/character")
            .then((res) => {
              this.setState({
                // here we create an empty 'edits' object for each row
                myData: res.data.results.map((d) => ({
                  ...pick(d, ["name", "status", "species"]),
                  edits: {}
                }))
              });
            })
            .finally(() => {
              this.setState({
                isLoading: false
              });
            });
        }
      
        handleChangeInput = ({ target }, index) => {
          const newData = [...this.state.myData];
          const { value, name } = target;
          newData[index].edits[name] = value;
          this.setState({
            myData: newData
          });
        };
      
        handleSubmitEdit = (index) => {
          const item = this.state.myData[index];
          // submit the edit to the api
          console.log(`Clicked on 'submit edit' for ${item.name} with edits:`);
          console.log(item.edits);
          console.log("Updated item: ");
          const { edits, ...orig } = item;
          const newItem = { ...orig, ...edits };
          console.log(newItem);
          // Once saved to api, we can update myData with newItem
          // and reset edits
          const newData = [...this.state.myData];
          newData[index] = { ...newItem, edits: {} };
          this.setState({
            myData: newData
          });
        };
      
        showButton = (index) => {
          const { edits } = this.state.myData[index];
          return !isEmpty(edits);
        };
      
        render() {
          let { myData, isLoading } = this.state;
          if (isLoading) {
            return "loading...";
          }
          return (
            <table>
              <tbody>
                {myData.map((row, index) => {
                  const { edits, ...restRow } = row;
                  return (
                    <tr key={index}>
                      {Object.keys(restRow).map((col) => {
                        return (
                          <td>
                            <label>
                              {col}:
                              <input
                                name={col}
                                value={edits[col] || restRow[col]}
                                onChange={(e) => this.handleChangeInput(e, index)}
                              />
                            </label>
                          </td>
                        );
                      })}
                      <td>
                        {this.showButton(index) && (
                          <button onClick={() => this.handleSubmitEdit(index)}>
                            Submit Edit
                          </button>
                        )}
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          );
        }
      }
      
      export default TourPage;
      

      【讨论】:

        猜你喜欢
        • 2016-06-13
        • 1970-01-01
        • 1970-01-01
        • 2021-09-21
        • 1970-01-01
        • 1970-01-01
        • 2017-04-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多