Viziontech Software Solutions
Software development is delicate.
We handle it carefully.

Drupal & Ajax - How to dynamically update view display

The following tutorial, will describe how to dynamically update your page with view results. It will be based on the Drupal & Ajax - Basic Tutorial, which breaks down the steps of implementing basic Ajax with Drupal. So if you still haven't read it, now will be a good time to do so.
I will also use the code from that tutorial to extend the implementation.

What I'm going to add in this tutorial is:
  1. Load an existing view.
  2. Setup view parameters for execution.
  3. Execute the view.
  4. Load the themed view to the JSON object and return it.

As you will see, there's no much difference between returning a simple static list of categories as I've done in the basic tutorial, and returning a view result. At the end of the day, both are html streams that are loaded to a JSON object which is returned to the client.
NOTE: If you already have a view that you want to use, you can skip steps 1-3, and use your own view (Skip to step 4).

Step 1 - Create "Product" content type
Let's define a new content type. This content type will be used to create content that we will use in this tutorial.
We will call our new content type "Simple Product". Define the following fields for the new content type we just created as follows:
  • Description
  • Price
  • Category
Only for the simplicity of this example, go ahead and define all fields as simple text fields.

Step 2 - Create content
It is now time to create "Simple Product" content items, so create a list of products(at least 6 products).
In the "Category" field value, for each content item, set one of the following values "books" or "movies" (3 products per category). This value will help us later to return a list of products based on that category.

Step 3 - Create the view
The next task you will need to complete is to create a view. It is out of the scope of this tutorial to explain how to do that, so if you are not familiar with the Views module, I urge you to read more about it before you continue.
So, with the Views modules, create a new view as follows:
  • Name the new view "products_by_category".
  • Define the fields you want this view to return
  • Define a view argument (type should be Content:Category).
  • Test your view to verify it returns the products you expect per category argument

Step 4 - Execute the view
If you remember, the original .module code, created a static html list, which was loaded into a JSON object and was returned as the function output as follows:
function dynamic_products_get_by_category_id($cat_id){
  $items = '';
  switch($cat_id){
    case 12: 
     $items = '<ul><li>Product 1</li><li>Product 2</li></ul>';
     break;
    case 20:
     $items = '<ul><li>Product 3</li><li>Product 4</li></ul>';
     break;  
  }
// create a JSON object. The object will contain a property named “products” that will be set with the $items variable. 
  return drupal_json(array('products'=>$items));
  exit;
}

The following code, calls the view we want to load, and returns its result
function dynamic_products_get_by_category_id($category){

  $viewName = 'products_by_category'; // The name of the view we are going to load

  $args = array($category);  // Array of arguments we set for the view. Only one argument in our example. your actual view may require additional arguments which you may need to set

  $displayId = 'page'; // The display id of for the view. 

  // Call the views_embed_view function to returned themed view output
  $res = views_embed_view($viewName, $displayId, $args);

// create a JSON object. The object will contain a property named “products” that will be set with the themed result of the executed view. 
  return drupal_json(array('products'=>$res));

  exit;
}
Few notes about the code:
This line, sets the arguments that should be passed to the view. In our case, the view accepts a single argument which is the category.
  $args = array($category); 

  $res = views_embed_view($viewName, $displayId, $args);

  return drupal_json(array('products'=>$res));
The views_embed_view function, which you can read more about it here, is called to return a themed result.
The function accepts as input parameters, the view name, the id of the display (i.e. default, page, block, etc.), and an array of view arguments.
The result, is html output containing the result of the view. This view can be themed as you would theme it if it wasn't loaded dynamically.
After we have the view result, we load it into a JSON object which will be returned as a response to the AJAX request.

Step 5 - Update page code
The last chnage we are going to make is to the page's code. The Html in the original tutorial was:
 
<div id=”topDiv”>
<a class="categoryLink" href="/products/get/12">Cat. 1</a>
<a class="categoryLink" href="/products/get/20">Cat. 2</a>
</div>
<div id="divProducts”></div>
We are going to change it to pass the correct category according to what we defined in step 2 ("books" or "movies"):
 
<div id=”topDiv”>
<a class="categoryLink" href="/products/get/books">Books</a>
<a class="categoryLink" href="/products/get/movies">Movies</a>
</div>
<div id="divProducts”></div>


That's it. You should be able to save and test you code.



Comments


Really great tutorial! It

Really great tutorial! It helped me a lot, keep up the good job!

Interesting

Great info. Thanks

Perfect

I am french, your tutorial is very clear. Big thanks

Great tutorial!

Im just wondering if there is a way to load a view display by its name instead of its 'id'.

I'm building a website where every item in the main menu call this ajax function in order to load a preview of the section; To make it easy to manage by my customer, im using the rel attribute of the menu item as the view display, but will be better if, instead of using 'block_1', 'block_2' etc.. i could use the display name, for example 'shop', 'rules', 'forum', etc..

any idea?

I 'solved' this creating an array in my function module, the keys are the display name and the values the display id, but it is impossible to edit for my customer.

Views api

Thanks Daniele.

Regarding you question, please take a look at the views api. Hope they contain the answer to what you look.
http://groups.drupal.org/node/10129

Zion

hook_init() calling theme is incompatible w/ core blocks module

Hi, excellent tutorial!

There is one problem in drupal 6.x with this method that I am trying to resolve. In a nutshell, if you call the theme function in hook_init() it breaks the blocks layout when using a separate admin theme. The details of this "non" issue are discussed here: http://drupal.org/node/219756.

What I am trying to accomplish requires permissions to display the views I'm loading with the ajax module. So this is the most eloquent and integrated solution. However, I really love the root_candy admin theme for all of the admin functionality as it is perfect for non-technical users.

I'm just starting to dig into this issue and was wondering if you have any ideas of how I can get around making that call to theme(). It seems like that would be the easiest way to work around this issue, and if it can be accomplished, this module would be bullet proof.

Thanks for the great tutorial.

Cheers,
JD

Im just wondering if

Im just wondering if there is a way to load a view display by its name instead of its 'id'.
I'm building a website where every item in the main menu call this ajax function in order to load a preview of the section; To make it easy to manage by my customer, im using the rel attribute of the menu item as the view display, but will be better if, instead of using 'block_1', 'block_2' etc.. i could use the display name, for example 'shop', 'rules', 'forum', etc..
any idea?
I 'solved' this creating an array in my function module, the keys are the display name and the values the display id, but it is impossible to edit for my customer.
_________
starlas eymour

view pagination is not working

I tried your trick, it worked fine for me.
Now the issue is that when the view is called through an ajax call the view ajax pager doesn't works.

Kindly help.

RE: view pagination is not working

Just a guess, this may have something to do with javascripts that are used by views and needs to be used also in your solution.
Do you see a javascript error in your browser when the page loads? when you try to use paging?
Use a script debugger to see how you views behave, and than check you ajax solution to see where exactly is the problem.

Kind regards,
Zion

Two points

Excellent tutorial. One suggestion and one gotcha:

1) SUGGESTION
To find the display_id, go to the Views page, where you define the View. Open Firebug and get to the Net tab. Preview the view you are interested in. Check the Post parameters that are listed in Firebug. You will that the display_id is listed there.

2) GOTCHA
When calling views_embed_view, note that if the $args parameter is a single string, DO NOT pass it as an array; just pass it as a string.

$viewName = 'my_custom_view'; // The name of the view we are going to load

$args = array('FOOBAR'); // Array of arguments we set for the view.

$displayId = 'page_1'; // The display id of for the view obtained with Firebug

// WRONG: passing the $args array will result in problems
$custom_view = views_embed_view($viewName, $displayId, $args);

// RIGHT: passing the string will work
$custom_view = views_embed_view($viewName, $displayId, 'FOOBAR');

In fact, this single line works for me:

$custom_view = views_embed_view('my_custom_view, 'page_1, 'FOOBAR');

100% Bullet proof tutorial

Hello Viziontech,

This tutorial is amazing, I made some alterations to fit my site but everything worked 100% with the first cut/paste, keep up the good work!

B Jordan

Typo in last code block

First of all, thank you for this tutorial! It's exactly what I was looking for and works great. On that note, people could be having problems populating the empty div because the code example is missing a closing > after "divProducts"


<div id="divProducts”</div>

should be

<div id="divProducts”></div>

Thanks again for both the Basic Ajax and Views tutorial.

Thanks for pointing that out

Fixed

THANK YOU!

I have been trying to figure out something like this for so long now, I've searched all over and asked for help numerous times on IRC with no luck! SO grateful!!

I just had to ask one question though, I implemented this on a site where several arguments are being passed into the view. The view displays teasers of the particular nodes, which are supposed to open modals (using popups module) when clicked. When I click to filter my view the correct markup is there for popups, but the JS doesn't work anymore.. any ideas?

I'm not having any luck

I'm not having any luck getting a response from clicking the links as well.

i am kind of new to the whole

i am kind of new to the whole ajax process and i have a view containing images on a page
i would like for you to be able to click on one of the images in the view and it is displayed on the same
page probably above the view so that image would change as long as you click on an image in the view. how would
i modify the code above to accomplish this

Dynamic loading of view images

Hello Pabo,

There are couples of way to implement what you are looking for, but I think you better explorer existing solutions that are out there.
There are few modules that already implement this type of functionality, and you would save time using one of them.

Take a look at:
- Views Galleria - http://drupal.org/project/views_galleria
- Album Photos - http://drupal.org/project/photos

If you still need help, let me know.
Zion

AJAX Pager

Hey, great couple of tutorials :)
Thanks to things like this Drupal evolves!
I'm trying to make my self this, I have follow the steps, but I have a problem. I have created a view with a pager and AJAX enabled (in the View), and it doesn't work how is supposed to work, if loads a ""empty page" with only raw data from view. not header, footer, etc.

View works great in the preview, but not when loaded AJAX way

Does it happens to you?
Thank you
Anna.

AJAX Pager

Hello Anna,

Thanks for your comment about the tutorials.

Regarding the issues you are having, did you follow the first tutorial(http://www.viziontech.co.il/tutorial1)?
I suggest you follow it carefully, as it describes in details what should be done to implement Ajax requests with Drupal.
If the first tutorial works for you, and you’re still having problems with “view” implementation, give me a shout and I’ll try to do my best to help.

Best regards
Zion

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Enter the characters (without spaces) shown in the image.