Took me a while to figure this out, but I have a method that works:
- You need to pass through the current post ID and the widget's ID to your AJAX method:
Widget's ID: Can be found on the wrapper div of your widget in the data-id
attribute.
Post ID: Elementor actually already stores this in a javascript global: window.elementorFrontendConfig.post.id
- Inside your AJAX action, use the following function to render a widget from the specified Post ID and Widget ID:
function render_element($postid, $elementid)
{
$document = \Elementor\Plugin::$instance->documents->get( $postid );
if ( ! $document ) {
return new \WP_Error(
'document_not_exist',
__( 'Document doesn\'t exist', 'elementor-pro' ),
[ 'status' => 404 ]
);
}
$element_data = $document->get_elements_data();
$widget = \Elementor\Utils::find_element_recursive( $element_data, $elementid );
if ( empty( $widget ) ) {
return new \WP_Error(
'Element_not_exist',
__( 'Posts widget doesn\'t exist', 'elementor-pro' ),
[ 'status' => 404 ]
);
}
// Override the global $post for the render.
query_posts(
[
'p' => $postid,
'post_type' => 'any',
]
);
\Elementor\Plugin::$instance->documents->switch_to_document( $document );
$html = $document->render_element($widget);
//Not sure if this is needed in AJAX context:
// \Elementor\Plugin::$instance->documents->restore_document();
// \wp_reset_query();
return [
'content' => $html,
];
}