4

Let's imagine I have the following situation:

I have a question form and I want to add answer choices to it (my user should be allowed to add as many choices as he wants).

So I have this ViewModel (being sent to the view).

public class QuestionEdit
{
    public int Id { get; set; }

    [Required]
    [StringLength(200)]
    public string Question { get; set; }

    public List<Choice> Choices { get; set; }
}

public class Choice
{
    public int Id { get; set; }

    [Required]
    [StringLength(200)]
    public string Choice { get; set; }

    public bool Correct {get; set;^}
}

My Controller's Edit Post looks like this:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit([Bind(Include = "Id,Question,Choices")] QuestionEdit vm)
    {
        if (ModelState.IsValid)
        {
            /*Removed for clarity*/
        }

        return View(vm)
    }

Is there any way of me getting the content from Choices and converting it to a javascript list, changing it as my user adds or removes items only by using javascript/ajax and when submitting the form, would it be a way for me to adding it back as if it were the Choices that my controller will be able to read?

I am aware that I could use the an custom EditorFor for this List, but everytime someone adds a new Choice I would have to post the entire form to add it and them get it back, so I wanted to change this only through javascript, as it requires only simple validations (not needing any server/database validation).

Thanks a lot.

Rafael Merlin
  • 2,517
  • 1
  • 25
  • 31
  • Yes, but you have not posted your view or the scripts so hard to give you an answer. –  Jan 28 '15 at 00:25
  • 1
    [This answer](http://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple-times-data-to-controller/28081308#28081308) may help –  Jan 28 '15 at 06:09

1 Answers1

5

You can use as much JavaScript and ajax as you need, as long as in your form you have inputs that are named in a way that the model binder expects.

What I mean by that is, you can create form inputs with a name attribute in the form of:

<input type="text" name="Choices[0].Id" />
<input type="text" name="Choices[0].Choice" />
<input type="hidden" name="Choices[0].Correct" />
<input type="text" name="Choices[1].Id" />
<input type="text" name="Choices[1].Choice" />
<input type="hidden" name="Choices[1].Correct" />

And so on. When you post your form, the model binder will attempt to take whatever values are attached and set them on your QuestionEdit object based on the name. So in the above case, vm.Choices in your action method will contain 2 items.

This link gives some pretty good examples that should point you in the right direction:

http://www.codeproject.com/Articles/551576/ASP-NET-MVC-Model-Binding-and-Data-Annotation

From there, it's up to your JavaScript to create input elements accordingly and append them to your form.

Hope this helps.

Jim Skerritt
  • 4,348
  • 2
  • 28
  • 25
  • Thanks a lot! I've struggled a bit to generate all the inputs with the proper naming, but the View persisted the information to the Controller. – Rafael Merlin Jan 28 '15 at 15:40