Tag Archives: JavaScript

postMessage in JavaScript

postMessage in JavaScript

The big problem with iframes is communication between the iframe and it's parent. When the origin of an iframe is the same as parent there's no problem. But when the domains are different it was impossible to change anything in iframe from parent for instance. postMessage solve this problem almost completely.

Two ways communication with postMessage

The cool part is that postMessage works almost on every browser including IE8. Let's start playing around with postMessage then.

Sending data with postMessage

Let us take a look on the snippet below

var iframe = document.getElementById('iframe').contentWindow;
iframe.postMessage('Hello iframe!', 'http://iframe.domain.com');

Yes, that's it:) In first line we are getting contentWindow of iframe with id="iframe". Let's assume that domain of page inside the iframe is http://iframe.domain.com

In second line we will send the message to this iframe via postMessage function. It takes 2 parameters. First one is data that we want to send to iframe. Basically it can be any kind of object, json, etc. but the safest way is to use String type. It is supported by all major browsers.

Second parameter is target domain. It should be the iframe URL. You can also put * to target any domain. But from security reasons and targeting only particular iframe with given domain I suggest to put the URL address:)

Receiving data with postMessage

Receiving data will take little more than 2 lines, but is as easy as sending. Take a look on example below:

var messageListener = function(event){
    //Optional check
    if(event.origin !== 'http://domain.com'){
        return;
    }

    //Do whatever You want to do with recieved data
    console.log(event.data);

    //Respond
    event.source.postMessage('Message recieved, thanks!', event.origin);
}

if(window.addEventListener){
    addEventListener('message', messageListener, false);
}else{
    attachEvent('onmessage', messageListener);
}

First of all we should write short function that will handle our message. It should take parameter that will have received message.

With event will come 3 basic properties that are important to postMessage

  • origin - contain domain from where message was posted
  • data - posted message
  • source - reference to sender window

First of all we can check if message should be accepted. It's optional check. Usually I don't care where from message was posted. But if we want to check, origin will help us.

In event.data we will have our posted data. Now world is Yours and You can do whatever You want to do with that:)

Quiet often we want to respond to the message, for instance send confirmation message or some status. We will use event.source.postMessage() function. As target domain pass event.origin, to send request to sender window.

But do not forget that You have to write another receiving function in parent window, that will handle onMessage request!

Last part is to bind our function using eventListener, or in older browser using attachEvent function.

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:


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.


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?