2

I am creating a simple survey system which is currently generating HTML such as this. This can of course be changed if the solution requires it.

<form id="surveyForm"> 
  <input type="hidden" value="1" name="surveyId" />
  <div class="questionContainer">
    <h4>What is 2 + 2?</h4>
      <div class="optionsContainer">
        <div class="optionContainer">
          <input id="option_1" value="1" type="radio" name="question_1" />
          <label for="option_1">3</label>
        </div>
        <div class="optionContainer">
          <input id="option_2" value="2" type="radio" name="question_1" />
          <label for="option_2">4</label>
        </div>
      <div class="optionContainer">
        <input id="option_3" value="3" type="radio" name="question_1" />
        <label for="option_3">5</label>
      </div>
    </div>
    <div class="freeTextContainer">
      <h4>Comments:</h4>
      <textarea id="freetext_1" name="freetext_1"></textarea>
    </div>
  </div>
  <!-- Multiple questionContainer may follow -->
</form>

So as you can see I end up with some POST variables, namely question_1, question_2 and so on, and freetext_1, freetext_2 and so on. The values of the radio buttons corresponds to an option id found in the backend database.

Now I want to use jQuery or similar to post the response using Ajax to an MVC API Controller.

So question 1; How do I use jQuery to serialize these values into a JSON string which I can decode server side, and how do I specify an MVC method server side which accepts this json string?

Question 2: The solution suggested above isn't very elegant, and I would like to serialize it in a way which can be translated to a POCO object structure usable as an input parameter in the MVC API Method, such as:

public class SurveyAnswer
{
    public int SurveyId { get; set; } // From a hidden field
    public List<QuestionAnswer> Answers{ get; set; }        
}

public class QuestionAnswer
{
    public int QuestionId { get; set;}
    public int OptionSelecion { get; set; }
    public string FreeText { get; set; }
}

and then an MVC method such as this:

[HttpPost]
public ActionResult PostAnswer(SurveyAnswer answer)
{
    ...
}

How would I go about serializing the form to achive the above?

havardhu
  • 3,576
  • 2
  • 30
  • 42

2 Answers2

0

You can serialize the form with the following code.

var formData = $("#surveyForm").serialize();

You can send that with a jQuery post like this

$.post('@Url.Action("Save", "ApiController")', $(this).serialize(), function(json) {
        // handle response
    }, "json");

Then if you whould use this model:

public class SurveyAnswer
{
    public int SurveyId { get; set; }
    public int question_1 { get; set; }        
}

you could send it to a MVC action like this

[HttpPost]
public JsonResult Save(SurveyAnswer Survey)
{
    // do work
    return new JsonResult { Data = new { Success = true } };
}

This doesn't answer you're second question but i hope it still helps you on you're way.

C. Molendijk
  • 2,614
  • 3
  • 26
  • 35
  • This is not viable, because I have no idea how many questions there are. That's why I need either a POCO with a list / array of answers (preferred), or just a JSON string which I can analyze myself using e.g. the JsonObject class server side. – havardhu Nov 29 '12 at 15:14
0

Not sure if this is what you want, but you could AJAXify using jQuery:

$(function() {
    $('#surveyForm').submit(function() {
        $.ajax({
            url: '/controller/PostAnswer
            data: $('#surveyForm').serializeArray(),
            type:'POST',
        });
        return false;
    });
});

And on server side:

[HttpPost]
public ActionResult PostAnswer(SurveyAnswer answer)
{
    return Json(new { success = true });
}

Have a look here for in-depth answers.

Community
  • 1
  • 1
tranceporter
  • 2,241
  • 1
  • 21
  • 23
  • How does serializeArray work? It sure wouldn't work with my current HTML? Please add some more info to your answer – havardhu Nov 29 '12 at 15:15
  • serialize() creates a queryString. So your info would be SurveyId=1&QuestionId=1&OptionSelection=2&FreeText=bhah serializeArray() creates key/value pairs : [{name: ‘SurveyId’, value: ‘1’}, {name: ‘QuestionId’, value: ‘1’}, {name: ‘OptionSelected’, value: ‘1’}, {name: ‘FreeText’, value: ‘blah’}]] – tranceporter Nov 29 '12 at 15:22
  • I see. thanks for your answer, it pointed me in the right direction I think. What was missing was the fact that the input elements should have the same name. In my HTML they were named question_1, question_2 etc, and freetext_1, freetext_2 etc. By renaming them to simply question and freetext, and adding a questionId hidden Field, I get the info required! :) I'll +1 / accept if you update your answer to reflect this. – havardhu Nov 29 '12 at 15:29
  • If you are doing a full HTTP POST, then that is correct. If you want to do a partial postback using AJAX, then you can use the jQuery method described above. – tranceporter Nov 29 '12 at 15:33
  • Also, instead of creating so much HTML by hand, use "@Html.LabelFor" or "@Html.RadioButtonFor". They are strongly typed, and are bound to Model. Have a look here: http://stackoverflow.com/questions/7098411/how-do-i-use-html-editorfor-to-render-radio-buttons-in-mvc3 – tranceporter Nov 29 '12 at 15:36
  • I can't seem to get it to work. Currently in my MVC Method the SurveyAnswer instance has the correct SurveyId, but the Answers list is empty – havardhu Nov 29 '12 at 16:02