Avatar of helpchrisplz
helpchrisplz asked on

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?
JavaScriptjQuery

Avatar of undefined
Last Comment
helpchrisplz

8/22/2022 - Mon
Rob

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

ASKER CERTIFIED SOLUTION
Rob

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
See how we're fighting big data
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
Julian Hansen

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.
ASKER
helpchrisplz

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

I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck
Rob

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

Rob

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

Julian Hansen

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

Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
Rob

(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

Julian Hansen

@tagit,
old habbit - make sure the script terminates at that point - effect is the same - but no ambiguity about what happens next ...
Rob

thanks and sure makes no difference just seems more violent ;)
This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
ASKER
helpchrisplz

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

SOLUTION
Log in to continue reading
Log In
Sign up - Free for 7 days
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
ASKER
helpchrisplz

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
ASKER
helpchrisplz

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

Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
ASKER
helpchrisplz

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

ASKER
helpchrisplz

ok so my php has to go above my doctype for it to work...

lol grrr
ASKER
helpchrisplz

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!
All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
Julian Hansen

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.
ASKER
helpchrisplz

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.
Julian Hansen

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.
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
Rob

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
ASKER
helpchrisplz

ok thanks am looking at this now for more understanding of the CMS
http://www.concrete5.org/marketplace/addons/ajax-lessons/