Редактирование текста при нажатии на кнопку

При нажатии на кнопку "Редактировать", которая появляется при наведении на три точки, появляющиеся при наведении на блок с задачей, текст "Задача 1" должен становиться редактируемым, а при повторном нажатии на кнопку ИЛИ при нажатии на ЛЮБОЕ место экрана кроме редактируемого текста, отредактированный пользователем текст сохраняется.

Как это сделать?

<div id="resch-tasks">
    <div class="daytasks-task">
            <form>
                <label>
                    <div class="label-text" id="label-text1">Задача 1</div>
                    <a>
                        <div class="task-dots" id="dots"></div>
                    </a>
                    <div class="dots" id="dotsmenu">
                        <button id="edit-task" type="button" class="dots-edit">Редактировать</button>
                    </div>
                </label>
            </form>
    </div>
</div>
body {
    background-color: #202020;
    overflow-y: hidden;
}

main {
    display: inline-block;
    position: absolute;
    padding: 70px 0 0 100px;
}

form {
    padding: 15px 15px 0 15px;
}

label {
    display: flex;
}

.daytasks-task {
    width: 250px;
    padding-bottom: 10px;
    font-family: Inter;
    font-size: 15px;
    font-weight: 500;
    color: rgb(179, 178, 178);
    border-radius: 14px;
    border: none;
    border: 1px solid #424242;
    margin-top: 10px;
    box-shadow: 0 0 10px 2px #1d1d1d;
}

.daytasks-task:hover {
    box-shadow: 0 0 1px;
}

.daytasks-task:hover .task-dots{
    opacity: 1;
    box-shadow: -10px 1px 9px 2px #202020;
}

.label-text {
    position: relative;
    display: inline-block;
    cursor: pointer;
    margin: 1% 0 0 1%;
}

.task-dots {
    background: #202020;
    background-image: url(imgs/3dots.png);
    background-size: cover;
    opacity: 0;
    width: 25px;
    height: 25px;
    display: inline-block;
    position: absolute;
    border: none;
    right: 3%;
    cursor: pointer;
    box-shadow: -5px 1px 9px 2px #202020;
    transition: all 0.2s;
}

.dots {
    width: 90%;
    height: auto;
    background-color: #1d1d1d;
    position: absolute;
    margin: 20px 0 0 85px;
    padding-bottom: 2px;
    z-index: 1;
    border-radius: 10px;
    box-shadow: 0 0 10px 5px #181818;
    display: none;
}

a:hover + .dots { 
    display: block;
}

.dots:hover { 
    display: block;
}

.dots-edit {
    width: 95.5%;
    height:35px;
    background-color: transparent;
    display: flex;
    align-items: center;
    margin: 5px;
    padding: 6px 6px 6px 10px;
    font-family: Inter;
    font-size: 13px;
    font-weight: 500;
    text-align: left;
    color: #c4c4c4;
    border: none;
    border-radius: 10px;
    cursor: pointer;
}

.dots-edit::before {
    content: "";
    background-image: url(/project/css/imgs/edit.png);
    background-size: cover;
    width: 20px;
    height: 20px;
    display: inline-block;
    vertical-align: sub;
    margin-right: 5px;
}

.dots-edit:hover {
    background-color: #2b2b2b;
}

Ответы (1 шт):

Автор решения: SwaD

Редактирование по кнопке можно сделать следующим образом:

Т.к. редактирование из браузера не возможно в теге div, то заменим его на input.

const inpEdit = document.getElementById('inpedit');

document.getElementById('btn').addEventListener('click', (event) => {
  if (inpEdit.readOnly) inpEdit.focus();
  inpEdit.readOnly = !inpEdit.readOnly;
  event.stopPropagation();
})

inpEdit.addEventListener('click', event => event.stopPropagation());

// Если сработает, значит клик не на кнопке и не на поле
document.addEventListener('click', () => inpEdit.readOnly = true);
.inputClass {
  border: none;
  width: 500px;
}

.inputClass:focus {
  border: 1px solid #333333;
  border-radius: 5px;
}

.inputClass:read-only {
  border: none;
  outline: none;
}
<input id="inpedit" type="text" class="inputClass" value="Какой то текст" readonly>
<br />
<button id="btn">edit</button>

Если жизненно необходимо, что бы был именно div, то надо будет все равно добавить input и по нажатию кнопки div скрывать, input отображать и вводимые данные дублировать в div. При потере фокуса обратно скрывать input и отображать div

Можно еще сделать фокусировку пользователя на поле ввода


Как мне справедливо напомнил @puffleeck в комментариях, что есть атрибут contentEditable, позволяющий редактировать содержимое элемента.

const div = document.getElementById('div');

document.getElementById('btn').addEventListener('click', (event) => {
  if (div.isContentEditable) {
    div.contentEditable = 'false';
  } else {
    div.contentEditable = 'true';
    div.focus();
  }
  event.stopPropagation();
});

div.addEventListener('click', event => event.stopPropagation());

document.addEventListener('click', () => div.contentEditable = 'false');
<div id="div" contenteditable='false'>Редактируемый текст</div>
<button id="btn">edit</button>

→ Ссылка