Search code examples
asp.net-mvc-4actionlinktempdata

MVC4 Sending data from a text box in Controller to View using ActionLink and TempData


Is there a way to utilize TempData with a ActionLink to pass data from a View to a Controller. I have a View that has client-side validation and I need to update a drop down list from a text box on the page without using a submit button. When using two submit type buttons the client side validation flags all the fields that have not been filled in. Essentially I want to be able to add a user defined category to the drop down list without having to jump to a different view for just a textbox and submit button.

I was not sure if I could do something like this:

<input type="text" name="NewCat" value="@TempData["newCat"]" placeholder="New Catagory"/>

I couldn't quite get it to work though...

The View:

@model Exercise4.Models.Quote

@{
    ViewBag.Title = "Create";
}

<h2>Create New Quote</h2>

@using (Html.BeginForm()) {
@Html.ValidationSummary(true)

<fieldset>
    <legend>Quotation Creation</legend>

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

    <aside>
        @using (Html.BeginForm("NewCatagory","Quote"))
        {
            <input type="text" name="NewCat" value="@TempData["newCat"]" placeholder="New Catagory"/>
            @Html.ActionLink("Add Catagory","NewCatagory","Quote")

        }
    </aside>

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

        @Html.TextBoxFor(model => model.QName)
        @Html.ValidationMessageFor(model => model.QName)

    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.QAuthor)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.QAuthor)
        @Html.ValidationMessageFor(model => model.QAuthor)
    </div>
    <p>
        <input type="submit" value="Create" />

    </p>
</fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

The Controller Section:

//
// Create New Catagory
public ActionResult NewCatagory()
{
    string value = TempData["newCat"] as string;
    if(!String.IsNullOrWhiteSpace(value))
    {
        Catagory cat = new Catagory();
        cat.CatName = value;
        db.Catagories.Add(cat);
        db.SaveChanges();
    }

    ViewBag.CatagoryID = new SelectList(db.Catagories, "CatagoryID", "CatName");
    return RedirectToAction("Create");
}

Any suggestions would be greatly appreciated either how to make this work or something a little more elegant.


Solution

  • This was my fix.

    I rendered a partial view

    Main View

    <div class="asideRight">
        <fieldset>
            <legend></legend>
            @Html.Partial("_AddCat", new Exercise4.Models.Category())
        </fieldset>
    </div>
    

    Partial View

    @model Exercise4.Models.Category
    
    <script src="~/Scripts/jquery-1.7.1.min.js"></script>
    <script src="~/Scripts/jquery.validate.min.js"></script>
    <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
    
    @using (Html.BeginForm("addCat", "Quote")) {
        @Html.ValidationSummary(true)
    
        <fieldset>
            <legend class="myLegend">Create New Category</legend>
    
            <div class="editor-field">
                @Html.EditorFor(model => model.CatName)
            </div>
    
            <p>
                <input class="mySubmit" type="submit" value="Create" />
            </p>
        </fieldset>
        <div class="myValidation">
            @Html.ValidationMessageFor(model => model.CatName)
            @Html.ValidationMessage("")
        </div>
    }
    

    This allowed me to post back to the controller and add the new category before returning to the Create View

    Controller Method

        [HttpPost]
        [Authorize]
        public ActionResult addCat(Category cat)
        {
            if (cat.CatName != null)
            {
                bool exists = db.Categories.Any(n => n.CatName.ToLower() == cat.CatName.ToLower());
                if (!exists)
                {
                    db.Categories.Add(cat);
                    db.SaveChanges();
                }
                else
                {
                    ModelState.AddModelError("", "You entered a duplicate Category Name");
                }
            }
    
            ViewBag.CategoryID = new SelectList(db.Categories.OrderBy(n => n.CatName), "CategoryID", "CatName");
            return RedirectToAction("Create");
        }