Syndicate

Feed

Using Ajax in Drupal 6

John K. VanDyk confirmed that Pro Drupal Development 2nd edition will be published early this summer. I don’t know about you but in Montreal it sure does not look like summer. We’re still in the dead of winter, and it’s one snowstorm after another.

Anywho, I got busy last night and, on a Drupal 6 install, I worked through chapter sweet seventeen of the Pro Drupal Development 1st edition book. The title of the chapter is "Using jQuery".

(Hey, here is an idea for a thread: name the one computer book you’ve actually read from cover to cover in your life. My answer: Pro Drupal Development, and probably just a few other books.)

You’ll find attached to this post a working digg-like module, different enough from the Drupal-5-compliant one provided with the book that I don’t believe I’ll receive any email about me committing copyright infringement.

So here are the eight changes you should bring to the module plus1 to make it work in Drupal 6.

But before we delve into this, here is something you should know. If you’ve worked through the example at the beginning of the chapter where we add jQuery code to a node, and you have not seen the first paragraph fade in as it did in Drupal 5, don't be alarmed. You’ll have to first hide the paragraph. When you think about it... the fact that this worked as is with an earlier version of the jQuery library is a bug.

In Drupal 5, after adding the following to a node, you would see the first paragraph fade in:

<?php
drupal_add_js('$(document).ready(function(){
  $("#one").fadeIn("slow");
  });',
  'inline'
  );
?>
<p id="one">Paragraph one</p>
<p>Paragraph two</p>
<p>Paragraph three</p>

In Drupal 6, you have to hide the paragraph first, then fade it in.

<?php
drupal_add_js('$(document).ready(function(){
  $("#one").hide().fadeIn("slow");
  });',
  'inline'
  );
?>
<p id="one">Paragraph one</p>
<p>Paragraph two</p>
<p>Paragraph three</p>

Or you may harness the full power of jQuery by selecting the first paragraph of the node’s content, and make that paragraph fade in for the duration of 5 seconds, ie: 5000 ms.

<?php
drupal_add_js('$(document).ready(function(){
  $(".content p:first").hide().fadeIn(5000);
  });',
  'inline'
  );
?>
<p>Paragraph one</p>
<p>Paragraph two</p>
<p>Paragraph three</p>

On with the show.

1. Open and edit your plus1.install file. Table creation for modules has been abstracted into a Schema API in Drupal 6.

In Drupal 5, we created our table {plus_1} this way:

<?php
// $Id$
/**
* Implementation of hook_install().
*/
function plus1_install() {
  switch (
$GLOBALS['db_type']) {
    case
'mysql':
    case
'mysqli':
     
db_query("CREATE TABLE {plus1_vote} (
        uid int NOT NULL default '0',
        nid int NOT NULL default '0',
        vote tinyint NOT NULL default '0',
        created int NOT NULL default '0',
        PRIMARY KEY (uid,nid),
        KEY score (vote),
        KEY nid (nid),
        KEY uid (uid)
      ) /*!40100 DEFAULT CHARACTER SET UTF8 */"
);
      break;
    case
'pgsql':
     
db_query("CREATE TABLE {plus1_vote} (
        uid int NOT NULL default '0',
        nid int NOT NULL default '0',
        vote tinyint NOT NULL default '0',
        created int NOT NULL default '0',
        PRIMARY KEY (uid,nid)
      );"
);
     
db_query("CREATE INDEX {plus1_vote}_score_idx ON {plus1_vote} (vote);");
     
db_query("CREATE INDEX {plus1_vote}_nid_idx ON {plus1_vote} (nid);");
     
db_query("CREATE INDEX {plus1_vote}_uid_idx ON {plus1_vote} (uid);");
      break;
  }
}
?>

In Drupal 6, we do this instead:

<?php
// $Id$
/**
* Implementation of hook_install().
*/
function plus1_install() {
 
// Create tables.
 
drupal_install_schema('plus1');
}
/**
* Implementation of hook_schema().
*/
function plus1_schema() {
 
$schema['plus1_vote'] = array(
   
'description' => t('The table used by the Plus1 module.'),
   
'fields' => array(
     
'uid' => array(
       
'description' => t('The primary identifier for the voter.'),
       
'type' => 'int',
       
'unsigned' => TRUE,
       
'not null' => TRUE),
     
'nid' => array(
       
'description' => t('The node that gets a vote.'),
       
'type' => 'int',
       
'unsigned' => TRUE,
       
'not null' => TRUE),
     
'vote' => array(
       
'description' => t('The vote.'),
       
'type' => 'int',
       
'size' => 'tiny',
       
'unsigned' => TRUE,
       
'not null' => TRUE),
     
'created' => array(
       
'description' => t('The timestamp of when the voter voted.'),
       
'type' => 'int',
       
'unsigned' => TRUE,
       
'not null' => TRUE)),
   
'primary key' => array(
     
'uid',
     
'nid'),
   
'indexes' => array(
     
'score' => array('vote')),
  );
  return
$schema;
}
/**
* Implementation of hook_uninstall().
*/
function plus1_uninstall() {
 
// Remove tables.
 
drupal_uninstall_schema('plus1');
}
?>

Note that we’re creating a composite key as primary key. The voter and the node he votes for will always come in a unique combination. In other words, you can give a thumbs up only once for a any given content.

2. We then modify our plus1.info file.

In Drupal 5:

name = Plus 1
description = "A +1 voting widget for nodes. "
version = "$Name$"

In Drupal 6:

name = Plus 1
description = "A +1 voting widget for nodes."
core = 6.x

('Version' is deprecated in Drupal 6.)

3. We change our use of the menu hook in plus1.module.

In Drupal 5 we had:

/**
* Implementation of hook_menu().
*/
function plus1_menu($may_cache) {
  $items = array();
  if ($may_cache) {
    $items[] = array(
      'path' => 'plus1/vote',
      'callback' => 'plus1_vote',
      'type' => MENU_CALLBACK,
      'access' => user_access('rate content'),
    );
  }
  return $items;
}

In Drupal 6, we do the following:

/**
* Implementation of hook_menu().
*/
function plus1_menu() {
  $items['plus1/vote/%'] = array(
    'title' => 'Vote',
    'page callback' => 'plus1_vote',
    // 'plus1' is the 0th arg. in the path, 'vote' is the 1st, 
    // and the node id is the 2nd...
    // hence, we pass array(2) to 'page arguments'
    'page arguments' => array(2), // where my wildcard is
    'access arguments' => array('rate content'),
    // always use MENU_CALLBACK for ajax requests
    'type' => MENU_CALLBACK,
  );
  return $items;
}
?>

Note that this symbol: % is a wildcard for the node hii-dee.

4. We modify the callback function plus1_vote($nid).

We have a new and improved way to write JSON in Drupal 6. We use the new function drupal_json($var = NULL). It sets the header for the JavaScript output to 'Content-Type: text/javascript; charset=utf-8'.

In Drupal 5:

/* This print statement will return results 
 * to the jQuery's request.
 */
print drupal_to_js(array(
  'score' => $score,
  'voted' => t('You voted'),
  )
);

In Drupal 6:

/* This print statement will return results 
 * to the jQuery's request.
 */
print drupal_json(array(
  'score' => $score, 
  'voted' => t('You voted'),
  )
);

5. We register our theme function.

In Drupal 6, all modules must register all their theme functions via the new hook hook_theme().

Therefore, we add the following function to our plus1.module file.

/**
* Implementation of hook_theme().
*/
function plus1_theme() {
  return array(
    'plus1_widget' => array(
      'arguments' => array('nid', 'score', 'is_author', 'voted'),
    ),
  );
}

6. We modify our theme function theme_plus1_widget($nid, $score, $is_author, $voted) to account for the change in signature of the function l() in Drupal 6.

In Drupal 5:

<?php
$output
.= l(t('Vote'), "plus1/vote/$nid", array('class' => 'plus1-link'));?>

?>

In Drupal 6:

<?php
$output
.= l(t('Vote'), "plus1/vote/$nid", array('attributes' => array('class' => 'plus1-link')));
?>

7. We thoroughly clean up our act when it comes to our jQuery.

In the source code of our Drupal 5-compliant version, the file jquery.plus1.js contained this:

// $Id$
// Global killswitch: only run if we are in a supported browser.
if (Drupal.jsEnabled) {
  $(document).ready(function(){
    $('a.plus1-link').click(function(){
      var voteSaved = function (data) {
        var result = Drupal.parseJson(data);
        $('div.score').fadeIn('slow').html(result['score']);
        $('div.vote').html(result['voted']);
      }
      $.get(this.href, null, voteSaved);
      return false;
    });
  });
}

In Drupal 6, we will NOT use the method Drupal.parseJson — that function is deprecated in Drupal 6. We’ll use the jQuery.getJSON method instead.

// $Id$
// Global killswitch: only run if we are in a supported browser.
if (Drupal.jsEnabled) {
  $(function(){
    $('a.plus1-link').click(function(){
      $.getJSON(this.href, function(json){
        $('div.score').hide().fadeIn('slow').html(json.score);
        $('div.vote').html(json.voted);
      });
      return false;
    });
  });
}

8. Then we’ll go and read about this wonderful jQuery method jQuery.getJSON. For your convenience

This module has been committed to Drupal CVS. The link to the project page is http://drupal.org/project/plus1.
AttachmentSizeHitsLast download
plus1.tar12 KB406 years 11 weeks ago
Last edited by Caroline Schnapp about 5 years ago.

One file is attached to this posting. Login or register to download this file.


Comments

I really hope the chapter

I really hope the chapter isn't called "Using Jquery" - it shows an utter lack of copyediting, and one of the most common, and egregious mistakes in any sort of writing: improper use of names. It's "jQuery", not Jquery (or, in your case, jquery). /me starts waxing poetic about googling for people, xeroxing rollerblades and white-outting typos whilst rollerblading. Fiddle-hee, fiddle-hoo!

good

agree with you

yes agree with you waaa

yes agree with you waaa

It's spelled correctly in the book

My bad. I white-outted the typos in my post.

***Warning: Pot calling kettle black***

@Morbus Iff
Many things can be said better with humility.

@Morbus

Wow. Just rip the guy apart over a name. I know it's jQuery too but no reason to be a snob over it!

Thanks

Hey thanks for a fantastique overview on converting this tutorial from drupal 5 to drupal 6. It's too been a book I read from cover to cover.

I actually needed this for work and was starting to convert original plus1 with zero exprience writing module for 6.x. Then decided to google "plus1" just for the hell of it and that's how I've come across your site :)

What I ended up doing was changing this thing from plus1 to plus1minus1, digg style. I am actually also planning to allow unauthenticated users to submit a vote, and I plan to use their IP address as a unique identifier so they don't vote twice. Or may do it with a cookie. Don't know yet.

Seeing as this module has been discontinued: http://drupal.org/project/vote_up_down, I decided to make plus1 sophisticated enough to replace it.

I may submit it to CVS on drupal, I haven't decided yet. Hope you don't mind? I will give credit to you.

Thanks again,
Vlad

What I ended up doing was

What I ended up doing was changing this thing from plus1 to plus1minus1, digg style. I am actually also planning to allow unauthenticated users to submit a vote, and I plan to use their IP address as a unique identifier so they don't vote twice.

I created a project for the module on Drupal.org. Maybe I should add an option to the module for minus 1 functionality. Damn it, then the name of the module really should have been plus1minus1, just like yours.

Using the IP address as unique identifier for anonymous voting seems like a better idea at first glance, and it'd be easier to implement too. People can clear their cookies (wicked people...).

Maybe I'll see you there: http://drupal.org/project/plus1

Well I have decided to

Well I have decided to release the code on sf.net for now, because drupal CVS admins are taking forever.

http://sourceforge.net/projects/plus1minus1/.

There are some screenshots, I styled it a little bit:

http://sourceforge.net/project/screenshots.php?group_id=232327

Anonymous voting yes some users can clear cookies etc. I've setup code to use IP address, but then changed back to cookies because where server is hosted it's VMWare and for some reason it doesn't see outside visitor's IP addresses. All visitors to that server appear as having same IP.

So anyway, even to a newbie developer I think it's pretty easy to modify. Here's module's code:

http://plus1minus1.cvs.sourceforge.net/plus1minus1/plus1minus1/plus1minu...

It's still pretty fresh but a good starting point to those who may need this.

Glad I could help, Vlad

Hope you don't mind? I will give credit to you.

Sure, no problem. And thank you :-)

Patiently Waiting For Pro Drupal Development 2nd Edition

I hope Matt finishes this soon! Lullabot's been spending time with a DVD learning series recently, so maybe that's taking up the time. I watched the first cut, and it's not bad. Covers a lot of stuff for newbies (including myself). So, it's not a bad supplement to the new edition. I just hope v.7 isn't too much different, now that I'm spending most my time with v.6.

Learning Drupal 6 Module Development

I hope Matt finishes this soon!

Amazon's publication date now for the second edition is August 25, 2008.

To me this is end of summer.

There's another great book on module development for Drupal 6 that you can get now: Learning Drupal 6 Module Development. It really is a great book too.

Please submit this to the drupal repository ASAP

Please submit this work to the drupal.org repository as soon as possible. What you have written verbatim.

If it does have bugs it is as at least good enough for a development snapshot release. The best way to work out any issues with this code will be to get it in front of as many developers as possible who can collaborate on the project.

If you don't feel comfortable doing it I can do it for you and you can contribute any changes to that project. I think the plus and minus features are good ideas. And user should only be able to digg/bury if they are logged in.

Done

This module has been committed to Drupal CVS. The link to the project page is http://drupal.org/project/plus1.

Great.

I will check it out. I am planning on using this module on rickyroad.com to rank games.

Thank you for the work you have done. This is what makes open-source a success.

You're welcome

The CSS applied to the voting widget out of the box is blah. The widget needs CSS styling. The module does come with a CSS file, but the rules in it beg for serious CSS overriding.

Eventually, I should make the widget more appealing out of the box.

Thank you so much for the nudge, Chris. I needed a little push.

I wonder if the module should support anonymous voting eventually. It's certainly something I would not use myself, though.

But before we delve into

But before we delve into this, here is something you should know. If you’ve worked through the example at the beginning of the chapter where we add jQuery code to a node, and you have not seen the first paragraph fade in as it did in Drupal 5, don't be alarmed. You’ll have to first hide the paragraph. When you think about it... the fact that this worked as is with an earlier version of the jQuery library is a bug.
http://e-papierossy.com.pl/en/e-papierosy/120-e-papierosy-gambit-77890.html
http://e-papierossy.com.pl/en/e-papierosy/118-e-papierosy-zerok-za54113.html
http://e-papierossy.com.pl/en/e-papierosy/116-e-papierosy-zerok-z11334.html
http://e-papierossy.com.pl/en/e-papierosy/114-e-papierosy-zerok-z5412.html

It looks great so far

We have put it on a sandbox server and it is working so far. Can you add the "Topherker" account to the developers list for our team? We would like to add a quick administration form so we can filter what nodes can have the widget and which wont. I will add the necessary artifacts and commit the changes in the next day or two. That is if we have your permission to do so.

I will add you now.

The module really needs an admin page to select content types, for sure.

Thank you!

Do you have a CVS account?

I am unable to grant topherker with CVS access to the module.

My account is having some issue

I don't have contributor status at the moment for the CVS root. Let me send off an email to the team. I will get back to you.

The CVS admins way have an issue with this

There may be an issue with a drupal 5.x version of plus1 and this version have a separate project space. If there is a project for a module that works in an earlier version of Drupal they do not want a separate project for the module for a new version of Drupal. They need to create a branch in CVS for the new code. I'm sorry I didn't even think of that.

But having said that, I can't find the drupal 5.x version of this project so it is possible that it is okay. There are other voting modules but nothing that I can find that does this specifically. Do you know if there is a formalized plus 1 project for drupal 5 or previous? I don't want to fudge it, if there is a project out there it should be merged into one. It may possibly take some time and red taping but overall its worth it to have everything done in a structured way.

I am resubmitting the CVS application for "topherker" based on our other modules so during this app process your project shouldnt come under question.

I will keep you updated.

Thanks

Thanks a lot for this great article : very usefull for writing ajax modules for Drupal 6 !

Hello Franck

An other and far more useful 'tutorial' on Ajax is chapter 5 of Learning Drupal 6 Module Development by Packt Publishing. The title of the chapter is Using JavaScript and Ajax/JSON in Modules. I have two qualms about the author's implementation though:

  1. The author, Matt Butcher, does not take advantage of the new Drupal 6 function drupal_json(). He manually goes about setting a header and writing JSON with printf.

    Here is the function he uses to return JSON to the browser...

    /**
     * Callback to handle requests for philquotes content.
     * @return string JSON data.
     */
    function philquotes_item() {
      $item = _philquotes_get_quote();  
      drupal_set_header('Content-Type: text/plain; charset: utf-8');
      printf(
        '{ "quote": { "origin": "%s", "text": "%s"}}', 
        $item->title, 
        $item->body
      );
    }

    While this would work for all modern browsers, and makes use of a Drupal helper function:

    /**
     * Callback to handle requests for philquotes content.
     * @return string JSON data.
     */
    function philquotes_item() {
      $item = _philquotes_get_quote();  
      drupal_json(array('text' => $item->body, 'origin' => $item->title));
    }
  2. The author uses a deprecated Drupal function to read the JSON returned from the Asynchronous HTTP request to Drupal, Drupal.parseJSON().

    Here is the content of the JavaScript file authored by Matt Butcher...

    // $Id$
    /**
     * The Philquotes object.
     */
    var Philquotes = {};
     
    if(Drupal.jsEnabled) {
      $(document).ready(
        function(){
          $("#philquotes-origin").after("<a>Next &raquo;</a>")
            .next().click(Philquotes.randQuote); 
        }
      );  
      /**
       * A function to fetch quotes from the server, and display in the 
       * designated area.
       */
      Philquotes.randQuote = function() {    
        $.get(Drupal.settings.philquotes.json_url, function(data) {      
          myQuote = Drupal.parseJson(data);      
          if(!myQuote.status || myQuote.status == 0) {
            $("#philquotes-origin").text(myQuote.quote.origin);
          	$("#philquotes-text").text(myQuote.quote.text);
          }      
        }); // End inline function
      } // End randQuote function
    }

    While the following works top notch, is far shorter, much more elegant (in my humble opinion), and it uses jQuery's getJSON()!

    // $Id$
    if (Drupal.jsEnabled) {
      jQuery(function() {
        jQuery('<a/>').text('Next &raquo;').attr('href', '#').appendTo(jQuery('#block-philquotes-0')).click(function(ev) {
          jQuery.getJSON(Drupal.settings.philquotes.json_url, function(json){
            jQuery('#philquotes-text').text(json.text);
            jQuery('#philquotes-origin').text(json.origin);
          });
          ev.preventDefault(); // same as a return false;
        });
      });
    }>

    Funny how I added the anchor... I went the other way around: I created the link and then appended it to the div element, using appendTo()... whereas the author found where to add the link first, and used the function after() on that insertion point in the document. Many ways to skin the kitty.

How to pass values as parameters via $.Get()

The approach taken by VanDyk and Westgate in the 1st and 2nd editions of "Pro Drupal Development" is the mapping an AJAX request to a URL which is then mapped to a call back function. Got it. But, no where is the litterature (print and online) can I find an example of using the
params parameter of the $.get(url, params, callback);

In my module, I have a unique hard coded url (e.g. "ActiveField/field-trip"). I noticed that VanDyk and Westgate use this.href, which makes sense because the AJAX call is based on the OnClick event of a link with plus1/vote/$nid. However, the path that is defined in function plus1_menu() is plus1/vote .

So, my question is how does one send values to Drupal via the params parameter?
I can see how to build the $.get() function call, but I cannot see how the Drupal function that maps to the callback URL will be able to handle the values coming in. Based on my understanding, the values need to come in as part of the URL like in views or plus1/vote/$nid

Drupal path is a query string

When trying to access the URL http://EXAMPLE.com/plus1/vote/4 for example, one is actually doing a GET request with params q=plus1/vote/4. The URL used by the web server, after rewriting the incoming request, is http://EXAMPLE.com/index.php?q=plus1/vote/4. That's why you see no mention of using some additional parameters with the GET request anywhere in Drupal's literature.

So what am I trying to say? You are stuck with using the q parameter, hence to use only url and not use data in jQuery.get(url, [data], [callback], [type]).

Follow up

Thank you for the feedback. Much appreciated.

Just to follow up, the way that I am passing data from the $.get() AJAX function down to Drupal is via the $_GET[] array. I got my module working in Drupal 5.x. I have ported it to Drupal 6x based on this article, which was very, very helpful!

I have started a forum topic at http://drupal.org/node/468724 because I hitting a very obscure bug. I have reference this article in the forum topic.

I welcome your insight.

As a block?

This is almost exactly what i need for a site i'm working on. I have a couple of questions though. How hard would it be to make this functionality print out as a block instead? Also, how hard would it be to limit how many nodes a user could vote on? I'm working on a contest site where voters get three votes they can apply to any entry.

Any help would be much appreciated,

thanks!

Thanks for the info!

I was looking at how to create modules, and also modules that also use jQuery in Drupal 6. You helped a ton! Thanks much. I'll go check out your project now.

Hi i am trying to send the

Hi

i am trying to send the AJAX request to the amazon module installed.

I created the menu item in the amazon_menu() function i.e.

$items['admin/settings/amazon/ajax'] = array(
'title' => 'AjaxRequest',
'page callback' => 'amazon_ajax_callback',
'file' => 'amazon.admin.inc',
'access callback' => 'user_access',
'access arguments' => array('ajax request'),
'type' => MENU_CALLBACK
);

And i created the request by
var url = 'http://localhost/books/admin/settings/amazon/ajax';
$.post(url,
{isbn_no:isbn_id},
function(data){
alert(data.isbn);
},'json');

But noting is happening.

Any help or suggestion would be greatly appriciated.

Thanks
Gaurav

Hello I'm dummy in Drupal! I

Hello I'm dummy in Drupal! I found a module which implement the function in AJAX that i want, but it only works in Drupal 5.X. I Prefer use it than username_check.module.

But before we delve into

But before we delve into this, here is something you should know. If you’ve worked through the example at the beginning of the chapter where http://e-papierossy.com.pl/en/e-papierosy/96-e-papierosy-gambit-5609.html we add jQuery code to a node, and you have not seen the first paragraph fade in as it did in Drupal 5, don't be alarmed. You’ll have to first hide the paragraph. When you think about it... the fact that this worked as is with an earlier version of the jQuery library is a bug.
http://e-papierossy.com.pl/en/e-papierosy/99-e-papierosy-gambit-1221.html

In Drupal 6's excellent

In Drupal 6's excellent SimpleTest module, a method called drupalPost() allows you to simulate a button press on a form by taking the form's data and using HTTP POST ...!

Drupal Solutions

If everybody explained things as meticulously as you, I'd be less lost than I am - unfortunately. You're doing a great job in explaining everything related to Drupal! swinger

jQuery provides a few

jQuery provides a few different Ajax commands, depending on your exact requirements. Here is the simplest Ajax .

Drupal is one of many

Drupal is one of many popular Web content management systems that run an open source policy.

Great animating ideas

Great animating ideas you have, as acted to become a good way to be aware that other people have the identical passion. I really hope to read even more things about it.
Shimla Manali Package | Shimla Kullu Manali Tour Packageiveke

Plus1

Hey, I've been struggling with this plus1 issue for some time now and finally found this thread which solved my problem. Thank you so much! lagerlogistik

Drupal CMS Services

Very informative post. I was looking for information about this topic and this post really helped me a lot. Thanks for sharing.

web design

I like the way you described the topic with such clarity. This is something I have been thinking about for a long time and you really captured the essence of the subject.
web design liverpool

Thanks for this information

Very great post. I was looking for ages to find information about this. THanks for sharing

Ajax forever

What is better than Ajax. But now we can use it as well in Dupral. Thanks for sharing

I would disagree

I would disagree. I found the above explanation much easier to understand than trying to figure out the Example module, which, as extensive as it seems, was entirely lacking application to my own use cases.

There's just no substitute for explaining the basics.

Would you please supply

Would you please supply for multiple input separated by commas? I want to make user tags, where the author can input more than one username into the autocomplete input separated by commas.

Thank you very much.

first project in Ajax

Just done my first little project in Ajax, this is really great and for beginners easy to learn. This site helps as well to understand it easier. Thanks

Worth Bookmarking

Sant Ritz facilities provide full family entertainment needs for your family and loved ones. Indulge in a serene and tranquil lifestyle right in the heart of Potong Pasir.

I found a module which

I found a module which implement the function in AJAX that i want, but it only works in Drupal 5.X.

well-written

Twin Fountains EC facilities provide full family entertainment needs for your family and loved ones. Indulge in a serene and tranquil lifestyle right in the heart of Woodlands.
Woodlands EC

Nice one..

Congress President and UPA Chairperson Sonia Gandhi inaugurated a conference of the South Asia Autism Network in New Delhi on Monday. Representatives from India, Bangladesh, Thailand and WHO, SEARO will participate in the daylong conference. sonia Gandhi|
Rahul Gandhi||
Priyanka Gandhi

Good thoughts and well-written

Bartley Ridge will be accessible via Bartley MRT station on the Circle Line. Commuting to Toa Payoh and Paya Lebar area as well as the city area is therefore very convenient. It is also near to many eateries along the Upper Serangoon area as well as NEX shopping mall.
Bartley Ridge

nice article

There is a new project going to come out in the market - Urban Vista, a condominium, which comes with prestigious and luxurious metropolitan concept, going to launch on 15th March 2013 (Friday, targeted date).

Urban Vista is a full condominium facilities residential project. It comprises 582 residential units and 3 shops spaces. It developed on a land size around 150,000 sqft. Urban Vista has 11 towers and it offers 1 bedroom, 2 bedroom, 2 bedroom dual key, 3 bedroom, 3 bedroom dual key, 4 bedroom, 4 bedroom dual key and penthouses. Urban Vista also offers various types of condo facilities such as kids' play pool, jacuzzi, yoga pavilion, clubhouse, wellness garden, car park, 24 hours securities, etc.

nice article

There is a new project going to come out in the market - Urban Vista, a condominium, which comes with prestigious and luxurious metropolitan concept, going to launch on 15th March 2013 (Friday, targeted date).

Urban Vista is a full condominium facilities residential project. It comprises 582 residential units and 3 shops spaces. It developed on a land size around 150,000 sqft. Urban Vista has 11 towers and it offers 1 bedroom, 2 bedroom, 2 bedroom dual key, 3 bedroom, 3 bedroom dual key, 4 bedroom, 4 bedroom dual key and penthouses. Urban Vista also offers various types of condo facilities such as kids' play pool, jacuzzi, yoga pavilion, clubhouse, wellness garden, car park, 24 hours securities, etc.
Urban Vista

I am impressed.

Belgravia Villas has full and unique facilities, which includes a guard house, clubhouse, children's playground, swimming pool, piano room, pool room, indoor gym, hydrotherapy beds, hydrotherapy baths, reading room, function room, onsen, jacuzzi.
The condo’s facilities provide full family entertainment needs for your family and loved ones. Indulge in a serene and tranquil lifestyle right in the heart of Ang Mo Kio.
Belgravia Villas

For vehicle owners, it takes

For vehicle owners, it takes less than 30 minutes to drive to the business hub and vibrant Orchard Road shopping district, via Tampines Expressway (TPE), Central Expressway (CTE) and Kallang-Paya Lebar Expressway (KPE)
Ecopolitan

Great

This is best site to spent time on .I just stumbled upon your chatty blog and wanted to say that I have really enjoyed reading your very well written blog posts. I will be your frequent visitor, that's for sure.

Seminar

I thought this piece was very smartly written, and it made me consider my own origins as a writer. As a writing instructor, I'm always worried about the future of my students. I wrote a blog post in response.

Jewel at Buangkok has full

Jewel at Buangkok has full and unique facilities, which includes a guard house, clubhouse, children's playground, swimming pool, Aerobic/Yoga room, piano room, pool room, indoor gym, hydrotherapy beds, hydrotherapy baths, reading room, function room, onsen, jacuzzi.
The condo’s facilities provide full family entertainment needs for your family and loved ones. Indulge in a serene and tranquil lifestyle right in the heart of Buangkok.
Jewel at Buangkok

J Gateway has full and

J Gateway has full and unique facilities, which includes a guard house, clubhouse, children's playground, swimming pool, Aerobic/Yoga room, piano room, pool room, indoor gym, hydrotherapy beds, hydrotherapy baths, reading room, function room, onsen, jacuzzi.
J Gateway

Jewel At Buangkok located at

Jewel At Buangkok located at Buangkok Drive 3 mins walk to Buangkok MRT station.

Jewel At Buangkok located at

Jewel At Buangkok located at Buangkok Drive 3 mins walk to Buangkok MRT station. Jewel Of Buangkok

I admire this post because

I admire this post because it give us enough knowledge on how to use Ajax in Drupal 6 . It really shared to us the different changes that we should bring to the module plus 1 to make it work in Drupal 6.

Corals At Keppel Bay
D'pristine

new township Iskandar

Coral Edge Residences has

Coral Edge Residences has full and unique facilities, which includes a guard house, clubhouse, Function Room & Indoor Gym Tennis Court, 50m Freeform Pool Pool Deck, Wading Pool, Splash Pool & Family Pool Jacuzzi & Hydro Spa, BBQ Area Dining and Play Fountain, Fitness Alcove & Children’s Playground and Garden Trail. The condo’s facilities provide full family entertainment needs for your family and loved ones. Indulge in a serene and tranquil lifestyle right in the heart of Punggol.
Thx
Coral Edge Residences

Pro Drupal Development 2nd edition

Thanks for the information that you have shared that the Pro Drupal Development 2nd edition will be published betimes this summer.
D'pristine

The condo’s facilities

The condo’s facilities provide full family entertainment needs for your family and loved ones. Indulge in a serene and tranquil lifestyle right in the heart of Bugis.
Several buses are available near Rocher Road and Beach Road along with shopping centers and restaurants.
DUO Residences

Thanks you, this is one of

Thanks you, this is one of the most interesting blogs that I have ever seen. Interesting article, Funny comment. Keep it up!
Jewel at Buangkok

I was impressed with your

I was impressed with your article. The information that you have shared on how to use Ajax Drupal 6 was very clear. Thanks!
Corals At Keppel Bay
D'pristine

Great Article! Keep it up!

Great Article! Keep it up! Tembusu Kovan

Thank you so much for

Thank you so much for sharing us some advice and tips on how to use Ajax Drupal 6 properly.
Corals At Keppel Bay
D'pristine

The condo’s facilities

The condo’s facilities provide full family entertainment needs for your family and loved ones. Indulge in a serene and tranquil lifestyle right in the heart of Punggol. http://www.braungresham.com/2013/05/david-braun-begins-summer-risk-management-webinar-series-on-52313/

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: <css> <html> <javascript> <mysql> <php> <span> <a> <b> <i> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <sup> <sub> <dd> <del> <blockquote> <img> <q> <p> <div>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <css>, <html>, <javascript>, <mysql>, <php>, <rails>, <ruby>.

More information about formatting options

CAPTCHA
I have to wonder if you're a human spammer or a machine, or less likely someone who cares to leave his or her thoughts behind.