views:

39

answers:

1

I'm having a hard time figuring out how to collect the data from a FormCollection when submitted for my form which collects the answers for a survey. Specifically my problem is with questions that have multiple choice options(radio buttons) and an other textbox field if the options did not apply.

My survey has the following structure:

QUESTION : [ QuestionId, Text, QuestionType, OrderIndex]

MULTIPLE_CHOICE_OPTIONS: [ MC_OptionId, QuestionId, OrderIndex, MC_Text]

ANSWER: [AnswerId,QuestionId, MC_OptionId (can be null), UserTextAnswer]

QUESTION_TYPES are: [Multiple_Choice, Multiple_Choice_wOtherOption, FreeText or Checkbox]

My view is rendering the form as follows(pseudo code to simplify):

//Html.BeginForm
foreach( Question q in Model.Questions)
{
   q.Text //display question text in html

   if (q.QuestionType == Multiple_Choice)
   {
       foreach( MultipleChoice_Option mc in Model.MULTIPLE_CHOICE_OPTIONS(opt => opt.QuestionId == q.QuestionId)
       {
           <radio name=q.QuestionId value=mc.MC_OptionId />
           // All OK, can use the FormCollectionKey to get the
           // QuestionId and its value to get the selected MCOptionId
       }
   }
    else if (q.QuestionType == Multiple_Choice_wOtherOption)
   {
       foreach( MultipleChoice_Option mc in Model.MULTIPLE_CHOICE_OPTIONS(opt => opt.QuestionId == q.QuestionId)
       {
           <radio name=q.QuestionId value=mc.MC_OptionId />
       }
       <textbox name=q.QuestionId />
       // ****Problem - I can get the QuestionId from the FormCollection Key, but
       // I don't know if the value is from the user entered
       // textbox or from a MCOptionId***
   }
}
 <button type="submit">Submit Survey</button>

   // Html.EndForm

I was doing it this way so back in the controller action that handles the post back I could read over the FormCollection by key to get the questionId, and the value for each index to get the MCOptionID. But in the case of the question with radio buttons and a textbox all with the same name key how would I determine if the form data is from the radio button or the text box.

I can see the way I'm doing this breaks because their could be the case where a question (id=1) has a MCOption w/ Id=5 so the radio button has value of 5 and the user enters 5 in the Other textbox. When the form submits I see the formcollection[key="1"] has the value 5 and I can't tell if that is from usertext or the radioButton value referencing a MCOptionId.

Is there a better way to approach this problem, either the db structure, view rendering code or the way the form controls are named? Maybe form collection is not the way to go but I was stumped how to post back and make the model binding work .

Thanks for any help, been going around in circles for something that seems pretty simple.

A: 

Consider this small refactoring...

//you're always rendering the radios, it seems?
RenderPartial("MultipleChoice", Model.MULTIPLE_CHOICE_OPTIONS.Where(x => 
                                   x.QuestionId == q.QuestionId));

if (q.QuestionType == Multiple_Choice_wOtherOption)
{   
   <textbox name="Other|" + q.QuestionId />      
}

and within that strongly typed partial view:

//Model is IEnumerable<MultipleChoice_Option >
foreach (MultipleChoice_Option mc in Model ) 
{
    <radio name=mc.Question.QuestionId value=mc.MC_OptionId />           
}

It seems your question was around the textbox name; being tied to the question by ID. In your controller, you'll have to explicitly know when to look for any value in the textbox.

 string userAnswer = Request.Form["OtherEntry|" + someQuestionID].ToString();
p.campbell