I was tasked with creating a pop-up survey for a project. Fairly simple whether I used the jQuery dialog or not so I added a “Thank you” dialog that displays the survey results with a lightweight, css-based bar chart just for fun.
There is also an ASP.NET version of this post.

Pop-up Behavior
- Pop-up survey opens when page loads. Pop-ups on window.unload or window close are being blocked by most browsers due to abuse and overuse.
- Cookie is set when survey submitted or user opts out (“No, thanks” click).
- Closing dialog will not set cookie
All survey data is stored in a database and jQuery .post is used to shuttle the information back and forth.
Code for the survey dialog:
<div id="survey" title="Pop-Up Survey">
<p id="surveyDenied"><a href="#">No, thanks</a></p>
<p>Pop-up survey that cookies browser on completion or on opt-out. Short 411 demo survey.</p>
<form id="popup_survey" name="popup_survey" method="post">
<p><strong>Pink or blue?</strong><br />
<input id="pink" type="radio" name="radio_color" value="pink" />Pink<br />
<input id="blue" type="radio" name="radio_color" value="blue" />Blue</p>
<p><strong>Soccer or futbol?</strong><br />
<input id="soccer" type="radio" name="radio_sport" value="soccer" />Soccer<br />
<input id="futbol" type="radio" name="radio_sport" value="futbol" />Futbol</p>
</form>
<div id="error_message"></div>
</div>
It’s just a couple of radio buttons and a place for an error message. The submit is handled by the dialog button.
Here is the survey dialog code:
$(function(){
$('#survey').dialog({
bgiframe: true,
autoOpen: false,
modal: true,
width: 500,
resizable: false,
buttons: {
Submit: function(){
if($("input[name='radio_color']:checked").val() !== undefined && $("input[name='radio_sport']:checked").val() !== undefined){
setCookie('POPsurvey','POPsurvey',30);
$.post("process_survey.php", $("#popup_survey").serialize(),
function(data){
if(data.db_check == 'fail'){
$("#error_message").html("<p>Database not available. Please try again.</p>");
} else {
$("div.pink").css("width",data.perPink);
$(".perPink").html(data.perPink + "% (" + data.totalPink + ")");
$("div.blue").css("width",data.perBlue);
$(".perBlue").html(data.perBlue + "% (" + data.totalBlue + ")");
$("div.soccer").css("width",data.perSoccer);
$(".perSoccer").html(data.perSoccer + "% (" + data.totalSoccer + ")");
$("div.futbol").css("width",data.perFutbol);
$(".perFutbol").html(data.perFutbol + "% (" + data.totalFutbol + ")");
$(".totalRes").html(data.totalRes);
$('#survey').dialog('close');
$('#survey_thanks').dialog('open');
}
}, "json");
}else{
$("#error_message").html("<p>Please answer all questions.</p>");
}
}
}
});
});
Lots of stuff but it does several things. First, on submit, it checks that the user answered both questions. Then it sets the cookie. And, finally, it sends the form data off via post and puts the response in elements on the page that are part of the “Thank you” dialog. Speaking of which…
The “Thank you” dialog code is thus:
<div id="survey_thanks" title="Pop-Up Survey - Thank You!">
<p>Thank you for taking the time to answer our survey. Your input will help us improve the site.</p>
<p>Responses: <span class="totalRes"></span></p>
<div class="progress-container">
pink <span class="perPink"></span>
<div class="pink"></div>
blue <span class="perBlue"></span>
<div class="blue"></div>
</div>
<div class="progress-container">
soccer <span class="perSoccer"></span>
<div class="soccer"></div>
futbol <span class="perFutbol"></span>
<div class="futbol"></div>
</div>
</div>
$(function(){
$('#survey_thanks').dialog({
bgiframe: true,
autoOpen: false,
modal: true,
width: 500,
resizable: false,
buttons: {
Close: function(){
$(this).dialog('close');
}
}
});
});
Processing the Survey
The process_survey page adds the answers to the database and brings back the totals that are calculated by a view.
$dbhost = 'YOUR_SERVER';
$dbuser = 'YOUR_USERNAME';
$dbpass = 'YOUR_PASSWORD';
$dbname = 'YOUR_DATABASE_NAME';
$conn = mysql_connect($dbhost, $dbuser, $dbpass) or die ('Error connecting to mysql');
mysql_select_db($dbname);
$db_check = 'OK';
$return_arr = array();
if (!$conn)
{
$db_check = 'fail';
}
if ($db_check === 'OK'){
$insert_sql = mysql_query("INSERT INTO survey (color,sport) VALUES ('".$_POST['radio_color']."','".$_POST['radio_sport']."')");
if (!$insert_sql) {
$db_check = 'fail';
}
}
if ($db_check === 'OK'){
$fetch = mysql_query("SELECT * FROM v_totals");
/* Retrieve and store in array the results of the query.*/
while ($row = mysql_fetch_array($fetch, MYSQL_ASSOC)) {
$return_arr["totalPink"] = $row['Pink'];
$return_arr["perPink"] = round($row['Pink']/($row['Pink']+$row['Blue']),2)*100;
$return_arr["totalBlue"] = $row['Blue'];
$return_arr["perBlue"] = round($row['Blue']/($row['Pink']+$row['Blue']),2)*100;
$return_arr["totalFutbol"] = $row['Futbol'];
$return_arr["perFutbol"] = round($row['Futbol']/($row['Futbol']+$row['Soccer']),2)*100;
$return_arr["totalSoccer"] = $row['Soccer'];
$return_arr["perSoccer"] = round($row['Soccer']/($row['Futbol']+$row['Soccer']),2)*100;
$return_arr["totalRes"] = $row['Total'];
}
/* Retrieve and display the results of the query. */
}
else {
$db_check = 'fail';
}
/* Free connection resources. */
mysql_close($conn);
$return_arr["db_check"] = $db_check;
echo json_encode($return_arr);
The totals for the return data are stored in a view to prevent separate and multiple calls to the database. The table and the view can be created in MySQL as such:
CREATE TABLE IF NOT EXISTS `survey` ( `id` int(11) NOT NULL AUTO_INCREMENT, `color` varchar(4) DEFAULT NULL, `sport` varchar(6) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; CREATE VIEW `v_totals` AS select (select count(`survey`.`color`) AS `Expr1` from `survey` where (`survey`.`color` = 'pink')) AS `Pink`,(select count(`survey_2`.`color`) AS `Expr2` from `survey` `survey_2` where (`survey_2`.`color` = 'blue')) AS `Blue`,(select count(`survey_2`.`sport`) AS `Expr3` from `survey` `survey_2` where (`survey_2`.`sport` = 'futbol')) AS `Futbol`,(select count(`survey_2`.`sport`) AS `Expr3` from `survey` `survey_2` where (`survey_2`.`sport` = 'soccer')) AS `Soccer`,(select count(`survey_2`.`id`) AS `Expr4` from `survey` `survey_2`) AS `Total` from `survey` limit 0,1;
Cookies
The code to handle setting, checking, and deleting cookies is standard javascript:
function setCookie(c_name,value,expiredays)
{
var exdate=new Date();
exdate.setDate(exdate.getDate()+expiredays);
document.cookie=c_name+ "=" +escape(value)+((expiredays==null) ? "" : ";expires="+exdate.toGMTString());
}
function getCookie(c_name)
{
if (document.cookie.length>0)
{
c_start=document.cookie.indexOf(c_name + "=");
if (c_start!=-1)
{
c_start=c_start + c_name.length+1;
c_end=document.cookie.indexOf(";",c_start);
if (c_end==-1) c_end=document.cookie.length;
return unescape(document.cookie.substring(c_start,c_end));
}
}
return "";
}
function checkCookie(c_name)
{
cookie_value=getCookie(c_name);
if (cookie_value=="") {
$('#survey').dialog('open');
}
}
function deleteCookie(c_name) {
document.cookie = c_name +'=; expires=Thu, 01-Jan-70 00:00:01 GMT;';
}
The style for the “Thank you” graph:
div.progress-container {
border: 1px solid #ccc;
width: 150px;
padding: 1px;
margin-bottom: 5px;
background: white;
}
div.progress-container > div {
height: 12px;
margin-bottom: 2px;
}
div.progress-container > div.pink {
background-color:#CC6699;
}
div.progress-container > div.blue {
background-color: #3366CC;
}
div.progress-container > div.soccer {
background-color: #006633;
}
div.progress-container > div.futbol {
background-color: #663333;
}
You’ll notice in the .post function that the width of the bar graph is set with the percent of responses for each answer that comes back from the database.
If this post helped you out, please consider donating to help pay the hosting fees. 100% of the donations go to the web host.

RSS
Twitter
45 Comments
@Craig
If it won't adversely effect anything in the application or your server, go ahead and change it to PHP 5. json_encode() is a PHP 5 function.
You can certainly do a next, next type of form within the dialog. You just program the dialog buttons to post to the database up until the last question which posts to the db and closes the survey dialog.
Also is it possible to have say the first question then a next and then it show another question so theres about 5 – 6 questions in total then after the last one it show submit and takes you to the results??
PHP4 shall i change it to 5?
@Craig
Here is your problem:
Call to undefined function: json_encode() in /home/sites/aloeveradrink.me/public_html/process_survey.php on line 63
What version of PHP are you running?
Yes, all the tables are setup and it stores the data ok but for some reason doesnt display the results.
@Craig
I use a view (v_totals) to generate the numbers to be returned. Do you have the view set up?
Hi Jen,
I am trying to create a customer survey and would like to use this and add more questions to it.
The thing is i have setup this here http://bit.ly/9mUCvW but it doesnt seem to show the results once submitted…
It stores them in the DB but doesnt move to the results on the page.
Any Ideas?
cheers
Craig
@leoleung,
You are going to have to work with this but here is the basic sql for the view that I exported from mySQL:
CREATE VIEW `v_totals` AS select (select count(`survey`.`color`) AS `Expr1` from `survey` where (`survey`.`color` = 'pink')) AS `Pink`,(select count(`survey_2`.`color`) AS `Expr2` from `survey` `survey_2` where (`survey_2`.`color` = 'blue')) AS `Blue`,(select count(`survey_2`.`sport`) AS `Expr3` from `survey` `survey_2` where (`survey_2`.`sport` = 'futbol')) AS `Futbol`,(select count(`survey_2`.`sport`) AS `Expr3` from `survey` `survey_2` where (`survey_2`.`sport` = 'soccer')) AS `Soccer`,(select count(`survey_2`.`id`) AS `Expr4` from `survey` `survey_2`) AS `Total` from `survey`
That's because I have not response after click the submit button…so i didn;t realize what the problem is…
COuld you please describe how to create the view in mysql?
One Trackback