Link to home
Start Free TrialLog in
Avatar of girlseekingcode
girlseekingcode

asked on

How do I add a sound notification to my chat box (PHP & jQuery)?

I'm working on creating a chat box (example here: http://tobealive.be/code/chat/chat2/index.php).

Each time a user enters a message in my chat box, I want them to hear a notification - exactly like this: http://www.chatbutton.com

Also exactly like http://www.chatbutton.com, I want my users to have the option to turn the sound notification off.

This is my first post here, so I hope I'm asking my question properly.  Thanks for viewing my question - very appreciated!



index.php:


<?
session_start();

if(isset($_GET['logout'])){	
	

	
	session_destroy();
	header("Location: index.php"); //Redirect the user
}

function loginForm(){
	echo'
	<div id="loginform">
	<form action="index.php" method="post">
		<p>Please enter your name to continue:</p>
		<label for="name">Name:</label>
		<input type="text" name="name" id="name" />
		<input type="submit" name="enter" id="enter" value="Enter" />
	</form>
	</div>
	';
}

if(isset($_POST['enter'])){
	if($_POST['name'] != ""){
		$_SESSION['name'] = stripslashes(htmlspecialchars($_POST['name']));
	}
	else{
		echo '<span class="error">Please type in a name</span>';
	}
}
?>
<!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>
<title>Chat - Customer Module</title>
<link type="text/css" rel="stylesheet" href="style.css" />
</head>

<?php
if(!isset($_SESSION['name'])){
	loginForm();
}
else{
?>
<div id="wrapper">
	<div id="menu">
		<p class="welcome"><b>Hi <?php echo $_SESSION['name']; ?>!</b></p>
		<!-- <p class="logout"><a id="exit" href="#">Exit Chat</a></p> -->
		<div style="clear:both"></div>
	</div>	
	<div id="chatbox"><?php
	if(file_exists("log.html") && filesize("log.html") > 0){
		$handle = fopen("log.html", "r");
		$contents = fread($handle, filesize("log.html"));
		fclose($handle);
		
		echo $contents;
	}
	?></div>
	
	<form name="message" action="">
		<input name="usermsg" type="text" id="usermsg" size="63" onfocus="if(this.value==this.defaultValue){this.value='';}" value="Hello!  Type your message here!  :)"/>
		<input name="submitmsg" type="submit"  id="submitmsg" value="Enter" />
	</form>
</div>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script type="text/javascript">
// jQuery Document
$(document).ready(function(){
	//If user submits the form
	$("#submitmsg").click(function(){	
		var clientmsg = $("#usermsg").val();
		$.post("post.php", {text: clientmsg});				
		$("#usermsg").attr("value", "");
		return false;
	});
	
	//Load the file containing the chat log
	function loadLog(){		
		var oldscrollHeight = $("#chatbox").attr("scrollHeight") - 20;
		$.ajax({
			url: "log.html",
			cache: false,
			success: function(html){		
				$("#chatbox").html(html); //Insert chat log into the #chatbox div				
				var newscrollHeight = $("#chatbox").attr("scrollHeight") - 20;
				if(newscrollHeight > oldscrollHeight){
					$("#chatbox").animate({ scrollTop: newscrollHeight }, 'normal'); //Autoscroll to bottom of div
				}				
		  	},
		});
	}
	setInterval (loadLog, 100);	//Reload file every .1 seconds
	
	//If user wants to end session
	$("#exit").click(function(){
		var exit = confirm("Are you sure you want to end the session?");
		if(exit==true){window.location = 'index.php?logout=true';}		
	});
});
</script>
<?php
}
?>
</body>
</html>

Open in new window

Avatar of Bruce Smith
Bruce Smith
Flag of United States of America image

I see this question has been neglected, sorry about that. You asked the question properly. This is really a simple JavaScript solution. You basically want a sound to play with an onclick event. So when a message is entered and the user hits some kind of "Post" button, you want the sound to play. Attached is sample code that will help you out. Also, the simple demo is here: http://www.patsmitty.com/ExpertsExchange/sound_effect_26875798/index.php

Cheers
index.php
Avatar of girlseekingcode
girlseekingcode

ASKER

Thank you so, so much!  I really appreciate your help.  :)  Your answer was well written and perfectly explained.  I definitely appreciate the sample code and demo.

The only catch is that I didn't clarify well enough what I'm looking for.  (Sorry!)  I need there to be a sound notification that all users hear when any user posts a message.  The main purpose of this is to audibly alert users when another user sends a chat message - particularly in cases where the chat message isn't seen visually because the window that contains the chat is open but not actively being viewed (as seen in apps like Google chat, Skype, or, again, http://www.chatbutton.com).  In other words, the sound alert is the only way for users to know that someone else is chatting when they aren't viewing the window containing the chat (i.e. when the window containing the chat is open but hidden or minimized or open behind another program or window)...kind of like a ringing phone in another room that a person doesn't see but can hear.  I hope I'm making sense...let me know if I need to clarify further.  :)

And thanks again for your wonderful help!!
Are you the chat posts going into a database or something?
Are the chat posts going into a database or something?

Excuse the Typos   :)
No worries on typos!  :)

The chat messages are being saved into a file entitled "log.html."  You can see this in the index.php code above.  Log.html is mentioned in two separate places within index.php:

#1
<div id="chatbox"><?php
	if(file_exists("log.html") && filesize("log.html") > 0){
		$handle = fopen("log.html", "r");
		$contents = fread($handle, filesize("log.html"));
		fclose($handle);
		
		echo $contents;
	}
	?></div>

Open in new window




#2
//Load the file containing the chat log
	function loadLog(){		
		var oldscrollHeight = $("#chatbox").attr("scrollHeight") - 20;
		$.ajax({
			url: "log.html",
			cache: false,
			success: function(html){		
				$("#chatbox").html(html); //Insert chat log into the #chatbox div				
				var newscrollHeight = $("#chatbox").attr("scrollHeight") - 20;
				if(newscrollHeight > oldscrollHeight){
					$("#chatbox").animate({ scrollTop: newscrollHeight }, 'normal'); //Autoscroll to bottom of div
				}				
		  	},
		});
	}
	setInterval (loadLog, 100);	//Reload file every .1 seconds

Open in new window


Log.html is also mentioned in a related filed named post.php:
<?
session_start();
if(isset($_SESSION['name'])){
	$text = $_POST['text'];
	
	$fp = fopen("log.html", 'a');
	fwrite($fp, "<div class='msgln'><div class='color'> <b>".$_SESSION['name']."</b> <small>(".date("g:i A").")</small>:</div> ".stripslashes(htmlspecialchars($text))."<small><small><br><br></small></small></div>");
	fclose($fp);
}
?>

Open in new window


Thanks again!  :)
Here's what I can think of that would be easiest: when a chat is posted, save the html file text as a variable like $prev_chat. When you load the log every .1 seconds, check the $prev_chat variable against the freshly-loaded log, if it's the same there has not been a new post, if they're different, there has been a new post so you would play the chime function just as in my previous post and then you set the $prev_chat variable to the freshly-loaded log.

The way you should really do this (if possible) would be to set up a database and roll off that so you could show individual new posts and such per user. Kind of like Facebook when you log in you can see the new notifications. Anyways, see what you think. Cheers
Thanks again for your help!  Seems Iike you have some great ideas - how exactly do I implement them? Forgive me, but I'm quite a novice.  Would you be able to provide sample code (ie that I can copy and paste into my code) with step by step instructions?  Hope I'm not asking too much here...it's just that your ideas sound good and I'd like to use them.  Whatever the case, thanks for all the time you've given me so far!  :)
Also - since I'm new to all this, should I be offering more points for this question?  As well, should I be accepting multiple solutions?
You're doing it fine. Make sure on future questions that you include all pertinent details in your original post. In this case your original question was answered via a JavaScript solution in my first comment. But then you had additional requirements which I don't mind accommodating, but some Experts will. I'm here to learn by helping folks out, even if it requires more than just "answering" the original question. By the way, thanks for using the code blocks when you posted your code. This helps a lot!

Anyhow, here is what your looking for, I think...
http://www.patsmitty.com/ExpertsExchange/notification_chime_26875798/chat.php

The source files are attached at the bottom of this post...

1. The JavaScript at the top of chat.php


var first_run = 0;
            var soundfile = "http://www.sound-effect.com/pirsounds/WEB_DESIGN_SOUNDS_WAV1/BUTTONS/CLICK15C.WAV";
            function playSound() {
                if (document.getElementById('isSound').checked===true) {
                    document.getElementById("dummy").innerHTML="<embed src=\""+soundfile+"\" hidden=\"true\" autostart=\"true\" loop=\"false\" />";
                }
            }
            //Load the file containing the chat log
            function loadLog(){
                var oldscrollHeight = $("#chatbox").attr("scrollHeight") - 20;
                $.ajax({
                    url: "log.html",
                    cache: false,
                    success: function(html){
                        prev_chat = $("#chatbox").html(); //get the last-known log.html contents via the chatbox div before updating the div in the next line
                        $("#chatbox").html(html); //Insert chat log into the #chatbox div
                        curr_chat = $("#chatbox").html(); //get the latest log.html contents via the upgraded chatbox div
                        if(curr_chat != prev_chat) { //conduct an if statement to see if the log.html file has changed
                            prev_chat = curr_chat;
                            if(first_run===0) {
                                first_run = 1; //if the user just loaded the page, we want to acknowledge that so the chime will play next time if there is a new chat
                            } else {
                                playSound();
                            }
                        }
                        var newscrollHeight = $("#chatbox").attr("scrollHeight") - 20;
                        if(newscrollHeight > oldscrollHeight){
                            $("#chatbox").animate({ scrollTop: newscrollHeight }, 'normal'); //Autoscroll to bottom of div
                        }
                    }
                });
            }
            setInterval (loadLog, 100);	//Reload file every .1 seconds

Open in new window

Line #1 sets a variable that we'll check a little later to see if the user has just loaded the page. If so, the chime will not sound because there won't have been any new posts since he's been on yet.

Lines #2 - #7 are the same function as before for the sound effect.

Lines #8 - #33 is the same logLoad() function that you wrote with a couple of additions:
          Lines #15, #17 - #25 do all the work for playing the notification sound if there has been a new post. For details / logic of what goes on in these lines, see the comments in the code.

That's it! The JavaScript that I have at the bottom may vary from yours as it just runs the AJAX to upgrade the log.html file via post.php.

If you have any further questions about any of this, don't be afraid to ask.

Cheers
chat.php
log.html
post.php
patsmitty, thank you SO MUCH!!  i can't tell you how much i appreciate all of your help.  your code was perfect and is working great.  all the time you've taken to answer my questions and explain everything is incredibly generous.  thanks for helping to teach people like me.  :)

---

in the course of working on the question i originally posted, i've come up with a second, related question:
how would i add the sound notification function you provided above to the following chat box?
http://www.linuxuser.at/chat/index.html

once again, i'm looking for sample code.  i've spent a lot of time trying to figure this out and, for the life of me, can't get it to function properly.

i don't know if i should be asking my second question in this thread or start a new one...or if i should be asking someone else since you've already helped me once...  

whatever the case, many, many thanks for your super help thus far!  :)

---

there are 3 files total (index.html, w.php, chat.txt) for http://www.linuxuser.at/chat/index.html :

1
index.html

 
<html>
	<head>
	<title>Ajax Chat 3.1 (Room 1)</title>
	<style type="text/css">
body 			{ padding-left:40px; background:#57767F; font-family:arial;}
input, textarea 	{ font-family: arial; color:white; background:#57767F; font-size: 14px; }
#content 		{ width:800px; text-align:left; margin-left:60px; }

#chatwindow 		{ border:1px solid #aaaaaa; padding:4px; background:#232D2F; color:white;  width:550px; height:auto; font-family:courier new;}
#chatnick 		{ border: none; border-bottom:1px solid #aaaaaa; padding:4px; background:#57767F;}
#chatmsg 		{ border: none; border-bottom:1px solid #aaaaaa; padding:4px; background:#57767F; }

#info 			{ text-align:left; padding-left:0px; font-family:arial; }
#info td 		{ font-size:12px; padding-right:10px; color:#DFDFDF;  }
#info .small 		{ font-size:12px; padding-left:10px; padding-right:0px;}

#info a 		{ text-decoration:none; color:white; }
#info a:hover 		{ text-decoration:underline; color:#CF9700;}
</style>
	</head>
	<body>
		<div id="info">
		<br>
			<table border="0">
				<tr>
					<td colspan="2">
						<a href="http://linuxuser.at/index.php?title=Most_Simple_Ajax_Chat_Ever"><font style="font-size:16px">Most Simple Ajax Chat</a> (v 3.1)</font><br>
					</td>	
				</tr>
				<tr>
					<td class="small">author</td>
					<td class="small"><a href="mailto:chris@linuxuser.at">chris at linuxuser dot at</a></td>				
				</tr>
				<tr>
					<td class="small">forum</td>
					<td class="small"><a href="http://forums.linuxuser.at/viewforum.php?f=6">forums.linuxuser.at</a></td>				
				</tr>
				<tr>
					<td class="small">home</td>
					<td class="small"><a href="http://www.linuxuser.at/index.php?title=Most_Simple_Ajax_Chat_Room">www.linuxuser.at</a></td>				
				</tr>
				<tr>
					<td class="small">source</td>
					<td class="small"><a href="http://www.linuxuser.at/chat/ajax_chat.zip">ajax_chat.zip</a></td>				
				</tr>
				<tr><td>&nbsp;</td></tr>
			</table>
					
		</div>
		
		
		<div id="content">
			<p id="chatwindow"> </p>		
<!--			<textarea id="chatwindow" rows="19" cols="95" readonly></textarea><br>
-->
			<input id="chatnick" type="text" size="9" maxlength="9" >&nbsp;
			<input id="chatmsg" type="text" size="60" maxlength="80"  onkeyup="keyup(event.keyCode);"> 
			<input type="button" value="add" onclick="submit_msg();" style="cursor:pointer;border:1px solid gray;"><br><br>
			<br>
		</div>

	</body>
</html>

<script type="text/javascript">
/****************************************************************
 * Most Simple Ajax Chat Script (www.linuxuser.at)		*
 * Version: 3.1							*
 * 								*
 * Author: Chris (chris[at]linuxuser.at)			*
 * Contributors: Derek, BlueScreenJunky (http://forums.linuxuser.at/viewtopic.php?f=6&t=17)
 *								*
 * Licence: GPLv2						*
 ****************************************************************/
 
/* Settings you might want to define */
	var waittime=800;		

/* Internal Variables & Stuff */
	chatmsg.focus()
	document.getElementById("chatwindow").innerHTML = "loading...";

	var xmlhttp = false;
	var xmlhttp2 = false;


/* Request for Reading the Chat Content */
function ajax_read(url) {
	if(window.XMLHttpRequest){
		xmlhttp=new XMLHttpRequest();
		if(xmlhttp.overrideMimeType){
			xmlhttp.overrideMimeType('text/xml');
		}
	} else if(window.ActiveXObject){
		try{
			xmlhttp=new ActiveXObject("Msxml2.XMLHTTP");
		} catch(e) {
			try{
				xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
			} catch(e){
			}
		}
	}

	if(!xmlhttp) {
		alert('Giving up :( Cannot create an XMLHTTP instance');
		return false;
	}

	xmlhttp.onreadystatechange = function() {
	if (xmlhttp.readyState==4) {
		document.getElementById("chatwindow").innerHTML = xmlhttp.responseText;

		zeit = new Date(); 
		ms = (zeit.getHours() * 24 * 60 * 1000) + (zeit.getMinutes() * 60 * 1000) + (zeit.getSeconds() * 1000) + zeit.getMilliseconds(); 
		intUpdate = setTimeout("ajax_read('chat.txt?x=" + ms + "')", waittime)
		}
	}

	xmlhttp.open('GET',url,true);
	xmlhttp.send(null);
}

/* Request for Writing the Message */
function ajax_write(url){
	if(window.XMLHttpRequest){
		xmlhttp2=new XMLHttpRequest();
		if(xmlhttp2.overrideMimeType){
			xmlhttp2.overrideMimeType('text/xml');
		}
	} else if(window.ActiveXObject){
		try{
			xmlhttp2=new ActiveXObject("Msxml2.XMLHTTP");
		} catch(e) {
			try{
				xmlhttp2=new ActiveXObject("Microsoft.XMLHTTP");
			} catch(e){
			}
		}
	}

	if(!xmlhttp2) {
		alert('Giving up :( Cannot create an XMLHTTP instance');
		return false;
	}

	xmlhttp2.open('GET',url,true);
	xmlhttp2.send(null);
}

/* Submit the Message */
function submit_msg(){
	nick = document.getElementById("chatnick").value;
	msg = document.getElementById("chatmsg").value;

	if (nick == "") { 
		check = prompt("please enter username:"); 
		if (check === null) return 0; 
		if (check == "") check = "anonymous"; 
		document.getElementById("chatnick").value = check;
		nick = check;
	} 

	document.getElementById("chatmsg").value = "";
	ajax_write("w.php?m=" + msg + "&n=" + nick);
}

/* Check if Enter is pressed */
function keyup(arg1) { 
	if (arg1 == 13) submit_msg(); 
}

/* Start the Requests! ;) */
var intUpdate = setTimeout("ajax_read('chat.txt')", waittime);

</script>

Open in new window


2
w.php

 
<?php
	/* author: chris at linuxuser.at 
		licence: GPLv2 
	*/
	
	$fn = "chat.txt";
	$maxlines = 18;
	$nick_length = 9;

	/* Set this to a minimum wait time between posts (in sec) */
	$waittime_sec = 0;	
	
	/* spam keywords */
	$spam[] = "nigger";
	$spam[] = "cum";
	$spam[] = "dick";
	$spam[] = "EAT coon";

	/* IP's to block */
	$blockip[] = "72.60.167.89";

	/* spam, if message IS exactly that string */	
	$espam[] = "ajax";
	
	/* Get Message & Nick from the Request and Escape them */
	$msg = $_REQUEST["m"];
	$msg = htmlspecialchars(stripslashes($msg));

	$n = $_REQUEST["n"];
	$n = htmlspecialchars(stripslashes($n));

	if (strlen($n) >= $nick_length) { 
		$n = substr($n, 0, $nick_length); 
	} else { 
		for ($i=strlen($n); $i<$nick_length; $i++) $n .= "&nbsp;";
	}

	if ($waittime_sec > 0) {
		$lastvisit = $_COOKIE["lachatlv"];
		setcookie("lachatlv", time());
 
		if ($lastvisit != "") {
			$diff = time() - $lastvisit;
			if ($diff < 5) { die();	}
		} 
	}

	if ($msg != "")  {
		if (strlen($msg) < 2) { die(); }
		if (strlen($msg) > 3) { 
			/* Smilies are ok */
			if (strtoupper($msg) == $msg) { die(); }
		}
		if (strlen($msg) > 150) { die(); }
		if (strlen($msg) > 15) { 
			if (substr_count($msg, substr($msg, 6, 8)) > 1) { die(); }
		}

		foreach ($blockip as $a) {
			if ($_SERVER["REMOTE_ADDR"] == $a) { die(); }
		}
		
		$mystring = strtoupper($msg);
		foreach ($spam as $a) {	
			 if (strpos($mystring, strtoupper($a)) === false) {
			 	/* Everything Ok Here */
			 } else {
			 	die();
			 }
		}		

		foreach ($espam as $a) {
			if (strtoupper($msg) == strtoupper($a)) { die(); }		
		}
				
		$handle = fopen ($fn, 'r'); 
		$chattext = fread($handle, filesize($fn)); fclose($handle);
		
		$arr1 = explode("\n", $chattext);

		if (count($arr1) > $maxlines) {
			/* Pruning */
			$arr1 = array_reverse($arr1);
			for ($i=0; $i<$maxlines; $i++) { $arr2[$i] = $arr1[$i]; }
			$arr2 = array_reverse($arr2);			
		} else {
			$arr2 = $arr1;
		}
		
		$chattext = implode("\n", $arr2);

		if (substr_count($chattext, $msg) > 2) { die(); }
		 
		$out = $chattext . $n . "&nbsp;| " . $msg . "<br>\n";
		$out = str_replace("\'", "'", $out);
		$out = str_replace("\\\"", "\"", $out);
		
		$handle = fopen ($fn, 'w'); fwrite ($handle, $out); fclose($handle);				
	}
?>

Open in new window



3
chat.txt

 
schurli&nbsp;&nbsp;&nbsp;| suddenly working again?<br>
chris&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| okay :)<br>
chris&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| is it working as well?<br>
chris&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| i believe so :D :D<br>
chris&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| how many lines?<br>
chris&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| not more?<br>
chris&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| okay<br>
tip&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| a few more <br>
tip&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| please<br>
judith&nbsp;&nbsp;&nbsp;&nbsp;| i love it<br>
judith&nbsp;&nbsp;&nbsp;&nbsp;| o yeah<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| asd<br>
oo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| asd<br>
oo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| ie compat<br>
chris&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| cool<br>
ooo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| asdasd<br>
ooo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| vºp<br>
ooo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| vúvÑ spam filter vñ<br>

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Bruce Smith
Bruce Smith
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
PATSMITTY YOU ARE THE BEST!

thank you for your extra super duper help!

thank you
thank you
thank you
! ! ! ! ! ! !

hope you have an incredible week  :)
Thanks man - you too! Glad to help.
patsmitty is awesome!  i am so grateful for his terrific help!