Thursday 24 February 2011

Drupal 6 - Webforms: Loading GIF on Submit

If you have a slow mail server, then submitting webforms can sometimes appear to do nothing for a while. For me, this is anywhere between 2 and 8 seconds, but I have read about a lot of other people in similar situations. While the problem is with the mail server, sometimes there's nothing that can be done about this, and a simple solution to keep the user calm is to add a little loading animation. No Ajax involved: the GIF is simply shown when the user clicks submit, and then after the wait, they will be taken to the success page.

1) Grab the right GIF animation from this amazing site: http://ajaxload.info/ and put it here: /sites/all/images/loading.gif

2) The CSS: make it so that the GIF is used when a certain class is applied to an input element
input.form-submit.loading-gif {
 background: url('/sites/all/images/loading.gif') 50% 1px no-repeat;
}

3) The jQuery script: in your theme dir, create js/submit-loading.js which will apply the CSS class to the submit button when it is clicked
$(document).ready(function()
{
    // preload image
    (new Image()).src = "/sites/all/images/loading.gif";
    
    $(".webform-client-form").submit(function() {
        // select the button
        var $button = $(this).find("#edit-submit");
        // remove the text, but persist the width of the button
        var $buttonWidth = $button.outerWidth();
        $button.attr('value', '').width($buttonWidth);
        // display the loading gif and disable the button
        $button.addClass("loading-gif").attr('disabled','disabled');
    });
});

4) Add the script only to the right page with a bit of PHP in your theme's template.php. See #2 in my article: Different ways of adding JavaScript to a page

Tuesday 22 February 2011

PHP Logging on Ubuntu 10.04 Lucid

PHP CONFIGURATION
Enable PHP logging by setting up the appropriate variables in your php.ini. If you don't know where your php.ini file is, try the command: locate php.ini, mine was here: /etc/php5/apache2/php.ini:
error_reporting = E_ALL & ~E_DEPRECATED
log_errors = On
error_log = /var/log/apache2/php_errors.log
EXTRA: if you want to show PHP errors on screen, set:
display_errors = On
To finish, we restart apache: sudo /etc/init.d/apache2 restart


PERMISSIONS
Then find out what your apache user is called: ps aux | grep apache (mine was www-data), and ensure that user has full permissions on the log file directory (/var/log/apache2/). The best way to do this is ensure the user has group access i.e. either add the user the group currently assigned to the directory, or change the directory's group to one that the user is in! On my system, the directory had the group: adm, and so I added www-data to that group (see /etc/group). You then need to give the directory full permissions for group access: sudo chmod 770 /var/log/apache2/

To register these changes, we need to log out and back in again.


TESTING
An easy way to generate a PHP error is to call an undefined function i.e. put this PHP code into one of your pages:
a_function_that_doesnt_exist();
Now when you visit that page, you will either get a PHP error on screen (if you enabled that), or your browser will just display a 403 error, but importantly, your new log file php_errors.log should have been created and had it's first error logged.


INLINE PHP CONFIGURATION
One other method worth noting is inline configuration. During development, you may decide you want to temporarily enable showing errors on the screen for a particular page. The easiest way to do this, is simply to add this line of PHP to the top of your PHP file:
ini_set('display_errors', TRUE);

Wednesday 2 February 2011

Drupal 6: Different ways of adding JavaScript to a page

REMEMBER
  • Always use drupal_add_js() as this lets Drupal handle it i.e. preprocess/cache it.
  • All of the examples assume your JS is in a script file, but you can also include an "inline" script by sending it as a string for the first argument, and setting the second to "inline" e.g. drupal_add_js('alert("Hello!")', 'inline');
  • If your script is in your theme directory, you can use path_to_theme() and then the relative path from there (with a preceding slash) e.g. path_to_theme().'/js/myscript.js'

1) Add a script to all pages
a) using template.php
drupal_add_js('sites/all/scripts/tweaks.js');
b) using your theme's .info file (the script needs to be somewhere within your theme directory)
scripts[] = script.js

2) Add a script to page(s) with a specific URL / URL pattern using template.php (the following will only add the script on site.com/my/page)
NOTE: if you are using URL aliases, you need to know the un-aliased version for this (see site.com/admin/build/path)
function mytheme_preprocess_page(&$vars) {
  if (arg(0) == 'my' && arg(1) == 'page' && arg(2) == null) {
    drupal_add_js(path_to_theme().'/js/myscript.js');
    $vars['scripts'] = drupal_get_js();
  }
}
OR use the following condition to add it to any pages that start with the URL site.com/my/page e.g. /my/page/1, /my/page/2, /my/page/2/edit etc.
if (arg(0) == 'my' && arg(1) == 'page') {...}
OR use the node ID
if (isset($vars['node']) && $vars['node']->nid == 23) {...}
OR apply to all nodes of a specific content type
if (isset($vars['node']) && $vars['node']->type == 'book') {...}

3) Add a script to a specific page by editing the page in Drupal, and setting the input format to "PHP code"
drupal_add_js('sites/all/scripts/tweaks.js');

4) Add a script to a block, which you can then setup to be included in a specific page or set of pages
drupal_add_js('sites/all/scripts/tweaks.js');


Also note that it is very similar to add stylesheets to pages. The function is drupal_get_css().


REFERENCES
http://drupal.org/node/304178
http://api.drupal.org/api/drupal/includes--common.inc/function/drupal_add_js/6
http://stackoverflow.com/questions/61735/include-css-or-javascript-file-for-specific-node-in-drupal-6