January

29

Pop-up Survey with jQuery UI Dialog

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.
pop-up survey

Pop-up Behavior

  1. Pop-up survey opens no matter what page of the website the user enters.
  2. Cookie is set when survey submitted or user opts out (“No, thanks” click).
  3. 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.

Demo

Download zip of all files

 

Further Reading:

  1. Using jQuery Datepicker and Dialog Box To Select Date Range
  2. Modal Confirmation Dialog on Form Submit: Javascript, jQuery UI, and Thickbox Varieties

39 Comments for Pop-up Survey with jQuery UI Dialog


Rudi Shumpert
January 29, 2010

Nice!

I'll bookmark this for sure.


jen
January 29, 2010

Thanks, Rudi.

Let me know if you ever want the complete source. I'll post it for you.

[...] This post was mentioned on Twitter by Rudi Shumpert, jen. jen said: New Post: Pop-up Survey with jQuery UI Dialog on jensbits.com: http://bit.ly/ceosHv [...]


Afiq
February 17, 2010

Hi jen, can I have the complete source please?
This is my email – @yahoo.com
Thank You


jen
February 18, 2010

@Afiq

On it's way to you now.


antonio
February 19, 2010

Hi,
Really nice work, i'd like to add this to my website, can you share the sources ?
Thank you


jen
February 19, 2010

@antonio

I put a zip of the files up. It includes the sql from my MySQL database. I use a view to tally the numbers. You will need to put your database credentials in the config file.

Hello Jen,
I love your work, thanks for this. I've been using other modal pop-up but without any cookie support. What you have here is exactly what I'm looking for. I plan to use it for collecting visitors info (opt-ins) not surveys.

How do I remove the "Submit" button from the pop-up? I'd love to replace the one I'm using at http://www.eugeneg.com

If you can direct me to the right direction, I would appreciate greatly!

Thanks a lot,
Eugene


Spyros
March 18, 2010

Exactly what I needed! Thank you Jen


rych
March 31, 2010

Nice, but missing what I'm looking for:
Any form should submit when the enter key is pressed while a form element has focus. Any suggestions on how to accomplish that with the jquery dialog ?
thanks!


jen
April 1, 2010

@rych
Take out the Submit button on the dialog and put your own submit button in the form.


leoleung
April 7, 2010

COuld you please describe how to create the view in mysql?


leoleung
April 7, 2010

That's because I have not response after click the submit button…so i didn;t realize what the problem is…


jen
April 7, 2010

@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`


Craig Smith
April 16, 2010

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


jen
April 16, 2010

@Craig
I use a view (v_totals) to generate the numbers to be returned. Do you have the view set up?


Craig Smith
April 16, 2010

Yes, all the tables are setup and it stores the data ok but for some reason doesnt display the results.


jen
April 16, 2010

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


Craig Smith
April 16, 2010

PHP4 shall i change it to 5?


Craig Smith
April 16, 2010

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


jen
April 16, 2010

@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.


Craig Smith
April 16, 2010

Ah ha that's done the trick thanks :)

Don't suppose you have an example with say two screens have you so I get a jist of the next button function?

I'm a bit new to all this but love to learn its great.

thanks

Craig


jen
April 16, 2010

@Craig
I may post another example like that but right now I got to get back to work. Unfortunately, I do not get paid for the stuff I put up on my blog.


Craig Smith
April 16, 2010

Oky doke, well hopefully you get time and ill definitely be checking back,

thanks :)


andy
April 22, 2010

Hi Jen,
Good Day! it was very helpful, except it does not display the result.I am using php5.x.I would appreciate very much if you could send me the complete source code for this.

regards,
andy


jen
April 23, 2010

@andy
The complete source code is available via the Download link in the post. The post has also been updated to simplify the process_survey.php and to include the SQL needed to set up the table and view for the database.


Raymond
April 24, 2010

May I have an ASP.NET version?


jen
April 24, 2010

@Raymond
If you know .NET you should be able to adapt it. Really, Raymond, it is difficult to pay the bills working for free.


Vinay
May 1, 2010

Jen,

Great stuff! But the download doesn't match the displayed code. Specifically, the two includes in process_survey.php (survey_config.php and db.php) are missing.

Vinay


Vinay
May 1, 2010

Just using the code displayed (not the downloaded) work! Thanks.


jen
May 1, 2010

@Vinay
Actually, they are not missing. If you look at the code in the post, where they are included is where you make your connection to the database. My database connections are included as separate files. However, I will update the zip because it is not exactly like the post.


Vinay
May 3, 2010

Jen,
Thanks for replying. How would you make this survey pop up on exit instead of entry?
Vinay


jen
May 3, 2010

@Vinay
If you google "Pop up on site exit" you should get several different ways to do that.


jank
June 14, 2010

Is there a way wherein the dialog box exits whenever the user clicks outside of it?


jen
June 15, 2010

@jank
Try this:

var dialogOverlayClose = function(event){ $('#survey').dialog('close'); }
$(document).bind('click', dialogOverlayClose);


jank
June 15, 2010

Thanks for the reply Jen but the effect right now is that clicking on the Survey dialog box itself exits the entire dialog box too.


jen
June 16, 2010

syed
July 2, 2010

Hi Jen,
I have read-only html table and add/edit/delete row options. if user want to edit data in table, they click on edit icon and it should load modal form with table row in editable mode. user modify it, click OK will pass new changes back to the read only table and click cancel will terminate the action without any changes.

Please let me know if you have similar example.
Many thanks


jen
July 2, 2010

@syed
I do not have an example of add/edit/delete rows in a table. Good idea for a new post. I try to get around to it sometime soon. Thanks.

Leave a comment

Why ask?

 

« | »