Editing Text On Double Click In React

January 23, 2021
by Moiz Shaikh
  • Featured image

You might have often come across websites and forms in specific where you can edit text simply by double clicking on it. What makes it so intriguing, is its seamless transition from being a static text to an editable field. In this article we will see just that. We will be creating one such react component from scratch which allows user to edit the text simply by double clicking on it. The basic idea is to toggle between and input element and a div when the user double clicks on it. So to begin, I’ve created an empty project using create-react-app, which i’ll be working in.

Double click edit in React

Editing text on double click in react

Setting up parent component.

In the parent component, we’ll need to store two piece of information. The input value, and a boolean to toggle between the input element and the div. In our case, we will have two separate sentences where user can change their name and website respectively.

App.js
import React, { useState } from 'react';
import Title from './Components/Title/title';
import './App.css';

const App = () => {
  const [firstName, setFirstName] = useState("Moiz");
  const [websiteName, setWebsiteName] = useState("Ciphertrick");
  const [firstNameInput, setFirstNameInput] = useState(false);
  const [websiteNameInput, setWebsiteNameInput] = useState(false);

  return (
    <div className = "Container">
      <div className = "Content">
        <Title>Double Click on the Name or Website to edit</Title>
      </div>
    </div>
  );
}
export default App;
title.js
import React from 'react';
import classes from './title.module.css';

const Title = (props) => {
    return (
      <div className = {classes.Heading}>{props.children}</div>
    )
}

export default Title;
In the app component the name and the website are initialized with Moiz and Ciphertrick as the default values. The firstNameInput and websiteNameInput are boolean states. These states will decide whether we render an input or a div element. The title component takes some text as children and simply displays the Title.

Setting the Editable component.

This is the component which does the magic. We will be attaching couple of Events inside this component and will pass certain props to render content.

Field.js
import React from 'react';
import classes from './field.module.css';

const Field = (props) => {
    return (
      <div className = {classes.TextField}>
        <div>{props.children}</div>
        {
        props.active ?
          <input value = {props.value} onChange = {props.inputChange} onBlur = {props.blur} autoFocus/>
            :
          <div onDoubleClick = {props.doubleClick} className = {classes.Change}>
            {props.value}
          </div>
        }
      </div>
    )
  }


export default Field;

The above code snippet represents the Field Component. It takes the active props which is essentially the value of either, firstNameInput or websiteNameInput state. The input element takes the value props and the onChange handler for a two way binding. The onChange handler is triggered every time the user types in something, and the value is passed down as value prop. The input element also uses an OnBlur event which gets triggered if the input element loses focus. In other words, clicking anywhere outside the input element will trigger the onBlur event. The event handler would then set the boolean states to false, thus rendering a div in the Field component. The autoFocus attribute automatically gets the focus when the input element is rendered

The div in the else condition uses the onDoubleClick handler which is kind of self explanatory. On a double click over the div, the boolean states in the App component are set to true and passed down to field component as active prop. Thus rendering the Input element. The Field component also take props.children to render a static text before the editable content.

Calling the Editable Component in App Component

App.js
import React, { useState } from 'react';
import Field from './Components/Field/field';
import Title from './Components/Title/title';
import './App.css';

const App = () => {

  const [firstName, setFirstName] = useState("Moiz");
  const [websiteName, setWebsiteName] = useState("Ciphertrick");
  const [firstNameInput, setFirstNameInput] = useState(false);
  const [websiteNameInput, setWebsiteNameInput] = useState(false);

  return (
    <div className = "Container">
      <div className = "Content">
        <Title>Double Click on the Name or Website to edit</Title>
       
        <Field value = {firstName}
               inputChange = {(e) => setFirstName(e.target.value)}
               doubleClick = {() => setFirstNameInput(true)}
               blur = {() => setFirstNameInput(false)}
               active = {firstNameInput}>Enter your first name</Field>

        <Field value = {websiteName}
               inputChange = {(e) => setWebsiteName(e.target.value)}
               doubleClick = {() => setWebsiteNameInput(true)}
               blur = {() => setWebsiteNameInput(false)}
               active = {websiteNameInput}>Enter your website</Field>
      </div>
    </div>
  );
}

export default App;

This is how the final App component looks. It now calls the Field Component and passes all the props down the chain. The doubleClick and blur event handlers set and unset the boolean states, whose value is passed down as active props and which in turn renders the input element or the div conditionally. The value and the inputChange props bind the input element. Finally the static text is passed between the Field tags as children.

This is how the final UI looks like.

Double click edit in React

Editing text on double click in react

Obviously there’s plenty of room to add other things like validation and stuff. You can also have a separate button to edit and submit instead of the onBlur event, but the onBlur just makes it look better.
You can find the full code repo along with the styling here! Github Repository

About

Full stack developer. Skilled in frontend technologies like React and Angular | Backend technologies like node and Express | SQL and NoSql Database. IoT hobbyist.

Get notified on our new articles

Subscribe to get the latest on Node.js, Angular, Blockchain and more. We never spam!
First Name:
Email:

Leave a Comment