swapping out text from php loop with js

hi all am new to javascript and need some help.

what am trying to make is a testimonial text slider / updater so i can show some nice customer feedback on a homepage for people to see how good we are rated.

the website has some guestbook submissions so i am getting them out of the database. I guess i want to loop through them and update the paragraph tag every 8 seconds then repeat this so it loops over all post and then restarts the loop over and over.

this is the code that i have managed to piece together by searching the internet.

<?php
// ADD PHP VARABLE TO ARRAY
$text= array();
	
	foreach($guestbook as $post) {
		$text[] = $post;
	}
?>

<script type="text/javascript">
var fromPHP=<? echo json_encode($text); ?>;

(function myLoop (i) {          
	setTimeout(function () {      
		for (i=0; i<fromPHP.length; i++) {

			var a= fromPHP[i];
			// update html with new text    
			 $("p").html(a);
			}

			if (--i) myLoop(i);      //  decrement i and call myLoop again if i > 0
   }, 8000)})(999999);               //  pass the number of iterations as an argument
</script>

Open in new window


i haven't tested my code yet but i want to know if this looks ok? and how i could animate the change in text (fade in) and is it ok to have a never ending loop, what should i load it in? document ready?
LVL 1
helpchrisplzAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

RobOwner (Aidellio)Commented:
I would personally simplify it by requesting the new guestbook submission every 8 sec using AJAX.
To make it easier, use jQuery:

<?php
if (array_key_exists('post',$_POST)) {
$text= array('wow you guys rock','what a champion','will use you guys next time, everytime','i\'ll be back');

	/*
	foreach($guestbook as $post) {
	$text[] = $post;
}
*/
echo $text[rand(0,3)];
return;
// if a request is made then process and return
}
else {
	//echo "hi";
}
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>PhpFiddle Initial Code</title>

<script type="text/javascript" src="/js/jquery/1.7.2/jquery.min.js"></script>

<script type="text/javascript">
/* 
* PhpFiddles REST API with JSON HTTP response supports Cross-Origin Resource Sharing, 
* and can be used with normal Ajax call in any web pages, for example, jQuery Ajax
*/
$(document).ready(function() {
	setInterval(getNextPost, 2000);
});
	function getNextPost() {
		//alert('calling');
		$.ajax({
			url: "<?php echo $_SERVER["SCRIPT_NAME"]; ?>",	
			type: "POST",	   // or "GET"
			data: 'post=1',
			cache: false,
			success: function(data) {
					$('#update').text(data);
			},
			error: function(data) {
				alert(data.result);
			}
		});
	}

</script>

<style type="text/css">
	
</style>

</head>

<body>

<div id='update' style="margin: 50px 10%;">
... updating ...
</div>

</body>
</html>

Open in new window

0
RobOwner (Aidellio)Commented:
Here is a demo of it working... obviously you can change the timeout to suit.  I had it at 2 sec so i didn't have to wait!  I also changed it to setInterval so it would repeat.

http://phpfiddle.org/main/code/4ms-x9d
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Julian HansenCommented:
If I read your code correctly you are going to be looping around and on each iteration calling myloop with a value of i - which is just overwritten. Each loop starts a new timer before the loop is finished - so it is going to grow exponentially - likely to crash everything.

Is this not what you want to do
var i = 0;
function myLoop()
{
    // Get the next item from the array of posts. We do this by
    // incrementing the i var and then taking the mod of this with the 
    // length which will produce an index in the range 0 to length-1

    var index = ( (i++) % fromPHP.length );

    // Fade out existing content, set new content and fade it back in again
    $("p").fadeOut('slow', function() {
         $("p").html(fromPHP[index]).fadeIn();
    });
}
$(function() {
    setInterval("myLoop()", 8000);
});

Open in new window

I have not tested this but the principle should be sound.
0
The Ultimate Tool Kit for Technolgy Solution Provi

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy for valuable how-to assets including sample agreements, checklists, flowcharts, and more!

helpchrisplzAuthor Commented:
Hi thanks for your help so far.

i have taken tagits example. What i have managed is:

got my data out the DB and into my array (s). I have tested my arrays so i know by code is working up to this point. now i am trying to update the html with 2 data changes. Can you just take a look at my code below to tell me what am doing wrong then i will be sorted. thank you.


// print_r ($text); my arrays are collecting the data! test successful!
// print_r ($name);

if (array_key_exists('post',$_POST)) {
	echo $text[rand(0,3)];
	echo $name[rand(0,3)];
	return;
	// if a request is made then process and return
}
else {
	//echo "hi";
}  
?>

<script type="text/javascript">
/* 
* PhpFiddles REST API with JSON HTTP response supports Cross-Origin Resource Sharing, 
* and can be used with normal Ajax call in any web pages, for example, jQuery Ajax
*/
$(document).ready(function() {
	setInterval(getNextPost, 2000);
});
	function getNextPost() {
		//alert('calling');
		$.ajax({
			url: "<?php echo $_SERVER["SCRIPT_NAME"]; ?>",	
			type: "POST",	   // or "GET"
			data: 'post=1',
			cache: false,
			success: function(data) {
					$('.quote').text(data);
					$('.test').name(data);
			},
			error: function(data) {
				alert(data.result);
			}
		});
	}

</script>



<div class="quote-box">
            <p class="quote">... updating ...</p>
          </div>
          <img class="quote-thingy" src="<?php echo $this->getThemePath()?>/images/9664dfda-13ef-49c9-b1e4-7bd6171e8aee_11-nubbin.png" width="42px" alt="9664dfda-13ef-49c9-b1e4-7bd6171e8aee_11-nubbin.png">
          <div class="w-clearfix by-section">
            <img class="person-icon" src="<?php echo $this->getThemePath()?>/images/82116c16-8d7d-444d-8ee6-de9ecd0fbba5_13-person-dude.png" width="66px" alt="82116c16-8d7d-444d-8ee6-de9ecd0fbba5_13-person-dude.png">
            <h3 class="test">... updating ...</h3>
          </div>

Open in new window

0
RobOwner (Aidellio)Commented:
Ok even though it should and probably does work, I wouldn't reference your quote and test <p> fields by class.  Give them an ID and reference them using the # instead of the .

that said your code looks ok.  Is it not doing something you're expecting it to?

Not sure if you're aware that:
echo $text[rand(0,3)];
echo $name[rand(0,3)];

Open in new window

will only return a random value from the first 4 elements of each array.  
Also worth nothing is whether the $name and $text arrays are related. ie does $text[3] relate to $name[3] as the above code will only "randomly" line up with the same index.  If they do relate then you'd need this
$rand_index = rand(0,3);
echo $text[$rand_index];
echo $name[$rand_index];

Open in new window

0
RobOwner (Aidellio)Commented:
in other words

<p class="quote">... updating ...</p>

becomes

<p id="quote">... updating ...</p>

and

<h3 class="test">... updating ...</h3>

becomes

<h3 id="test">... updating ...</h3>

then your code:

$('#quote').text(data);
$('#test').text(data);

Open in new window

0
Julian HansenCommented:
if (array_key_exists('post',$_POST)) {
	echo $text[rand(0,3)];
	echo $name[rand(0,3)];
	return;
	// if a request is made then process and return
}

Open in new window


The above is going to dump one long string - when it arrives at the success function both the .quote and .text elements will end up with the same string. If you are goin to go the AJAX route (not sure if that is the right way - if you have small number of text items then your original solution is better) but if you are then
$result = array();
$index = rand(0,3); // In case text and name are related
if (array_key_exists('post',$_POST)) {
	$result['text'] = $text[$index];
	$result['name'] = $name[$index];
}
die(json_encode($result));

Open in new window

In your success function
		$.ajax({
			url: "<?php echo $_SERVER["SCRIPT_NAME"]; ?>",	
			type: "POST",	   // or "GET"
			data: 'post=1',
			cache: false,
			dataType: 'json', // Add this
			success: function(data) {
                                        // JSON object returned
					$('.quote').text(data.text);
					$('.test').name(data.name);
			},
			error: function(data) {
				alert(data.result);
			}
		});

Open in new window

0
RobOwner (Aidellio)Commented:
(no points for this comment, I think it's good to reiterate this point)

@JulianH's made a good point about your method of sending data back to the browser.

It makes more sense as he's pointed out to collect the data, encode it and then send it back (with the die()).  

Side note for @JulianH: Curious as to your use of die() and not something like:

echo json_encode($result); 
return;

Open in new window

0
Julian HansenCommented:
@tagit,
old habbit - make sure the script terminates at that point - effect is the same - but no ambiguity about what happens next ...
0
RobOwner (Aidellio)Commented:
thanks and sure makes no difference just seems more violent ;)
0
helpchrisplzAuthor Commented:
hi thanks for everything you have both helped me understand better.

where am at:
am getting undefined :(

when using die(json_encode($result)); my page source stopped with [] so i used

echo json_encode($result);
      return;      

not sure how to fix the undefined pop up.

code so far:

$result = array();
$index = rand(0,3); // In case text and name are related
if (array_key_exists('post',$_POST)) {
	$result['text'] = $text[$index];
	$result['name'] = $name[$index];
	// print_r ($result); this outputs one text and name successfully.
	echo json_encode($result); 
	return;	
}
?>
<script type="text/javascript">
$(document).ready(function() {
	setInterval(getNextPost, 2000);
});
	function getNextPost() {
		//alert('calling');
		$.ajax({
			url: "<?php echo $_SERVER["SCRIPT_NAME"]; ?>",	
			type: "POST",	   // or "GET"
			data: 'post=1',
			cache: false,
			dataType: 'json', 
			success: function(data) {
                   // JSON object returned
					$('#quote').text(data.text);
					$('#test').name(data.name);
					
			},
			error: function(data) {
				alert(data.result);
				// am getting undefined :(
			}
		});
	}
</script> 

<div class="quote-box">
            <p id="quote" class="quote">... updating ...</p>
          </div>
          <img class="quote-thingy" src="<?php echo $this->getThemePath()?>/images/9664dfda-13ef-49c9-b1e4-7bd6171e8aee_11-nubbin.png" width="42px" alt="9664dfda-13ef-49c9-b1e4-7bd6171e8aee_11-nubbin.png">
          <div class="w-clearfix by-section">
            <img class="person-icon" src="<?php echo $this->getThemePath()?>/images/82116c16-8d7d-444d-8ee6-de9ecd0fbba5_13-person-dude.png" width="66px" alt="82116c16-8d7d-444d-8ee6-de9ecd0fbba5_13-person-dude.png">
            <h3 id="test" class="test">... updating ...</h3>
          </div>

Open in new window

0
Julian HansenCommented:
am getting undefined :(

when using die(json_encode($result)); my page source stopped with [] so i used

Sounds like your php script is not sending back what it should.

Before we fix that - one small change - that should have been in the first bit
// Initialise the array to have the expected members
$result = array(
    'text' => '', 
    'name' => ''
);
$index = rand(0,3); // In case text and name are related
// I also prefer isset or empty to the array_key_exists
if (isset($_POST['post'])) {
	$result['text'] = $text[$index];
	$result['name'] = $name[$index];
	// print_r ($result); this outputs one text and name successfully.
	echo json_encode($result); 
	return;	
}

Open in new window


Having said that - test your PHP script directly by making a small temporary chane

if (isset($_POST['post'])) {

Open in new window

to
if (isset($_REQUEST['post'])) {

Open in new window

Now call it in the address bar

yourscript.php?post=1

See what output you get.

If it is as expected then change REQUEST back to POST and in your code check the Console (FF / Chrome) to see what is being sent to the server and what is being returned.

I think your undefined is coming from a blank JSON string being returned - data.text is not defined - so we need to see why the return from the script is not right.
0
helpchrisplzAuthor Commented:
i have added your suggestions and still get the undefined so using:
http://localhost/sites/tseoc/?post=1
with $_REQUEST

i see this in the source code:
{"text":"Can.t thank you enough for the fantastic job you have done in promoting The Suitcase Saver.  Three enquiries this week from uk airports, Spain and Belgium and I know they have came from your hard work...","name":"Karen Duncan"}

could it be because the ajax isn't allowed to access my page?
All my code is on my homepage that is part of a theme i built for the CMS concrete5.
at the top of the themes template i have <?php  defined('C5_EXECUTE') or die(_("Access Denied.")); ?>

if i remove that it still says undefined though.
if i put it back to POST then i dont see anything in Console after refresh
0
helpchrisplzAuthor Commented:
ok testing away from the CMS.

i have created a index.php in the root of my xampp htdocs with the following code:

still getting undefined though.

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>  

<?php
$text= array('wow you guys rock','what a champion','will use you guys next time, everytime','i\'ll be back');
$name= array('bob','beeb','hotbill','i\bebbbf');
$result = array(
    'text' => '', 
    'name' => ''
);
$index = rand(0,3); // In case text and name are related
if (isset($_POST['post'])) {
	$result['text'] = $text[$index];
	$result['name'] = $name[$index];
	// print_r ($result); this outputs one text and name successfully.
	echo json_encode($result); 
	return;	
}
?>
<script type="text/javascript">
$(document).ready(function() {
	setInterval(getNextPost, 2000);
});
	function getNextPost() {
		//alert('calling');
		$.ajax({
			url: "<?php echo $_SERVER["SCRIPT_NAME"]; ?>",	
			type: "POST",	   // or "GET"
			data: 'post=1',
			cache: false,
			dataType: 'json', 
			success: function(data) {
                   // JSON object returned
					$('#quote').text(data.text);
					$('#test').name(data.name);
					
			},
			error: function(data) {
				alert(data.result);
				// am getting undefined :(
			}
		});
	}
</script> 

<p id="quote" class="quote">... updating ...</p>        
<h3 id="test" class="test">... updating ...</h3>

Open in new window

0
helpchrisplzAuthor Commented:
its working when i do it like this: with doctype

<?php
$text= array('wow you guys rock','what a champion','will use you guys next time, everytime','i\'ll be back');
$name= array('bob','beeb','hotbill','i\bebbbf');
$result = array(
    'text' => '', 
    'name' => ''
);
$index = rand(0,3); // In case text and name are related
if (isset($_POST['post'])) {
	$result['text'] = $text[$index];
	$result['name'] = $name[$index];
	// print_r ($result); this outputs one text and name successfully.
	echo json_encode($result); 
	return;	
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>  
<script type="text/javascript">
$(document).ready(function() {
	setInterval(getNextPost, 2000);
});
	function getNextPost() {
		//alert('calling');
		$.ajax({
			url: "<?php echo $_SERVER["SCRIPT_NAME"]; ?>",	
			type: "POST",	   // or "GET"
			data: 'post=1',
			cache: false,
			dataType: 'json', 
			success: function(data) {
                   // JSON object returned
					$('#quote').text(data.text);
					$('#test').text(data.name);
					
			},
			error: function(data) {
				alert(data.result);
				// am getting undefined :(
			}
		});
	}
</script> 
</head>
<p id="quote">... updating ...</p>        
<h3 id="test">... updating ...</h3>

</body>
</html>

Open in new window

0
helpchrisplzAuthor Commented:
ok so my php has to go above my doctype for it to work...

lol grrr
0
helpchrisplzAuthor Commented:
Its not working when i put the code above my doctype; in my CMS theme but it does work when i test outside of the CMS. I will try and read up on using ajax in concrete5

i found this link that i expect will help me: http://www.concrete5.org/community/forums/block_requests/ajax-call-access-denied./


thanks!
0
Julian HansenCommented:
You should not put the php in the same file as your output code. It should go in its own php file. It has only one purpose and that is to send back the text - don't mix that up with your index file.

Also time to move to HTML5 maybe ... doctype is a bit outdated.
0
helpchrisplzAuthor Commented:
ye i use Html5 in my themes.. was only useing that doctype as tagits example code used it.

why did i need to use url: "<?php echo $_SERVER["SCRIPT_NAME"]; ?>",:
when i shouldn't have it all in one file?

it echos the root url.

 

thanks.
0
Julian HansenCommented:
That was based on the assumption that you would be calling back to the page that contained the AJAX call.

You can do it that way but personally I prefer my AJAX functions to be in spearate scripts. They perform very specific tasks with very specific output that usually does not require a full doctype / head /body declaration - so mixing them up with a script that has those things is potentially a problem.

I would simply hard code the path to the script that handles the request in place of echo'ing the SCRIPT_NAME server var out.
0
RobOwner (Aidellio)Commented:
That was there for testing. Posting back to the same file makes it easier to show what's going on but Julian is right, it is good practice to have the components separated
0
helpchrisplzAuthor Commented:
ok thanks am looking at this now for more understanding of the CMS
http://www.concrete5.org/marketplace/addons/ajax-lessons/
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.