Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save thelebster/2924c773208aec180e02 to your computer and use it in GitHub Desktop.

Select an option

Save thelebster/2924c773208aec180e02 to your computer and use it in GitHub Desktop.
Drupal 7 Views - fix ajax attached to exposed filters #cimpleodev #drupal #views

Ajax call does not trigger the callback function. This is related to the fact that the Views uses $_GET, and ajax uses $_POST.

Issue: https://www.drupal.org/node/1183418

Possible error message: "Invalid form POST data"

diff --git a/js/exposed-form-ajax.js b/js/exposed-form-ajax.js
new file mode 100644
index 0000000..d568458
--- /dev/null
+++ b/js/exposed-form-ajax.js
@@ -0,0 +1,24 @@
+/**
+ * @file
+ * Handles Views' exposed form AJAX data submission.
+ */
+(function ($) {
+
+ /*
+ * Gets Form build info from settings and adds it to ajax data.
+ *
+ * @see views_exposed_form_ajax_enable().
+ */
+ Drupal.behaviors.ViewsExposedFormAjax = {
+ attach: function(context, settings) {
+ for (var ajaxObject in Drupal.ajax) {
+ for(var name in Drupal.settings.ViewsExposedFormInfo) {
+ if (Drupal.ajax[ajaxObject].options && Drupal.ajax[ajaxObject].options.data._triggering_element_name == name) {
+ jQuery.extend(Drupal.ajax[ajaxObject].options.data, Drupal.settings.ViewsExposedFormInfo[name]);
+ }
+ }
+ }
+ }
+ };
+
+})(jQuery);
diff --git a/views.module b/views.module
index fc427f4..8b33acf 100644
--- a/views.module
+++ b/views.module
@@ -2025,6 +2025,83 @@ function views_form_views_exposed_form_alter(&$form, &$form_state) {
$form['form_build_id']['#access'] = FALSE;
$form['form_token']['#access'] = FALSE;
$form['form_id']['#access'] = FALSE;
+ // AJAX behaviors need these data, so we add it back in #after_build.
+ $form['#after_build'][] = 'views_exposed_form_ajax_enable';
+}
+
+/**
+ * Checks whether the exposed form will use ajax and passes required
+ * form information removed in views_form_views_exposed_form_alter().
+ */
+function views_exposed_form_ajax_enable(&$form, &$form_state) {
+ // In order for Ajax to work, we need the form build info. Here we
+ // check if #ajax has been added to any form elements, and if so,
+ // pass this info as settings via Javascript, which get attached to
+ // the submitted form on Ajax form submissions.
+ // #ajax property can be set not only for the first level of the form,
+ // so we look for it in the whole form.
+ $ajax_info = array();
+ $ajax_elements = views_exposed_form_ajax_lookup_recursive($form);
+ // Determine if form is being processed.
+ $triggering_element_name = '';
+ if (!empty($form_state['input']['_triggering_element_name'])) {
+ $triggering_element_name = $form_state['input']['_triggering_element_name'];
+ }
+ // When we have multiple elements with #ajax set on exposed form
+ // we need to pass only triggering element name to Javascript.
+ // Otherwise #ajax will work only for the first element.
+ if (!empty($triggering_element_name) && !empty($ajax_elements)) {
+ // Check if element has #ajax property set.
+ if (in_array($triggering_element_name, $ajax_elements)) {
+ $ajax_elements = array(
+ $triggering_element_name => $triggering_element_name,
+ );
+ }
+ else {
+ $ajax_elements = array();
+ }
+ }
+ if (!empty($ajax_elements)) {
+ $form_info = array(
+ 'form_id' => $form['#form_id'],
+ 'form_build_id' => $form['#build_id'],
+ );
+ // Anonymous users don't get a token.
+ if (!empty($form['#token'])) {
+ $form_info['form_token'] = $form['#token'];
+ }
+ foreach ($ajax_elements as $element_name) {
+ $ajax_info[$element_name] = $form_info;
+ }
+ drupal_add_js(array('ViewsExposedFormInfo' => $ajax_info), 'setting');
+
+ // Add the javascript behavior that will handle this data.
+ $form['#attached']['js'][] = array(
+ 'weight' => 100,
+ 'data' => drupal_get_path('module', 'views') . '/js/exposed-form-ajax.js',
+ );
+ }
+ return $form;
+}
+
+/**
+ * Recursively looks for the #ajax property for every form elemet.
+ * @param $elements
+ * The element array to look for #ajax property.
+ *
+ * @return
+ * Array of the elements names where #ajax was found.
+ */
+function views_exposed_form_ajax_lookup_recursive($elements) {
+ $ajax_elements = array();
+ foreach (element_children($elements) as $key) {
+ if (!empty($elements[$key]['#name']) && !empty($elements[$key]['#ajax'])) {
+ $ajax_elements[$elements[$key]['#name']] = $elements[$key]['#name'];
+ }
+ // Recursive call to look for #ajax in element's childrens.
+ $ajax_elements += views_exposed_form_ajax_lookup_recursive($elements[$key]);
+ }
+ return $ajax_elements;
}
/**ьв
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment