Can we be systematic about my question?

I would like to recreate this JavaScript function on my homepage http://www.gchalker.com

My example is shown on this page: http://raphaeljs.com/image-rotation.html

I have the .js within my theme directory in a folder /js

Now I need to embed the .js into my page by what code snippet to what file in my site?

The I have to get the function loaded...by what snippet into what file.

Then how do I call the function on my page and how do I add an ID to my image?

Please help? Thank you.

G

Comments

orkideh’s picture

Sorry Dude it is not clear for me,

you want to know how to add .js file to your page ?
or
you want know how to write that javascript in example ?

gchalker@princeton.edu’s picture

The wild roses grow where ever I roam!

Like anything in this reality Drupal is a journey.

Learning how to add hooks has been a brick wall which is not forthcoming from the Drupal community, sorry.

Still determining if I really like this new world order. Based on what you can give and not what you take, it seems that all the taking in being done under the scene with the elite few. I think they call that communism? I understand that money is the root of all evil, however, it is a necessary evil unless the world is able to give everything for free. Which I doubt will ever happen considering its resources are becoming more and more scarce. Don't think so? Are we not on the verge of disruption the very core of this planet? Yeah! It's called fracking and 'em folks are making millions!

That said, I still need help and have taken matters into my own hands. I actually purchased reading them until I am done bookmarking, highlighting, and comprehending.

Thanks for your help dude orkideh, but I will figure it out on my own and get back to you.

Warm regards, g.

Jaypan’s picture

Is the page you linked to the one that you want to add the script to, or another page on that site? How is the page in question being created? Is it a node? Is it a template (example page--front.tpl.php)? Is it a custom path you've created with hook_menu? A view?

Each of these has a different method of adding the script, so a little more information is necessary.

Jaypan’s picture

This user never replied to my question, and since I'm sure that this page will be found by others searching for the same question, I'm going to give a few examples based on different page generation methods that I listed above:

1) A node:
Solution - implement hook_node_view() and add your script to the $node->content array as follows:

function my_module_node_view($node, $viewmode, $langcode)
{
  $node->content['#attached']['js'][] = array
  (
    'type' => 'file',
    'data' => drupal_get_path('module', 'my_module') . '/my_script.js',
  );
}

2) A template. For example, the user may have page--front.tpl.php.
Solution - We need to implement the preprocess hook for the template, in our template.php file. The actual function name will be THEME_NAME_preprocess_TEMPLATE(). In the above case, the template is 'page', so we want to implement THEME_NAME_preprocess_page() as follows:

function my_theme_preprocess_page(&$vars)
{
  if($vars['is_front'])
  {
    drupal_add_js(drupal_get_path('theme', 'my_theme') . '/my_script.js');
  }
}

3) A custom page created with hook_menu():
Solution - when creating a page with a callback path, using hook_menu(), it's best to return a render array, so that the page can be overridden further down the line. We can also attach our script to this render array. Example:

// Create a path using hook_menu()
function my_module_menu()
{
  $menu['my_path'] = array
  (
    'title' => 'My Page',
    'callback path' => 'my_page_callback',
    'access callback' => TRUE,
  );
  return $menu;
}

// Our callback path
<?php
function my_page_callback()
{
  $page_contents = t('These are the contents of my page');
  $page_array = array
  (
    '#markup' => $page_contents,
    '#attached' => array
    (
      'js' => array
      (
        array
        (
          'type' => 'file',
          'data' => drupal_get_path('module', 'my_module') . '/my_script.js',
        ),
      ),
    ),
  );

  // return the render array with the attached JS
  return $page_array;
}

4) A view
Solution - implement hook_preprocess_views_view() and attach the js for your view and view name. In this hook, the view information is stored in $vars['view'], and we want to look at two items in particular, the view name, and the view current_display. The view name is the name of the overall view, when creating a new view, as it's listed on the views list page. The current_display is the name of the display being used inside that view. By default, it will be page_X (for a page) where X is the number of the page created. I generally override the name of the current_view however to something more descriptive. But I will use page_1 in this example:

function mytheme_preprocess_views_view(&$vars) {
  if ($vars['view_array']['#name'] == 'view_name') {
    $vars['#attached']['js'][] = [
      'type' => 'file',
      'data' => drupal_get_path('theme', 'my_theme') . '/my_script.js',
    ];
  }
}

I have attached a file in each of the above examples, but in all cases, I could have attached some settings, an external script, or inline JS as well.

gchalker@princeton.edu’s picture

Dear Jaypan,

Thanks so much for working on this with me. Moving forward with my Javascript problem. I was able to include my raphael.js file in by adding to my .info file:

scripts[] = js/raphael.js

I checked my content type and it is an article which I assume makes it a node.

I have to add this javascript to the header of the file. My image has an ID of bee.

window.onload = function () { var src = document.getElementById("bee").src, angle = 0; document.getElementById("holder").innerHTML = ""; var R = Raphael("holder", 640, 480); R.circle(320, 240, 200).attr({fill: "#000", "fill-opacity": .5, "stroke-width": 5}); var img = R.image(src, 160, 120, 320, 240); var butt1 = R.set(), butt2 = R.set(); butt1.push(R.circle(24.833, 26.917, 26.667).attr({stroke: "#ccc", fill: "#fff", "fill-opacity": .4, "stroke-width": 2}), R.path("M12.582,9.551C3.251,16.237,0.921,29.021,7.08,38.564l-2.36,1.689l4.893,2.262l4.893,2.262l-0.568-5.36l-0.567-5.359l-2.365,1.694c-4.657-7.375-2.83-17.185,4.352-22.33c7.451-5.338,17.817-3.625,23.156,3.824c5.337,7.449,3.625,17.813-3.821,23.152l2.857,3.988c9.617-6.893,11.827-20.277,4.935-29.896C35.591,4.87,22.204,2.658,12.582,9.551z").attr({stroke: "none", fill: "#000"}), R.circle(24.833, 26.917, 26.667).attr({fill: "#fff", opacity: 0})); butt2.push(R.circle(24.833, 26.917, 26.667).attr({stroke: "#ccc", fill: "#fff", "fill-opacity": .4, "stroke-width": 2}), R.path("M37.566,9.551c9.331,6.686,11.661,19.471,5.502,29.014l2.36,1.689l-4.893,2.262l-4.893,2.262l0.568-5.36l0.567-5.359l2.365,1.694c4.657-7.375,2.83-17.185-4.352-22.33c-7.451-5.338-17.817-3.625-23.156,3.824C6.3,24.695,8.012,35.06,15.458,40.398l-2.857,3.988C2.983,37.494,0.773,24.109,7.666,14.49C14.558,4.87,27.944,2.658,37.566,9.551z").attr({stroke: "none", fill: "#000"}), R.circle(24.833, 26.917, 26.667).attr({fill: "#fff", opacity: 0})); butt1.translate(10, 181); butt2.translate(10, 245); butt1[2].click(function () { angle -= 90; img.stop().animate({transform: "r" + angle}, 1000, "<>"); }).mouseover(function () { butt1[1].animate({fill: "#fc0"}, 300); }).mouseout(function () { butt1[1].stop().attr({fill: "#000"}); }); butt2[2].click(function () { angle += 90; img.animate({transform: "r" + angle}, 1000, "<>"); }).mouseover(function () { butt2[1].animate({fill: "#fc0"}, 300); }).mouseout(function () { butt2[1].stop().attr({fill: "#000"}); }); // setTimeout(function () {R.safari();}); }; I created a file called rotate.js without the

tags and placed it in my js folder.

So would I add your script for a node to my template.php? Or create a separate php file? Do you think it will work?

function my_module_node_view($node, $viewmode, $langcode)
{
  $node->content['#attached']['js'][] = array
  (
    'type' => 'file',
    'data' => drupal_get_path('module', 'my_module') . 'js/rotate.js',
  );
}

Thanks for your help again.

Regards gchalker

Jaypan’s picture

First, you most likely don't want raphael.js being included in your .info file, as it will then be included on every page load. Unless you are using it on every page load, this is overkill. Therefore you should include it at the same time, in the same manner, as rotate.js. And on that note, I'd use this:

function my_module_node_view($node, $viewmode, $langcode)
{
  if($node->type == 'article')
  {
    $node->content['#attached']['js'][] = array
    (
      'type' => 'file',
      'data' => drupal_get_path('module', 'my_module') . 'js/raphael.js',
    );
    $node->content['#attached']['js'][] = array
    (
      'type' => 'file',
      'data' => drupal_get_path('module', 'my_module') . 'js/rotate.js',
    );
  }
}

But please note that this will add the file to every article node. If you want to add it only for a specific article, then you need to get the nid of that article, and instead of checking $node->type, you would check $node->nid.

DeNelo’s picture

Or, you can add the javascript like this in your module:

  if ($node->nid == 684) { //Looking for the specific node
    drupal_add_js(drupal_get_path('module', 'my_module') . '/js/myscript.js');
  }

For some reason,
$node->content['#attached']['js']
didn't work for me.

Jaypan’s picture

What hook were you adding it in? Also, are you using D7 or a different version?

Jaypan’s picture

Two more things:

1) In Drupal, you do not use window.onload, you use Drupal.behaviors. Read more about this, and the Drupal 7 JavaScript API here: https://drupal.org/node/751744
2) You can wrap your code in <code></code> tags, making it easier to read. If it's PHP, you can wrap your code in <?php ?> tags.

gchalker@princeton.edu’s picture

Thanks Jaypan,

Let me work on this tomorrow. Late here on the east coast. I seem to understand what I need to do, yet I want to spend time reading the 751744 so I understand it. I will do that tomorrow.

It is javascript, so Drupal likes <code> instead of <script></script>?
Also, in what file do I put the php script in?

Can you tell me where you set the alerts so that I get an email when someone replies to my threads. I do remember the capabilities of doing so. Or was that in google.api?

Good night! And thanks again.

This will be awesome if I can get it to work.

gchalker@princeton.edu’s picture

Dear Jaypan,

http://www.gchalker.com/

I think everything is in the right place now. But rotate.js is still not coming in. I have this is template.php:

function my_module_node_view($node, $viewmode, $langcode)
{
if($node->type == 'article')
{
$node->content['#attached']['js'][] = array
(
'type' => 'file',
'data' => drupal_get_path('module', 'my_module') . 'js/raphael.js',
);
$node->content['#attached']['js'][] = array
(
'type' => 'file',
'data' => drupal_get_path('module', 'my_module') . 'js/rotate.js',
);
}
}

Rotate.js reads:

(function ($) {
Drupal.behaviors.my_module = {
attach: function () {
var src = document.getElementById("bee").src,
angle = 0;
document.getElementById("holder").innerHTML = "";
var R = Raphael("holder", 640, 480);
R.circle(320, 240, 200).attr({fill: "#000", "fill-opacity": .5, "stroke-width": 5});
var img = R.image(src, 160, 120, 320, 240);
var butt1 = R.set(),
butt2 = R.set();
butt1.push(R.circle(24.833, 26.917, 26.667).attr({stroke: "#ccc", fill: "#fff", "fill-opacity": .4, "stroke-width": 2}),
R.path("M12.582,9.551C3.251,16.237,0.921,29.021,7.08,38.564l-2.36,1.689l4.893,2.262l4.893,2.262l-0.568-5.36l-0.567-5.359l-2.365,1.694c-4.657-7.375-2.83-17.185,4.352-22.33c7.451-5.338,17.817-3.625,23.156,3.824c5.337,7.449,3.625,17.813-3.821,23.152l2.857,3.988c9.617-6.893,11.827-20.277,4.935-29.896C35.591,4.87,22.204,2.658,12.582,9.551z").attr({stroke: "none", fill: "#000"}),
R.circle(24.833, 26.917, 26.667).attr({fill: "#fff", opacity: 0}));
butt2.push(R.circle(24.833, 26.917, 26.667).attr({stroke: "#ccc", fill: "#fff", "fill-opacity": .4, "stroke-width": 2}),
R.path("M37.566,9.551c9.331,6.686,11.661,19.471,5.502,29.014l2.36,1.689l-4.893,2.262l-4.893,2.262l0.568-5.36l0.567-5.359l2.365,1.694c4.657-7.375,2.83-17.185-4.352-22.33c-7.451-5.338-17.817-3.625-23.156,3.824C6.3,24.695,8.012,35.06,15.458,40.398l-2.857,3.988C2.983,37.494,0.773,24.109,7.666,14.49C14.558,4.87,27.944,2.658,37.566,9.551z").attr({stroke: "none", fill: "#000"}),
R.circle(24.833, 26.917, 26.667).attr({fill: "#fff", opacity: 0}));
butt1.translate(10, 181);
butt2.translate(10, 245);
butt1[2].click(function () {
angle -= 90;
img.stop().animate({transform: "r" + angle}, 1000, "<>");
}).mouseover(function () {
butt1[1].animate({fill: "#fc0"}, 300);
}).mouseout(function () {
butt1[1].stop().attr({fill: "#000"});
});
butt2[2].click(function () {
angle += 90;
img.animate({transform: "r" + angle}, 1000, "<>");
}).mouseover(function () {
butt2[1].animate({fill: "#fc0"}, 300);
}).mouseout(function () {
butt2[1].stop().attr({fill: "#000"});
});
}
};

})(jQuery);

Yet still no buttons. It doesn't even look like rotate.js is loading.
Am I getting any closer?

FYI... this will be the only article that I create on my site.

Thanks again for your help!

g. :>)

Jaypan’s picture

If this is your actual code:

function my_module_node_view($node, $viewmode, $langcode)

Then you will need to change 'my_module' to the machine name of your theme. You will also need to clear your cache.

I would also suggest changing this:

(function ($) {
Drupal.behaviors.my_module = {
attach: function () {

To this:

(function ($) {
Drupal.behaviors.my_module = {
attach: function () {
  alert("script loaded");

This will let you know if your script has properly loaded, helping you figure out where you need to debug (if this alert does not appear, then the script is not loaded).

dagoodgamez’s picture

Hi, i wanna add a js file to a view page. I tried using the last example you show. I created a new module, and included

function my_theme_preprocess_views_view(&$vars)
{
  if($vars['view']->name == 'my_view' && $vars['view']->current_display == 'page_1')
  {
    $vars['view']['#attached']['js'][] = array
    (
      'type' => 'file',
      'data' => drupal_get_path('theme', 'my_theme') . '/my_script.js',
    );
 }
}

in the my_module.module file, but it doesnt work. Could you help me to get this work?

Thanks in advance!

Jaypan’s picture

You'll need to change the following:
my_theme => Machine name of your module
my_view => Machine name of your view
page_1 => Machine name of the display of the view you want to show
drupal_get_path('theme', 'my_theme') => drupal_get_path('module', MODULE MACHINE NAME) (change MODULE_MACHINE NAME)
my_script.js => name of your script

dagoodgamez’s picture

Yes, i already did that, i was showing the above code just as an example. But it's still not working.

Jaypan’s picture

Must be something else wrong with your code then.

nagy.balint’s picture

I think i know what is wrong.
$vars['view'] is an object.
Yet later in the code the attach is done by
$vars['view']['#attached']
Which throws PHP Fatal error: Cannot use object of type view as array

drupsforyou’s picture

Well, you can add your js path to the .info file.
Ex : scripts[] = js/yourJS.js

You have to write your code in a such a way, so that your function will work as per your need.

Jaypan’s picture

That will add the script to every page. This user wants to attach the scripts to a single page.

drupsforyou’s picture

Then try to use the below function.
drupal_add_js("PATH OF YOUR JS FILE")

badger_fruit’s picture

Use this to "include" the .JS file into your page--xxxx.tpl.php

drupal_add_js('sites/all/themes/yourtheme/js/file.js');

Then you can use it 'as normal'; for example, if you have a function in file.js that is called "eatmybadger()", then you can assign it either using jQuery or hard-code into the HTML like so:-

<img onclick='eatmybadger();' src='' .....

As for the other questions on adding an ID to your image, well, it all depends on how you get the image in the first place.
For my galleries, I have a simple PHP loop embedded into the page--xxxxtpl.php page which looks something like this:-

forech ($imageset as $image_id => $image_data) {
  echo '<img 
    onclick="
      eatmybadger(' . $image_data -> image_filename . ');
    " 
    src="' . $image_data -> image_source . '"
    ><br />';
}

I hope this helps!

Jaypan’s picture

Adding the script in page.tpl.php will include the script on every page. The question at hand is how to include the script on a single page.

badger_fruit’s picture

Sorry, wasn't being clear ... I don't mean include it on page.tpl.php but on his appropriate template page; for example on my configuration, I have a page called page--archive-gallery.tpl.php and the drupal_add_js function that I suggested is used on that page; the code included in my JS file is then only available/called on that page, which is what the OP desires.

gchalker@princeton.edu’s picture

So I need to put this script in:

drupal_add_js('sites/all/themes/likeable/js/rapheal.js');

Somewhere in my page.tpl.php file? The mandala page is my home page when you land on www.gchalker.com and a page call /mandala.

That will include the rapheal.js on the mandala page only?
I will have to take it out of my .info file.

Now for the header script listed in a reply above.
Would I do the same in the page.tpl.php file?

Oy vey. This is complicated!

Thanks for your help though! I appreciate it!

Regards, gchalker

Anonymous’s picture

The Meta Tags module tucks all sorts of things in the head of a single node. (Title, description, canonical, rel="prev", etc...)

Why can't that same module just be configured to offer a feature where there's an input box where you can place any text you want for insertion into the head portion of the html, with you just being responsible for it having correct syntax? So much about Drupal is like doing your job handcuffed. Yeah, you can do it, it's just incredibly inconvenient.

Jaypan’s picture

JavaScript is not a meta tag, so it doesn't really make sense to have it as part of that module.

drupal_lib’s picture

I seem to be stuck on this and would really appreciate if anyone could point me in the right direction. I've tried a number of things and can't seem to find a fix.  I have a Javascript file that I only want to load on the node add page of a particular content type (ex - node/add/registration).  What is the best way to go about doing this?  

Jaypan’s picture

Use the #attached key of the form in hook_form_alter().

drupal_lib’s picture

Thanks so much for pointing me in that direction.  I have tried a few variations in template.php with no luck.  I am including an example below. I greatly appreciate any input.

function hook_form_alter(&$form, &$form_state, $form_id) {

// Check form being passed
if ($form_id == 'registration_node_form') {
  
// Scripts
$build['#attached']['js'] = array(
  './js/registration.js' => array(
    'type' => 'internal',
  ),
);
  }
}

Jaypan’s picture

1) Please wrap your code in code tags. You can do this with the button in the editor when creating a post that looks like a document with the characters <> in the bottom right corner.

2) Did you name your function hook_form_alter()? Or did you use the actual naming convention of your module? If the former, you need to read up on hooks (https://www.youtube.com/watch?v=pGXwWpyYxSo). If the latter, then please post the machine name of the module you used, as well as the actual name of the hook_form_alter() implementation you used.

3) Have you confirmed that your hook is being called? You need to clear the registry before it will be picked up.

4) Have you confirmed you got the correct form ID? Where did you get this form ID.

5) You've added your JS to the $build variable, which doesn't exist in that function. You should be adding your JS to the $form object.

6) Is this Drupal 7 or Drupal 8? If 8, you need to attach your JS with a library, rather than to the 'js' element.

That should give you some things to work with.

I'd suggest opening a new issue if this doesn't work.

drupal_lib’s picture

Thanks for the tips.  Tweaking 2 & 5 worked.  Appreciate your help!