Web-Based Surveys Made Easy

Introduction
Most Web masters, at one time or another, are asked to create an online survey for their company's web site. This isn't a terribly difficult task with just plain HTML and traditional ASP, but suppose you'd like to be able to create a survey quickly -- I mean really quickly -- and you don't want to be stuck with the same look and feel you used last time. Rather, you want to create a survey with completely new questions and a fresh new look and feel. Well, that might be a bit time consuming, depending on how much of your original code you're able to reuse.

Suppose there existed an easy-to-use component that could be added to an ASP.NET Web page using a simple declarative syntax like <asp:Survey.../>, and POOF!, you've got a survey. Wouldn't that make life easier? Well, that control exists. It's called WebSurvey, and it's an ASP.NET Server Control I created specifically for the purpose of generating customizable web-based surveys quickly and easily.

To add such surveys to your Web site, all you need is copy of the assembly (the .dll file, available at the end of this article) and some basic knowledge of XML. In this article I will show you how you can use WebSurvey to quickly and easily add surveys to your Web site. In a future article I will examine the inner workings of the WebSurvey control in more detail.

Using the WebSurvey Control
Generating a survey with the WebSurvey control is surprisingly easy. If you've ever worked with an ASP.NET Web page before, and if you can create a little bit of well-formed XML, you should have the survey up and running in no time. To begin, you'll need to create an ASP.NET page to house the WebSurvey Control.

<%@ Register TagPrefix = "sstchur" Namespace = "sstchur.web.survey" Assembly = "sstchur.web.survey" %>
<%@ Page Language = "C#" %>

<html>
  <body>
    <form runat = "server">
      <sstchur:WebSurvey id = "ws" SurveyFile = "survey.xml" AnswersFile = "answers.xml" runat = "server"/>
    </form>
  </body>
</html>

The first thing to notice is the @Register directive that registers the control. This directive tells the ASP.NET Web page that any declarative Web control syntax prefixed with sstchur references a control defined in the sstchur.web.survey assembly and namespace. (The sstchur.web.survey assembly contains the class for the WebSurvey control, and this assembly will need to be added to your Web application's /bin directory.)

If you are using Visual Studio .NET, you can add the survey control to the Toolbox and then drag and drop it onto an ASP.NET Web page's Designer. This will automatically add the @Register directive and the declarative syntax in the ASP.NET Web page's HTML portion. You'll also need to add the assembly to the project's References folder. (This has the effect of adding the file to the application's /bin directory.)

In the HTML portion you'll find the declarative syntax for the WebSurvey control, <sstchur:WebSurvey ... >. Wherever you place this syntax is where the control will be rendered. You'll notice a few of the control's properties have been assigned declaratively (you could also use the Properties pane in the Designer in VS.NET). The WebSurvey control derives from System.Web.UI.WebControls.WebControl, meaning that it has all of the properties that a standard ASP.NET Web control has, such as BackColor, Font, Height, Width, and so on. In addition, WebSurvey has two other required properties:

  • SurveyFile - relative path to the XML file that contains the survey's questions.
  • AnswersFile - relative path to the XML file that will store the answers to the survey's questions. (This file need not exist initially).

Creating the survey.xml File
A FileNotFoundException is thrown.As it stands right now, the sample code we examined above won't run if the SurveyFile, survey.xml, has not yet been created. If the WebSurvey control cannot find the specified SurveyFile, it will throw a FileNotFoundException, as shown in the screenshot to the right. In order to remedy this problem, you need to create an XML-based file that contains the survey's questions. Let's see how to do that now.

Begin by opening Notepad or the text editor of your choice. Create a new file named websurvey.xml that contains the following XML:

<?xml version = "1.0"?>

<WebSurvey redirecturl = "websurvey.aspx" allowrepeats = "false" cookiename = "sstchur:Survey1">
  <Group id = "grp_PersonalInfo" nextimage = "finish.gif">
    <Question id = "Name" type = "shortans" cols = "40" required = "true">
      <Statement>Please enter your first name:</Statement>
    </Question>
  </Group>
</WebSurvey>

The survey after adding the first question. With this sample survey file, we now have a working survey example. If you revisit the page, instead of receiving a FileNotFoundException, you'll instead see a screen similar to the one shown to the left. Granted, it's not terribly exciting at this point, but we'll take care of that a little later on.

For now, let's examine the tags in this XML file and the attributes that go along with them. The <WebSurvey> tag is the XML document's root element and has three attributes, all of which are required.

  • redirecturl -- The file to display once the survey has been completed. It could be the same file (as in the example) or a completely different file.
  • allowrepeats -- When set to true, this attribute tells the WebSurvey to allow the same user to complete the survey multiple times. Any other value is interpreted as false and will not allow repeats. This is accomplished by checking for the existence of a cookie defined by the cookiename attribute.
  • cookiename -- The name of the cookie to be generated in the event that repeats are not allowed. This can be any string, but I would recommend keeping the cookies names as unique as possible.

The <WebSurvey> element can consist of a number of <Group> elements, specifying a set of questions on one particular page. That is, each <Group>...</Group> pair specifies one page of questions in the survey. Note that every survey requires AT LEAST one <Group> tag. Each <Group> element has three attributes.

  • id (required) -- A unique ID assigned to the <Group> tag. It can be any valid string, but should be unique from any other <Group> tag's ID.
  • nextimage (required) -- Name of an image file (JPG or GIF) used as the "Next" or "Finish" button. If you have only one page of questions, it acts as a Finish (or Submit) button. If you have multiple pages, it acts as a Next button for all pages except the last page.
  • backimage -- This attribute is only applicable if you have multiple pages of questions in your survey. Otherwise, it is meaningless and ignored. If you have multiple <Group> tags, this attribute is required on all <Group> tags EXCEPT the first one.

Each <Group> element can consist of a variable number of <Question> elements. Each <Question> element represents a question the user is asked. The <Question> element has a variant number of attributes (depending on the type of question we're dealing with). Here are some of the more germane attributes.

  • id -- A unique ID to represent this question. This can be essentially anything, but I would recommend something that describes the question.
  • type -- Can be one of 4 types: mcss (multiple choice, single selection); mcms (multiple choice, multiple selection); shortans (short answer); or essay.
  • required -- true if the question if required. Any other value is interpreted as false.
  • rows -- Applicable only to questions of type essay. This attribute defines how many rows (the height) of the Text Area.
  • cols -- Applicable to question of type shortans and essay. This attributes defined how many columns (the width) of the TextBox.

Inside the <Question> element you'll find a <Statement> element. The <Statement> element contains the text that is displayed for the question. HTML markup is valid here, but keep in mind that we're dealing with XML so XML formatting rules apply - all tags need to be closed (for example, <br> needs to be <br />) and properly nested, and attribute values must be within quotation marks.

For a more extensive explanation of WebSurvey tags and attributes, visit my controls Web site at http://www.sycbp.com/controls/websurvey/.

An Example Survey
To demonstrate the survey XML file, let's look at a complete, multi-page survey example. Before we look at the updated survey.xml file, I took a moment to gussy up the ASP.NET Web page's HTML syntax, which improves the appearance of the survey results. I used a bit of CSS and some tables for positioning.

<%@ Register TagPrefix = "sstchur" Namespace = "sstchur.web.survey" Assembly = "sstchur.web.survey" %>
<%@ Page Language = "C#" %>

<html>
  <head>
    <script runat = "server">
      public void Page_Load(object server, EventArgs e)
      {
        if (ws.PreviouslyCompleted) {
          pnlPreviouslyCompleted.Visible = true;
          pnlSurvey.Visible = false;
        } else {
          pnlSurvey.Visible = true;
          pnlPreviouslyCompleted.Visible = false;
        }
      }
    </script>
    
    <style type = "text/css">
      body, table, td
      {
        font-family: arial;
        font-size: 12px;
        color: #336699;
      }
    </style>
  </head>
  
  <body bgcolor = "#ffffff">
    
    <table border = 0 cellpadding = 0 cellspacing = 0 width = 100% height = 100%>
      <tr valign = "top" align = "center">
        <td width = 100% height = 100%>
  
          <table border = 0 cellpadding = 10 cellspacing = 0 width = 500 style = "border: solid 1px #000000;">
            <tr valign = "top" align = "left">
              <td>
                <br/>
                <p align = "center"><h3>WebSurvey Demo</h3></p>
          
                <asp:Panel id = "pnlSurvey" Visible = "false" runat = "server">
                  <form runat = "server">
                    <sstchur:WebSurvey id = "ws"
                                       SurveyFile = "survey.xml"
                                       AnswersFile = "answers.xml"
                                       runat = "server"/>
                  </form>                    
                </asp:Panel>
                
                <asp:Panel id = "pnlPreviouslyCompleted" Visible = "false" runat = "server">
                  Thank you for taking our survey.
                </asp:Panel>
              </td>
            </tr>
          </table>
            
        </td>
      </tr>
    </table>
  </body>
</html>

The updated HTML contains some tables and CSS to pretty up the appearance a bit, but the most important thing to notice is the C# additions made to the Page_Load event handler. I've added an if statement which checks to see if the survey is "displayable" (the property PreviouslyCompleted is a Boolean value which returns true if the survey can be displayed, and false otherwise). If the survey is "displayable" (i.e. the user had not yet taken it), the <asp:Panel> whose id is phSurvey will be made visible. If the survey is not "displayable", the <asp:Panel> with id phPeviouslyCompleted is made visible.

While we've made some significant changes to the user interface, our survey is still rather devoid of content. Let's add a intro page to the survey, a few more questions, and while we're at it, I'll introduce a few new tags. Update the survey.xml file with the following XML markup:

<?xml version = "1.0"?>

<WebSurvey redirecturl = "websurvey.aspx" allowrepeats = "false" cookiename = "WS:Survey1">
  <Group id = "grp_Intro" nextimage = "next.gif">
    <Separator>
      <p><b>WebSurvey Introduction</b></p>
      
      <p>Thank you for taking the time to read my article on 4GuysFromRolla.Com.  The survey you are
      viewing was created for demo purposes.  Hopefully, it will give you an idea of how flexible
      the WebSurvey control is.</p>
      
      <p>As you can see, this page contains no questions, it serves as nothing more than an Intro
      or "filler" page.  You can place anything you want in this section, including HTML (as long
      as it is well-formed with regards to XML.</p>
      
      <p>Ok, enough intro.  To get started with the survey, simply click the Next button.</p>
    </Separator>
  </Group>
  
  <Group id = "grp_PersonalInfo" backimage = "back.gif" nextimage = "next.gif">  
    <Separator><b>Page 1 of 2: Personal Information</b></Separator>
    
    <Question id = "FName" type = "shortans" cols = "30" required = "true">
      <Statement><b>First Name:</b></Statement>
    </Question>
    
    <Question id = "LName" type = "shortans" cols = "30" required = "true">
      <Statement><b>Last Name:</b></Statement>
    </Question>
    
    <Question id = "Email" type = "shortans" cols = "30" required = "true">
      <Statement><b>Email Address:</b></Statement>
    </Question>
  </Group>
  
  <Group id = "grp_Favorites" backimage = "back.gif" nextimage = "finish.gif">  
    <Separator><b>Page 2 of 2: Your Favorite Stuff</b></Separator>
    
    <Question id = "FavColor" type = "mcss" layout = "vertical" required = "true">
      <Statement><b>Favorite Color:</b></Statement>
      <Responses>
        <Response>Red</Response>
        <Response>Blue</Response>
        <Response>Green</Response>
      </Responses>
    </Question>
    
    <Question id = "FavFoods" type = "mcms" required = "false">
      <Statement><b>Favorite Foods (Ctrl + Click to Multiple Select):</b></Statement>
      <Responses>
        <Response>Green Eggs and Ham</Response>
        <Response>Beer</Response>
        <Response>Pizza</Response>
        <Response>Sushi</Response>
        <Response>Steak</Response>
        <Response>Crabs</Response>
      </Responses>
    </Question>
    
    <Question id = "Description" type = "essay" cols = "30" rows = "4" required = "false">
      <Statement><b>Tell us about yourself:</b></Statement>
    </Question>

  </Group>  
</WebSurvey>

While the survey file has grown quite a bit, don't feel overwhelmed, it's still pretty simple. The first thing to notice is that I've added two new <Group> tags, giving us a total of three. This means that our survey will span three pages. However, one thing you may find interesting is that the first <Group> tag doesn't actually contain any questions, it only contains one simple <Separator> tag.

The <Separator> element is very powerful and is one of the features that allows for extreme customization of the WebSuvey Control. You can place a <Separator> essentially anywhere in the XML file, and within the <Separator>, you can place all kinds of HTML to help spice up your survey. I haven't done anything earth-shattering in my example. Just a few short sentences explaining that page one is an intro page, but it gives you an idea of what's possible.

The second <Group> tag has been altered a bit from our earlier example. First off, I added a backimage attribute so that the user can return to the intro page if he desires. Secondly, I changed the nextimage attribute to next.gif instead of finish.gif, since this <Group> tag no longer represents the last page of the survey.

Some of you might be wondering if you can use traditional buttons instead of image buttons. Unfortunately, the answer is no. It is something I am considering implementing, but for the time being, you'll need to create at least one GIF or JPEG image to represent your buttons. These images can reside anywhere, as long as you use a relative path to refer to them in the XML file.

I've also added two new questions to this group. One asks for the user's last name, and the other requests his email address. Since both of these questions are short answer questions, which we've already covered, they don't require much explanation.

The third <Group> tag gets a little more interesting. Here was have a <Question> of type mcss (multiple choice, single selection). It's fairly obvious, but mcss questions have a predefined set of responses. Take a look at the Favorite Color question. Each <Response> element within the <Responses> element represents one possible answer. mcss questions are always displayed using radio buttons.

The next question, a mcms (multiple choice, multiple selection) question, functions in much the same was as the mcss question, only users are allow to select multiple answers by using Ctrl + Click. Questions of type mcms are displayed using a ListBox Control.

The last question is an essay question, and take two simple attributes, cols and rows, which define the width and height of the TextArea. It's pretty self-explanatory. Essays questions offer the user a TextArea in which to type long responses. They are a perfect choice for allow the user to provide additional comments.

The screenshots below show the updated WebSurvey in action...

survey.livedemo1.gif
survey.livedemo2.gif
survey.livedemo3.gif
survey.livedemo4.gif

The answers.xml File
survey.answers.gif A survey isn't much good without any answers. When a user completes a survey, the results are stored in an XML-formatted file as specified via the WebSurvey's AnswersFile property. The file's structure is pretty simple. Every time someone completes the survey, you get a new <AnswerSet> element appended to the file. Within each <AnswerSet> element you will see various <Answer> tags. These are the tags that represent the answers to the survey. Each <Answer> tag will have an questionId attribute with it, so you know which question it refers to. A screenshot of the answers XML file is shown to the right.

At first glace, it might seem like this is a rather clumsy way to collect the answers to the survey. And I must admit myself, that if you have an extremely extensive survey with thousands of respondants, it is. However, the most important thing to keep in mind here, is that all of the data is kept in tact using this method. Therefore, a savvy programmer could quite easily write a script that extracts the data from the XML file and writes it to a database. Or, as I have often done myself, you could simply write a script that uses XQuery to directly query the data from the XML file. To see a quick and dirty example of what you can accomplish using XQuery, take a look at my Favorite Colors Poll.

Conclusion
This has been a rather whirlwind tour of the WebSurvey Control. We covered how to use the control in an ASP.NET Web page and how to create the websurvey.xml file that goes with it. If you have any questions or comments, or are having trouble implementing WebSurvey on your site, please don't hesitate to drop me a line at [email protected]. I check my email pretty regularly, so I should get back to you quickly.

That about wraps it up for this article. If you're wondering how I wrote this control, you'll have to wait till next time. Though I won't give you the source code outright, I will touch on the concepts I used to create this monster. And if you're so inclined, it should give you sufficient knowledge create a WebSurvey Control of your own. Additionally, a future article will look at working with the data in the Answers XML file in more detail.

Happy Programming!

發佈了156 篇原創文章 · 獲贊 0 · 訪問量 28萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章