diff --git a/gmap3_tools.inc b/gmap3_tools.inc
index e1c7d8a..93664d5 100644
--- a/gmap3_tools.inc
+++ b/gmap3_tools.inc
@@ -54,7 +54,71 @@ define('GMAP3_TOOLS_DEFAULT_MARKERS_POSITION_CENTER_ZOOM', 'center zoom');
  */
 function gmap3_tools_add_map($options) {
   static $init = FALSE;
+  if (!$init) {
+    $init = TRUE;
+    drupal_add_js(gmap3_tools_get_library_url(), 'external', array('scope' => 'footer'));
+    drupal_add_js(drupal_get_path('module', 'gmap3_tools') . '/gmap3_tools.js', array('scope' => 'footer'));
+  }
+
+  // Merge custom map options with defaults.
+  $options = gmap3_tools_get_options($options);
+
+  // Add map configuration options to js.
+  drupal_add_js(array('gmap3_tools' => array('maps' => array($options))), 'setting');
+}
+
+/**
+ * Attaches the JS to a given form using '#attached'.
+ *
+ * @param array $options
+ *   Gmap configuration array. Check $defaults array for list of all supported
+ *   options.
+ * @param array $form
+ *   The form the JS gets attached to.
+ */
+function gmap3_tools_attach_js($options, &$form) {
+  if (!is_array($form)) {
+    return;
+  }
+
+  static $init = FALSE;
+  if (!$init) {
+    $init = TRUE;
+    // Add JS using the #attached property in order to prevent breaking on
+    // validation errors
+    $form['#attached']['js'] = array(
+      array(
+        'data' => gmap3_tools_get_library_url(),
+        'type' => 'external',
+      ),
+      array(
+        'data' => drupal_get_path('module', 'gmap3_tools') . '/gmap3_tools.js',
+        'scope' => 'footer',
+      ),
+    );
+  }
 
+  // Merge custom map options with defaults.
+  $options = gmap3_tools_get_options($options);
+
+  // Add map configuration options to js.
+  $form['#attached']['js'][] = array(
+    'data' => array(
+      'gmap3_tools' => array(
+        'maps' => array($options)
+      ),
+    ),
+    'type' => 'setting',
+  );
+}
+
+/**
+ * Returns the default JS settings for the map.
+ *
+ * @return array
+ *   The default JS settings.
+ */
+function gmap3_tools_get_options($options) {
   static $defaults = array(
     // Map html element id.
     'mapId' => NULL,
@@ -116,24 +180,23 @@ function gmap3_tools_add_map($options) {
     ),
   );
 
-  if (!$init) {
-    $init = TRUE;
-    // Visit https://code.google.com/apis/console and generate new api key if
-    // you need it.
-    $lib_url = '//maps.googleapis.com/maps/api/js?&sensor=false';
-    if ($api_key = variable_get('gmap3_tools_api_key', NULL)) {
-      $lib_url .= '&key=' . $api_key;
-    }
-    drupal_add_js($lib_url, 'external', array('scope' => 'footer'));
+  return gmap3_tools_array_union_recursive($defaults, $options);;
+}
 
-    drupal_add_js(drupal_get_path('module', 'gmap3_tools') . '/gmap3_tools.js', array('scope' => 'footer'));
+/**
+ * Getter for the google maps JS library.
+ *
+ * @return string
+ *   The library including API key, if one is set.
+ */
+function gmap3_tools_get_library_url() {
+  // Visit https://code.google.com/apis/console and generate new api key if
+  // you need it.
+  $lib_url = '//maps.googleapis.com/maps/api/js?&sensor=false';
+  if ($api_key = variable_get('gmap3_tools_api_key', NULL)) {
+    $lib_url .= '&key=' . $api_key;
   }
-
-  // Merge custom map options with defaults.
-  $options = gmap3_tools_array_union_recursive($defaults, $options);
-
-  // Add map configuration options to js.
-  drupal_add_js(array('gmap3_tools' => array('maps' => array($options))), 'setting');
+  return $lib_url;
 }
 
 /**
