次の方法で共有


HowTo: Create a quizzing application with SharePoint 2007

With SharePoint 2007 "Survey" list template, I recently created a quizzing application.  The thing with survey list is that it stack ranks the questions taking into account how many of the respondents favored each options within that question.  But for a quizzing application, we need to be able to stack rank the respondents on how many of their options where correct.  "Survey" list template, traditionally (by-design) cannot be used for a quiz requirement, but will some careful planning and custom-coding, I was able to make use of the SharePoint survey list template to organize a quiz within our organization.

Some preliminary work:

First, I had to setup a list that will host my questions, choices and the correct answer.  I also setup a custom field to figure-out if a question is already used in a quiz and to compute results for a particular quiz.  Below is a screen-shot of how this list looks like:

image

The tool to create quiz and compute results:

I created this tool based on the "business requirement" we had.  There are several hard-coding etc.,  However, it could be extended to suit your needs.  All that's really needed is to understand how the choices selected by respondents are to be read and computed to formulate their individual scores.

Tool UI to create the quiz:

image

The section highlighted above, is going to create a list of type survey.  It will use the "Quiz Questions and Answers" list as the source for filling itself up with questions and choices.  In my case, the quiz needs to be within a sub site.  I type in the full URL of the sub site and click "Get Lists" to populate the drop-down control.  Then provide the quiz title and description (actually the survey title and description) and specify the number of questions I need to consume in this quiz from the source list.  The "Day (1, 2, 3 etc.,)" is a parameter that I use to mark the questions in the source list "Quiz Questions and Answers" to denote they are already used.  This is mapped to the column "Used" shown in the screen-shot of "Quiz Questions and Answers" list above.  Once the quiz list is created after clicking the "Create Quiz" button shown above, the source list will look like the below screen-shot:

image

As we can see, the first 5 questions' "Used" column is now filled with 1, which is my custom parameter to denote those questions are used in day 1 quiz.  I also use this to compute results, specifically to see which questions I need to pick up from the entire list - this way it's going to be optimized and the computation would be much faster with minimum overhead on the server.

Code:

The GetLists() method returns all the lists that are not marked "hidden".  This is the method that will return our q & a list and populate the drop-down control.

 void GetLists()
         {
             try
             {
                 comboBox1.Items.Clear();
                 richTextBox1.Clear();
                 using (SPSite site = new SPSite(textBox1.Text.Trim()))
                 {
                     using (SPWeb web = site.OpenWeb())
                     {
                         SPListCollection lists = web.Lists;
                         foreach (SPList list in lists)
                         {
                             if (list.Hidden != true)
                                 comboBox1.Items.Add(list.Title);
                         }
                         comboBox1.SelectedIndex = 0;
                     }
                 }
             }
             catch (Exception _e)
             {
                 richTextBox1.Text += "Message: " + _e.Message + Environment.NewLine + Environment.NewLine +
                     "Stack Trace: " + _e.StackTrace;
             }
         }

The CreateQuiz() method creates the quiz list (of type Survey list).  The most important part here is the "foreach" loop that populates the questions and answers in the form of a survey question and choices.

 void CreateQuiz()
         {
             richTextBox1.Clear();
             try
             {
                 using (SPSite site = new SPSite(textBox1.Text.Trim()))
                 {
                     using (SPWeb web = site.OpenWeb())
                     {
                         int counter = 0;
                         int fldCnt = 3;
                         string question = string.Empty;
                         StringCollection choices = new StringCollection();
                         Guid quizId = web.Lists.Add(textBox2.Text.Trim(), textBox3.Text.Trim(), SPListTemplateType.Survey);
                         richTextBox1.Text += "Quiz list created.  Id: " + quizId.ToString() + Environment.NewLine;
                         SPList quiz = web.Lists[quizId];
                         quiz.ReadSecurity = 2;
                         quiz.WriteSecurity = 2;
                         quiz.AllowMultiResponses=false;
                         richTextBox1.Text += "ReadSecurity set to: " + quiz.ReadSecurity.ToString() + Environment.NewLine;
                         richTextBox1.Text += "WriteSecurity set to: " + quiz.WriteSecurity.ToString() + Environment.NewLine;
                         quiz.BreakRoleInheritance(false);
                         quiz.Update();
                         richTextBox1.Text += "Reading \"Unused\" items from source list" + Environment.NewLine;                        
                         foreach (SPListItem sListItem in web.Lists[comboBox1.SelectedItem.ToString()].Items)
                         {
                             if (counter < Convert.ToInt32(textBox4.Text.Trim()))
                             {
                                 if (sListItem["Used"].ToString().Equals("0"))
                                 {
                                     question = sListItem["Question"].ToString();
                                     choices.Add(sListItem["Option1"].ToString());
                                     choices.Add(sListItem["Option2"].ToString());
                                     choices.Add(sListItem["Option3"].ToString());
                                     choices.Add(sListItem["Option4"].ToString());
                                     choices.Add(sListItem["Option5"].ToString());
                                     counter++;
                                     string fldName = quiz.Fields.Add(question, SPFieldType.Choice, true, false, choices);
                                     SPFieldChoice choiceFld = (SPFieldChoice)quiz.Fields[fldCnt];
                                     choiceFld.EditFormat = SPChoiceFormatType.RadioButtons;
                                     choiceFld.Update();
                                     fldCnt++;
                                     richTextBox1.Text += "Added quiz question and options..." + Environment.NewLine;
                                     quiz.Update();
                                     choices.Clear();
                                     sListItem["Used"] = textBox6.Text.ToString();
                                     sListItem.Update();
                                     web.Update();
                                 }
                             }
                             else
                             {
                                 break;
                             }                            
                         }
                         if (textBox1.Text.EndsWith("/"))
                         {
                             richTextBox1.Text += "Quiz URL: " + HttpUtility.UrlPathEncode(textBox1.Text.Trim() + "Lists/" + textBox2.Text.Trim() + "/NewForm.aspx") + Environment.NewLine;
                         }
                         else
                         {
                             richTextBox1.Text += "Quiz URL: " + HttpUtility.UrlPathEncode(textBox1.Text.Trim() + "/Lists/" + textBox2.Text.Trim() + "/NewForm.aspx") + Environment.NewLine;
                         }
                     }
                 }
                 richTextBox1.Text += "All suskess...!";
             }
             catch(Exception _e)
             {
                 richTextBox1.Text += "Message: " + _e.Message + Environment.NewLine + Environment.NewLine +
                     "Stack Trace: " + _e.StackTrace;
             }
         }

The permissions:

After the quiz list is created there's one other thing I had to do, which is to setup permissions.  In my case, it was a quiz organized within my org so we had a security distribution list covering all the prospective quiz takers.  So, I created a new "Permission Level" in SharePoint with the following options turned on:

  • Add Items - Add items to lists, add documents to document libraries, and add Web discussion comments.
  • View Items - View items in lists, documents in document libraries, and view Web discussion comments.
  • View Application Pages - View forms, views, and application pages. Enumerate lists.
  • View Pages - View pages in a Web site.
  • Open - Allows users to open a Web site, list, or folder in order to access items inside that container.

Now I have my custom permission level with the kind of permission I need.  I also have a new quiz list created.  I simply assign the security distribution list to the quiz list with the custom permission level I created.  I can do this through code too, however, do to time constraint (I built this quizzing application in just under 4 hrs time), I opted to do this manually.

Well, in the code, the Read/Write Securities for the survey list are set to 2, which means "Users have Read access only to items that they create" and "Write only my items" respectively.  However, once a user answers all questions and submits the quiz, he/she can always edit it at anytime or even delete his/her response and attend a quiz again.  One of my "business requirement" was to prevent this scenario and custom permission levels just did that trick.  If the above is done then when a user responds to the quiz and tries to view their response - they can, however they will not be able to edit/delete their response.

"And the winner is..." - the computation part:

Now, coming to the quiz winner computation part as shown below:

image

On clicking "Get Quiz Lists" the drop-down will be populated with lists of type survey.  And clicking "Compute Results" will create another list sorted according to the total score and the earliest response.  This results list is also available as an STP file enclosed in this post.

Code:

The GetQuizLists() method populates the quiz lists drop-down with survey lists.

 void GetQuizLists()
         {
             try
             {
                 comboBox2.Items.Clear();
                 using (SPSite site = new SPSite(textBox5.Text.Trim()))
                 {
                     using (SPWeb web = site.OpenWeb())
                     {
                         foreach (SPList list in web.Lists)
                         {
                             if (list.BaseType == SPBaseType.Survey)
                             {
                                 comboBox2.Items.Add(list.Title);
                             }
                         }
                         comboBox2.SelectedIndex = 0;
                     }
                 }
             }
             catch (Exception _e)
             {
                 richTextBox1.Text += "Message: " + _e.Message + Environment.NewLine + Environment.NewLine +
                     "Stack Trace: " + _e.StackTrace;
             }
         }

The ComputeResults() method is the most important method that computes who the winner is depending on the Nth day of the quiz.  It compares individual quiz takers' response with the correct answer and increments a counter to compute the total score for an individual.  It does this for all the quiz takers and finally creates another results list using a template (enclosed).  This section in the code is where you'll find multiple hard-coding stuffs, so just go through the code and customize it per your need.

 void ComputeResults()
         {
             richTextBox1.Clear();
  
             using (SPSite site = new SPSite(textBox5.Text.Trim()))
             {
                 using (SPWeb web = site.OpenWeb())
                 {
                     int score = 0;
                     SPList sList = web.Lists["Quiz Questions and Answers"];
                     SPQuery query = new SPQuery();
                     query.Query = "<Where><Eq><FieldRef Name='Used'/><Value Type='Number'>" +
                         Convert.ToInt32(textBox7.Text.Trim()) + "</Value></Eq></Where>";
                     SPListItemCollection sItems = sList.GetItems(query);
                     string name = string.Empty;
                     DateTime datetime = DateTime.Now;
                     string quizTitle = comboBox2.SelectedItem.ToString();
                     SPList resultList = null;
                     foreach (SPListItem response in web.Lists[comboBox2.SelectedItem.ToString()].Items)
                     {
                         foreach (SPListItem sItem in sItems)
                         {
                             name = (string)response["Created By"];
                             name = name.Substring(name.IndexOf("#") + 1);
                             datetime = (DateTime)response["Modified"];
                             string ans = (string)response[sItem["Question"].ToString()];
                             if (ans.Equals(sItem["Correct Answer"].ToString().Trim()))
                             {
                                 score++;
                             }
                         }
  
                         SPListTemplate listTemplate = site.GetCustomListTemplates(web)["quiz_results"];
                         Guid newResultList = new Guid();
                         try
                         {
                             newResultList = web.Lists["Results for " + quizTitle].ID;
                         }
                         catch (ArgumentException _ae)
                         {
                             newResultList = web.Lists.Add("Results for " + quizTitle, "quiz results", listTemplate);
                             web.Update();
                         }
                         resultList = web.Lists[newResultList];
                         SPListItem resultItem = resultList.Items.Add();
                         resultItem["Login"] = name;
                         resultItem["Points"] = score;
                         resultItem["DateTime"] = datetime;
                         resultItem.Update();
                         score = 0;
                     }
                     richTextBox1.Text += "All done... check \"https://mossquiz" + resultList.DefaultViewUrl + "\" for results" + Environment.NewLine;                    
                 }
             }
            
  
             try
             { }
             catch (Exception _e)
             {
                 richTextBox1.Text += "Message: " + _e.Message + Environment.NewLine + Environment.NewLine +
                     "Stack Trace: " + _e.StackTrace;
             }
         }

End Note:

SharePoint being a collaborative and sharing platform should have provisioned such a quizzing template out of the box, but sadly there isn't one.  However, there's lot of demand for such utilities because most organizations conduct quiz/test of these sort a lot targeted towards readiness and learning.  The above solution can also be built into a feature and deployed as a solution package, however, that will be a larger implementation as we might have to automate few things and provide a web interface to manage it.

I hope this post and the tool was useful to you as it was highly useful to me (have used it in more than one quizzing events and so far am successful :) ).

Keep exploring!

CreateQuiz.zip

Comments

  • Anonymous
    December 16, 2008
    Hi Sridhar, Being a noob to Sharepoint,can you pls elaborate how i can use the zip file that you have attached? Thanks

  • Anonymous
    December 16, 2008
    Hi Shiva, It's a windows application.  You can unzip it using WinZip/WinRar and you'll find the complete solution and 2 STP files as mentioned. Cheers, Sridhar

  • Anonymous
    January 05, 2009
    Hi: Thanks so much for the post.  However, I do not see the link to the tool.  Would you please point me to the place to download the tool or its source codes?  Thanks again. GreenTT

  • Anonymous
    March 04, 2009
    Sridhar, I think this is an awesome concept and I have been trying to do the same thing for a while now. I get an immediate error when attempt to "Get List" or anything using your CreateQuiz tool. Is there something I'm missing here?

  • Anonymous
    March 20, 2009
    Hi Sridhar, Great post for me.I face these type of requirement for our internal.Your tool gives a stater idea.I have developed a feature for my req.In this i have been enouncing the result immediatly.I updated the code @ http://naveedshare-licensetoplay.blogspot.com/2009/03/how-to-create-quiz-application-using.html my blog.

  • Anonymous
    April 08, 2009
    The comment has been removed

  • Anonymous
    May 13, 2009
    Hi Shridhar Awesome post!! But since I am new to Sharepoint I dont know how to use the zip file to actually create the application..could you direct me as I want to implement it in our local portal Regards Kashti

  • Anonymous
    July 01, 2009
    Hi, I have opened the quiz creator, however I cannot get the lists from my URL, it has an error which says "Unhandled exception has occurred in your application" Any ideas as to why this is? Thanks Pete

  • Anonymous
    August 03, 2009
    Hi Shridhar, Really a nice post! :) However i would like the user to get redirected automatically to a new result page when they click on the finish button on survey page. I am new to MOSS, please guide me achieving this. Thanks, Akshay.

  • Anonymous
    August 26, 2009
    HI, Can u please email me the zip file ? at the mail id mentioned radhika.mukund7@gmail.com

  • Anonymous
    August 27, 2009
    Since you are using the object model, do you not have to run the Windows tool on the server itself?  Wouldn't you need to use MOSS web services (instead of the object model) to run this from a workstation?

  • Anonymous
    November 10, 2010
    Hi Sridar....   ur tool is awesome..... is that compatiblt to SHAREPOINT 2010 ?

  • Anonymous
    January 18, 2011
    Does anybody know what will happen with this app if the user hits the BACk button?  Will there be more than one answer? Thanks.

  • Anonymous
    January 18, 2011
    Does anybody know what will happen with this app if the user hits the BACk button?  Will there be more than one answer? Thanks.

  • Anonymous
    January 18, 2011
    Does anybody know what will happen with this app if the user hits the BACk button?  Will there be more than one answer? Thanks.

  • Anonymous
    March 15, 2012
    Hi Sridhar, Is it possible to convert this Windows Application to Web Part? Please let me know. Thank you Sri

  • Anonymous
    March 16, 2012
    Hi Shridhar, I am running a smilar project. Please let me in sharing the complete details one by one. I need exactly what you have created for my project as we are stopping the paper use and going go green :) Please respond to my email- dobhal.subhash@gmail.com Regards, Subhash D

  • Anonymous
    April 02, 2015
    Information was good, I like your post. Looking forward for more on this topic. <a href="staygreenacademy.com/.../">SharePoint 2013 Administrator Training Online</a>