drupal_add_js and form caching

We encourage users to post events happening in the community to the community events group on https://www.drupal.org.
BWPanda's picture

I have some jQuery code that acts on the core search form for my site (it hides the default text ('Search...') when you click/focus on the search field and shows it again (on blur) if you leave it blank). This code is in an external .js file. I have added this file to my site (using drupal_add_js) by placing it in my site's implementation of hook_form_FORM_ID_alter.

However, it seems form caching is causing problems with this - when I flush all caches the jQuery works fine, but when I reload or go to a new page, it stops working.
How do you make the jQuery code run on each page the form is located on, regardless of caching?

Comments

Send js from theme layer

markus_petrux's picture

One method to do so is using a #pre_render callback in the $form.

<?php
function ...

 
// Let's say this is part of your hook_form_alter() stuff.
 
$form['#pre_render'][] = 'mymodule_search_form_pre_render';
}

function
mymodule_search_form_pre_render($form) {
 
drupal_add_js(...);
  return
$form;
}
?>

Still not working

BWPanda's picture

Hmm, still not working... (work on initial page load, but not subsequent ones; same as before)

BTW, I got confused - it's not the core search form I'm editing, it's a contrib module's own search form (in case that matters).

Here's my module code:

<?php
/<strong>
*
Implementation of hook_form_FORM_ID_alter().
*/
function
bwpanda_form_search_by_page_form_alter(&$form, &$form_state) {
 
// Reconfigure Search By Page form
 
$form['keys']['#size'] = 15;
 
$form['keys']['#default_value'] = 'Search...';
 
$form['keys']['#prefix'] = '<div class="clear-block">';
 
$form['submit']['#type'] = 'image_button';
 
$form['submit']['#src'] = 'sites/panda.id.au/themes/panda/images/search.png';
 
$form['submit']['#name'] = 'op';
 
$form['submit']['#suffix'] = '</div>';
 
$form['#pre_render'][] = 'bwpanda_search_by_page_js';
}

/</
strong>
*
Pre-render function for bwpanda_form_search_by_page_form_alter().
*/
function
bwpanda_search_by_page_js($form) {
 
// Add javascript
 
drupal_add_js(drupal_get_path('module', 'bwpanda') .'/search-by-page.js', 'module');

  return
$form;
}
?>

And in case I've done something wrong in my jQuery, here's the javascript code:

Drupal.behaviors.pandaSearchByPage = function(context) {

  var searchBox = '.search-by-page-form .form-item input.form-text';
  var text = 'Search...';

  $(searchBox).focus(function() {
    if ($(this).val() == text) {
      $(this).val('');
    }
  });

  $(searchBox).blur(function() {
    if ($(this).val() == '') {
      $(this).val(text);
    }
  });

};

Have you found a solution? :)

heliosabc's picture

Have you found a solution? :)

Assuming the solution is to

ezra-g's picture

Assuming the solution is to disable caching you might try adding, at the top of your form function:

$_SERVER['REQUEST_METHOD'] = 'post';
$GLOBALS['config']['cache'] = FALSE;

to disable caching. You can see an example of this in the uc_signup module which disables caching so that this form can be generated uniquely even for anonymous users.

Didn't work either...

BWPanda's picture

I added

<?php
// Disable caching so jQuery runs properly
$GLOBALS['config']['cache'] = FALSE;
?>
to the top of my hook_form_FORM_ID_alter implementation, but it doesn't seem to have done anything - Works after clearing cache, but when going to a different page, it stops working.

I then tried adding

<?php
$_SERVER
['REQUEST_METHOD'] = 'post';
?>
as well, but that just replaced the form with the Development menu...

BTW, this issue can be seen on my site: http://panda.id.au (it's the search form on the right).

Block caching enabled?

markus_petrux's picture

If this is a custom block, then you may need to tell Drupal to not cache this one. Look at how search_block() uses the BLOCK_NO_CACHE constant.

The search_by_page module

BWPanda's picture

The search_by_page module doesn't specify a cache value, so uses the default BLOCK_CACHE_PER_ROLE. I added 'cache' => BLOCK_NO_CACHE, to the module, but upon saving and flushing all caches, the problem persists!

Is someone able to test my site to make sure it's not just me?
What am I doing wrong?

Bump

BWPanda's picture

I'm currently working on two three projects that need this solution, so any and all help would be much appreciated!

Drupal 7!

RobLoach's picture

<?php
/**
* Implementation of hook_form_FORM_ID_alter().
*/
function bwpanda_form_search_by_page_form_alter(&$form, &$form_state) {
 
// Reconfigure Search By Page form
 
$form['keys']['#size'] = 15;
 
$form['keys']['#default_value'] = 'Search...';
 
$form['keys']['#prefix'] = '<div class="clear-block">';
 
$form['submit']['#type'] = 'image_button';
 
$form['submit']['#src'] = 'sites/panda.id.au/themes/panda/images/search.png';
 
$form['submit']['#name'] = 'op';
 
$form['submit']['#suffix'] = '</div>';
 
$form['#attached']['js'][drupal_get_path('module', 'bwpanda') .'/search-by-page.js'] = array();
}
?>

I'm guessing that doesn't

BWPanda's picture

I'm guessing that doesn't work for Drupal 6 then...?

Still struggling with this.

How about a low tech

hershel's picture

How about a low tech solution? Include the JS file using hook_init() and then find a way to make sure it only executes when you want it to, by using a unique id for the form (or for an element in the form) or the block. Or set your theme to set a class or id in the BODY tag based on the URL and then check that. Or even parse the URL in JS.

Just some ideas. Including the JS for all pages should store it in the cache anyway and that sounds like the main issue.

--
CiviHosting -- Drupal and CiviCRM Hosting Specialists -- 100% Satisfaction Guaranteed

BWPanda Module

RobLoach's picture

Since this is the "bwpanda" module, I'm sure just sticking it in a global bwpanda.js wouldn't be a problem.

hmdnawaz's picture

I want to add facebook like button through drupal_add_js().
I wrote the following code but it did not work

<?php
drupal_add_js
('<script src="http://connect.facebook.net/en_US/all.js#xfbml=1"></script>', 'inline');
?>

This returns nothing.
I then wrote this code

<?php
drupal_set_html_head
('<script src="http://connect.facebook.net/en_US/all.js#xfbml=1"></script><fb:like show_faces="true" width="450"></fb:like>');
?>

It works fine but the button appear at the top of the page and i want it to display with content. It would appear at the top because of the head funciton.

Any one who can help me.

I've got the exact same

heliosabc's picture

I've got the exact same problem, when I clear the cache it works great, but when I reload the page it doesn't work anymore. Have you found a solution?