Как сделать плавающую метку, которая может перемещаться вверх, когда фокус или имеет контент в React? - PullRequest
0 голосов
/ 14 мая 2019

Я пытаюсь создать группу ввода, когда вход сфокусирован или имеет содержимое внутри, метка будет двигаться вверх так:

input {
  padding: 10px 0;
  box-sizing: border-box;
  box-shadow: none;
  outline: none;
  border: none;
  border-bottom: 2px solid #999;
  width: 100%;
}

.box {
  margin: 100px;
  position: relative;
}

label {
  position: absolute;
  top: 10px;
  left: 0;
  color: #999;
  transition: .5s;
  pointer-events: none;
}

input:focus~label,
input:valid~label {
  top: -12px;
  left: 0;
  color: crimson;
  font-weight: bold;
}
<div class="box">
  <input type="text" required='' id="name">
  <label for="name">Name</label>
</div>

<div class="box">
  <input type="text" required='' id="email">
  <label for="name">email</label>
</div>

Однако я не знаю, как это сделать в React, также я могу знать, как не использовать обязательный в html и input: valid метод в css, так как я управляю проверкой через форму Formik в js.Большое вам спасибо!

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div className="form-group">

  <Field type="text" name="name" placeholder="Name" onFocus={this.handleInputFocus} onBlur={this.handleInputBlur} className={formProps.errors.name && formProps.touched.name ? 'is-invalid form-control' : 'form-control'} />
  <label htmlFor="name">Name</label>

  <ErrorMessage name="email" component="div" className="invalid-feedback" />
</div>

<div className="form-group">

  <Field type="text" name="email" placeholder="Email" onFocus={this.handleInputFocus} onBlur={this.handleInputBlur} className={formProps.errors.email && formProps.touched.email ? 'is-invalid form-control' : 'form-control'} />
  <label htmlFor="email">Email</label>

  <ErrorMessage name="email" component="div" className="invalid-feedback" />
</div>

Ответы [ 2 ]

1 голос
/ 15 мая 2019

Мне нравится подход css, который вы использовали в первом примере.

вот несколько простых js, если это поможет.

  function updateinputfield() {
    var x = document.getElementById("apninput");
    if (x.value.length < 36) {
      x.style.width = ((x.value.length) * 0.63) + 'rem';
    }
  }

  function moveUpPlaceholder() {
    var y = document.getElementById("floatingLabel");
    y.classList.add("labelMoveUp");
    y.innerHTML = "Insert Your Code";
    y.style.color = "rgba(0, 0, 0, 0.85)";
  }

  function moveDownPlaceholder() {
    var x = document.getElementById("apninput");
    var y = document.getElementById("floatingLabel");
    if (x.value.length == 0) {
      y.classList.remove("labelMoveUp");
      y.innerHTML = "Ex. 953-123-444-323";
      y.style.color = "rgba(0, 0, 0, 0.35)";
    }
  }




  function getvalueofInput() {
    var x = document.getElementById("apninput").value;
    alert(x);
  }
.form {
  background: #e4f1fe;
  width: 140px;
  min-width: 140px;
  font-size: 1.2rem;
  padding: 8px;
  border: 2px solid #c5eff7;
  border-radius: 4px 0 0 4px;
  margin-right: 0;
  text-align: left;
  outline: none;
}

span {
  display: inline-block;
}

p {
  font-family: 'Arial', sans-serif;
}

.submitSpan {
  padding: 10px;
  font-size: 1.2rem;
  background: lightblue;
  border-radius: 0 4px 4px 0;
  cursor: pointer;
  transition: all 0.34s ease-in-out;
  margin-left: 0;
}

.floating-label {
  position: absolute;
  top: 13.33px;
  left: 12px;
  color: rgba(0, 0, 0, 0.35);
  pointer-events: none;
  transition: all 0.5s ease-in-out;
  font-size: 1rem;
}

.inputcontainer {
  position: relative;
  display: inline-flex;
}

.labelMoveUp {
  top: -20px;
  left: 2px;
  font-size: 0.8rem;
}

.submitSpan:hover {
  background: lightgreen;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
}
<br>
<span><p>Type a number inside this field </p></span>
<!-- dummy input text >  933-444-123-444-213-444-424-411-437 -->
<br>
<br>
<span class="inputcontainer">

<input type="text" value="" id="apninput" class="form" placeholder="" oninput="updateinputfield()" onchange="updateinputfield()" onfocus="moveUpPlaceholder()" onblur="moveDownPlaceholder()">
 
<span class="submitSpan" onclick="getvalueofInput()">Submit</span>

<span class="floating-label" id="floatingLabel">Ex. 953-123-444-323</span>


</span>
0 голосов
/ 15 мая 2019

Спасибо большое, ребята!Я просто найду способ сделать это: D!Однако я не уверен, что есть лучший способ сделать код чище для нескольких входов в Formik.

class App extends React.Component {
  constructor() {
    super();
    this.state = {
        name: '',
        email:'',
        nameActive: false,
        emailActive: false
    }
  }
  activateField=(e)=> { 
    console.log();
    this.setState({
     [`${e.target.name}Active`]: true
    })
   
  }
  
  disableField=(e)=> {
    this.setState({
      [`${e.target.name}Active`]: false
   })
 }

 disableFocus=(e)=> {
  if (e.target.value === "") {
        this.disableField(e);
   }
 }

 handleChange=(e)=> {
  this.setState({
   [e.target.name]: e.target.value,
  });
   if (e.target.value === "") {
      this.disableField(e);
   } else {
      this.activateField(e);
   }

  
 }
  
  
  render() {
    return (
      <div>
    <form>
     <div className="field-group">
     <label className={this.state.nameActive ? "active" : ""}>
       Name
     </label>
     <input
      className="normal"
      type="text"
      value={this.state.name}
      onFocus={this.activateField}
      onBlur={this.disableFocus}
      onChange={this.handleChange}
       name="name"
     />
     </div>
      
      
      
     <div className="field-group">
      <label className={this.state.emailActive ? "active" : ""}>
       Email
      </label>
      <input
      className="normal"
      type="text"
      value={this.state.email}
      onFocus={this.activateField}
      onBlur={this.disableFocus}
      onChange={this.handleChange}
      name="email"
      />
     </div>
      
      
    </form>
   </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("app"));
input {
  padding: 10px 0;
  box-sizing:border-box;
  box-shadow:none;
  outline:none;
  border:none;
  border-bottom: 2px solid #999;
  width:100%;
}

.field-group {
  margin:100px;
  position:relative;
}
label  {
  position:absolute;
  top:10px;
  left:0;  
  color: #999;
  transition:.5s;
  pointer-events:none;
  
}

label.active {
  transform: translateY(-25px);
  transition:.5s;
  color: crimson;
  font-weight:bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
...