diff --git a/feeds_ui/feeds_ui.admin.inc b/feeds_ui/feeds_ui.admin.inc
index d8e0a841236f4e07596f42304acbe8c2861ca2fd..fb63c8cc86eb2bd627e332320895aec63b27381e 100644
--- a/feeds_ui/feeds_ui.admin.inc
+++ b/feeds_ui/feeds_ui.admin.inc
@@ -104,7 +104,6 @@ function feeds_ui_overview_form($form, &$form_status) {
     $importer_form[$importer->id] = array(
       '#type' => 'checkbox',
       '#default_value' => !$importer->disabled,
-      '#attributes' => array('class' => array('feeds-ui-trigger-submit')),
     );
 
     if ($importer->disabled) {
@@ -117,7 +116,6 @@ function feeds_ui_overview_form($form, &$form_status) {
   $form['submit'] = array(
     '#type' => 'submit',
     '#value' => t('Save'),
-    '#attributes' => array('class' => array('feeds-ui-hidden-submit')),
   );
   return $form;
 }
@@ -145,7 +143,6 @@ function feeds_ui_overview_form_submit($form, &$form_state) {
  *   of $from_importer.
  */
 function feeds_ui_create_form($form, &$form_state, $from_importer = NULL) {
-  $form['#attached']['js'][] = drupal_get_path('module', 'feeds_ui') . '/feeds_ui.js';
   $form['#from_importer'] = $from_importer;
   $form['name'] = array(
     '#type' => 'textfield',
@@ -422,7 +419,6 @@ function feeds_ui_edit_page($importer, $active = 'help', $plugin_key = '') {
 function feeds_ui_plugin_form($form, &$form_state, $importer, $type) {
   $plugins = FeedsPlugin::byType($type);
 
-  $form = array();
   $form['#importer'] = $importer->id;
   $form['#plugin_type'] = $type;
 
@@ -442,7 +438,6 @@ function feeds_ui_plugin_form($form, &$form_state, $importer, $type) {
   $form['submit'] = array(
     '#type' => 'submit',
     '#value' => t('Save'),
-    '#attributes' => array('class' => array('feeds-ui-hidden-submit')),
   );
   return $form;
 }
@@ -463,7 +458,6 @@ function feeds_ui_plugin_form_submit($form, &$form_state) {
  */
 function theme_feeds_ui_plugin_form($variables) {
   $form = $variables['form'];
-  drupal_add_js(drupal_get_path('module', 'feeds_ui') . '/feeds_ui.js');
   $output = '';
 
   foreach (element_children($form['plugin_key']) as $key) {
@@ -493,9 +487,6 @@ function theme_feeds_ui_plugin_form($variables) {
  *   FeedsProcessor, a flag can tell whether mapping is supported or not.
  */
 function feeds_ui_mapping_form($form, &$form_state, $importer) {
-  drupal_add_js(drupal_get_path('module', 'feeds_ui') . '/feeds_ui.js');
-
-  $form = array();
   $form['#importer'] = $importer->id;
   $form['#mappings'] = $mappings = $importer->processor->getMappings();
   $form['help']['#markup'] = feeds_ui_mapping_help();
@@ -570,31 +561,36 @@ function feeds_ui_mapping_form($form, &$form_state, $importer) {
   if (isset($source_options)) {
     $form['source'] = array(
       '#type' => 'select',
-      '#options' => array('' => t('Select a source')) + $source_options,
+      '#title' => t('Source'),
+      '#title_display' => 'invisible',
+      '#options' => $source_options,
+      '#empty_option' => t('- Select a source -'),
+      '#description' => t('An element from the feed.'),
     );
   }
   else {
     $form['source'] = array(
       '#type' => 'textfield',
+      '#title' => t('Source'),
+      '#title_display' => 'invisible',
       '#size' => 20,
-      '#default_value' => t('Name of source field'),
-      '#attributes' => array('class' => array('hide-text-on-focus')),
+      '#default_value' => '',
+      '#description' => t('The name of source field.'),
     );
   }
   $form['target'] = array(
     '#type' => 'select',
-    '#options' => array('' => t('Select a target')) + $target_options,
-  );
-  $form['add'] = array(
-    '#type' => 'submit',
-    '#value' => t('Add'),
-    '#submit' => array('feeds_ui_mapping_form_add_submit'),
-    '#validate' => array('feeds_ui_mapping_form_add_validate'),
+    '#title' => t('Target'),
+    '#title_display' => 'invisible',
+    '#options' => $target_options,
+    '#empty_option' => t('- Select a target -'),
+    '#description' => t('The field that stores the data.'),
   );
-  $form['save'] = array(
+
+  $form['actions'] = array('#type' => 'actions');
+  $form['actions']['save'] = array(
     '#type' => 'submit',
     '#value' => t('Save'),
-    '#attributes' => array('class' => array('feeds-ui-hidden-submit')),
   );
   return $form;
 }
@@ -719,40 +715,36 @@ function feeds_ui_mapping_settings_form_callback($form, $form_state) {
 }
 
 /**
- * Validation for source and target selection.
+ * Validation handler for feeds_ui_mapping_form().
  */
-function feeds_ui_mapping_form_add_validate($form, &$form_state) {
-  if ($form_state['values']['source'] == '') {
-    form_set_error('source', t('You must select a mapping source.'));
-  }
-  if ($form_state['values']['target'] == '') {
-    form_set_error('target', t('You must select a mapping target.'));
-  }
-}
+function feeds_ui_mapping_form_validate($form, &$form_state) {
+  if (empty($form_state['values']['source']) xor empty($form_state['values']['target'])) {
 
-/**
- * Submit handler for add button on feeds_ui_mapping_form().
- */
-function feeds_ui_mapping_form_add_submit($form, &$form_state) {
-  $importer = feeds_importer($form['#importer']);
-  try {
-    $mappings = $form['#mappings'];
-    $mappings[] = array(
-      'source' => $form_state['values']['source'],
-      'target' => $form_state['values']['target'],
-      'unique' => FALSE,
-    );
-    $importer->processor->addConfig(array('mappings' => $mappings));
-    $importer->save();
-    drupal_set_message(t('Mapping has been added.'));
-  }
-  catch (Exception $e) {
-    drupal_set_message($e->getMessage(), 'error');
+    // Check triggering_element here so we can react differently for ajax
+    // submissions.
+    switch ($form_state['triggering_element']['#name']) {
+
+      // Regular form submission.
+      case 'op':
+        if (empty($form_state['values']['source'])) {
+          form_error($form['source'], t('You must select a mapping source.'));
+        }
+        else {
+          form_error($form['target'], t('You must select a mapping target.'));
+        }
+        break;
+
+      // Be more relaxed on ajax submission.
+      default:
+        form_set_value($form['source'], '', $form_state);
+        form_set_value($form['target'], '', $form_state);
+        break;
+    }
   }
 }
 
 /**
- * Submit handler for save button on feeds_ui_mapping_form().
+ * Submission handler for feeds_ui_mapping_form().
  */
 function feeds_ui_mapping_form_submit($form, &$form_state) {
   $importer = feeds_importer($form['#importer']);
@@ -785,6 +777,7 @@ function feeds_ui_mapping_form_submit($form, &$form_state) {
     foreach ($remove_flags as $k) {
       unset($mappings[$k]);
       unset($form_state['values']['mapping_weight'][$k]);
+      drupal_set_message(t('Mapping has been removed.'), 'status', FALSE);
     }
   }
 
@@ -796,6 +789,23 @@ function feeds_ui_mapping_form_submit($form, &$form_state) {
   }
 
   $processor->addConfig(array('mappings' => $mappings));
+
+  if (!empty($form_state['values']['source']) && !empty($form_state['values']['target'])) {
+    try {
+      $mappings = $processor->getMappings();
+      $mappings[] = array(
+        'source' => $form_state['values']['source'],
+        'target' => $form_state['values']['target'],
+        'unique' => FALSE,
+      );
+      $processor->addConfig(array('mappings' => $mappings));
+      drupal_set_message(t('Mapping has been added.'));
+    }
+    catch (Exception $e) {
+      drupal_set_message($e->getMessage(), 'error');
+    }
+  }
+
   $importer->save();
   drupal_set_message(t('Your changes have been saved.'));
 }
@@ -860,7 +870,6 @@ function feeds_ui_mapping_settings_optional_unique_form($mapping, $target, $form
  */
 function theme_feeds_ui_overview_form($variables) {
   $form = $variables['form'];
-  drupal_add_js(drupal_get_path('module', 'feeds_ui') . '/feeds_ui.js');
   drupal_add_css(drupal_get_path('module', 'feeds_ui') . '/feeds_ui.css');
 
   // Iterate through all importers and build a table.
diff --git a/feeds_ui/feeds_ui.js b/feeds_ui/feeds_ui.js
deleted file mode 100644
index f5e8b7b1a889084a76cd8a65722721cfb083c9a0..0000000000000000000000000000000000000000
--- a/feeds_ui/feeds_ui.js
+++ /dev/null
@@ -1,62 +0,0 @@
-
-Drupal.behaviors.feeds = function() {
-
-  // Hide text in specific input fields.
-  $('.hide-text-on-focus').focus(function() {
-    $(this).val('');
-  });
-
-
-  // Hide submit buttons of .feeds-ui-hidden-submit class.
-  $('input.form-submit.feeds-ui-hidden-submit').hide();
-
-  /**
-   * Tune checkboxes on mapping forms.
-   * @see feeds_ui_mapping_form() in feeds_ui.admin.inc
-   */
-
-  // Attach submit behavior to elements with feeds-ui-trigger-submit class.
-  $('.feeds-ui-trigger-submit').click(function() {
-    // Use click, not form.submit() - submit() would use the wrong submission
-    // handler.
-    $('input.form-submit.feeds-ui-hidden-submit').click();
-  });
-
-  // Replace checkbox with .feeds-ui-checkbox-link class with a link.
-  $('.feeds-ui-checkbox-link:not(.processed)').each(function(i) {
-    $(this).addClass('processed').after(
-      '<a href="#" onclick="return false;" class="feeds-ui-trigger-remove">' + $('label', this).text() + '</a>'
-    ).hide();
-  });
-
-  // Check the box and then submit.
-  $('.feeds-ui-trigger-remove').click(function() {
-    // Use click, not form.submit() - submit() would use the wrong submission
-    // handler.
-    $(this).prev().children().children().children().attr('checked', 1);
-    $('input.form-submit.feeds-ui-hidden-submit').click();
-  });
-
-  // Replace radio with .feeds-ui-radio-link class with a link.
-  $('.feeds-ui-radio-link:not(.processed)').parent().each(function(i) {
-    checked = '';
-    if ($(this).children('input').attr('checked')) {
-      checked = ' checked';
-    }
-    $(this).addClass('processed').after(
-      '<a href="#" onclick="return false;" class="feeds-ui-check-submit' + checked + '" id="' + $(this).children('input').attr('id') + '">' + $(this).parent().text() + '</a>'
-    );
-    $(this).hide();
-  });
-
-  // Hide the the radio that is selected.
-  $('.feeds-ui-check-submit.checked').parent().hide();
-
-  // Check the radio and then submit.
-  $('.feeds-ui-check-submit').click(function() {
-    // Use click, not form.submit() - submit() would use the wrong submission
-    // handler.
-    $('#' + $(this).attr('id')).attr('checked', 1);
-    $('input.form-submit.feeds-ui-hidden-submit').click();
-  });
-};
diff --git a/tests/feeds.test b/tests/feeds.test
index a2bac291e742a29f6aa777f8b9d90b5c33298735..480a5db7f9e6fb5941b6258b9721db4285b4c2ed 100644
--- a/tests/feeds.test
+++ b/tests/feeds.test
@@ -409,7 +409,7 @@ class FeedsWebTestCase extends DrupalWebTestCase {
       $mapping = array('source' => $mapping['source'], 'target' => $mapping['target']);
 
       // Add mapping.
-      $this->drupalPost($path, $mapping, t('Add'));
+      $this->drupalPost($path, $mapping, t('Save'));
 
       // If there are other configuration options, set them.
       if ($config) {
@@ -434,8 +434,6 @@ class FeedsWebTestCase extends DrupalWebTestCase {
   /**
    * Remove mappings from a given configuration.
    *
-   * This function mimicks the Javascript behavior in feeds_ui.js
-   *
    * @param array $mappings
    *   An array of mapping arrays. Each mapping array must have a source and
    *   a target key and can have a unique key.