Как добавить динамические строки в таблицу WordPress без плагинов

В WordPress часто возникает задача вывести таблицу с динамическими данными, где пользователь может добавлять новые строки без перезагрузки страницы и без использования сторонних плагинов. В этой статье мы разберем, как реализовать такую функциональность с помощью собственных скриптов и PHP, используя AJAX и REST API WordPress.

Почему стоит создавать динамические таблицы без плагинов

Многие разработчики по умолчанию ищут готовые плагины для создания таблиц, но они часто перегружают сайт лишним кодом, снижают производительность и ограничивают кастомизацию. Контроль над кодом позволяет создавать именно тот функционал, который нужен, без лишних зависимостей.

Кроме того, реализация динамических таблиц с AJAX и REST API дает современный, отзывчивый интерфейс, который улучшает пользовательский опыт.

Рассмотрим пример, в котором мы создадим таблицу, позволяющую добавлять, редактировать и удалять строки динамически с сохранением данных в базе WordPress.

Создаем таблицу в шаблоне WordPress

Для начала создадим простую HTML-таблицу в нужном месте шаблона или через шорткод. Таблица будет выводиться с заголовками и пустым <tbody>, куда мы будем добавлять строки динамически.

<table id="wp-shablon-table" border="1" cellpadding="5" cellspacing="0">
  <thead>
    <tr>
      <th>Имя</th>
      <th>Email</th>
      <th>Действия</th>
    </tr>
  </thead>
  <tbody>
    <!-- строки будут добавляться сюда -->
  </tbody>
</table>
<button id="wp-shablon-add-row">Добавить строку</button>

Кнопка ниже будет запускать добавление новой строки.

Добавление динамических строк с помощью JavaScript и jQuery

Подключим скрипт, который будет реагировать на нажание кнопки и добавлять новую строку с полями ввода. Для простоты используем jQuery, который уже есть в WordPress по умолчанию.

jQuery(document).ready(function($) {
  $('#wp-shablon-add-row').on('click', function() {
    const newRow = `
      <tr>
        <td><input type="text" name="wp_shablon_name[]" placeholder="Имя" /></td>
        <td><input type="email" name="wp_shablon_email[]" placeholder="Email" /></td>
        <td><button class="wp-shablon-save-row">Сохранить</button> <button class="wp-shablon-delete-row">Удалить</button></td>
      </tr>
    `;
    $('#wp-shablon-table tbody').append(newRow);
  });

  // Удаление строки
  $('#wp-shablon-table').on('click', '.wp-shablon-delete-row', function() {
    $(this).closest('tr').remove();
  });

  // Сохранение строки
  $('#wp-shablon-table').on('click', '.wp-shablon-save-row', function(e) {
    e.preventDefault();
    const row = $(this).closest('tr');
    const name = row.find('input[name="wp_shablon_name[]"]').val();
    const email = row.find('input[name="wp_shablon_email[]"]').val();

    if(!name || !email) {
      alert('Пожалуйста, заполните все поля.');
      return;
    }

    // AJAX-запрос на сохранение
    $.ajax({
      url: wp_shablon_ajax_object.ajax_url,
      method: 'POST',
      data: {
        action: 'wp_shablon_save_row',
        name: name,
        email: email,
        security: wp_shablon_ajax_object.nonce
      },
      success: function(response) {
        if(response.success) {
          alert('Строка успешно сохранена');
          // Можно добавить логику после сохранения, например, блокировать редактирование
          row.find('input').prop('disabled', true);
          row.find('.wp-shablon-save-row').remove();
        } else {
          alert('Ошибка сохранения: ' + response.data);
        }
      }
    });
  });
});

Этот код добавляет строку с двумя полями: имя и email, а также кнопками для сохранения и удаления. При сохранении происходит AJAX-запрос для сохранения данных на сервер.

Обработка AJAX-запроса в functions.php

Теперь добавим обработчик AJAX в файл functions.php вашей темы или в плагин. Этот обработчик будет проверять безопасность, валидировать данные и сохранять их в базу данных.

add_action('wp_enqueue_scripts', 'wp_shablon_enqueue_scripts');
function wp_shablon_enqueue_scripts() {
  wp_enqueue_script('wp-shablon-script', get_template_directory_uri() . '/js/wp-shablon.js', ['jquery'], null, true);

  wp_localize_script('wp-shablon-script', 'wp_shablon_ajax_object', [
    'ajax_url' => admin_url('admin-ajax.php'),
    'nonce' => wp_create_nonce('wp_shablon_nonce')
  ]);
}

add_action('wp_ajax_wp_shablon_save_row', 'wp_shablon_save_row_callback');
add_action('wp_ajax_nopriv_wp_shablon_save_row', 'wp_shablon_save_row_callback');
function wp_shablon_save_row_callback() {
  check_ajax_referer('wp_shablon_nonce', 'security');

  $name = isset($_POST['name']) ? sanitize_text_field($_POST['name']) : '';
  $email = isset($_POST['email']) ? sanitize_email($_POST['email']) : '';

  if(empty($name) || empty($email) || !is_email($email)) {
    wp_send_json_error('Неверные данные');
  }

  global $wpdb;
  $table_name = $wpdb->prefix . 'wp_shablon_table';

  $result = $wpdb->insert($table_name, [
    'name' => $name,
    'email' => $email,
    'created_at' => current_time('mysql')
  ]);

  if($result) {
    wp_send_json_success();
  } else {
    wp_send_json_error('Ошибка при записи в базу');
  }
  wp_die();
}

Обратите внимание, что мы используем отдельную таблицу в базе данных wp_shablon_table. Ее нужно создать заранее через установочный скрипт или вручную.

Создание таблицы базы данных для хранения данных

Для хранения данных добавьте следующую функцию в плагин или functions.php, которая выполнится при активации и создаст таблицу, если она отсутствует:

function wp_shablon_create_table() {
  global $wpdb;
  $table_name = $wpdb->prefix . 'wp_shablon_table';
  $charset_collate = $wpdb->get_charset_collate();

  $sql = "CREATE TABLE IF NOT EXISTS $table_name (
    id mediumint(9) NOT NULL AUTO_INCREMENT,
    name varchar(100) NOT NULL,
    email varchar(100) NOT NULL,
    created_at datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
    PRIMARY KEY  (id)
  ) $charset_collate;";

  require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
  dbDelta($sql);
}
register_activation_hook(__FILE__, 'wp_shablon_create_table');

Запускать эту функцию нужно при активации плагина. Если вы используете тему, можно вызвать ее вручную или через хук after_switch_theme.

Загрузка и отображение сохраненных данных

Чтобы при загрузке страницы отображать уже сохраненные строки, добавим функцию, которая достанет данные из базы и выведет их в таблицу.

function wp_shablon_render_saved_rows() {
  global $wpdb;
  $table_name = $wpdb->prefix . 'wp_shablon_table';
  $rows = $wpdb->get_results("SELECT * FROM $table_name ORDER BY id DESC");

  if(!$rows) return '';

  $html = '';
  foreach($rows as $row) {
    $html .= "<tr>";
    $html .= "<td>" . esc_html($row->name) . "</td>";
    $html .= "<td>" . esc_html($row->email) . "</td>";
    $html .= "<td>Сохранено</td>";
    $html .= "</tr>";
  }
  return $html;
}

Вставьте вызов echo wp_shablon_render_saved_rows(); внутрь <tbody> вашей таблицы, чтобы отобразить существующие данные.

Дополнительно: Улучшение UX и валидация

Можно добавить более продвинутую валидацию email и имени на стороне клиента, использовать spinners или индикаторы загрузки при отправке AJAX, а также подтверждения при удалении строк, если реализовать сохранение удаления в базе.

Для оптимизации кода и удобства поддержки можно оформить весь функционал в отдельный плагин, где будет логика создания таблицы, AJAX-обработчики и скрипты.

Заключение

Таким образом, мы рассмотрели, как на практике реализовать динамические таблицы в WordPress без использования плагинов, с возможностью добавлять и сохранять строки на лету. Такой подход позволяет создавать легкие, быстрые и удобные интерфейсы, полностью контролируемые разработчиком.

Если вы хотите расширить функционал, можно интегрировать это с плагинами WPShop, например, использовать ABC Pagination для удобной постраничной навигации по большим таблицам.

Как удалить сериализованные данные из базы данных WordPress правильно
15.09.2026
Как правильно оптимизировать шаблоны WordPress для быстрой загрузки
01.10.2026
Как отключить заказ без оплаты и наличные на самовывоз в WooCommerce
10.08.2026
Как отключить XML-RPC в WordPress и не сломать внешние интеграции
22.09.2026
Как добавить динамический фильтр записей в шаблон WordPress
26.09.2026