I created a custom Gutenberg block which was working fine till wp 6.3.2 .
But after updating to 6.4.2 , it is not working.
when i am entering data it is showing the data and post is also updated. But on front end there is no data.
When I refresh the post edit page then also fields are empty.
Ref: I created the block to store and show products from different marketplace.
I set an attribute “products” for the row. and created a form to enter new product row.
here is my js code:
const { __ } = wp.i18n; // Import __() from wp.i18n
const { registerBlockType } = wp.blocks; // Import registerBlockType() from wp.blocks
const { InspectorControls, useBlockProps } = wp.blockEditor;
const { PanelBody } = wp.components;
const { Fragment } = wp.element;
const { TextControl } = wp.components;
/**
* Register: custom products Gutenberg Block.
*
*/
registerBlockType('wp-market/wp-market-products', {
apiVersion: 2,
title: __('Manual Products'),
icon: 'shield',
attributes: {
products: {
type: 'array',
default: []
}
},
/**
* The edit function describes the structure of your block in the context of the editor.
* This represents what the editor will render when the block is used.
*
*/
edit: function (props) {
const { products, newProduct } = props.attributes;
var blockProps = useBlockProps();
// to create edit element
function createEditEl() {
let data = [];
// Heading
data.push(React.createElement(
"h6",
null,
"Manual Products"
));
// entered product
data.push(React.createElement(
"div",
{ class: 'product-rows-gutenberg' },
createGutenbergManualProductRows()
));
// new product
data.push(React.createElement(
"div",
{ class: 'new-manual-product-gutenberg' },
createGutenbergManualProductNew()
));
return data;
}
// function for product rows
function createGutenbergManualProductRows() {
let data = [React.createElement("h6", { class: "sub-heading" }, ["Added products"])]
// rows
if (products && products.length > 0) {
products.map((product, index) => {
data.push(React.createElement(
"div",
{ className: 'manual-product-row-wrapper' },
formatProductRow(product, index)
));
});
} else {
data.push(React.createElement(
"div",
{ className: 'manual-product-row-wrapper no-product' },
"No product added"
));
}
return data;
}
// to create product row
function formatProductRow(product, index) {
let data = [];
data.push(
React.createElement(
'div',
{
className: 'column column-id'
},
[
product.id ? product.id : '',
// edit field
createEditField('id',blockProps.id, index, product.id)
]
)
);
data.push(
React.createElement(
'div',
{ className: 'column column-title' },
product.title ? product.title : '',
// edit field
createEditField('title',blockProps.id, index, product.title)
)
);
data.push(
React.createElement(
'div',
{ className: 'column column-price' },
product.price ? product.price : '',
// edit field
createEditField('price',blockProps.id, index, product.price)
)
);
data.push(
React.createElement(
'div',
{ className: 'column column-link' },
product.link ? product.link : '',
// edit field
createEditField('link',blockProps.id, index, product.link)
)
);
if (product.image) {
data.push(
React.createElement(
'div',
{ className: 'column column-image' },
[
React.createElement(
'img',
{
src: product.image
}
),
// edit field
createImageEdit(blockProps.id, index)
]
)
);
} else {
data.push(
React.createElement(
'div',
{ className: 'column column-image no-img' },
// edit field
createImageEdit(blockProps.id, index)
)
);
}
data.push(
React.createElement(
'div',
{ className: 'column column-store' },
product.store ? product.store : '',
// edit field
createEditField('store',blockProps.id, index, product.store, true)
)
);
//button to delete the row
data.push(
React.createElement(
'button',
{ className: '', onClick: function () { products.splice(index, 1); props.setAttributes({ products: products.slice() }); } },
'-'
)
);
return data;
}
// refresh the image preview
function refreshGutenbergManualUploadImage(src) {
let imgEl = document.querySelector('#' + blockProps.id + 'new-image-preview');
let textEl = document.querySelector('#' + blockProps.id + 'new-image-text');
if (src.length) {
imgEl.src = src;
textEl.classList.add('hidden');
imgEl.classList.remove('hidden');
}
else {
imgEl.src = '';
textEl.classList.remove('hidden');
imgEl.classList.add('hidden');
}
}
// create store options
function createStoreOptions(value = '') {
let data = [];
if (wp_market_block_stores) {
wp_market_block_stores.map(store => {
data.push(
React.createElement(
'option',
{
value: store.slug
},
store.name
)
);
})
}
return data;
}
// editing image
function createImageEdit(blockId, index){
return React.createElement(
'span',
{
className: 'column-edit-button dashicons dashicons-edit',
onClick: function (e) {
e.preventDefault();
var image_frame;
if (image_frame) {
image_frame.open();
}
// Define image_frame as wp.media object
image_frame = wp.media({
title: 'Select Media',
multiple: false,
library: {
type: 'image',
}
});
image_frame.on('close', function () {
// On close, get selections and save to the hidden input
// plus other AJAX stuff to refresh the image preview
var selection = image_frame.state().get('selection');
var gallery_srcs = new Array();
var gallery_ids = new Array();
var my_index = 0;
selection.each(function (attachment) {
gallery_srcs[my_index] = attachment['attributes']['url'];
gallery_ids[my_index] = attachment['id'];
my_index++;
});
var srcs = gallery_srcs.join(",");
var ids = gallery_ids.join(",");
if(srcs){
products[index]['image'] = srcs;
props.setAttributes({ products: products.slice() });
}
});
image_frame.open();
}
}
);
}
// create edit field
function createEditField(name, block_id, index, value, isStore = false) {
return [
React.createElement(
'span',
{
className: 'column-edit-button dashicons dashicons-edit',
onClick: () => showEditColumn(name, block_id, index, value)
}
),
React.createElement(
'div',
{
className:'column-edit-field hidden',
id: 'edit-column-' + name + '_block-id_' + block_id + '_index_' + index
},
[
isStore ?
React.createElement(
'select',
{
className: 'edit-column-value'
},
createStoreOptions()
)
:
React.createElement(
'input',
{
className: 'edit-column-value'
}
),
React.createElement(
'button',
{
className: 'edit-column-save'
},
React.createElement(
'span',
{
className: 'dashicons dashicons-yes-alt',
onClick: () => saveEditColumn(name, block_id, index)
}
)
),
React.createElement(
'button',
{
className: 'edit-column-cancel'
},
React.createElement(
'span',
{
className: 'dashicons dashicons-dismiss',
onClick: () => cancelEditColumn(name, block_id, index)
}
)
)
]
)
]
}
// to show the edit field for a column
function showEditColumn(name, blockId, index, value = '') {
let field = document.querySelector('#edit-column-' + name + '_block-id_' + blockId + '_index_' + index);
if(field && field.classList.contains('hidden')) {
field.classList.remove('hidden');
field.querySelector('.edit-column-value').value = value;
}
}
// to save the changes in edit field
function saveEditColumn(name, blockId, index){
let field = document.querySelector('#edit-column-' + name + '_block-id_' + blockId + '_index_' + index);
if(field) {
let newValue = field.querySelector('.edit-column-value').value;
products[index][name] = newValue;
field.classList.add('hidden');
field.querySelector('.edit-column-value').value = '';
}
props.setAttributes({ products: products.slice() });
}
// to cancel the editing
function cancelEditColumn(name, blockId, index){
let field = document.querySelector('#edit-column-' + name + '_block-id_' + blockId + '_index_' + index);
if(field) {
field.classList.add('hidden');
field.querySelector('.edit-column-value').value = '';
}
}
// create new row
function createGutenbergManualProductNew() {
let data = [React.createElement("h6", { class: "sub-heading" }, ["Add new product"])]
// id
data.push(
React.createElement(
"label",
{ for: blockProps.id + 'new-id', class: 'manual-product-label' },
[
React.createElement("span", null, "Product ID"),
React.createElement(
"input",
{ type: "text", name: 'manual-product-id', id: blockProps.id + 'new-id' },
)
]
)
);
// title
data.push(
React.createElement(
"label",
{ for: blockProps.id + 'new-title', class: 'manual-product-label' },
[
React.createElement("span", null, "Title"),
React.createElement(
"input",
{ type: "text", name: 'manual-product-title', id: blockProps.id + 'new-title' },
)
]
)
);
// price
data.push(
React.createElement(
"label",
{ for: blockProps.id + 'new-price', class: 'manual-product-label' },
[
React.createElement("span", null, "Price"),
React.createElement(
"input",
{ type: "text", name: 'manual-product-price', id: blockProps.id + 'new-price' },
)
]
)
);
// link
data.push(
React.createElement(
"label",
{ for: blockProps.id + 'new-link', class: 'manual-product-label' },
[
React.createElement("span", null, "Link"),
React.createElement(
"input",
{ type: "url", name: 'manual-product-link', id: blockProps.id + 'new-link' },
)
]
)
);
// image
data.push(
React.createElement(
"label",
{ for: blockProps.id + 'new-image', class: 'manual-product-label image-upload' },
[
React.createElement("span", null, "Image"),
React.createElement(
"div",
{
id: blockProps.id + 'new-image-text',
className: 'new-image-text'
},
'No Image'
),
React.createElement(
"img",
{
id: blockProps.id + 'new-image-preview',
className: 'hidden preview'
}
),
React.createElement(
"input",
{
type: "button",
name: 'manual-product-image-upload',
id: blockProps.id + 'new-image-upload',
value: 'Select image',
onClick: function (e) {
e.preventDefault();
var image_frame;
if (image_frame) {
image_frame.open();
}
// Define image_frame as wp.media object
image_frame = wp.media({
title: 'Select Media',
multiple: false,
library: {
type: 'image',
}
});
image_frame.on('close', function () {
// On close, get selections and save to the hidden input
// plus other AJAX stuff to refresh the image preview
var selection = image_frame.state().get('selection');
var gallery_srcs = new Array();
var gallery_ids = new Array();
var my_index = 0;
selection.each(function (attachment) {
gallery_srcs[my_index] = attachment['attributes']['url'];
gallery_ids[my_index] = attachment['id'];
my_index++;
});
var srcs = gallery_srcs.join(",");
var ids = gallery_ids.join(",");
document.querySelector('#' + blockProps.id + 'new-image').value = srcs;
refreshGutenbergManualUploadImage(srcs);
});
image_frame.open();
}
},
),
React.createElement(
"input",
{
type: "hidden",
name: 'manual-product-image',
id: blockProps.id + 'new-image'
},
)
]
)
);
// store
data.push(
React.createElement(
"label",
{ for: blockProps.id + 'new-store', class: 'manual-product-label' },
[
React.createElement("span", null, "Store"),
React.createElement(
"select",
{
name: 'manual-product-store',
id: blockProps.id + 'new-store'
},
createStoreOptions()
)
]
)
);
// add button
data.push(
React.createElement(
'button',
{
className: 'add-manual-product', onClick: function () {
products.push(
{
id: document.querySelector('#' + blockProps.id + 'new-id').value,
title: document.querySelector('#' + blockProps.id + 'new-title').value,
price: document.querySelector('#' + blockProps.id + 'new-price').value,
link: document.querySelector('#' + blockProps.id + 'new-link').value,
image: document.querySelector('#' + blockProps.id + 'new-image').value,
store: document.querySelector('#' + blockProps.id + 'new-store').value,
}
);
props.setAttributes({ products: products.slice() });
}
},
'+'
)
);
return data;
}
let returnEL = createEditEl();
return React.createElement('div', blockProps, returnEL);
},
});
I entered the product details and added to the row and it was showing in the row. I click on update post, products were still showed in the row.
But when I am refreshing the post edit page the products is empty.
It should show the products which I have added.