content logo

React Forms:

React Messaging Form with Animating Labels

In this post, as you can see, using React, we have a form that can be used to get information such as user feedback. This form has two text fields and a text area. Next to each of the fields in this form is a black icon. This border icon has a relatively thick black color.

#

React Dynamic Form Code

#

React Elements Animation

#

React Contact us Form

#

HTML Labels Effect

<!-- This script got from frontendfreecode.com -->
<div id="reactMount"></div><a style="font-size: 8pt; text-decoration: none" target="_blank" href="http://frontendfreecode.com">Free Frontend</a>
                                                                            
body {
  background: #e4e4e4;
}
.container {
  max-width: 100%;
}
form {
  width: 90%;
  max-width: 600px;
  padding: 50px;
  margin: 20px auto;
  background: white;
  box-shadow: 0 5px 15px -6px rgba(0, 0, 0, 0.25);
}
.form-group {
  position: relative;
}
.form-group.active label {
  font-size: 12px;
  line-height: 20px;
  color: #999;
}
.form-group i {
  display: block;
  position: absolute;
  top: 20px;
  left: 10px;
  line-height: 33px;
  z-index: 5;
  width: 35px;
  border: 3px solid #444;
  text-align: center;
  border-radius: 50%;
}
i{
  transition: all 0.4s ease-out;
}
input:not([type=submit]), textarea {
  position: relative;
  padding: 40px 30px 30px 60px !important;
  font-size: 24px;
  line-height: 64px;
  outline: none !important;
  background: none !important;
  border-radius: 0 !important;
  border: none;
  box-shadow: none !important;
  border-bottom: 1px solid #d9d9d9;
}
input:not([type=submit]).invalid + i, textarea.invalid + i {
  color: #9b59b6 !important;
  border-color: #9b59b6 !important;
  transform: rotateY(360deg);
}
input:not([type=submit]).invalid + i:after, textarea.invalid + i:after {
  display: block !important;
  position: absolute;
  width: 100%;
  content: "";
  height: 3px;
  background: #9b59b6;
  top: 50%;
  left: 0;
  transform: translateY(-50%) rotate(-45deg);
}
input:not([type=submit]).valid + i, textarea.valid + i {
  color: #2ecc71 !important;
  border-color: #2ecc71 !important;
  transform: rotateY(0deg);
}
input[type=submit] {
  display: block;
  border: none;
  padding: 20px 30px;
  margin: 0 auto;
  font-weight: bold;
  transition: all 0.3s ease-out;
  outline: none;
}
input[type=submit]:hover {
  background: #282828;
  color: white;
}
label {
  display: block;
  position: absolute;
  top: 5px;
  left: 60px;
  line-height: 70px;
  font-size: 20px;
  z-index: 5;
  transition: all 0.3s ease-out;
}
label .valid-message {
  display: none;
}
@keyframes fadeIn {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
const { Component, PropTypes } = React;
class Form extends Component {
  constructor(props) {
    super(props);
    this.fields = [
    { name: 'name', type: 'input', subtype: 'text', label: "First Name", icon: "user", validation: 'name', required: true, validMessage: "3 or more characters", valid: false },
    { name: 'email', type: 'input', subtype: 'email', icon: "envelope", validation: 'email', label: "Email", required: true, validMessage: "Valid email", valid: false },
    { name: 'message', type: 'textarea', icon: "comment", validation: 'message', label: "Your Message", required: false, validMessage: "3 or more characters", valid: false }];
    this.validation = {
      email: /[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-z0-9-]+(\.[a-z0-9-]+)*/,
      name: /[a-zA-Z0-9]{3,}/,
      message: /[a-zA-Z0-9]{3,}/ };
    this.state = {};
    this.fields.map(field => {
      this.state[field.name] = { content: false, valid: false };
    });
  }
  updateField(field, value, valid) {
    var obj = {};
    obj[field] = { content: value, valid: valid };
    this.setState(obj);
  }
  validate(e) {
    e.preventDefault();
    for (let i in this.state) {
      if (!this.state[i].valid) return false;
    }
    console.log('all clear');
  }
  renderFields() {
    return this.fields.map(field => {
      return /*#__PURE__*/React.createElement(Field, { type: field.type, subtype: field.subtype, name: field.name, label: field.label, required: field.required, key: field.name, updateFunc: this.updateField.bind(this), validation: this.validation[field.validation], validMessage: field.validMessage, icon: field.icon });
    });
  }
  render() {
    return /*#__PURE__*/(
      React.createElement("form", { className: "form", onSubmit: e => {this.validate(e);}, noValidate: true },
      this.renderFields(), /*#__PURE__*/
      React.createElement("div", { className: "container" }, /*#__PURE__*/
      React.createElement("input", { className: "", type: "submit", value: "Send" }))));
  }}
class Field extends Component {
  constructor(props) {
    super(props);
    this.hasFocus = false;
    this.state = { value: "", dirty: false, valid: false };
  }
  updateField(e) {
    var valid = this.validate(e.target.value);
    this.setState({ value: e.target.value, dirty: true, valid: valid });
    this.props.updateFunc(this.props.name, e.target.value, valid);
  }
  handleFocus() {
    this.setState({ hasFocus: true });
  }
  handleBlur() {
    this.setState({ hasFocus: false });
  }
  handleLabelClick(e) {
    e.preventDefault();
    if (this.state.hasFocus) return false;
    this.refs.input.focus();
    this.setState({ hasFocus: true });
  }
  validate(str) {
    return str.match(this.props.validation);
  }
  render() {
    const focusClass = this.state.value.length || this.state.hasFocus ? 'active' : "";
    const validClass = !this.state.dirty ? "" : this.state.valid ? "valid" : "invalid";
    const validMessage = this.props.validMessage ? /*#__PURE__*/React.createElement("span", { className: "valid-message" }, "(", this.props.validMessage, ")") : "";
    const label = this.props.label ? /*#__PURE__*/
    React.createElement("label", { htmlFor: this.props.name, onClick: e => {this.handleLabelClick(e);} }, this.props.label, " ", validMessage) : "";
    const icon = !this.props.icon ? "" : this.state.valid ? /*#__PURE__*/React.createElement("i", { className: `fa fa-thumbs-up` }) : /*#__PURE__*/React.createElement("i", { className: `fa fa-${this.props.icon}` });
    switch (this.props.type) {
      case 'input':
        return /*#__PURE__*/(
          React.createElement("div", { className: `form-group ${focusClass}` }, /*#__PURE__*/
          React.createElement("input", { ref: "input", className: `form-control  ${validClass}`, name: this.props.name, id: this.props.name, type: this.props.subtype, required: this.props.required, value: this.state.value, onChange: e => {this.updateField(e);}, onFocus: e => {this.handleFocus();}, onBlur: e => {this.handleBlur();} }),
          icon,
          label));
      case 'textarea':
        return /*#__PURE__*/(
          React.createElement("div", { className: `form-group ${focusClass}` }, /*#__PURE__*/
          React.createElement("textarea", { ref: "input", className: `form-control  ${validClass}`, name: this.props.name, id: this.props.name, required: this.props.required, onChange: e => {this.updateField(e);}, onFocus: e => {this.handleFocus();}, onBlur: e => {this.handleBlur();} }, this.state.value),
          icon,
          label));
      default:
        return /*#__PURE__*/React.createElement("div", null, "incomplete field");}
  }}
ReactDOM.render( /*#__PURE__*/React.createElement(Form, null), document.getElementById('reactMount'));
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css'>
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css'>
<script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.min.js'></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- This script got from frontendfreecode.com -->

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css'>
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css'>
<script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.min.js'></script>
<style>
body {
  background: #e4e4e4;
}
.container {
  max-width: 100%;
}
form {
  width: 90%;
  max-width: 600px;
  padding: 50px;
  margin: 20px auto;
  background: white;
  box-shadow: 0 5px 15px -6px rgba(0, 0, 0, 0.25);
}
.form-group {
  position: relative;
}
.form-group.active label {
  font-size: 12px;
  line-height: 20px;
  color: #999;
}
.form-group i {
  display: block;
  position: absolute;
  top: 20px;
  left: 10px;
  line-height: 33px;
  z-index: 5;
  width: 35px;
  border: 3px solid #444;
  text-align: center;
  border-radius: 50%;
}
i{
  transition: all 0.4s ease-out;
}
input:not([type=submit]), textarea {
  position: relative;
  padding: 40px 30px 30px 60px !important;
  font-size: 24px;
  line-height: 64px;
  outline: none !important;
  background: none !important;
  border-radius: 0 !important;
  border: none;
  box-shadow: none !important;
  border-bottom: 1px solid #d9d9d9;
}
input:not([type=submit]).invalid + i, textarea.invalid + i {
  color: #9b59b6 !important;
  border-color: #9b59b6 !important;
  transform: rotateY(360deg);
}
input:not([type=submit]).invalid + i:after, textarea.invalid + i:after {
  display: block !important;
  position: absolute;
  width: 100%;
  content: "";
  height: 3px;
  background: #9b59b6;
  top: 50%;
  left: 0;
  transform: translateY(-50%) rotate(-45deg);
}
input:not([type=submit]).valid + i, textarea.valid + i {
  color: #2ecc71 !important;
  border-color: #2ecc71 !important;
  transform: rotateY(0deg);
}
input[type=submit] {
  display: block;
  border: none;
  padding: 20px 30px;
  margin: 0 auto;
  font-weight: bold;
  transition: all 0.3s ease-out;
  outline: none;
}
input[type=submit]:hover {
  background: #282828;
  color: white;
}
label {
  display: block;
  position: absolute;
  top: 5px;
  left: 60px;
  line-height: 70px;
  font-size: 20px;
  z-index: 5;
  transition: all 0.3s ease-out;
}
label .valid-message {
  display: none;
}
@keyframes fadeIn {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
</style>

</head>
<body>
<div id="reactMount"></div><div id="bcl"><a style="font-size:8pt;text-decoration:none;" href="http://www.devanswer.com">Free Frontend</a></div>
<script>
const { Component, PropTypes } = React;
class Form extends Component {
  constructor(props) {
    super(props);
    this.fields = [
    { name: 'name', type: 'input', subtype: 'text', label: "First Name", icon: "user", validation: 'name', required: true, validMessage: "3 or more characters", valid: false },
    { name: 'email', type: 'input', subtype: 'email', icon: "envelope", validation: 'email', label: "Email", required: true, validMessage: "Valid email", valid: false },
    { name: 'message', type: 'textarea', icon: "comment", validation: 'message', label: "Your Message", required: false, validMessage: "3 or more characters", valid: false }];
    this.validation = {
      email: /[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-z0-9-]+(\.[a-z0-9-]+)*/,
      name: /[a-zA-Z0-9]{3,}/,
      message: /[a-zA-Z0-9]{3,}/ };
    this.state = {};
    this.fields.map(field => {
      this.state[field.name] = { content: false, valid: false };
    });
  }
  updateField(field, value, valid) {
    var obj = {};
    obj[field] = { content: value, valid: valid };
    this.setState(obj);
  }
  validate(e) {
    e.preventDefault();
    for (let i in this.state) {
      if (!this.state[i].valid) return false;
    }
    console.log('all clear');
  }
  renderFields() {
    return this.fields.map(field => {
      return /*#__PURE__*/React.createElement(Field, { type: field.type, subtype: field.subtype, name: field.name, label: field.label, required: field.required, key: field.name, updateFunc: this.updateField.bind(this), validation: this.validation[field.validation], validMessage: field.validMessage, icon: field.icon });
    });
  }
  render() {
    return /*#__PURE__*/(
      React.createElement("form", { className: "form", onSubmit: e => {this.validate(e);}, noValidate: true },
      this.renderFields(), /*#__PURE__*/
      React.createElement("div", { className: "container" }, /*#__PURE__*/
      React.createElement("input", { className: "", type: "submit", value: "Send" }))));
  }}
class Field extends Component {
  constructor(props) {
    super(props);
    this.hasFocus = false;
    this.state = { value: "", dirty: false, valid: false };
  }
  updateField(e) {
    var valid = this.validate(e.target.value);
    this.setState({ value: e.target.value, dirty: true, valid: valid });
    this.props.updateFunc(this.props.name, e.target.value, valid);
  }
  handleFocus() {
    this.setState({ hasFocus: true });
  }
  handleBlur() {
    this.setState({ hasFocus: false });
  }
  handleLabelClick(e) {
    e.preventDefault();
    if (this.state.hasFocus) return false;
    this.refs.input.focus();
    this.setState({ hasFocus: true });
  }
  validate(str) {
    return str.match(this.props.validation);
  }
  render() {
    const focusClass = this.state.value.length || this.state.hasFocus ? 'active' : "";
    const validClass = !this.state.dirty ? "" : this.state.valid ? "valid" : "invalid";
    const validMessage = this.props.validMessage ? /*#__PURE__*/React.createElement("span", { className: "valid-message" }, "(", this.props.validMessage, ")") : "";
    const label = this.props.label ? /*#__PURE__*/
    React.createElement("label", { htmlFor: this.props.name, onClick: e => {this.handleLabelClick(e);} }, this.props.label, " ", validMessage) : "";
    const icon = !this.props.icon ? "" : this.state.valid ? /*#__PURE__*/React.createElement("i", { className: `fa fa-thumbs-up` }) : /*#__PURE__*/React.createElement("i", { className: `fa fa-${this.props.icon}` });
    switch (this.props.type) {
      case 'input':
        return /*#__PURE__*/(
          React.createElement("div", { className: `form-group ${focusClass}` }, /*#__PURE__*/
          React.createElement("input", { ref: "input", className: `form-control  ${validClass}`, name: this.props.name, id: this.props.name, type: this.props.subtype, required: this.props.required, value: this.state.value, onChange: e => {this.updateField(e);}, onFocus: e => {this.handleFocus();}, onBlur: e => {this.handleBlur();} }),
          icon,
          label));
      case 'textarea':
        return /*#__PURE__*/(
          React.createElement("div", { className: `form-group ${focusClass}` }, /*#__PURE__*/
          React.createElement("textarea", { ref: "input", className: `form-control  ${validClass}`, name: this.props.name, id: this.props.name, required: this.props.required, onChange: e => {this.updateField(e);}, onFocus: e => {this.handleFocus();}, onBlur: e => {this.handleBlur();} }, this.state.value),
          icon,
          label));
      default:
        return /*#__PURE__*/React.createElement("div", null, "incomplete field");}
  }}
ReactDOM.render( /*#__PURE__*/React.createElement(Form, null), document.getElementById('reactMount'));
</script>

</body>
</html>
Preview