diff --git a/core/lib/Drupal/Core/Render/Element/Tableselect.php b/core/lib/Drupal/Core/Render/Element/Tableselect.php
index cc6aefd..d063f03 100644
--- a/core/lib/Drupal/Core/Render/Element/Tableselect.php
+++ b/core/lib/Drupal/Core/Render/Element/Tableselect.php
@@ -232,6 +232,7 @@ public static function processTableselect(&$element, FormStateInterface $form_st
               '#return_value' => $key,
               '#default_value' => isset($value[$key]) ? $key : NULL,
               '#attributes' => $element['#attributes'],
+              '#ajax' => isset($element['#ajax']) ? $element['#ajax'] : NULL,
             );
           }
           else {
diff --git a/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php b/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php
index 22622e7..120f69a 100644
--- a/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php
+++ b/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php
@@ -44,6 +44,27 @@ function testMultipleTrue() {
   }
 
   /**
+   * Test the presence of ajax functionality for all options.
+   */
+  function testAjax() {
+    $rows = array('row1', 'row2', 'row3');
+    // Test checkboxes (#multiple == TRUE).
+    foreach ($rows as $row) {
+      $element = 'tableselect[' . $row . ']';
+      $edit = array($element => TRUE);
+      $result = $this->drupalPostAjaxForm('form_test/tableselect/multiple-true', $edit, $element);
+      $this->assertFalse(empty($result), t('Ajax triggers on checkbox for @row.', array('@row' => $row)));
+    }
+    // Test radios (#multiple == FALSE).
+    $element = 'tableselect';
+    foreach ($rows as $row) {
+      $edit = array($element => $row);
+      $result = $this->drupalPostAjaxForm('form_test/tableselect/multiple-false', $edit, $element);
+      $this->assertFalse(empty($result), t('Ajax triggers on radio for @row.', array('@row' => $row)));
+    }
+  }
+
+  /**
    * Test the display of radios when #multiple is FALSE.
    */
   function testMultipleFalse() {
diff --git a/core/modules/system/tests/modules/form_test/form_test.module b/core/modules/system/tests/modules/form_test/form_test.module
index ee4c137..7114a29 100644
--- a/core/modules/system/tests/modules/form_test/form_test.module
+++ b/core/modules/system/tests/modules/form_test/form_test.module
@@ -104,3 +104,10 @@ function form_test_form_form_test_vertical_tabs_access_form_alter(&$form, &$form
   $form['fieldset1']['#access'] = FALSE;
   $form['container']['#access'] = FALSE;
 }
+
+/**
+ * Ajax callback that returns the form element.
+ */
+function form_test_tableselect_ajax_callback($form, FormStateInterface $form_state) {
+  return $form['tableselect'];
+}
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectFormBase.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectFormBase.php
index f618c92..5c3b383 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectFormBase.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestTableSelectFormBase.php
@@ -34,11 +34,17 @@ function tableselectFormBuilder($form, FormStateInterface $form_state, $element_
     $form['tableselect'] = $element_properties;
 
     $form['tableselect'] += array(
+      '#prefix' => '<div id="tableselect-wrapper">',
+      '#suffix' => '</div>',
       '#type' => 'tableselect',
       '#header' => $header,
       '#options' => $options,
       '#multiple' => FALSE,
       '#empty' => t('Empty text.'),
+      '#ajax' => array(
+        'callback' => 'form_test_tableselect_ajax_callback',
+        'wrapper' => 'tableselect-wrapper',
+      ),
     );
 
     $form['submit'] = array(
