Hey folks,

I've got an Ajax script, using the Jquery js library, that takes an array of quotes, currently hard-wired into a randomquotes.php file (but could easily be adjusted to take the quotes from a database), and updates the page with a random quote every 5 seconds. It seems to be working relatively well, but the plan is to extend this into a module (or to adjust the existing quote module to do this).

Has anyone done this type of work before? I know already that I will need to adjust the Jquery library a little bit to remove some function duplication, so I'm prepared to do this.

However if someone has something like this scripted already, it would be especially handy.

You can check out what I'm talking about here.

Dave

Comments

jasonwhat’s picture

http://drupal.org/node/93139

Read through the thread. It now can use views module or category module to filter and use what you like...so you could make a node type called quote, or category/taxonomy called quote for a regular node and pull results from that dynamically.

dwees’s picture

Yeah I tried the Showcase module, but I couldn't get it to work properly, and it appeared to have function naming duplications with another module on one of my sites.

However, using Jquery (in modified form - thanks to the jquery47 module) and a bit of my own Javascript, I managed to get the quotes updating nicely.

Basically I can enter these quotes as a custom node using CCK, then pull a random quote out of my database using Ajax. I had to modify my page.tpl.php file to include both my custom Javascript (named randomquote.js if you have a JS viewer with your browser) and jquery-modified-compressed.js with each page.

You can view what I've got going (on a test-site, no production values here) at www.unitorganizer.com/drup.

The next step is to make sure that the random background colors and the random quotes don't repeat. #1 is going to be much easier for me than #2...I sense some $_POST data being passed back and forth.

Dave

bluecobalt’s picture

Hey Dave,

The quotes block is awesome! I've been imagining something similar, and would love a copy of your code. Would you please post it here for all of us once you have it figured out?

thanks,
blue

Blue Cobalt
dianovo, inc.
http://www.dianovo.com

Blue Cobalt
http://livingparadise.org
Conscious living for a better world.

dwees’s picture

Okay, this shouldn't be too hard to do.

1. Download the jquery47 module and upload it to your modules folder of your website. It doesn't need to be installed...

2. Download and install the CCK module, and enable the various submodules it includes.

3. Using CCK, create a custom node called 'quote'. It should have a single textfield with the name 'quote' as well.

4. Create a custom block and inside that block place the html:

<div id="quote">There is no time like the present.<br /><br />-Anonymous</div>

The div id of quote is to give the Javascript I've written a place to put the quote. The default quote is there so that users see something when they view the page. You could probably fix this with php to show a random quote on each page refresh as well, but I haven't bothered yet as I was mostly testing to make sure that this works.

5. Create a Javascript file, name it randomquote.js and upload it to a folder called /misc/js folder (which should be in the base directory of your Drupal site). This should contain the following Javascript:

function updateDiv(text) {
	var randomColor = new Array("#cdf8d9","#68a8d9","#ebaf41","#e06c41","#ffffe5","#72c055");
	var quote = document.getElementById("quote");
	var b = Math.round(Math.random()*5);
	quote.style.backgroundColor = randomColor[b];
	quote.innerHTML = text;
	return;
}

function badReturn() {
	updateDiv("There is no day like tomorrow.<br /><br > -anonymous");
	return;
}

var IntervalId;
IntervalId = setInterval('JQ.ajax({type: "POST", error: badReturn, url: "http://www.yourdomain.com/misc/randomquote.php", success: updateDiv, dataType: "html"})', 10000);

In the last line of this file, you may notice an absolute URL, which should you should change to point directly at your copy of the randomquote.php file.

The updateDiv function has some random colors which you can adjust (RGB format probably works here too). If you want to increase the number of random colors, then change the *5 in the var b line to whatever number is appropriate.

Also, you can adjust the badReturn function with a different quote. This is just so the users see something if the Ajax fails to connect to the server for some reason. You can also adjust the 10000 milliseconds at the end to some other number, this is supposed to be how often the quote is refreshed.

5. Create a file called randomquote.php and inside this file place the following code:

<?php

$select = "SELECT `field_enter_quote_value` FROM `node_content_quote`";

define(db_host, "localhost");
define(db_user, "your_database_user");
define(db_pass, "your_database_password");
define(db_link, mysql_connect(db_host,db_user,db_pass));
define(db_name, "your_drupal_database");

$connected = mysql_select_db(db_name); 	

$result = mysql_query($select);

if (!$result) {
	die('Invalid query: ' . mysql_error());
}

$num = mysql_num_rows($result);

for ($i = 0; $i < $num; $i++) {
	$quotes[$i] = mysql_result($result, $i);
}

srand((double)microtime()*1000000);
$a = rand(0, count($quotes)-1);
echo $quotes[$a];

?>

Note that you will have to adjust the database settings in here to exactly match your settings in the file 'settings.php' which can be found in your sites/default folder of your Drupal site. Also you may notice there is a $select variable in there, which is a database query. You will probably want to confirm that this SELECT is correct using something like phpmyadmin to confirm the name of the field.

6. Create a bunch of quote nodes, using the new custom node type called 'quote' so that you have something to populate your random quote block with.

7. In your page.tpl.php file, add the following lines between the <head> and </head> tags.

  <script type="text/javascript" src="<?php print $base_path ?>/modules/jquery47/jquery-modified-compressed.js"></script>
  <script type="text/javascript" src="<?php print $base_path ?>/misc/js/randomquote.js"></script>

These may need to be modified depending on what you've named your various files and where you've placed them.

You will probably also want to style the quotes, which handily have the CSS ID of 'quote' which makes it easy to adjust. I'm currently using:

#quote {
	display: block;
	height: 180px;
	border: 1px solid black;
}

in my style.css file. You could place a default background color in here as well, which will show up only on the page refreshes.

Hope this works out for you, let me know if I've made any mistakes in my explanation.

Dave

dksdev01’s picture

Hello Everybody,

Why don't we use drupal cms capability and create a page content for Dave step 5 above.
I think this will be better so that we can always have administration without doing ftp.
Just modified step 5 a bit...

// function to check request type 
function isAjaxCall() {
return isset($_SERVER['HTTP_X_REQUESTED_WITH']) &&
$_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
}

// prepare sql for database query
$select = "SELECT `field_enter_quote_value` FROM `node_content_quote`";

$result = db_query($select);

if (!$result) {
    die('Invalid query: ' . db_error());
}

$num = db_num_rows($result);

for ($i = 0; $i < $num; $i++) {
    $quotes[$i] = db_result($result, $i);
}

srand((double)microtime()*1000000);
$a = rand(0, count($quotes)-1);
echo $quotes[$a];    // echo only quotes for ajax request 
if(isAjaxCall()) {       // print no more content if ajax request 
exit;
}
else {
// for drupal node view
}
dwees’s picture

We'd need to modify the Ajax function as well to make sure it points to this page.

Dave

dksdev01’s picture

yes, Only will have to put new url to .ajax call. New Will look like --
IntervalId = setInterval('JQ.ajax({type: "POST", error: badReturn, url: "http://www.yourdomain.com/?q=node/ID", success: updateDiv, dataType: "html"})', 10000);

or

IntervalId = setInterval('JQ.ajax({type: "POST", error: badReturn, url: "http://www.yourdomain.com/node/ID", success: updateDiv, dataType: "html"})', 10000);

ID should be replaced with node id or url-aliases.

dwees’s picture

You could also check to see if the $_POST variable is set properly. I'm currently using the same function to set up the first quote (with an Iframe unfortunately...) so that I have a random quote ready for each new page view.

My new block has this code inside it:

<div id="quote"><iframe src="http://www.unitorganizer.com/drup/misc/randomquote.php" scrolling="no" frameborder="0" style="display:block;height:180px;width:180px;margin:0px;">Do not train children to learning by force and harshness, but direct them to it by what amuses their minds, so that you may be better able to discover with accuracy the peculiar bent of the genius of each.<br /><br />
- Plato</iframe></div>

and randomquote.php has been updated to have:

<?php

$select = "SELECT `field_enter_quote_value` FROM `node_content_quote`";

define(db_host, "localhost");
define(db_user, "database_user");
define(db_pass, "database_password");
define(db_link, mysql_connect(db_host,db_user,db_pass));
define(db_name, "database_name");

$connected = mysql_select_db(db_name); 	

$result = mysql_query($select);

if (!$result) {
	die('Invalid query: ' . mysql_error());
}

$num = mysql_num_rows($result);

for ($i = 0; $i < $num; $i++) {
	$quotes[$i] = mysql_result($result, $i);
}

srand((double)microtime()*1000000);
$a = rand(0, count($quotes)-1);

if (!isset($_POST['a'])) {
	echo "<html>\n";
	echo "<head>\n";
	echo "<style type=\"text/css\"> body { padding: 0px; margin: 0px; width: 180px; background-color: #FFCC00;} </style>\n";
	echo "</head>";
	echo "<body>";
}
echo $quotes[$a];

if (!isset($_POST['a'])) {
	echo "</body>";
}

?>

Notice the styling. This is to make the iframe behave as much as possible the same as the random quotes called by Ajax. It's an ugly solution, but it seems to be working. Also, in case the user doesn't have a modern browser, or one that fails to display Iframes, there is an internal quote that will show up on each page instead.

I've also added the same background-color to the CSS, which makes it less obvious that the first quote is being loaded differently than the others.

Dave

lbn.kiev.ua’s picture

Guys, there is a simplest way to get random record from database (MySQL):

SELECT * FROM table ORDER BY RAND() LIMIT 1

dwees’s picture

The problem with a random query from SQL is that there is no way to determine if you've done that query before, at least in PHP I can pass a quote id to the client, and then back again to confirm that the quote I've just randomized isn't the same as the one I just used.

Dave

RobRoy’s picture

Doesn't this work?

SELECT * FROM table WHERE nid != 23 ORDER BY RAND() LIMIT 1

Where 23 is the current node id?

--
Rob
Drupal Architect
Electronic Insight Corporation

Learn how you can contribute to Drupal.