Creating an AJAX Link in Drupal

What I want is a standard link, that when clicked does things. I want to do some server side processing, that returns a result, that can be processed locally (aka in the browser).

For example, click an “active” icon for a product. The product is made inactive and the “active” icon is replaced with an “inactive” icon.

Step 1: The link

In this example I am creating two links

  1. An AJAX based link. It will attempt to run its magic, but if javascript is off, will resort back to the standard HTML way fo doing things.
  2. A standard (non-AJAX) link that will replicate what will happen if javascript if not working.
function mymodule_link() {
    drupal_add_library('system', 'drupal.ajax');
    $linkwith = l(t('With'), 'mymodule/link/callback/nojs/', array('attributes' => array('class' => array('use-ajax'))));
    $linkwithout = l(t('Without'), 'mymodule/link/callback/nojs/');
    return "{$linkwith} {$linkwithout}
HERE

";
}

The important things to note here are

  • The “magic” “/nojs/” appended to the target. This gets stripped off on startup if javascript is active - telling us which path to follow.
  • The “use-ajax” class assigned to the link object so that Drupal knows that this is a AJAX command.
  • The inclusion of the AJAX library so the magic can happen.

Step 2: The Callback

This is the function that will receive the AJAX or standard HTML request and process it. In this case, I am simply appending some text to my “messagediv” DIV defined in the output above.

function mymodule_link_callback($type = 'ajax') {
    if ($type == 'ajax') {
        $output = t("This is some content delivered via AJAX");
        $commands = array();
        $commands[] = ajax_command_append('#messagediv', $output);
        $page = array(
                '#type' => 'ajax',
                '#commands' => $commands
        );
        ajax_deliver($page);
    }
    else {
        $output = t("This is some content delivered via a page load.");
        return $output;
    }
}

Step 3: Define the Menu

function mymodule_link() {
    $items = array();
   ....

    $items['mymodule/link'] = array(
            'title' => 'Test AJAX Linking',
            'page callback' => "mymodule_link",
            'access callback' => TRUE,
            'type' => MENU_NORMAL_ITEM,
    );

    $items['mymodule/link/callback'] = array(
            'title' => 'Test AJAX Linking Callback/Response',
            'page callback' => "mymodule_link_callback",
            'access callback' => TRUE,
            'type' => MENU_CALLBACK,
    );

    return $items;
}

And it is all done.

Passing Variables

Now the only thing to do is pass some variables. In this case, lets have two - value1 and value2.

So our main function changes to

function mymodule_link() {
    drupal_add_library('system', 'drupal.ajax');

    $value1 = 6;
    $value2 = 7;

    $linkwith = l(t('With'), 'mymodule/link/callback/' . $value1 . '/' . $value2 . '/nojs/', array('attributes' => array('class' => array('use-ajax'))));
    $linkwithout = l(t('Without'), 'mymodule/link/callback/' . $value1 . '/' . $value2 . '/nojs/');

    return "{$linkwith} {$linkwithout}
HERE

";
}

My Callback function now accepts two extra variables like so

function mymodule_link_callback($value1, $value2, $type = 'ajax') {
    if ($type == 'ajax') {
        $output = t("This is some content delivered via AJAX :v1, :v2", array(
                ":v1" => $value1,
                ":v2" => $value2,
        ));
        $commands = array();
        $commands[] = ajax_command_append('#messagediv', $output);
        $page = array(
                '#type' => 'ajax',
                '#commands' => $commands
        );
        ajax_deliver($page);
    }
    else {
        $output = t("This is some content delivered via a page load :v1, :v2", array(
                ":v1" => $value1,
                ":v2" => $value2,
        ));
        return $output;
    }
}

And the callback menu defines two variables

$items['mymodule/link/callback/%/%'] = array(
        'title' => 'Test',
        'page callback' => "mymodule_link_callback",
        'page arguments' => array(
                3,
                4
        ),
        'access callback' => TRUE,
        'type' => MENU_CALLBACK,
);

Done.

Leave a Reply

Your email address will not be published. Required fields are marked *