Drupal 7 Ajax and Views

Drupal Views AjaxHello everybody!

Today I want to share some technique that we are using in our Drupal projects a lot. Sometimes we need button like load more, which will send custom ajax. Default drupal mechanism for ajax is not perfect. What if you will want to modify the result? So I will show you simple example of how to use custom Drupal views ajax. We are using Drupal 7 with Views module.

Using drupal views ajax

Let's look at the snippet below. This basic piece of code will help you with drupal views ajax.

$.ajax({
    url: Drupal.settings.basePath + 'views/ajax',
    type: 'post',
    data: {
        view_name: 'view_name',
        view_display_id: 'view_display_id'
    },
    dataType: 'json',
    success: function (response) {
        if (response[1] !== undefined) {
            var viewHtml = response[1].data;
            //...
            Drupal.attachBehaviors();
        }
    }
});

First of all, it's based on jQuery. If you want to use it in different framework, you can use similar parameters, it should work without any problems:)

OK, so let's analyze this snippet. There are few important lines of code:

url: Drupal.settings.basePath + 'views/ajax',

First is the URL. You can leave it as it is. Drupal.settings.basePath returns base path to your website like http://mywebsite.com/. Than we are using default drupal views ajax mechanism (views/ajax). You can send it as GET or POST request. It is up to you which one you want to use.

data: {
        view_name: 'view_name',
        view_display_id: 'view_display_id'
    },

This is important part. In order to get data from our view, you have to know it's name and display_id. This informations are available in admin panel (look at the screenshot below)

Click Structure -> Views -> {Name of your view} -> Edit

Drupal Views screenshot

 

In our case we will use Question List view. After that pick the page/block you want to get via ajax.

Drupal Views page screenshot

In our case we are using DMP Q&A page. Our machine name of this page is page_4. If it's the only page click on it again and notice the URL change. In our case URL looks like this:

URL for Drupal Views Ajax

 

 

The highlighted parts are the informations we need.

  • questions_list is our view_name
  • page_4 is our view_display_id

This are two most important parameters. You can use more parameters, but it depends on the view and what you want to do with it. For example if you want to load more result you can use per_page parameter and page with stands for numbers of item displayed per page and number of page (first page is 0, second is 1). But remember, if you want to use pagination like that you have to turn it on in view in pager section. If it'll be turned off it won't work. You can use filters values etc. Everything depends on you view configuration.

if (response[1] !== undefined) {
    var viewHtml = response[1].data;
    //...
    Drupal.attachBehaviors();
}

In success function we handle response from server.

First we have to check if there's any result. Drupal will send you response of 2 elements array. Stuff that we need is in [1] element. If there is no [1] element, it means that probably you are passing wrong data. Check it again! In viewHtml we have html data from our view. You can append it, modify it, play as you like.

It's good to use

Drupal.attachBehaviors();

after changing your html code. It will attach certain javascript behaviors  to the new ajaxed content.

Practical example of Drupal Views Ajax

Practical example of drupal ajax views for fetching second page of questions here (using Questions List and DMP Q&A):

$.ajax({
    url: Drupal.settings.basePath + 'views/ajax',
    type: 'post',
    data: {
        view_name: 'questions_list',
        view_display_id: 'page_4',
        per_page: 12,
        page: 1
    },
    dataType: 'json',
    success: function (response) {
        if (response[1] !== undefined) {
            var viewHtml = response[1].data;
            $('#question-container').append(viewHtml);
            Drupal.attachBehaviors();
        }
    }
});

 

Any questions? Or maybe you have better solution?

 

  • Pingback: Render block programmatically in Drupal 7 - astaz3l blog()

  • yasser

    Thanks for this, it is very useful, but is there any way you can pass filters to the view ?
    my situation is that I have a view with contextual filter(which are passed through URL) , Ajax enabled, I implemented the previous JS Code and it is working except that when I do filter the results and then do the sort , the filters are gone, that’s because the view is reloaded completely without considering the filters. Any ideas ?

    • astaz3l

      Hi yasser!
      My question is – do You want to handle it on PHP or JS side? I think in both cases You can use view_args to pass arguments to contextual filters.

  • Alexander Zatko

    I printed the code and taped it to my garage door. It does not load the view when I look at it. Where am I making a mistake ? =8-|

    • Krystian

      You’ve made my day with your comment 😂
      All I can say is that this article is from 2013 and it worked fine back then. Not sure about the printing and taping it to garage door, but who knows?

      • Alexander Zatko

        I found basically the same code mentioned in stackoverflow and at least one another place, but none of them mentioned where to put it and how to invoke it. Couple of other folks on the SO also asked the same – albeit differently formulated question (no taping to garage door … :-), so I guess the problem is to at least some degree real. Thanks for checking the comments 🙂

        • Krystian

          Thanks for clarification, maybe I should have mention where to put it. I quickly browsed through what I wrote back then.
          I don’t really have access to this project anymore so it’s just a guess, but the code is standard jQuery code that triggers AJAX request. In my case it was just clicking on load more button below article list. So this code was fired on click. This code should be wrapped in $('.load-more-button').click(function(){
          $.ajax({...}) // code from above here...
          });

          You can add the custom JS code by drupal_add_js() function if I remember it correctly and link it to your code. Here is a guide how to add custom JS code in Drupal: https://www.drupal.org/docs/7/api/javascript-api/adding-javascript-to-your-theme-or-module
          I know it’s outdated but last time I wrote anything in Drupal was about 5 years ago so I’m not really sure what are the best practices now.
          Will that information help you anyhow?

          • Alexander Zatko

            I figured out that I could modify the Jquery Alax Load module that I already use for loading nodes to load also (multiple) comments, therefore I did not end up using this code. However, it might come handy if – in the future – I need to load a view for example, which the mentioned module can’t do. Thank you.

  • Hello, am having an error with my website built with drupal7. An HTTP error occured Result code 403. Path:aetcongo/views/ajax ….You dont have permission to access aetcongo/views/ajax. I cannot search anything from the form. Please help…Thx