diff --git a/src/Form/IndexForm.php b/src/Form/IndexForm.php
index f322f0c..74bf682 100644
--- a/src/Form/IndexForm.php
+++ b/src/Form/IndexForm.php
@@ -63,25 +63,6 @@ class IndexForm extends EntityForm {
   }
 
   /**
-   * Retrieves all available servers as an options list.
-   *
-   * @return string[]
-   *   An associative array mapping server IDs to their labels.
-   */
-  protected function getServerOptions() {
-    $options = array();
-    /** @var \Drupal\search_api\ServerInterface[] $servers */
-    $servers = $this->entityTypeManager
-      ->getStorage('search_api_server')
-      ->loadMultiple();
-    foreach ($servers as $server_id => $server) {
-      // @todo Special formatting for disabled servers.
-      $options[$server_id] = Html::escape($server->label());
-    }
-    return $options;
-  }
-
-  /**
    * {@inheritdoc}
    */
   public function form(array $form, FormStateInterface $form_state) {
@@ -149,7 +130,6 @@ class IndexForm extends EntityForm {
       '#title' => $this->t('Data sources'),
       '#description' => $this->t('Select one or more data sources of items that will be stored in this index.'),
       '#default_value' => $index->getDatasourceIds(),
-      '#multiple' => TRUE,
       '#required' => TRUE,
       '#attributes' => array('class' => array('search-api-checkboxes-list')),
       '#ajax' => array(
@@ -238,13 +218,52 @@ class IndexForm extends EntityForm {
 
     $this->buildTrackerConfigForm($form, $form_state, $index);
 
+    $server_options = [];
+    $status_disabled = [
+      ':input[name="server"]' => [
+        'value' => '',
+      ],
+    ];
+    /** @var \Drupal\search_api\ServerInterface[] $servers */
+    $servers = $this->entityTypeManager
+      ->getStorage('search_api_server')
+      ->loadMultiple();
+    foreach ($servers as $server_id => $server) {
+      if ($server->status()) {
+        $label = Html::escape($server->label());
+      }
+      else {
+        $args = [
+          '@server' => $server->label(),
+        ];
+        $label = $this->t('@server <em>(disabled)</em>', $args);
+        $status_disabled[':input[name="server"],.dummy-' . $server_id] = [
+          'value' => $server_id,
+        ];
+      }
+      $server_options[$server_id] = $label;
+    }
+
+    $default_server = $index->hasValidServer() ? $index->getServerId() : '';
+    if (!$default_server && $index->isNew() && count($server_options) == 1) {
+      $default_server = key($server_options);
+    }
+    $server_options = array(
+      '' => '<em>' . $this->t('- No server -') . '</em>',
+    ) + $server_options;
     $form['server'] = array(
       '#type' => 'radios',
       '#title' => $this->t('Server'),
       '#description' => $this->t('Select the server this index should use. Indexes cannot be enabled without a connection to a valid, enabled server.'),
-      '#options' => array('' => '<em>' . $this->t('- No server -') . '</em>') + $this->getServerOptions(),
-      '#default_value' => $index->hasValidServer() ? $index->getServerId() : '',
+      '#options' => $server_options,
+      '#default_value' => $default_server,
     );
+    if (!$default_server) {
+      // The Core "radios" element has a bug that makes it impossible to set the
+      // default to a radio with empty value. We therefore need to use this
+      // workaround.
+      $form['server']['']['#default_value'] = TRUE;
+    }
 
     $form['status'] = array(
       '#type' => 'checkbox',
@@ -253,13 +272,9 @@ class IndexForm extends EntityForm {
       '#default_value' => $index->status(),
       // Can't enable an index lying on a disabled server or no server at all.
       '#disabled' => !$index->status() && (!$index->hasValidServer() || !$index->getServerInstance()->status()),
-      // @todo This doesn't seem to work and should also hide for disabled
-      //   servers. If that works, we can probably remove the last sentence of
-      //   the description.
       '#states' => array(
-        'invisible' => array(
-          ':input[name="server"]' => array('value' => ''),
-        ),
+        'disabled' => $status_disabled,
+        'unchecked' => $status_disabled,
       ),
     );
 
@@ -332,12 +347,15 @@ class IndexForm extends EntityForm {
           $datasource_form = $form['datasource_configs'][$datasource_id];
         }
         $datasource_form_state = SubformState::createForSubform($datasource_form, $form, $form_state);
-        $form['datasource_configs'][$datasource_id] = $datasource->buildConfigurationForm($datasource_form, $datasource_form_state);
-
-        $show_message = TRUE;
-        $form['datasource_configs'][$datasource_id]['#type'] = 'details';
-        $form['datasource_configs'][$datasource_id]['#title'] = $this->t('Configure the %datasource datasource', array('%datasource' => $datasource->label()));
-        $form['datasource_configs'][$datasource_id]['#open'] = $index->isNew();
+        $datasource_form = $datasource->buildConfigurationForm($datasource_form, $datasource_form_state);
+
+        if ($datasource_form) {
+          $show_message = TRUE;
+          $form['datasource_configs'][$datasource_id] = $datasource_form;
+          $form['datasource_configs'][$datasource_id]['#type'] = 'details';
+          $form['datasource_configs'][$datasource_id]['#title'] = $this->t('Configure the %datasource datasource', array('%datasource' => $datasource->label()));
+          $form['datasource_configs'][$datasource_id]['#open'] = $index->isNew();
+        }
       }
     }
 
diff --git a/src/Plugin/search_api/datasource/ContentEntity.php b/src/Plugin/search_api/datasource/ContentEntity.php
index 646523a..4dfed69 100644
--- a/src/Plugin/search_api/datasource/ContentEntity.php
+++ b/src/Plugin/search_api/datasource/ContentEntity.php
@@ -465,8 +465,6 @@ class ContentEntity extends DatasourcePluginBase implements EntityDatasourceInte
         '#title' => $this->t('Bundles'),
         '#options' => $bundles,
         '#default_value' => $this->configuration['bundles']['selected'],
-        '#size' => min(4, count($bundles)),
-        '#multiple' => TRUE,
       );
     }
 
@@ -490,7 +488,6 @@ class ContentEntity extends DatasourcePluginBase implements EntityDatasourceInte
         '#title' => $this->t('Languages'),
         '#options' => $this->getTranslationOptions(),
         '#default_value' => $this->configuration['languages']['selected'],
-        '#multiple' => TRUE,
       );
     }
 
diff --git a/src/Plugin/search_api/processor/IgnoreCharacters.php b/src/Plugin/search_api/processor/IgnoreCharacters.php
index 10b009e..99a4132 100644
--- a/src/Plugin/search_api/processor/IgnoreCharacters.php
+++ b/src/Plugin/search_api/processor/IgnoreCharacters.php
@@ -80,7 +80,6 @@ class IgnoreCharacters extends FieldsProcessorPluginBase {
       '#title' => $this->t('Ignored character properties'),
       '#options' => $character_sets,
       '#default_value' => $this->configuration['strip']['character_sets'],
-      '#multiple' => TRUE,
     );
 
     return $form;
diff --git a/src/Plugin/search_api/processor/Property/RenderedItemProperty.php b/src/Plugin/search_api/processor/Property/RenderedItemProperty.php
index b67bb31..e46de78 100644
--- a/src/Plugin/search_api/processor/Property/RenderedItemProperty.php
+++ b/src/Plugin/search_api/processor/Property/RenderedItemProperty.php
@@ -34,16 +34,17 @@ class RenderedItemProperty extends ConfigurablePropertyBase {
     $configuration = $field->getConfiguration();
     $index = $field->getIndex();
     $form['#tree'] = TRUE;
+    $form['#attached']['library'][] = 'search_api/drupal.search_api.admin_css';
 
     $roles = user_role_names();
     $form['roles'] = array(
-      '#type' => 'select',
+      '#type' => 'checkboxes',
       '#title' => $this->t('User roles'),
       '#description' => $this->t('Your item will be rendered as seen by a user with the selected roles. We recommend to just use "@anonymous" here to prevent data leaking out to unauthorized roles.', array('@anonymous' => $roles[AccountInterface::ANONYMOUS_ROLE])),
       '#options' => $roles,
-      '#multiple' => TRUE,
       '#default_value' => $configuration['roles'],
       '#required' => TRUE,
+      '#attributes' => array('class' => array('search-api-checkboxes-list')),
     );
 
     $form['view_mode'] = array(
diff --git a/src/Plugin/search_api/processor/RoleFilter.php b/src/Plugin/search_api/processor/RoleFilter.php
index f72c0d3..5e4224a 100644
--- a/src/Plugin/search_api/processor/RoleFilter.php
+++ b/src/Plugin/search_api/processor/RoleFilter.php
@@ -69,12 +69,10 @@ class RoleFilter extends ProcessorPluginBase implements PluginFormInterface {
       '#default_value' => (int) $this->configuration['default'],
     );
     $form['roles'] = array(
-      '#type' => 'select',
+      '#type' => 'checkboxes',
       '#title' => $this->t('Roles'),
       '#options' => $options,
-      '#multiple' => TRUE,
-      '#size' => min(4, count($options)),
-      '#default_value' => array_combine($this->configuration['roles'], $this->configuration['roles']),
+      '#default_value' => $this->configuration['roles'],
     );
     return $form;
   }
diff --git a/src/Plugin/views/argument/SearchApiFulltext.php b/src/Plugin/views/argument/SearchApiFulltext.php
index e21c9c4..363d1d9 100644
--- a/src/Plugin/views/argument/SearchApiFulltext.php
+++ b/src/Plugin/views/argument/SearchApiFulltext.php
@@ -98,14 +98,14 @@ class SearchApiFulltext extends SearchApiStandard {
 
     $fields = $this->getFulltextFields();
     if (!empty($fields)) {
+      $form['#attached']['library'][] = 'search_api/drupal.search_api.admin_css';
       $form['fields'] = array(
-        '#type' => 'select',
+        '#type' => 'checkboxes',
         '#title' => $this->t('Searched fields'),
         '#description' => $this->t('Select the fields that will be searched. If no fields are selected, all available fulltext fields will be searched.'),
         '#options' => $fields,
-        '#size' => min(4, count($fields)),
-        '#multiple' => TRUE,
         '#default_value' => $this->options['fields'],
+        '#attributes' => array('class' => array('search-api-checkboxes-list')),
       );
       $form['conjunction'] = array(
         '#title' => $this->t('Operator'),
diff --git a/src/Plugin/views/argument/SearchApiMoreLikeThis.php b/src/Plugin/views/argument/SearchApiMoreLikeThis.php
index ec1b513..7bc563c 100644
--- a/src/Plugin/views/argument/SearchApiMoreLikeThis.php
+++ b/src/Plugin/views/argument/SearchApiMoreLikeThis.php
@@ -44,14 +44,14 @@ class SearchApiMoreLikeThis extends SearchApiStandard {
     }
 
     if ($fields) {
+      $form['#attached']['library'][] = 'search_api/drupal.search_api.admin_css';
       $form['fields'] = array(
-        '#type' => 'select',
+        '#type' => 'checkboxes',
         '#title' => $this->t('Fields for similarity'),
         '#description' => $this->t('Select the fields that will be used for finding similar content. If no fields are selected, all available fields will be used.'),
         '#options' => $fields,
-        '#size' => min(8, count($fields)),
-        '#multiple' => TRUE,
         '#default_value' => $this->options['fields'],
+        '#attributes' => array('class' => array('search-api-checkboxes-list')),
       );
     }
     else {
diff --git a/src/Plugin/views/filter/SearchApiFulltext.php b/src/Plugin/views/filter/SearchApiFulltext.php
index 4e90c6d..cf39ac5 100644
--- a/src/Plugin/views/filter/SearchApiFulltext.php
+++ b/src/Plugin/views/filter/SearchApiFulltext.php
@@ -159,14 +159,14 @@ class SearchApiFulltext extends FilterPluginBase {
 
     $fields = $this->getFulltextFields();
     if (!empty($fields)) {
+      $form['#attached']['library'][] = 'search_api/drupal.search_api.admin_css';
       $form['fields'] = array(
-        '#type' => 'select',
+        '#type' => 'checkboxes',
         '#title' => $this->t('Searched fields'),
         '#description' => $this->t('Select the fields that will be searched. If no fields are selected, all available fulltext fields will be searched.'),
         '#options' => $fields,
-        '#size' => min(4, count($fields)),
-        '#multiple' => TRUE,
         '#default_value' => $this->options['fields'],
+        '#attributes' => array('class' => array('search-api-checkboxes-list')),
       );
     }
     else {
diff --git a/tests/src/Functional/IntegrationTest.php b/tests/src/Functional/IntegrationTest.php
index 3bfbd64..40d1053 100644
--- a/tests/src/Functional/IntegrationTest.php
+++ b/tests/src/Functional/IntegrationTest.php
@@ -336,6 +336,7 @@ class IntegrationTest extends SearchApiBrowserTestBase {
     $this->assertSession()->pageTextContains('Please configure the used datasources.');
 
     $this->submitForm([], 'Save and add fields');
+    $this->checkForMetaRefresh();
     $this->assertSession()->pageTextContains('The index was successfully saved.');
     $this->indexStorage->resetCache([$index2_id]);
     $index = $this->indexStorage->load($index2_id);
@@ -463,6 +464,7 @@ class IntegrationTest extends SearchApiBrowserTestBase {
       'name' => 'IndexName',
       'id' => 'user_index',
       'datasources[entity:user]' => TRUE,
+      'server' => '',
     ];
 
     $this->drupalGet('admin/config/search/search-api/add-index');
@@ -471,6 +473,7 @@ class IntegrationTest extends SearchApiBrowserTestBase {
     $this->assertSession()->pageTextContains('Please configure the used datasources.');
 
     $this->submitForm([], 'Save');
+    $this->checkForMetaRefresh();
     $this->assertSession()->statusCodeEquals(200);
     $this->assertSession()->pageTextContains('The index was successfully saved.');
     $this->assertSession()->pageTextContains($edit['name']);
@@ -542,6 +545,7 @@ class IntegrationTest extends SearchApiBrowserTestBase {
       'datasource_configs[entity:node][bundles][selected][page]' => FALSE,
     ];
     $this->submitForm($edit, 'Save');
+    $this->checkForMetaRefresh();
     $this->assertSession()->pageTextContains('The index was successfully saved.');
 
     $tracked_items = $this->countTrackedItems();
@@ -647,7 +651,11 @@ class IntegrationTest extends SearchApiBrowserTestBase {
     $this->getCalledMethods('backend');
     $article1->save();
     $methods = $this->getCalledMethods('backend');
-    $this->assertEquals(['indexItems'], $methods, 'Update successfully tracked.');
+    $expected = [
+      'indexItems',
+      'indexItems',
+    ];
+    $this->assertEquals($expected, $methods, 'Update successfully tracked.');
 
     $article1->search_api_skip_tracking = TRUE;
     $article1->save();
@@ -747,6 +755,7 @@ class IntegrationTest extends SearchApiBrowserTestBase {
     $this->drupalGet($this->getIndexPath('edit'));
     $this->assertHtmlEscaped($content_type_name);
     $this->submitForm($edit, 'Save');
+    $this->checkForMetaRefresh();
     $this->assertSession()->pageTextContains('The index was successfully saved.');
 
     $this->addField(NULL, 'rendered_item');
@@ -1336,6 +1345,7 @@ class IntegrationTest extends SearchApiBrowserTestBase {
     ];
     $this->drupalGet($settings_path);
     $this->submitForm($edit, 'Save');
+    $this->checkForMetaRefresh();
     $this->assertSession()->pageTextContains('The index was successfully saved.');
 
     $this->executeTasks();
@@ -1371,6 +1381,7 @@ class IntegrationTest extends SearchApiBrowserTestBase {
     ];
     $this->drupalGet($settings_path);
     $this->submitForm($edit, 'Save');
+    $this->checkForMetaRefresh();
     $this->assertSession()->pageTextContains('The index was successfully saved.');
 
     // After saving the new index, we should have called reindex.
diff --git a/tests/src/Functional/ProcessorIntegrationTest.php b/tests/src/Functional/ProcessorIntegrationTest.php
index a8cdb02..5ab0bad 100644
--- a/tests/src/Functional/ProcessorIntegrationTest.php
+++ b/tests/src/Functional/ProcessorIntegrationTest.php
@@ -473,13 +473,15 @@ TAGS
   public function checkRoleFilterIntegration() {
     $this->enableProcessor('role_filter');
 
-    $configuration = [
+    $form_values = [
       'default' => 1,
       'roles' => [
-        'anonymous',
+        'anonymous' => 'anonymous',
       ],
     ];
-    $this->editSettingsForm($configuration, 'role_filter');
+    $configuration = $form_values;
+    $configuration['roles'] = array_values($configuration['roles']);
+    $this->editSettingsForm($configuration, 'role_filter', $form_values);
   }
 
   /**
@@ -502,7 +504,8 @@ TAGS
     $this->assertSession()->responseContains(new FormattableMarkup('Field %label was added to the index.', $args));
     $this->assertSession()->addressEquals($this->getIndexPath('fields/rendered_item/edit'));
     $edit = [
-      'roles[]' => ['authenticated'],
+      'roles[anonymous]' => '0',
+      'roles[authenticated]' => 'authenticated',
       'view_mode[entity:node][article]' => 'default',
       'view_mode[entity:node][page]' => 'teaser',
     ];
@@ -510,6 +513,25 @@ TAGS
 
     $this->assertSession()->addressEquals($this->getIndexPath('fields'));
     $this->assertSession()->responseContains('The field configuration was successfully saved.');
+    $this->submitForm([], 'Save');
+
+    $config = $this->loadIndex()->getField('rendered_item')->getConfiguration();
+    $expected = [
+      'roles' => [
+        'anonymous' => '0',
+        'authenticated' => 'authenticated',
+      ],
+      'view_mode' => [
+        'entity:node' => [
+          'article' => 'default',
+          'page' => 'teaser',
+        ],
+        'entity:user' => [
+          'user' => '',
+        ],
+      ],
+    ];
+    $this->assertEquals($expected, $config, '"Rendered item" field config saved correctly.');
   }
 
   /**
