Tym Pollack
Tym Pollack

Reputation: 125

mvc3 model uses list - not storing to database

This is my first MVC3 project and thought it'd be a bit simpler to accomplish this, but I've had a lot of issues. This seems to be the one trouble for which I've not encountered a solution. Posting here as a last resort.

My issue is that the Ingredients list never seems to populate in the database when a new Recipe is created. I've even tried hard-coding a list in the controller when the rest of the data is saved, but it still doesn't do anything. As far as I can tell, there's not even a field for Ingredients in the DB anywhere. Can anyone point out what I'm doing wrong? Much thanks.

Model:

public class Recipe
{
    public int ID { get; set; }

    [Required]
    public string Title { get; set; }

    [Required]
    [Display(Name = "Type of Meal")]
    public int TypeID { get; set; }

    [Required]
    public string Instructions { get; set; }

    [Display(Name = "Submitted By")]
    public string UserName { get; set; }

    public IList<string> Ingredients { get; set; }

    public virtual MealType Type { get; set; }
}

Create View:

@model final.Models.Recipe

@{
    ViewBag.Title = "Recipe Finder - New Recipe";
}

<h2>New Recipe</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script type="text/javascript">
    //adds an ingredient field on the fly
    var numIngredients = 0;
    function addIngredient() {
        $('#ingredientlist').append('<tr><td><input type="text" name="Ingredients[' + numIngredients++ + ']" value="' + $('#AddIngredient').val() + '" readonly="true" tabindex="-1" /></tr></td>');

        $('#AddIngredient').val('');
        $('#AddIngredient').focus();
    }

    function onKeyPress(e) {
        var keycode;

        if (window.event) {
            keycode = window.event.keyCode;
        }
        else if (e) {
            keycode = e.which;
        }
        else {
            return true;
        }

        //for addingredient field, add ingredient and not submit
        //  else mimic submit
        if (keycode == 13) {
            if (document.activeElement.id == "AddIngredient") {
                addIngredient();
                return false;
            }
            document.getElementById('btnSubmit').click();
        }

        return true;
    }

    //intercepts form submit instead of using submit button to disable addingredient textbox
    //  this prevents the value/field from posting
    function preSubmit() {
        $('#AddIngredient').attr('disabled', 'true');
        document.getElementsByTagName('form')[0].submit();
    }

    //intercepts users pressing the enter key
    if (document.layers) document.captureEvents(Event.KEYPRESS);
    document.onkeypress = onKeyPress;
</script>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
<fieldset>
    <legend>by @User.Identity.Name</legend>

    <div class="editor-label">
        @Html.LabelFor(model => model.Title)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Title)
        @Html.ValidationMessageFor(model => model.Title)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.TypeID, "Type")
    </div>
    <div class="editor-field">
        @Html.DropDownList("TypeID", String.Empty)
        @Html.ValidationMessageFor(model => model.TypeID)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.Ingredients)
    </div>
    <div class="editor-field">
        @Html.TextBox("AddIngredient")
        <input type="button" value="Add Ingredient" onclick="addIngredient()" tabindex="-1" />
        <table id="ingredientlist">
        </table>
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.Instructions)
    </div>
    <div class="editor-field">
        @Html.TextAreaFor(model => model.Instructions, new { rows = "7", cols = "77" })
        @Html.ValidationMessageFor(model => model.Instructions)
    </div>

    @Html.HiddenFor(model => model.UserName)

    <p>
        <input type="button" value="Submit" onclick="preSubmit()" id="btnSubmit" />
    </p>
</fieldset>
}

Controller:

    [HttpPost]
    public ActionResult Create(Recipe recipe)
    {

        if (ModelState.IsValid)
        {
            db.Recipes.Add(recipe);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        ViewBag.TypeID = new SelectList(db.MealTypes, "ID", "Type", recipe.TypeID);
        return View(recipe);
    }

The POST fields I can see send all the information successfully, as seen below, I'm not sure what the issue is, or at this point what I haven't already tried.

Title:test recipe
TypeID:2
Ingredients[0]:test0
Ingredients[1]:test1
Ingredients[2]:test2
Ingredients[3]:test3
Instructions:this is a test
UserName:tym

Upvotes: 0

Views: 633

Answers (1)

twoflower
twoflower

Reputation: 6830

You may want to check this page about storing a list of strings associated with an entity.

Upvotes: 1

Related Questions