Step-by-Step Guide to Implement Inline Editing in WordPress

1. Enqueue JavaScript and Localize Script

In your plugin’s admin script enqueue function, add:

php

function enqueue_inline_editing_scripts() {
// Enqueue jQuery if not already included
wp_enqueue_script('jquery');

// Enqueue your custom inline editing script
wp_enqueue_script('inline-editing-script', PLUGIN_URL . 'admin/js/inline-editing.js', array('jquery'), '1.0.0', true);

// Localize script to pass AJAX URL and nonce
wp_localize_script('inline-editing-script', 'inlineEditAjax', array(
'ajaxurl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('inline-edit-nonce') // Create a nonce for security
));
}

add_action('admin_enqueue_scripts', 'enqueue_inline_editing_scripts');

2. Create JavaScript for Inline Editing

Create a JavaScript file named inline-editing.js in admin/js/:

javascript

jQuery(document).ready(function($) {
// Handle input blur event for saving changes
$('.editable-score-input').on('blur', function() {
var $input = $(this);
var newValue = $input.val().trim();
var fieldId = $input.data('field');

console.log('Field ID:', fieldId);
console.log('New Value:', newValue);

updateScore(fieldId, newValue);
});

// Function to send AJAX request to update the score
function updateScore(fieldId, newValue) {
var gameId = fieldId.split('_').pop(); // Extract game ID from field ID
var scoreType = fieldId.includes('road') ? 'road_team_score' : 'home_team_score';

console.log('Game ID:', gameId);
console.log('Score Type:', scoreType);

$.ajax({
url: inlineEditAjax.ajaxurl, // Use localized AJAX URL
type: 'POST',
data: {
action: 'update_game_score', // Action for AJAX handler
game_id: gameId,
score_type: scoreType,
new_value: newValue,
nonce: inlineEditAjax.nonce // Pass the nonce for security
},
success: function(response) {
console.log('AJAX Response:', response);

if (response.success) {
var $input = $('[data-field="' + fieldId + '"]');
$input.addClass('success-border');

// Remove success border after a delay
setTimeout(function() {
$input.removeClass('success-border');
}, 3000);
} else {
console.error('Error:', response.data.message);
}
},
error: function(xhr, status, error) {
console.error('AJAX Error:', status, error);
}
});
}
});

3. PHP AJAX Handler

Add the AJAX handler function in your plugin’s main PHP file:

php

function update_game_score() {
// Verify nonce for security
check_ajax_referer('inline-edit-nonce', 'nonce');

global $wpdb;
$table_name = $wpdb->prefix . 'your_table_name_here'; // Replace with your actual table name

// Get the score, game ID, and score type from the request
$new_value = intval($_POST['new_value']);
$game_id = intval($_POST['game_id']);
$score_type = sanitize_text_field($_POST['score_type']);

// Validate input to prevent SQL injection
if (!in_array($score_type, ['road_team_score', 'home_team_score'], true)) {
wp_send_json_error(array('message' => 'Invalid score type.'));
return;
}

// Update the database
$updated = $wpdb->update(
$table_name,
array($score_type => $new_value),
array('id' => $game_id),
array('%d'),
array('%d')
);

if ($updated !== false) {
wp_send_json_success(array('message' => 'Score updated successfully.'));
} else {
wp_send_json_error(array('message' => 'Failed to update score.'));
}
}

// Hook for logged-in users
add_action('wp_ajax_update_game_score', 'update_game_score');

// Hook for non-logged-in users (if needed, otherwise omit)
add_action('wp_ajax_nopriv_update_game_score', 'update_game_score');

4. Define CSS for Styling

Add CSS to style the inputs and success state:

In your admin/css/inline-editing.css file:

css

/* Basic styling for editable inputs */
.editable-score-input {
width: 50px; /* Adjust width as needed */
padding: 5px;
text-align: center;
border: 2px dashed #ccc; /* Initial border style */
border-radius: 3px;
background-color: #f9f9f9;
outline: none; /* Remove default outline */
transition: border-color 0.3s; /* Smooth transition for border color */
}

/* Styling when the input is focused */
.editable-score-input:focus {
border: 2px solid #0073aa; /* Border color when focused */
background-color: #fff; /* White background on focus */
}

/* Success state styling for inputs */
.success-border {
border-color: #28a745 !important; /* Green border for success */
background-color: #e6ffe6; /* Light green background for success */
}

5. PHP: Display the Editable Table

In your WordPress List Table class, define the columns that require inline editing:

php

function column_road_team_score($item) {
$score = esc_attr($item['road_team_score']);
$field_id = 'road_team_score_' . $item['id'];

// Return input directly for inline editing
$output = '<input type="text" class="editable-score-input" data-field="' . $field_id . '" value="' . $score . '">';
return $output;
}

function column_home_team_score($item) {
$score = esc_attr($item['home_team_score']);
$field_id = 'home_team_score_' . $item['id'];

// Return input directly for inline editing
$output = '<input type="text" class="editable-score-input" data-field="' . $field_id . '" value="' . $score . '">';
return $output;
}

Summary of What to Change

  • JavaScript:
    • Update ajaxurl and nonce if they change for different plugins.
    • Adjust action and data fields according to the plugin’s context.
  • PHP:
    • Ensure table names, column names, and validation logic match your database schema and plugin’s needs.
  • CSS:
    • Customize styling as needed to fit the look and feel of your admin interface.
  • Paths:
    • Ensure paths in wp_enqueue_script and wp_localize_script are correctly set based on your plugin’s directory structure.

Reuse This Template

By following these encapsulated steps and snippets, you can easily implement and reuse inline editing functionality across different WordPress plugins by adapting specific parts of the code to match your database schema and plugin context. Feel free to refer to this guide whenever you need to add similar functionality to other plugins!

If you need further adjustments or have questions, feel free to ask!