How WordPress handles ajax for quick edit
Triggering the event
The inlineEditPost object is registered as global. It contains an init()
method, which is called when the document is loaded. This method attach a 'click'
event listener to elements with the .editinline
CSS class, it also attach a 'click'
event listener and a 'keydown'
event listener to the inline edit form.
The first event will open this inline edit form, while the two others will call the inlineEditPost.save(id)
. This method calls jQuery’s $.post()
method, with the following arguments :
params = {
action: 'inline-save',
post_type: typenow,
post_ID: id,
edit_date: 'true',
post_status: page
};
fields = $('#edit-'+id).find(':input').serialize();
params = fields + '&' + $.param(params);
// Make ajax request.
$.post( ajaxurl, params,
function(r) {
// ... code executed upon AJAX response
},
'html');
Where id
is passed has parameter to the f inlineEditPost.save()
method, and page
is retrieved in the form.
Then an AJAX request is sent to the server, to the /wp-admin/admin-ajax.php URL, which is registered in the ajaxurl
global variable.
Handling the request
This script triggers the wp_ajax_{$action} dynamic hook, where {$action}
is replaced by the value used in the action
parameter of the AJAX request (in this case, 'inline-save'
).
The AJAX action of the WordPress Core are registered in the file /wp-admin/includes/ajax-actions.php, their names corresponding to the syntax : wp_ajax_{$action_name}
. Because this structure matches the hook name (with only the -
replaced by _
), the function wp_ajax_inline_save()
will be called here.
This function, as well as every WordPress AJAX functions, starts by calling an ajax_check_referer()
in order to verify both the WordPress nonce1 and the HTTP REFERER2. It then uses the parameters of the request from PHP’s $_POST
superglobal. If these parameters are validated, it then executes the business logic, which is updating the post matching the given post_ID
parameter.
When this is done, the function processes the new HTML to be rendered. It does so by instantiating a WP_Posts_List_Table, which takes a WP_Screen as parameter. This WP_Screen
corresponds to the user’s admin panel before triggering the request, and it’s identifier is passed in the $_POST['screen']
parameter. It allows WP_Posts_List_Table
to access WP_Screen::$post_type
property, containing the name of the Post Type3 being edited. The wp_ajax_inline_save()
function can then call the WP_List_Table::display_rows()
method that will directly outputs HTML.
Processing the response
The previous $.post()
method passed an anonymous function as third argument, this is the code that will be executed asynchronously4, when the server will respond to the AJAX request. This is what it looks like:
function(r) {
var $errorNotice = $( '#edit-' + id + ' .inline-edit-save .notice-error' ),
$error = $errorNotice.find( '.error' );
$( 'table.widefat .spinner' ).removeClass( 'is-active' );
$( '.ac_results' ).hide();
if (r) {
if ( -1 !== r.indexOf( '<tr' ) ) {
$(inlineEditPost.what+id).siblings('tr.hidden').addBack().remove();
$('#edit-'+id).before(r).remove();
$( inlineEditPost.what + id ).hide().fadeIn( 400, function() {
// Move focus back to the Quick Edit button. $( this ) is the row being animated.
$( this ).find( '.editinline' )
.attr( 'aria-expanded', 'false' )
.focus();
wp.a11y.speak( inlineEditL10n.saved );
});
} else {
r = r.replace( /<.[^<>]*?>/g, '' );
$errorNotice.removeClass( 'hidden' );
$error.html( r );
wp.a11y.speak( $error.text() );
}
} else {
$errorNotice.removeClass( 'hidden' );
$error.html( inlineEditL10n.error );
wp.a11y.speak( inlineEditL10n.error );
}
}
The r
argument is the response from WordPress admin-ajax.php
script, that has executed the wp_ajax_inline_save()
function. As we’ve seen, this function has outputted HTML, so the fourth argument passed to the inlindeEditPost.save()
method is the string 'html'
, which indicates to jQuery the expected datatype for this response.
There is three possibilities here:
- the PHP script succeeded, and the response will effectively be a valid HTML formatted string
- the PHP script failed, and the response is empty (?).
- the PHP script respond with an HTML formatted error report.
In this last case, this error report will be inserted into the HTML element dedicated to notifying AJAX errors.
In the second case, the script will get the error message stored in the inlineEditL10n
javascript object instead. This error string is registered on the server side by the WP_Scripts::localize() method in /wp-includes/script-loader.php, this allows it to be translated with the other WordPress strings.
In the first case, it will find the HTML element corresponding to the item that has been edited, and replace it with the HTML contained in the AJAX response. Then it closes the “quick edit” menu.
In both cases, the script will also outputs the error or success message in a special section of the HTML dedicated to screen readers. This happens through WordPress wp.a11y component’s speak() method.