Drupal 7 - How to add Javascript to a View

ryanka picture ryanka · Oct 11, 2012 · Viewed 7.7k times · Source

Basically what I'm trying to do is add a line of javascript code to each row iteration in a view.

In Drupal 6 this used to be accomplished with Views Custom Field which has now been integrated into Drupal 7.

When I try to use the "Global: Custom text" field it strips out my script tags.

Any ideas?

Please note: I don't want to use drupal_add_js as this needs to be dynamically inserted and I'd prefer to not use it inline (messy). A unique tooltip will popup based on the JS provided and I need the actual row ID.

Thanks in Advance!!

Answer

David Watson picture David Watson · Oct 11, 2012

Responded on Twitter, but for the benefit of others who run into the same situation (and for the sake of clarifying) I thought I'd repost here.

Generally, I wouldn't recommend views_php - there are numerous downsides to enabling/using PHP filters that have already been discussed at length, and it adds the bloat of another module when you really don't need it. You can still use drupal_add_js() in a preprocess function in this case and keep things plenty dynamic.

In short, you have a list of elements that you need to bind the same event to. Event delegation immediately comes to mind as a possible solution. Instead of n event handlers, you now have one for your parent container, which will make your page more responsive. You don't need jQuery for this, but if you prefer look into using .delegate()

As for how to get the ID from this external JS file, simple: make sure it's in the source markup you're grabbing. Assuming you're looking for the row ID, you can typically find it in the class "views-row-N" for each row. Otherwise, you'll want to add the class-id to the template by some other means. Inside the event handler for the target element (your row, an element matching .views-row within your parent element), parse the ID from the class you intend to use and execute the rest of your script based on the value you find from there.

This approach has a number of benefits: it's one less module, it's one less source of security headaches, your JS is all in one place, you're binding fewer event handlers, your markup is lighter and easier to read, and event delegation means this technique will still work even if elements are added to the DOM dynamically later for some reason. As for the specifics, it would help to know exactly what you intend to do with the popup. Is it making an AJAX call to another node? Is it doing something based on the position in the list? I'd be happy to clarify my answer from there.