diff --git a/panopoly-magic.js b/panopoly-magic.js
index 6a34244..87030a9 100644
--- a/panopoly-magic.js
+++ b/panopoly-magic.js
@@ -27,6 +27,14 @@
    */
   Drupal.behaviors.panopolyMagicAutosubmit = {
     attach: function (context, settings) {
+      // Replaces click with mousedown for submit so both normal and ajax work.
+      $('.ctools-auto-submit-click', context).click(function(event) {
+        if ($(this).hasClass('ajax-processed') {
+          event.stopImmediatePropagation();
+          $(this).trigger('mousedown');
+          return false;
+        }
+      });
       // 'this' references the form element
       function triggerSubmit (e) {
         var $this = $(this);
diff --git a/panopoly_magic.module b/panopoly_magic.module
index 8060d7c..976b1ec 100644
--- a/panopoly_magic.module
+++ b/panopoly_magic.module
@@ -292,53 +292,57 @@ function panopoly_magic_form_alter(&$form, &$form_state, $form_id) {
         unset($configuration['image_link']);
       }
     }
-    $content = (empty($preview_subtype)) ? ctools_content_render($pane->type, $pane->subtype, $configuration, $keywords, $args, $context) : ctools_content_render($pane->type, $preview_subtype, $configuration, $keywords, $args, $context);
 
-    // Create the preview fieldset
-    if ($form_id == 'fieldable_panels_panes_fieldable_panels_pane_content_type_edit_form' || is_object($content)) {
-
-      // Create the fieldset with appropriate content
-      $form['widget_preview'] = array(
-        '#type' => 'fieldset',
-        '#title' => 'Preview',
-        '#attributes' => array('class' => array('widget-preview', 'widget-preview-single')),
-        '#collapsible' => FALSE,
-        '#weight' => -100,
-      );
-      $form['widget_preview']['preview'] = array(
-        '#markup' => (!empty($style['render pane'])) ? theme($style['render pane'], array('content' => $content, 'pane' => $pane, 'display' => $display, 'style' => $style, 'settings' => $pane->style['settings'])) : theme('panels_pane', array('content' => $content, 'pane' => $pane, 'display' => $display)),
-      );
-
-      // Remove the clearfix for preview floating
-      if (isset($form['aligner_start'])) {
-        $form['aligner_start']['#markup'] = str_replace('clearfix', '', $form['aligner_start']['#markup']);
-      }
+    // Creates preview outside of form itself to fix various bugs, like form
+    // inside form and double rendering.
+    $form['#post_render'][] = 'panopoly_magic_form_post_render_preview';
+    $form['#panopoly_magic_preview_info'] = array(
+      'preview_subtype' => $preview_subtype,
+      'pane' => $pane,
+      'configuration' =>  $configuration,
+      'keywords' => $keywords,
+      'args' => $args,
+      'context' => $context,
+      'style' => $style,
+      'display' => $display,
+    );
 
-      $preview_attributes = array(
-        'class' => array(
-          'widget-preview-button',
-          'ctools-use-ajax',
-        ),
-      );
+    // Remove the clearfix for preview floating
+    if (isset($form['aligner_start'])) {
+      $form['aligner_start']['#markup'] = str_replace('clearfix', '', $form['aligner_start']['#markup']);
+    }
 
-      // If live previewing, don't show button, and autoupdate.
-      if (variable_get('panopoly_magic_live_preview', 1) == 1) {
-        $preview_attributes['style'] = 'display: none';
-        $preview_attributes['class'][] = 'ctools-auto-submit-click';
-      }
+    $preview_attributes = array(
+      'class' => array(
+        'widget-preview-button',
+      ),
+    );
 
-      // Create the preview refresh button
-      $form['buttons']['preview'] = array(
-        '#type' => 'button',
-        '#value' => t('Update Preview'),
-        '#wizard type' => 'next',
-        '#attributes' => $preview_attributes,
-      );
+    // If live previewing, don't show button, and autoupdate.
+    if (variable_get('panopoly_magic_live_preview', 1) == 1) {
+      $preview_attributes['style'] = 'display: none';
+      $preview_attributes['class'][] = 'ctools-auto-submit-click';
+    }
 
-      // Autosubmit the form
-      ctools_add_js('auto-submit');
-      $form['#attributes']['class'][] = 'ctools-auto-submit-full-form';
+    // Create the preview refresh button
+    $form['buttons']['preview'] = array(
+      '#type' => 'button',
+      '#value' => t('Update Preview'),
+      '#attributes' => $preview_attributes,
+      '#ajax' => array(
+        'callback' => 'panopoly_magic_ajax_update_preview',
+        'wrapper' => 'panopoly-form-widget-preview',
+       ),
+    );
+    // If not just updating preview, drupal is going to try and rebuild the
+    // which is not desired as it skips cache and breaks ajax.
+    if ($form_state['input']['op'] == t('Update Preview')) {
+      $form_state['executed'] = TRUE;
     }
+
+    // Autosubmit the form
+    ctools_add_js('auto-submit');
+    $form['#attributes']['class'][] = 'ctools-auto-submit-full-form';
   }
   
    /**
@@ -349,7 +353,7 @@ function panopoly_magic_form_alter(&$form, &$form_state, $form_id) {
     if (!empty($form['buttons']['return'])) {
       $form['buttons']['return']['#value'] = t('Save');
     }
-    $form['buttons']['#weight'] = (!empty($form['widget_preview']['#weight'])) ? ($form['widget_preview']['#weight'] +1 ): -99;
+    $form['buttons']['#weight'] = -99;
   }
 
   /**
@@ -404,6 +408,46 @@ function panopoly_magic_form_alter(&$form, &$form_state, $form_id) {
   }
 }
 
+
+/**
+ * Ajax callback that just returns the rendered preview.
+ */
+function panopoly_magic_ajax_update_preview($form, $form_state) {
+  if (isset($form_state['values']) && isset($form['#panopoly_magic_preview_info']['configuration'])) {
+    $form['#panopoly_magic_preview_info']['configuration'] = $form_state['values'] + $form['#panopoly_magic_preview_info']['configuration'];
+  }
+  return panopoly_magic_form_post_render_preview('', $form);
+}
+
+/**
+ * Add the preview to the form output.
+ *
+ * It is done here so the form is fully processed.
+ */
+function panopoly_magic_form_post_render_preview($output, $form) {
+  extract($form['#panopoly_magic_preview_info']);
+  $content = (empty($preview_subtype)) ? ctools_content_render($pane->type, $pane->subtype, $configuration, $keywords, $args, $context) : ctools_content_render($pane->type, $preview_subtype, $configuration, $keywords, $args, $context);
+
+  // Create the fieldset with appropriate content
+  $preview = array(
+    '#type' => 'fieldset',
+    '#title' => 'Preview',
+    '#attributes' => array(
+      'id' => 'panopoly-form-widget-preview',
+      'class' => array('widget-preview', 'widget-preview-single'),
+    ),
+    '#collapsible' => FALSE,
+    '#weight' => -100,
+  );
+  if (!empty($content)) {
+    $preview['preview']['#markup'] = (!empty($style['render pane'])) ? theme($style['render pane'], array('content' => $content, 'pane' => $pane, 'display' => $display, 'style' => $style, 'settings' => $pane->style['settings'])) : theme('panels_pane', array('content' => $content, 'pane' => $pane, 'display' => $display));
+  }
+  else {
+    $preview['preview']['#markup'] = t('[no preview]');
+  }
+  return drupal_render($preview) . $output;
+}
+
 /**
  * Recursively parse form elements to add special autosubmit handling on a per field-type basis.
  */
@@ -722,7 +766,6 @@ function panopoly_magic_form_views_content_views_panes_content_type_edit_form_al
 
   // Add a custom submit handler to our preview and submit option
   $form['#submit'][] = 'panopoly_magic_views_content_type_modal_submit';
-  $form['buttons']['preview']['#submit'][] = 'panopoly_magic_views_content_type_modal_submit';
 }
 
 /**
