JSFiddle - React, Tailwind, and code Playground

by Alexey Mishin

HTML

<ul class="joke-list">
  <li class="joke">
    <p id="13" class="editable">
      The state of development in 2017: “Please don’t apply if you don’t have the core concepts of programming, and you depend upon copying and pasting the code from StackOverflow/saved file.”
    </p>
    <button class="editBtn">Edit</button>
  </li>
  <li class="joke">
    <p id="13" class="editable">
      The state of development in 2017: “Please don’t apply if you don’t have the core concepts of programming, and you depend upon copying and pasting the code from StackOverflow/saved file.”
    </p>
    <button class="editBtn">Edit</button>
  </li>
  <li class="joke">
    <p id="13" class="editable">
      The state of development in 2017: “Please don’t apply if you don’t have the core concepts of programming, and you depend upon copying and pasting the code from StackOverflow/saved file.”
    </p>
    <button class="editBtn">Edit</button>
  </li>
</ul>

CSS

ul {
  margin: 0;
  margin-left: 20px;
  padding: 0;
}

li {
  list-style: none;
}

JavaScript

const jokeList = document.querySelector(`.joke-list`);

class Joke {
	constructor(container) {
  	this.container = container;
  	this.jokeTextElement = this.container.querySelector(`.editable`);
    this.editBtn = this.container.querySelector(`button`);
  }
  
  init() {
  	this.editingArea = document.createElement(`textarea`);
    this.copyProperties(this.jokeTextElement, this.editingArea);
    
    this.btnsContainer = document.createElement(`div`);
    const saveBtn = document.createElement(`button`);
    const cancelBtn = document.createElement(`button`);
    
    saveBtn.textContent = `Save`;
    cancelBtn.textContent = `Cancel`;
    
    saveBtn.addEventListener(`click`, () => {
    	this.save();
    });
    cancelBtn.addEventListener(`click`, () => {
    	this.cancel();
    });
    
   	this.btnsContainer.appendChild(saveBtn);
    this.btnsContainer.appendChild(cancelBtn);
    
    this.edit();
  }
  
  copyProperties(original, copy) {
  	const textContentStyle = getComputedStyle(original);
    copy.textContent = original.textContent.trim();
    copy.style.font = textContentStyle.font;
    copy.style.margin = `${textContentStyle.margin}`;
    copy.style.padding = `${textContentStyle.padding}`;
    copy.style.width = `${original.offsetWidth}px`;
    copy.style.height = `${original.offsetHeight}px`;
  }
  
  replace(currentElement, futureElement) {
  	const elementContainer = currentElement.parentNode;
    
  	elementContainer.insertBefore(futureElement, currentElement);
   	elementContainer.removeChild(currentElement);
  }
  
  edit() {
  	this.replace(this.jokeTextElement, this.editingArea);
    this.replace(this.editBtn, this.btnsContainer);
  }
  
  read() {
  	this.replace(this.editingArea, this.jokeTextElement);
    this.replace(this.btnsContainer, this.editBtn);
  }
  
  save() {
  	this.jokeTextElement.textContent = this.editingArea.value;
    this.read();
  }
  
  cancel() {
  	this.read();
  }
}

const JokeListOnClickHandler = function(e) {
	if...