background image

Content tagged with: javascript

Eric's picture

In this tutorial, I'll show a way to pass PHP/Drupal variables to javascript using drupal_add_js(), and a way you can debug javascript variables using the FireBug console.

I'll start by creating a hook_menu() implementation to establish a page callback:

<?php
function helper_menu() {

 
$items = array();
 
 
$items['js-vars'] = array(
   
'title' => t('Javascript Variables'),
   
'description' => t('Javascript Variables'),
   
'page callback' => 'helper_page_callback_js_vars',
   
'access arguments' => array('access content'),
   
'type' => MENU_CALLBACK,   
  );
 
  return
$items;

}
?>

Next, I'll define the page callback:

<?php
function helper_page_callback_js_vars() {

 
// include module javascript file
 
drupal_add_js(drupal_get_path('module','helper') . '/js/helper.js');

 
// define variables you'd like to pass to the DOM
 
$js_vars = array(
   
'js_vars' => array(
     
'message' => t('Hello @username', array('@username' => $GLOBALS['user']->name)),
     
'an_array' => array(
       
'color' => t('red'),
       
'name' => t('Eric'),
      ),
    ),
  );
 
 
// pass variables to javascript
 
drupal_add_js($js_vars, 'setting');
 
 
// generate some page output
 
return "TEST";

}
?>

And here is the contents of the javascript include file I stuck in my module directory:

$(document).ready(function(){

  // debug variables directly in FireBug
  console.debug(Drupal.settings.js_vars);
 
  // popup mesage passed from Drupal
  alert(Drupal.settings.js_vars.message);
 
});

When viewing this page in a browser, you'll see the following. The javascript popup window is using variables passed directly from a Drupal/PHP array:
javascript popup

The console.debug() javascript method was used to send data directly to the FireBug console. If you open FireBug, you'll see the following:
FireBug Console

If you click on the Object shown, you can drill into the variables further:
FireBug Console

Eric's picture

I recently implemented the Panels module to create a page layout with 3 columns. I added background images to the columns, repeating on the y axis to span the entire length of the column. The problem I encountered: you cannot predict how tall the content will be in your columns and they will be staggered. To provide a more uniform styling, I added some jQuery to find the tallest column and set the shorter ones to the max height.

$(document).ready(function(){

  // keep track of the tallest column
  var tallest = 0;

  // loop through columns and find the tallest
  $('#panel_other_programs .panel-panel').each(function(){
    if ( $(this).outerHeight(true) > tallest )
      tallest = $(this).outerHeight(true);
  });

  // loop through columns and adjust height as necessary
  $('#MY-PANEL-UNIQUE-IDENTIFIER .panel-panel').each(function(){
   
    // check if current column needs to be adjusted
    if ( $(this).outerHeight(true) < tallest ) {
      // set new height
      $(this).height( tallest );
    }
  });

});

Now, all the columns should have a uniform height and the backgrounds should all span the entire length of each column.

Eric's picture

In this tutorial, I'll show you how you can expose your search form on another site using jQuery. At first, I thought about scraping the form's html using AJAX.. and quickly remembered you cannot easily do that. Which lead me to review the AJAX functionality included in jQuery. Bingo, one of my favorites: jQuery.getJSON. To summarize this code, I create a callback function to display the form's json-ified html which can then be easily embedded on another site.

First I defined the menu hook:

<?php
function MYMODULE_menu() {

 
$items = array();

 
// add a page callback for the url: "external-search.js"
 
$items['external-search.js'] = array(
   
'page callback' => '_MYMODULE_external_search',
   
'type' => MENU_CALLBACK,
   
'access arguments' => array('search content'),
  );
   
  return
$items;
   
}
?>

Then I created the callback function for the menu callback:

<?php
function _MYMODULE_external_search() {

 
// create a json string of the search form html
 
$json = drupal_to_js(drupal_get_form('search_form'));
   
 
// format the json as a callback function
  // see: http://docs.jquery.com/Ajax/jQuery.getJSON for more information
 
if ($_GET['jsoncallback']) {
   
$json = $_GET['jsoncallback'] . "(" . $json . ");";
  }
   
 
// output the json
 
print $json;

 
// stop the script, so the theme layer is not applied
 
die;
}
?>

One problem though, the form submits locally. That can be fixed using a form_alter function:

<?php
function MYMODULE_form_alter(&$form, $form_state, $form_id) {
   
 
// check for external search form and set form action to be full path
 
if ($form_id == 'search_form' && arg(0)=='external-search.js') {
   
// change the form action to be the full path
   
$form['#action'] = 'http://' . $_SERVER['HTTP_HOST'] . $form['#action'];
  }
}
?>

Now, if you clear your cache and go to http://YOURSITE/external-search.js, you should see the JSON (and nothing else).

Lastly, you can embed the code on another site using a few lines of jQuery. You can even pull the jQuery from your site if the external site does not have jQuery included.

<!-- Include jQuery (as necessary) -->
<script type='text/javascript' src='http://YOURSITE/misc/jquery.js' ></script>

<!-- create a div container to contain the search form -->
<div id='embedded_search'></div>

<!-- add the jQuery to embed the form -->
<script type='text/javascript'>
$(document).ready(function(){
  // make the ajax request
  $.getJSON("http://YOURSITE/external-search.js?jsoncallback=?",
    function(data){
      // append the form to the container
      $('#embedded_search').append(data);           
    }
  );
});
</script>

Now people should be able to access your site's search form from another site!

Eric's picture

This quick code snippet will show you how to update every external link on your site to open in a new window using jQuery. You can put this code in the script.js file in your theme.

$(document).ready(function(){

  // apply to all <a> tags that have an href that starts with "http"
  $("a[href^='http']").each(function(){

    // remove http:// and https://
    link = $(this).attr('href');
    if (link.substring(0,7)=='http://') {
      link = link.substring(7);
    } else if (link.substring(0,8)=='https://') {
      link = link.substring(8);
    } else {
      return;
    }

    // spilt on '/'
    split1 = link.split('/');

    // compare href hostname to site hostname
    if (split1[0]!=location.hostname) {
      // add target attribute to link
      $(this).attr('target','_blank');
    }

  });

});

Eric's picture

In this tutorial I'll show how I integrated Open Flash Charts into a Drupal view to create a fancy flash based chart from CCK node data.

Let's start by creating a new CCK node type to contain the data. I called mine "graph_data".

I added an integer field called "field_data".

I created a bunch of nodes, populating them with a random integer from 0 to 100.

I added a view called "Graph" to show all of my data. I filtered by node type and published, added sort criteria, chose "Unformatted" for Style, chose how many items to show (100), and added a page view.

At this point, you'll need to download and incorporate the Open Flash Charts library. You can download the library here or by visiting their website and clicking on Downloads in the top right. Uncompress the download and copy the entire directory (version-2-ichor) into your theme directory.

Sample directory structure:

/sites/all/themes/YOURTHEME/version-2-ichor

I created a new file in my theme directory called "views-view-unformatted--Graph.tpl.php" (see: Theme Information section on the View edit page) to override it's output. I put the guts of my code in this file:

<?php
// loop through the view results and populate a numeric array
$values = array();
foreach (
$view->result as $k => $v) {
 
$values[] = intval($v->node_data_field_data_field_data_value);
}

// include OFC PHP library
require_once(path_to_theme() . '/version-2-ichor/php-ofc-library/open-flash-chart.php');

// create a new line object
$line = new line();

// set the view values to the line object
$line->set_values( $values );

// create a new flash object
$chart = new open_flash_chart();

// add the line object to the chart object
$chart->add_element( $line );

// create a new x_axis object
$x = new x_axis();

// set the number of steps
$x->set_steps(10);

// add the x_axis object to the chart
$chart->set_x_axis($x);

// create a new y_axis object
$y = new y_axis();

// set the range of the y axis, based on the min/max view values
$y->set_range(min($values),max($values));

// set the number of steps
$y->set_steps(10);

// add the y_axis object to the chart
$chart->set_y_axis($y);
?>


<!-- Include Javascript libraries -->
<script type="text/javascript" src="<?php print base_path() . path_to_theme(); ?>/version-2-ichor/js/json/json2.js"></script>
<script type="text/javascript" src="<?php print base_path() . path_to_theme(); ?>/version-2-ichor/js/swfobject.js"></script>
<script type="text/javascript">
swfobject.embedSWF("<?php print base_path() . path_to_theme(); ?>/version-2-ichor/open-flash-chart.swf", "my_chart", "350", "200", "9.0.0");
</script>

<!-- Add Javascript to initialize the chart and load its data -->
<script type='text/javascript'>

function open_flash_chart_data() {
  return JSON.stringify(data);
}

function findSWF(movieName) {
  if (navigator.appName.indexOf("Microsoft")!= -1) {
    return window[movieName];
  } else {
    return document[movieName];
  }
}

// output the graph data into a javascript variable
var data = <?php echo $chart->toPrettyString(); ?>;
</script>

<!-- Output a container div for the chart -->
<div id="my_chart"></div>

Here's a screenshot of my new flash integrated view