How to Add a Single Editable Button to Your Blog
This guide shows you how to add a single editable button with a fixed title and editable body. The input field auto-resizes as the user types.
Step 1: Add HTML
<div class="eb-widget" data-title="Reminder" data-body="Click to edit."></div>
Step 2: Add CSS
<style>
.eb-widget {
font-family: sans-serif;
display: inline-block;
margin: 1rem;
max-width: 100%;
vertical-align: top;
}
.eb-display {
display: inline-block;
padding: 0.4rem 0.6rem;
border: 1px solid #ccc;
border-radius: 0.5rem;
background: #f9f9f9;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
cursor: pointer;
white-space: pre-line;
width: fit-content;
max-width: 100%;
}
.eb-title {
font-weight: bold;
font-size: 1rem;
color: #222;
margin-bottom: 0.2rem;
}
.eb-body {
font-size: 0.95rem;
color: #333;
white-space: pre;
}
.eb-edit {
display: none;
padding: 0.4rem 0.6rem;
border: 1px solid #aaa;
border-radius: 0.5rem;
background: #fff;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
max-width: 100%;
position: relative;
}
.eb-edit .eb-title {
font-weight: bold;
margin-bottom: 0.3rem;
color: #222;
}
.eb-textarea {
font-size: 1rem;
font-family: inherit;
line-height: 1.4;
padding: 0.4rem;
border: 1px solid #aaa;
border-radius: 0.3rem;
resize: none;
width: auto;
min-width: 4ch;
box-sizing: content-box;
overflow: hidden;
display: block;
transition: width 0.1s ease;
}
.eb-mirror {
position: absolute;
visibility: hidden;
white-space: pre-wrap;
padding: 0.4rem;
font-size: 1rem;
font-family: inherit;
line-height: 1.4;
border: 1px solid transparent;
box-sizing: content-box;
max-width: 100%;
}
.eb-widget.editing .eb-display { display: none; }
.eb-widget.editing .eb-edit { display: block; }
</style>
Step 3: Add JavaScript
<script>
(function () {
function createEditableWidget(root, titleText, bodyText) {
root.innerHTML = `
<div class="eb-display" tabindex="0" role="button">
<div class="eb-title">${titleText}</div>
<div class="eb-body">${bodyText}</div>
</div>
<div class="eb-edit">
<div class="eb-title">${titleText}</div>
<textarea class="eb-textarea" rows="1" placeholder="Enter body text..."></textarea>
<div class="eb-mirror"></div>
</div>
`;
const display = root.querySelector('.eb-display');
const body = display.querySelector('.eb-body');
const textarea = root.querySelector('.eb-textarea');
const mirror = root.querySelector('.eb-mirror');
function resize() {
mirror.textContent = textarea.value || textarea.placeholder || '';
mirror.style.display = 'inline-block';
textarea.style.height = 'auto';
textarea.style.height = textarea.scrollHeight + 'px';
textarea.style.width = mirror.offsetWidth + 5 + 'px';
}
function enterEditMode() {
root.classList.add('editing');
textarea.value = body.textContent.trim();
resize();
setTimeout(() => {
textarea.focus();
textarea.select();
}, 0);
}
function commitEdit() {
const newText = textarea.value.trim();
if (newText) body.textContent = newText;
root.classList.remove('editing');
}
function cancelEdit() {
root.classList.remove('editing');
}
display.addEventListener('click', enterEditMode);
display.addEventListener('keydown', e => {
if (e.key === 'Enter') {
e.preventDefault();
enterEditMode();
}
});
textarea.addEventListener('input', resize);
textarea.addEventListener('keydown', e => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
commitEdit();
} else if (e.key === 'Escape') {
e.preventDefault();
cancelEdit();
} else {
requestAnimationFrame(resize);
}
});
textarea.addEventListener('blur', commitEdit);
}
document.querySelectorAll('.eb-widget').forEach(root => {
const title = root.dataset.title || 'Title';
const body = root.dataset.body || '';
createEditableWidget(root, title, body);
});
})();
</script>
Step 4: Copy Button Script
<script>
function copyCode(btn) {
const codeElement = btn.nextElementSibling;
if (!codeElement) return;
const text = codeElement.innerText;
navigator.clipboard.writeText(text).then(() => {
btn.classList.add('copied');
setTimeout(() => btn.classList.remove('copied'), 1000);
});
}
</script>
No comments:
Post a Comment