Table of Contents

  1. Objective
  2. Structure
  3. Styles
  4. Code

Objective

Make an editable label. When the label is clicked, a textbox shows up allowing the user to edit the label. To edit, the user has to press the ENTER key, otherwise the changes are ignored.

Requires using event handlers in Javascript and setting element class names dynamically.

Structure

In this tutorial we will use a single <div> to represent our edit-in-place element (with class "editable-in-place":

  <div class="editable-in-place" >
  <div class="inside ">click to edit me</div>
    <input class="inside hide" value="click to edit me" size="15" max="20">
</div>

The outer <div> two other elements: another <div> to hold the "label", and an <input> to allow editing. Notice that the <input> is initially hidden with the css class "hide".

Styles

In order to make it easier to position the “label” and “editor”, we set the position of the root element to relative:

  .editable-in-place {
    margin:auto;
    position:relative;
    width: 400px;
    height: 200px;
    font-size:36px;
    font-family:"Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", "DejaVu Sans", Verdana, sans-serif;
    background-color:#048ED2;
}

.editable-in-place input {
    box-sizing: border-box;
    font-size: inherit;
    font-family: inherit;
    background-color: #2A9AD2;
    border:none;
    padding:0;
    margin:0;
}

.editable-in-place .inside{
    position:absolute;
    margin: 0;
    padding: 0;
    text-align:center;
    width:400px;
    left:0px;
    top: 50%;
    transform: translateY(-50%);
}

.hide {
    visibility:hidden;
}

The “hide” class is the most important class in this demo: it allows us to easily show and hide the editor and label. (This could have been accomplished by setting the style properties in Javascript, but using a CSS class is more flexible in other more complex situations).

Code

For edit-in-place to work, we need to attach a click listener to our outer element: the clicked function in our code. (In this demo, we are using just one editable-in-place element. But the same function could be attached to additional elements.)

When a click occurs, we need to make a number of checks: * if the user clicked on the input element, than we do nothing because he must be editing it. * if the user clicked on the label element, than we want to switch to editing. We need show the <input> and hide the label element. Additionaly, we need to add a keydown listener to the <input> to detect the ENTER key and turn off the editing. * if the user clicks outside the label but inside the outer <div>, than we cancel the editing.

  window.addEventListener('DOMContentLoaded', documentLoaded);

function documentLoaded() {
    document.getElementsByClassName("editable-in-place")[0].addEventListener("click", clicked);;
}

function clicked(evt) {
    // get the <input> and check if it is hidden
    var input = this.querySelector("input");
    var label = this.querySelector("div");

    if (evt.target === input) {
        // if user clicked on <input> do nothing, he is editing

    } else if (evt.target === label) {
        // <input> was hidden, make it visible
        input.classList.remove("hide");

        // and hide the label
        label.classList.add("hide");

        // fill the <input> with the text from the label
        input.value = label.innerHTML;

        // adicionar o listener para detectar o fim da edicao com "ENTER"
        input.addEventListener("keydown", function keydown(evt) {

            // 13 is the code for ENTER
            if (evt.keyCode === 13) {
                label.innerHTML = input.value;
                label.classList.remove("hide");
                input.classList.add("hide");

                // its important to remove the keydown listener, otherwise in a subsequent edit
                // we will end up with several keydown listeners running
                input.removeEventListener("keydown", keydown);
            }

        });
        input.focus();
    } else {
        // <input> was visible, hide it without modifying the value
        input.classList.add("hide");

        // show the label
        label.classList.remove("hide");
    }

}


509 0 2