Skip to content

Instantly share code, notes, and snippets.

@razaanstha
Created December 6, 2023 16:55
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save razaanstha/ec3710e1136d060678df782d3e33c3b7 to your computer and use it in GitHub Desktop.
Save razaanstha/ec3710e1136d060678df782d3e33c3b7 to your computer and use it in GitHub Desktop.
ContentEditable - ACF Block
<?php
/**
* Block: Hero
* --------------------------------
* The hero block for all pages.
*/
$block_data = get_fields();
?>
<div>
<?php if (!empty($block_data['hero_label'])) : ?>
<div>
<strong data-acf-field="hero_label"><?php echo $block_data['hero_label']; ?></strong>
</div>
<?php endif; ?>
<div>
<h1 data-acf-field="hero_title"><?php echo $block_data['hero_title']; ?></h1>
<?php if (!empty($block_data['hero_description'])) : ?>
<p data-acf-field="hero_description"><?php echo $block_data['hero_description']; ?></p>
<?php endif; ?>
</div>
</div>
window.addEventListener('DOMContentLoaded', () => {
if (window.acf) {
window.acf.addAction('render_block_preview', (event) => {
// Find all the data-acf-field elements in the block preview and add contenteditable=true to them when clicked maybe requires double clicking
const editableElements = event?.[0].querySelectorAll('[data-acf-field]');
if (editableElements) {
editableElements.forEach((element) => {
element.addEventListener('click', () => {
element.setAttribute('contenteditable', true);
// Get the current selected block
const selectedBlock = window.wp.data.select('core/block-editor').getSelectedBlock();
// Find the acf field with the data attribute value and update the value in the input field only if the input field is type
const inputField = document.querySelector(
`div[data-type="text"][data-name="${element.dataset.acfField}"] input,
div[data-type="textarea"][data-name="${element.dataset.acfField}"] textarea`
);
// When the input contenteditbale is true and update the input field value for preview
if (inputField) {
element.addEventListener('input', () => {
inputField.value = element.innerHTML;
});
}
// When the element is blurred remove the contenteditable attribute and update the block data
element.addEventListener('blur', () => {
element.removeAttribute('contenteditable');
// Update the block's ACF data
window.wp.data
.dispatch('core/block-editor')
.updateBlockAttributes(selectedBlock.clientId, {
data: {
...selectedBlock.attributes.data,
[element.dataset.acfField]: element.innerHTML,
},
});
});
});
});
}
});
}
});

okay

So, I was exploring the Gutenberg Block Editor, and as a developer, I found many aspects of the block editor to be lacking. As someone who has always created sites using ACF, the new Gutenberg editor doesn't seem like a viable option for developers and simply irritating as its not maintainbale (Patterns and custom blocks are headache). Most clients prefer not to deal with technical complexities and don't need all those controls. This led me to explore ACF Blocks. I was searching for a straightforward solution that clients could use to simply bold, italicize, and edit text freely, and this is the solution I ended up with.


Usage: To edit text, simply add the data-acf-field attribute to the element, along with its field name. This process is illustrated below in the acf-block.php file. For instance, to edit the Hero Label field, add the attribute data-acf-field="hero_label.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment