diff --git a/salsa_advocacy/salsa_advocacy.module b/salsa_advocacy/salsa_advocacy.module
index 31b05ce..0c7033c 100644
--- a/salsa_advocacy/salsa_advocacy.module
+++ b/salsa_advocacy/salsa_advocacy.module
@@ -181,6 +181,21 @@ function salsa_advocacy_petition_form($form, &$form_state, $action) {
   }
   $action_content_detail = entity_load('salsa_action_content_detail', FALSE, array('action_content_KEY' => $action_content->action_content_KEY));
   $action_content_detail = reset($action_content_detail);
+
+  // Check if progress bar is enabled.
+  if (!empty($action->Signature_Goal) && $action->Signatures != 'Do not show signatures') {
+    // Add the progress bar.
+    salsa_entity_add_progress_bar(
+      $form_state,
+      salsa_advocacy_get_supporter_actions_total($action),
+      $action->Signature_Goal,
+      $form
+    );
+
+    // Set weight in order to display on top of supporter fieldset.
+    $form['progress']['#weight'] = -200;
+  }
+
   if ($action_content_detail->Recommended_Content) {
     // @todo For some reason petition content are highlighted on public page,
     // so I added the prefix and suffix, but it can be removed if there is no need.
@@ -344,6 +359,9 @@ function salsa_advocacy_petition_form_submit($form, &$form_state) {
   // Create a new one or update existing supporter.
   salsa_entity_supporter_fieldset_submit($form, $form_state);
 
+  // Clear the cached count of supporter actions on this action.
+  cache_clear_all('salsa_advocacy_supporter_action_count:' . $form_state['salsa_object']->action_KEY, 'cache');
+
   // Save comments, if any.
   if (!empty($form_state['values']['Comment'])) {
     $supporter_action_comment = new SalsaEntity(array(), 'salsa_supporter_action_comment');
@@ -409,6 +427,7 @@ function salsa_advocacy_petition_form_submit($form, &$form_state) {
  * Salsa targeted action form callback.
  */
 function salsa_advocacy_targeted_form($form, &$form_state, $action) {
+  $form_state['salsa_object'] = $action;
   $action_content = reset(entity_load('salsa_action_content', FALSE, array('action_KEY' => $action->action_KEY)));
   $action_content_detail = reset(entity_load('salsa_action_content_detail', FALSE, array('action_content_KEY' => $action_content->key)));
   $action_target = reset(entity_load('salsa_action_target', FALSE, array('action_KEY' => $action->action_KEY)));
@@ -504,6 +523,17 @@ function salsa_advocacy_targeted_form($form, &$form_state, $action) {
       }
     }
 
+    // Check if progress bar is enabled.
+    $field_key = variable_get('salsa_advocacy_targeted_goal_field');
+    if (!empty($action->{$field_key})) {
+      salsa_entity_add_progress_bar(
+        $form_state,
+        salsa_advocacy_get_supporter_actions_total($action),
+        $action->{$field_key},
+        $form
+      );
+    }
+
     // Action content fieldset.
     $form['action_content'] = array(
       '#type' => 'fieldset',
@@ -566,9 +596,6 @@ function salsa_advocacy_targeted_form($form, &$form_state, $action) {
     // Add hidden fields.
     salsa_advocacy_targeted_form_hidden_fields($form, $form_state);
 
-    // Submit this form directly to salsa page.
-    $form['#action'] = variable_get('salsa_api_url') . '/o/' . $action->organization_KEY . '/action/wrapperProcessAction2.jsp';
-
     // Submit button.
     $form['submit'] = array(
       '#type' => 'submit',
@@ -586,6 +613,39 @@ function salsa_advocacy_targeted_form($form, &$form_state, $action) {
 }
 
 /**
+ * Submit handler for the single target action form.
+ *
+ * Necessary to clear the cache for the supporter actions count and for the
+ * mollom captcha validation.
+ */
+function salsa_advocacy_targeted_form_submit($form, &$form_state) {
+  $action = $form_state['salsa_object'];
+  // Clear the cached count of supporter actions on this action.
+  cache_clear_all('salsa_advocacy_supporter_action_count:' . $action->action_KEY, 'cache');
+
+  // Eventually submit the data to the salsa page.
+  $salsa_url = variable_get('salsa_api_url') . '/o/' . $action->organization_KEY . '/action/wrapperProcessAction2.jsp';
+  // Get data from raw request body instead of using http_build_query() as
+  // fields with same names get missing that way.
+  $options = array(
+    'method' => 'POST',
+    'data' => file_get_contents('php://input'),
+    'headers' => array(
+      'Content-Type' => 'application/x-www-form-urlencoded',
+    ),
+  );
+  drupal_http_request($salsa_url, $options);
+
+  // Redirect the the configured uri or the frontpage otherwise.
+  if (!empty($action->redirect_path)) {
+    $form_state['redirect'] = $action->redirect_path;
+  }
+  else {
+    $form_state['redirect'] = '<front>';
+  }
+}
+
+/**
  * Hidden fields for targeted actions form.
  */
 function salsa_advocacy_targeted_form_hidden_fields(&$form, $form_state) {
@@ -1044,6 +1104,27 @@ function salsa_advocacy_fetch_action_targets($action_key) {
  *   A form array set for theming by theme_salsa_advocacy_settings_form()
  */
 function salsa_advocacy_settings_form($form, &$form_state) {
+  // Custom fields used as goal for progress bars on action forms.
+  $custom_fields = salsa_entity_custom_fields('action');
+  if (!empty($custom_fields)) {
+    $form['progress'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Progress bar'),
+    );
+
+    foreach ($custom_fields as $field_name => $field) {
+      $options[$field_name] = $field['label'];
+    }
+    $form['progress']['salsa_advocacy_targeted_goal_field'] = array(
+      '#type' => 'select',
+      '#title' => t('Salsa Advocacy Goal Field'),
+      '#description' => t('Salsa custom field that contains the submission goal for actions.'),
+      '#options' => $options,
+      '#default_value' => variable_get('salsa_advocacy_targeted_goal_field'),
+      '#empty_option' => t('- None -'),
+    );
+  }
+
   $form['items']['#tree'] = TRUE;
 
   // Fetch custom fields.
@@ -1152,19 +1233,49 @@ function theme_salsa_advocacy_settings_form($variables) {
  * Submit handler for advocacy settings form.
  */
 function salsa_advocacy_settings_form_submit($form, &$form_state) {
-  $custom_fields_settings = array();
-  foreach ($form_state['values']['items'] as $item) {
-    $custom_fields_settings[$item['name']] = array(
-      'weight' => $item['weight'],
-      'fixed_value' => $item['fixed'],
-      'default_value' => $item['default_value'],
-      'default_value_callback' => '',
-      'enabled' => $item['enabled'] ? TRUE : FALSE,
-    );
+  if (isset($form_state['values']['items'])) {
+    $custom_fields_settings = array();
+    foreach ($form_state['values']['items'] as $item) {
+      $custom_fields_settings[$item['name']] = array(
+        'weight' => $item['weight'],
+        'fixed_value' => $item['fixed'],
+        'default_value' => $item['default_value'],
+        'default_value_callback' => '',
+        'enabled' => $item['enabled'] ? TRUE : FALSE,
+      );
+    }
+    variable_set('salsa_advocacy_custom_fields', $custom_fields_settings);
   }
-  variable_set('salsa_advocacy_custom_fields', $custom_fields_settings);
+
+  // Set the field for the barometer goal targeted actions.
+  variable_set('salsa_advocacy_targeted_goal_field', $form_state['values']['salsa_advocacy_targeted_goal_field']);
+
   cache_clear_all('salsa_advocacy_mapping', 'cache');
   cache_clear_all('salsa_advocacy_filters', 'cache');
   cache_clear_all('salsa_advocacy_custom_fields', 'cache');
   drupal_set_message(t('Settings have been saved.'));
 }
+
+/**
+ * Retrieves the supporter action objects related to a given action.
+ *
+ * Caches the data that is fetched from Salsa if the count isn't cached yet,
+ * otherwise cached data is returned.
+ *
+ * @param object $action
+ *   The Salsa entity of type action.
+ *
+ * @return int
+ *   The amount ob supporter actions for the given action.
+ */
+function salsa_advocacy_get_supporter_actions_total($action) {
+  $cache = cache_get('salsa_advocacy_supporter_action_count:' . $action->action_KEY);
+  if (!$cache) {
+    $salsa_api = salsa_api();
+    $count = $salsa_api->getCount('supporter_action', array('action_KEY' => $action->action_KEY));
+    cache_set('salsa_advocacy_supporter_action_count:' . $action->action_KEY, $count);
+    return $count;
+  }
+
+  return $cache->data;
+}
diff --git a/salsa_donate_page/includes/salsa_donate_page.css b/salsa_donate_page/includes/salsa_donate_page.css
deleted file mode 100644
index 7ebcf7a..0000000
--- a/salsa_donate_page/includes/salsa_donate_page.css
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * @file
- * CSS style definitions for salsa donate page module.
- */
-
-.donate-page-barometer-progress {
-  background-color: #598EDE;
-  position: absolute;
-  height: 22px;
-}
-
-.donate-page-barometer {
-  background-color: #C3C3C3;
-  border: 1px solid #000;
-  width: 30%;
-  position: relative;
-  height: 22px;
-}
-
-.donate-page-donation-goal {
-  font-weight: bold;
-  margin-bottom: 10px;
-}
-
-.donate-page-barometer-label {
-  position: absolute;
-  height: 20px;
-  z-index: 1;
-  font-weight: bold;
-  padding: 2px 0px 2px 6px;
-}
-
-.donate-page-barometer-wrapper {
-  margin-bottom: 1em;
-}
\ No newline at end of file
diff --git a/salsa_donate_page/salsa_donate_page.module b/salsa_donate_page/salsa_donate_page.module
index 7e07ad4..c15f422 100644
--- a/salsa_donate_page/salsa_donate_page.module
+++ b/salsa_donate_page/salsa_donate_page.module
@@ -45,13 +45,6 @@ function salsa_donate_page_menu() {
  */
 function salsa_donate_page_theme() {
   return array(
-    'salsa_donate_page_progress_bar' => array(
-      'variables' => array(
-        'goal' => NULL,
-        'value' => NULL,
-        'total' => NULL,
-      ),
-    ),
     'salsa_donate_page_donors_list' => array(
       'variables' => array(
         'row_values' => array(),
@@ -85,6 +78,21 @@ function salsa_donate_page_mollom_form_info($form_id) {
 }
 
 /**
+ * Implements hook_salsa_entity_progress_bar_labels_alter().
+ *
+ * Add currencies to the amounts and change the labels of the donation progress
+ * bar.
+ */
+function salsa_donate_page_salsa_entity_progress_bar_labels_alter(&$labels, $form_id) {
+  if ($form_id == 'salsa_donate_page_form') {
+    $labels['goal'] = salsa_entity_get_amount($labels['goal'], TRUE);
+    $labels['total'] = salsa_entity_get_amount($labels['total'], TRUE);
+    $labels['goal_label'] = t('Donation goal:');
+    $labels['total_label'] = t('Donated:');
+  }
+}
+
+/**
  * Donate Page form.
  *
  * @todo State / Province should be dynamic.
@@ -110,11 +118,6 @@ function salsa_donate_page_form($form, &$form_state, $donate_page, $view_mode) {
         'data' => drupal_get_path('module', 'salsa_entity') . '/salsa_donate_page/js/salsa_donate_page.behaviors.js',
       ),
     ),
-    'css' => array(
-      array(
-        'data' => drupal_get_path('module', 'salsa_donate_page') . '/includes/salsa_donate_page.css'
-      ),
-    ),
   );
 
   // Add default required fields for a donation.
@@ -210,9 +213,15 @@ function salsa_donate_page_form($form, &$form_state, $donate_page, $view_mode) {
     '#title' => t('Donation Amount'),
   );
 
-  $form['Donation']['progress'] = array(
-    '#markup' => salsa_donate_page_get_barometer($donate_page),
-  );
+  $field_key = variable_get('salsa_donations_goal_field');
+  if (!empty($donate_page->{$field_key})) {
+    salsa_entity_add_progress_bar(
+      $form_state,
+      salsa_donate_page_total_donation_amount($donate_page->donate_page_KEY),
+      $donate_page->{$field_key},
+      $form
+    );
+  }
 
   if (variable_get('salsa_donations_donors_list_row_count', 0)) {
     $form['Donation']['donors_list'] = salsa_donate_page_get_donors_list($donate_page);
@@ -1014,20 +1023,6 @@ function salsa_donate_page_get_latest_donations($donate_page_key, $limit) {
 }
 
 /**
- * Theme function for the donation barometer.
- */
-function theme_salsa_donate_page_progress_bar($vars) {
-  $output =  '<div class="donate-page-barometer-wrapper">';
-  $output .=   '<div class="donate-page-donation-goal">' . t('Donation goal:') . '&nbsp;' . $vars['goal'] . '</div>';
-  $output .=   '<div class="donate-page-barometer">';
-  $output .=     '<span class="donate-page-barometer-label">' . t('Donated:') . '&nbsp;' . $vars['total'] . '</span>';
-  $output .=     '<div class="donate-page-barometer-progress" style="width:' . min($vars['value'], 100) . '%;"></div>';
-  $output .=   '</div>';
-  $output .= '</div>';
-  return $output;
-}
-
-/**
  * Theme function for the donors list.
  */
 function theme_salsa_donate_page_donors_list($vars) {
@@ -1064,31 +1059,6 @@ function theme_salsa_donate_page_donors_list($vars) {
 }
 
 /**
- * Wrapper function to get the markup of the barometer.
- *
- * @param object $donate_page
- *   The salsa donation object.
- *
- * @return string
- *   The markup of the barometer.
- */
-function salsa_donate_page_get_barometer($donate_page) {
-  $field_name = variable_get('salsa_donations_goal_field');
-  // Return an empty string if the goal isn't set.
-  if (empty($donate_page->{$field_name})) {
-    return '';
-  }
-  $total = salsa_donate_page_total_donation_amount($donate_page->donate_page_KEY);
-  $goal = $donate_page->{$field_name};
-  $value = (($total / $goal) < 1) ? ($total / $goal) : 1;
-  return theme('salsa_donate_page_progress_bar', array(
-    'goal' => salsa_entity_get_amount($goal, TRUE),
-    'value' => min(round($value * 100), 100),
-    'total' => salsa_entity_get_amount(salsa_donate_page_total_donation_amount($donate_page->donate_page_KEY), TRUE),
-  ));
-}
-
-/**
  * Wrapper that prints the markup for the donors list.
  *
  * @param object $donate_page
diff --git a/salsa_entity.api.php b/salsa_entity.api.php
index bbec6ae..dbeb17e 100644
--- a/salsa_entity.api.php
+++ b/salsa_entity.api.php
@@ -145,3 +145,20 @@ function hook_salsa_query_TAG_alter(array &$conditions, EntityFieldQuery $query)
   // Define a different order field, prepend - for descending order.
   $conditions['#order'] = array('-field_name_2');
 }
+
+/**
+ * Alter the labels that are displayed within the progress bar.
+ *
+ * @param int $goal
+ *   The number representing the total width of the progress bar.
+ * @param int $form_id
+ *   The form id (form function name) of the form that adds the progress bar.
+ */
+function hook_salsa_entity_progress_bar_labels_alter(&$labels, $form_id) {
+  if ($form_id == 'salsa_donate_page_form') {
+    $labels['goal'] = salsa_entity_get_amount($labels['goal'], TRUE);
+    $labels['total'] = salsa_entity_get_amount($labels['total'], TRUE);
+    $labels['goal_label'] = t('Donation goal:');
+    $labels['total_label'] = t('Donated:');
+  }
+}
diff --git a/salsa_entity.module b/salsa_entity.module
index 8f39734..d671661 100644
--- a/salsa_entity.module
+++ b/salsa_entity.module
@@ -66,10 +66,46 @@ function salsa_entity_theme() {
         'title' => NULL,
       ),
     ),
+    'salsa_entity_progress_bar' => array(
+      'variables' => array(
+        'goal' => NULL,
+        'value' => NULL,
+        'total' => NULL,
+        'goal_label' => NULL,
+        'total_label' => NULL,
+        'barometer_type' => NULL,
+        'entity_id' => NULL,
+      ),
+    ),
   );
 }
 
 /**
+ * Implements hook_library().
+ */
+function salsa_entity_library() {
+  // Library with required JS and CSS for the progress bar.
+  $libraries['progress_bar'] = array(
+    'title' => 'Salsa entity progress bar library',
+    'version' => '1.0',
+    'js' => array(
+      drupal_get_path('module', 'salsa_entity') . '/theme/salsa_entity.js' => array(),
+    ),
+    'css' => array(
+      drupal_get_path('module', 'salsa_entity') . '/theme/salsa_progress_bar.css' => array(
+        'type' => 'file',
+        'media' => 'screen',
+      ),
+    ),
+    'dependencies' => array(
+      // Require jQuery UI core by System module.
+      array('system', 'ui.progressbar'),
+    ),
+  );
+  return $libraries;
+}
+
+/**
  * Implements hook_form_FORM_ID_alter() for salsa_api_system_settings().
  */
 function salsa_entity_form_salsa_api_system_settings_alter(&$form, &$form_state) {
@@ -95,6 +131,19 @@ function salsa_entity_form_salsa_api_system_settings_alter(&$form, &$form_state)
       'salsa_entity_submit_clear_describe_cache',
     ),
   );
+
+  $form['salsa_entity_settings'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Common settings'),
+  );
+
+  $form['salsa_entity_settings']['salsa_entity_progress_bar_animation'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Progress bar animation'),
+    '#description' => t('If enabled, progress bars on donate pages, single target and petition action forms will get animated with a load effect on page load.'),
+    '#default_value' => variable_get('salsa_entity_progress_bar_animation', FALSE),
+  );
+
   return $form;
 }
 
@@ -825,6 +874,88 @@ function salsa_entity_filter_info() {
 }
 
 /**
+ * Creates the markup of the barometer.
+ *
+ * Also adds the corresponding CSS to the form and gives other modules a chance
+ * to alter the labels that will be used.
+ *
+ * @param array $form_state
+ *   The form state of the requesting form which also contains the salsa entity
+ *   object among other useful stuff.
+ * @param int $total
+ *   Counted amount for the current progress.
+ * @param string $goal_field_key
+ *   Key for the property on the salsa object that contains the goal amount.
+ * @param array $form
+ *   The form on which the progress bar will be displayed, passed by reference.
+ *
+ * @return string
+ *   The markup for the barometer.
+ */
+function salsa_entity_add_progress_bar($form_state, $total, $goal, &$container) {
+  // Don't allow rendering of progress bar without values that make sense.
+  if (!$total && !$goal) {
+    return '';
+  }
+
+  // Calculate the percentage of the total for the styling of the progress bar.
+  $value = (($total / $goal) < 1) ? ($total / $goal) : 1;
+  $form_id = $form_state['build_info']['form_id'];
+  $entity_id = $form_state['build_info']['args'][0]->key;
+
+  // Give other modules a chance to alter the labels.
+  $labels = array(
+    'goal' => $goal,
+    'total' =>  $total,
+    'goal_label' => t('Goal', array(), array('context' => $form_id)),
+    'total_label' => t('Total', array(), array('context' => $form_id)),
+  );
+  drupal_alter('salsa_entity_progress_bar_labels', $labels, $form_id);
+
+  if (variable_get('salsa_entity_progress_bar_animation', FALSE)) {
+    // Add the progress bar css, js and jq library to the requesting form.
+    $container['#attached']['library'][] = array('salsa_entity', 'progress_bar');
+    // Add settings that will be used by the JS that adds the load effect to the
+    // progress bar.
+    $js_settings = array(
+      'entity_id' => $entity_id,
+      'total_label' => $labels['total_label'],
+      'total' => $labels['total'],
+      'goal' => $labels['goal'],
+      'total_string' => variable_get('salsa_entity_progress_bar_total_string', '@total_label @total'),
+      'total_args' => variable_get('salsa_entity_progress_bar_total_replacements', array(
+        '@total_label' => $labels['total_label'],
+        '@total' => $labels['total'],
+      )),
+      'animation_speed' => variable_get('salsa_entity_progress_bar_animation_speed', 50),
+    );
+    $container['#attached']['js'][] = array(
+      'data' => array('salsaEntityProgressBar' => array($js_settings)),
+      'type' => 'setting',
+    );
+  }
+  else {
+    // Animation is disabled, add only CSS to the form.
+    $container['#attached']['css'] = array(
+      drupal_get_path('module', 'salsa_entity') . '/theme/salsa_progress_bar.css'
+    );
+  }
+
+  // Theme the progress bar with the collected values and add it to the form.
+  $container['progress'] = array(
+    '#markup' => theme('salsa_entity_progress_bar', array(
+      'goal' => $labels['goal'],
+      'goal_label' => $labels['goal_label'],
+      'total' => $labels['total'],
+      'total_label' => $labels['total_label'],
+      'value' => min(round($value * 100), 100),
+      'barometer_type' => $form_id,
+      'entity_id' => $entity_id,
+    )),
+  );
+}
+
+/**
  * Filter process callback to render an entity.
  */
 function _salsa_entity_filter_entity_view($text, $filter, $format, $langcode, $cache, $cache_id) {
@@ -853,3 +984,17 @@ function _salsa_entity_filter_replace_callback($matches) {
     }
   }
 }
+
+/**
+ * Theme function for the progress barometer.
+ */
+function theme_salsa_entity_progress_bar($vars) {
+  $output =  '<div class="salsa-barometer-wrapper salsa-entity-' . $vars['entity_id'] . '">';
+  $output .=   '<div class="salsa-barometer-goal">' . $vars['goal_label'] . '&nbsp;' . $vars['goal'] . '</div>';
+  $output .=   '<div class="salsa-barometer">';
+  $output .=     '<span class="salsa-barometer-label">' . $vars['total_label'] . '&nbsp;' . $vars['total'] . '</span>';
+  $output .=     '<div class="salsa-barometer-progress" style="width:' . min($vars['value'], 100) . '%;"></div>';
+  $output .=   '</div>';
+  $output .= '</div>';
+  return $output;
+}
diff --git a/salsa_my_donate_page/salsa_my_donate_page.module b/salsa_my_donate_page/salsa_my_donate_page.module
index a124b15..e5142e1 100644
--- a/salsa_my_donate_page/salsa_my_donate_page.module
+++ b/salsa_my_donate_page/salsa_my_donate_page.module
@@ -617,7 +617,7 @@ function salsa_my_donate_page_form($form, &$form_state, $supporter_my_donate_pag
   );
 
   $form['progress']['progressbar'] = array(
-    '#theme' => 'salsa_donate_page_progress_bar',
+    '#theme' => 'salsa_entity_progress_bar',
     '#goal' => salsa_entity_get_amount($total, TRUE),
     '#total' => salsa_entity_get_amount($current, TRUE),
     '#value' => $percent,
diff --git a/theme/salsa_entity.js b/theme/salsa_entity.js
new file mode 100644
index 0000000..85b6a83
--- /dev/null
+++ b/theme/salsa_entity.js
@@ -0,0 +1,68 @@
+/**
+ * @file
+ * JS Behaviors for the salsa entity module.
+ */
+(function($) {
+  Drupal.behaviors.salsaEntityProgressBar = {
+    attach: function(context, settings) {
+      var progress_conf = Drupal.settings.salsaEntityProgressBar;
+      for (var i = 0; i < progress_conf.length; i++) {
+        var config = progress_conf[i];
+        var $wrapper = $('.salsa-entity-' + config['entity_id']);
+        var $progress_bar = $wrapper.find('.salsa-barometer');
+        var $label = $wrapper.find('.salsa-barometer-label');
+        var $progress_indicator = $wrapper.find('.salsa-barometer-progress');
+
+        $progress_bar.progressbar({
+          value: false,
+          change: function() {
+            $label.text($progress_bar.progressbar( "value" ) + "%");
+          }
+        });
+
+        var current_progress_percentage = parseNumericValue(config['total'])/parseNumericValue(config['goal']) * 100;
+        setTimeout(progress, config['animation_speed']);
+
+        /**
+         * Increases value and width of the progress bar.
+         *
+         * Calls itself after some timeout until the maximum value is reached.
+         */
+        function progress() {
+          var val = $progress_bar.progressbar( "value" ) || 0;
+          // Increase the value for 1% point.
+          $progress_bar.progressbar("value", ++val);
+          $progress_indicator.css('width', val + "%");
+
+          if (val < current_progress_percentage) {
+            setTimeout(progress, config['animation_speed']);
+          }
+          else {
+            // Display label that was set on the server.
+            $label.text(Drupal.formatString(config['total_string'], config['total_args']));
+          }
+        }
+
+        /**
+         * Replaces certain string parts.
+         *
+         * If those aren't replaced, parseInt might fail to parse certain
+         * numeric values.
+         *
+         * @param string value
+         *   String value to parse from.
+         *
+         * @return Integer
+         *   The parsed integer.
+         */
+        function parseNumericValue (value) {
+          value = value.replace(",", "");
+          value = value.replace("'", '');
+          value = value.replace("`", '');
+          value = value.replace("$", '');
+          return parseInt(value);
+        }
+      }
+    }
+  }
+}(jQuery));
diff --git a/theme/salsa_progress_bar.css b/theme/salsa_progress_bar.css
new file mode 100644
index 0000000..b676ef7
--- /dev/null
+++ b/theme/salsa_progress_bar.css
@@ -0,0 +1,35 @@
+/**
+ * @file
+ * CSS style definitions for salsa barometer/progress bar.
+ */
+
+.salsa-barometer-progress {
+  background-color: #598EDE;
+  position: absolute;
+  height: 22px;
+}
+
+.salsa-barometer {
+  background-color: #C3C3C3;
+  border: 1px solid #000;
+  width: 30%;
+  position: relative;
+  height: 22px;
+}
+
+.salsa-donation-goal {
+  font-weight: bold;
+  margin-bottom: 10px;
+}
+
+.salsa-barometer-label {
+  position: absolute;
+  height: 20px;
+  z-index: 1;
+  font-weight: bold;
+  padding: 2px 0px 2px 6px;
+}
+
+.salsa-barometer-wrapper {
+  margin-bottom: 1em;
+}
