[Back to: Simple Survey Page 1]
The survey uses the DynamicControlsPlaceholder control by Denis Baur to allow ViewState to be maintained for the dynamically created Survey controls.
The DisplaySurvey method dynamically creates the table used to hold the Survey:
#region DisplaySurvey private void DisplaySurvey() { // Add elements to the DCP panel // Create Table Table objTable = new Table(); // Add the Table to DCP panel DCP.Controls.Add(objTable); objTable.ID = "ResultsTable"; SimpleSurveyDataContext SimpleSurveyDataContext = new SimpleSurveyDataContext(); var SurveyQuestions = from SurveyDataItems in SimpleSurveyDataContext.SurveyDataItems where SurveyDataItems.ModuleID == ModuleId where SurveyDataItems.Visible == true orderby SurveyDataItems.SortOrder select SurveyDataItems; foreach (var SurveyQuestion in SurveyQuestions) { TableRow objTableRow = new TableRow(); TableCell QuestionCell = new TableCell(); TableCell AnswerCell = new TableCell(); objTableRow.Cells.Add(QuestionCell); objTableRow.Cells.Add(AnswerCell); objTable.Rows.Add(objTableRow); // Display Question string strRequired = (SurveyQuestion.Required == true) ? "<font color='#cc0000'>*</font>" : ""; string strMoney = (SurveyQuestion.Type == "Money") ? "$" : ""; Label objLabel = new Label(); QuestionCell.Controls.Add(objLabel); QuestionCell.Style.Add(HtmlTextWriterStyle.TextAlign, "right"); objLabel.Text = String.Format("{0}{1}:{2}", strRequired, SurveyQuestion.DataName, strMoney); // Display Answer Form Element AnswerFormElement(AnswerCell, SurveyQuestion.Type, SurveyQuestion.SurveyDataItemID.ToString()); // Create ID's for controls so they will be persisted in ViewState objTableRow.ID = String.Format("{0}", SurveyQuestion.SurveyDataItemID.ToString()); QuestionCell.ID = String.Format("{0}_QuestionCell", SurveyQuestion.SurveyDataItemID.ToString()); AnswerCell.ID = String.Format("{0}_AnswerCell", SurveyQuestion.SurveyDataItemID.ToString()); objLabel.ID = String.Format("{0}_QuestionLabel", SurveyQuestion.SurveyDataItemID.ToString()); } ltValidation.Text = "<br /><i>(Items marked <font color='#cc0000'>*</font> are required)</i><br />"; } #endregion
The AnswerFormElement method determines the proper control to use to gather each answer and adds it to the control collection. Note that the FileUpload control is used to allow images to be uploaded.
#region AnswerFormElement private void AnswerFormElement(TableCell QuestionCell, string SurveyQuestionType, string strSurveyDataItemID) { switch (SurveyQuestionType) { case "Text": TextBox objLargeTextBox = new TextBox(); QuestionCell.Controls.Add(objLargeTextBox); objLargeTextBox.ID = String.Format("{0}_Answer", strSurveyDataItemID); objLargeTextBox.TextMode = TextBoxMode.MultiLine; objLargeTextBox.Columns = 25; objLargeTextBox.Rows = 2; objLargeTextBox.MaxLength = 200; break; case "Dropdown": DropDownList objDropDownList = new DropDownList(); QuestionCell.Controls.Add(objDropDownList); objDropDownList.ID = String.Format("{0}_Answer", strSurveyDataItemID); objDropDownList.Items.AddRange(AddListItems(Convert.ToInt32(strSurveyDataItemID))); break; case "Radio Buttons": RadioButtonList objRadioButtonList = new RadioButtonList(); QuestionCell.Controls.Add(objRadioButtonList); objRadioButtonList.ID = String.Format("{0}_Answer", strSurveyDataItemID); objRadioButtonList.Items.AddRange(AddListItems(Convert.ToInt32(strSurveyDataItemID))); break; case "Check Boxes": CheckBoxList objCheckBoxList = new CheckBoxList(); QuestionCell.Controls.Add(objCheckBoxList); objCheckBoxList.ID = String.Format("{0}_Answer", strSurveyDataItemID); objCheckBoxList.Items.AddRange(AddListItems(Convert.ToInt32(strSurveyDataItemID))); break; case "Integer": TextBox objIntegerTextBox = new TextBox(); QuestionCell.Controls.Add(objIntegerTextBox); objIntegerTextBox.ID = String.Format("{0}_Answer", strSurveyDataItemID); objIntegerTextBox.Columns = 4; break; case "Double": TextBox objDoubleTextBox = new TextBox(); QuestionCell.Controls.Add(objDoubleTextBox); objDoubleTextBox.ID = String.Format("{0}_Answer", strSurveyDataItemID); objDoubleTextBox.Columns = 4; break; case "Money": TextBox objMoneyTextBox = new TextBox(); QuestionCell.Controls.Add(objMoneyTextBox); objMoneyTextBox.ID = String.Format("{0}_Answer", strSurveyDataItemID); objMoneyTextBox.Columns = 4; break; case "Email": TextBox objEmailTextBox = new TextBox(); QuestionCell.Controls.Add(objEmailTextBox); objEmailTextBox.ID = String.Format("{0}_Answer", strSurveyDataItemID); objEmailTextBox.Columns = 35; break; case "Date": TextBox objDateTextBox = new TextBox(); QuestionCell.Controls.Add(objDateTextBox); objDateTextBox.ID = String.Format("{0}_Answer", strSurveyDataItemID); objDateTextBox.Columns = 10; break; case "Website": TextBox objWebsiteTextBox = new TextBox(); QuestionCell.Controls.Add(objWebsiteTextBox); objWebsiteTextBox.ID = String.Format("{0}_Answer", strSurveyDataItemID); objWebsiteTextBox.Columns = 35; break; case "Image": FileUpload objUploadTextBox = new FileUpload(); QuestionCell.Controls.Add(objUploadTextBox); objUploadTextBox.ID = String.Format("{0}_Answer", strSurveyDataItemID); break; } } #endregion
When an entry is submitted, the following methods are run to perform validation, upload any images, and if there are no errors, save the data:
// Validate Required Fields colValidationList = ValidateRequiredFields(colCompleteSurveyItems); if (colValidationList.Count > 0) { DisplayValidationErrors(colValidationList); return; } // Validate Field Types colValidationList = ValidateFieldValues(colCompleteSurveyItems); if (colValidationList.Count > 0) { DisplayValidationErrors(colValidationList); return; } // Upload any images bool boolUploadComplete = UploadImages(colCompleteSurveyItems); if (!boolUploadComplete) { colValidationList.Add("There was an error uploading a image file."); colValidationList.Add("Only .jpg/.jpeg/.gif allowed."); DisplayValidationErrors(colValidationList); return; } // Save data SaveSurveyItems(colCompleteSurveyItems); DisplaySurveyValues();
The following code saves the responses to the database:
#region SaveSurveyItems private void SaveSurveyItems(List<SurveyItem> colCompleteSurveyItems) { SimpleSurveyDataContext SimpleSurveyDataContext = new SimpleSurveyDataContext(); // Get all current items var CurrentDataAnswers = from SurveyDataAnswers in SimpleSurveyDataContext.SurveyDataAnswers from SurveyDataItems in SimpleSurveyDataContext.SurveyDataItems where SurveyDataAnswers.SurveyDataItemID == SurveyDataItems.SurveyDataItemID where SurveyDataItems.ModuleID == ModuleId where SurveyDataAnswers.UserID == UserId select SurveyDataAnswers; // Delete all current Items SimpleSurveyDataContext.SurveyDataAnswers.DeleteAllOnSubmit(CurrentDataAnswers); SimpleSurveyDataContext.SubmitChanges(); // Add all new items foreach (var SurveyItem in colCompleteSurveyItems) { if (SurveyItem.ItemTypeName != "CheckBoxList") { SurveyDataAnswer objSurveyDataAnswer = new SurveyDataAnswer(); objSurveyDataAnswer.UserID = UserId; objSurveyDataAnswer.SurveyDataItemID = SurveyItem.SurveyDataItemID; objSurveyDataAnswer.Value = SurveyItem.ItemValue; SimpleSurveyDataContext.SurveyDataAnswers.InsertOnSubmit(objSurveyDataAnswer); SimpleSurveyDataContext.SubmitChanges(); } else { // For Check boxes, multiple rows are saved char[] delimiterChars = { ',' }; string[] SurveyValues = SurveyItem.ItemValue.Split(delimiterChars); foreach (string SurveyValue in SurveyValues) { SurveyDataAnswer objSurveyDataAnswer = new SurveyDataAnswer(); objSurveyDataAnswer.UserID = UserId; objSurveyDataAnswer.SurveyDataItemID = SurveyItem.SurveyDataItemID; objSurveyDataAnswer.Value = SurveyValue; SimpleSurveyDataContext.SurveyDataAnswers.InsertOnSubmit(objSurveyDataAnswer); SimpleSurveyDataContext.SubmitChanges(); } } } } #endregion
A single Linq to SQL query is all that is needed to display the results for Dropdowns, Radio Buttons, and Check Boxes:
#region DisplaySurveyResults private void DisplaySurveyResults() { SimpleSurveyDataContext SimpleSurveyDataContext = new SimpleSurveyDataContext(); var results = from SurveyDataItems in SimpleSurveyDataContext.SurveyDataItems from SurveyDataAnswers in SimpleSurveyDataContext.SurveyDataAnswers where SurveyDataItems.SurveyDataItemID == SurveyDataAnswers.SurveyDataItemID where SurveyDataItems.ModuleID == ModuleId where SurveyDataItems.Visible == true where (SurveyDataItems.Type == "Dropdown" || SurveyDataItems.Type == "Radio Buttons" || SurveyDataItems.Type == "Check Boxes") group SurveyDataItems by SurveyDataItems.SurveyDataItemID into Questions select new { Question = SimpleSurveyDataContext.SurveyDataItems.Where(x => x.SurveyDataItemID == Convert.ToInt32(Questions.Key)).FirstOrDefault().DataName, Options = from SurveyDataAnswers in SimpleSurveyDataContext.SurveyDataAnswers where SurveyDataAnswers.SurveyDataItemID == Questions.Key where SurveyDataAnswers.Value != "" group SurveyDataAnswers by SurveyDataAnswers.Value into SurveyOptions select new { Option = SurveyOptions.Key, Count = SurveyOptions.Count().ToString() }, Count = Questions.Count().ToString() }; lvResults.DataSource = results; lvResults.DataBind(); } #endregion
The administrator survey results also requires only one Linq to SQL query:
#region LoadUserResults private void LoadUserResults() { if (ddlUser.Items.Count > 0) { SimpleSurveyDataContext SimpleSurveyDataContext = new SimpleSurveyDataContext(); var results = from SurveyDataItems in SimpleSurveyDataContext.SurveyDataItems from SurveyDataAnswers in SimpleSurveyDataContext.SurveyDataAnswers where SurveyDataItems.SurveyDataItemID == SurveyDataAnswers.SurveyDataItemID where SurveyDataItems.ModuleID == ModuleId where SurveyDataAnswers.UserID == Convert.ToInt32(ddlUser.SelectedValue) orderby SurveyDataItems.SortOrder select new { Question = SurveyDataItems.DataName, Answer = SurveyDataAnswers.Value }; if (results.Count() > 0) { gvAnswers.DataSource = results; gvAnswers.DataBind(); } } } #endregion
This module allows an administrator to create a form that can capture all the standard HTML form types including file upload. While it can provide basic form input functionality, it is designed to tabulate responses.
Primarily this module is intended to provide an example of using Linq to Objects, and Linq to SQL to greatly reduce the amount of code that would be otherwise required.
Buy DotNetNuke Modules from Snowcovered |
DotNetNuke™ is a registered trademark of DotNetNuke Corporation.