Search code examples
javascriptjqueryasp.net-mvcrazorviewbag

How to get value from an input control on a View (MVC)


I'm working on small mvc application, and on one point I need a value from my Controller's Method, and my plan is to store that value in a ViewBag and get it on a View, so I did next:

ViewBag.SuccessBody = "This is a test";

And on my Razor View what I did was next:

<input id="customInput" type="hidden" value='@(ViewBag.SuccessBody)' />

//For testing purpose I tried with example below also ..

<input id="customInputAgain" type="hidden" class="form-control" value="@(ViewBag.SuccessBody)">

And when View loads I tried to get a value so I wrote this:

 <script>

        $(document).ready(function () {
            var customVal = $("#customInput").val();
            var customValAgain = $("#customInputAgain").val();

            alert(customVal);
            alert(customValAgain);

        });
</script>

I even tried adding a

alert(customVal.value);

alert(customValAgain.value);

But it is not working also, so looks like I am not retrieving values from my Controller/ViewBag that is reason why alert allways show empty space - nothing.

EDIT :

I am setting this ViewBag value on a Edit of my article, acttualy on a [HttpPost] EDIT, so when user clicks Save Changes [HttpPost] EDIT method is invoked and when data is probably inserted in a database I am setting ViewBag value and redirecting user to same [HttpGet] Edit method. Here is how that does looks:

[HttpPost]
public ActionResult Edit(ArticleEditViewModel model)
{
            if (ModelState.IsValid)
            {
                //Rest of the code
                ViewBag.SuccessBody = "This is a test";
                return RedirectToAction("Edit/" + product.Id, "Article");
            }
            else
            {
              return View("NotFound");
            }
            return View(model);
}

As you can see guys I defined ViewBag but I can not get the value on a View which should be stored in a input control..

Maybe the issue is because I defined a ViewBag in a HttpPost Action method and not in HttpGet where from I'm "opening the view" ?


Solution

  • I would use .attr() as I prefer explicitly knowing what I'm targeting:

    var customVal = $("#customInput").attr("value");
    

    As for the server-side, make sure that ViewBag.SuccessBody is actually declared and returns something.

    public ActionResult FooAction()
    {
        ViewBag.SuccessBody = "This is a test";
        return View();
    }
    

    Also make sure that you're returning ViewBag.SuccessBody from the correct action method, to it's corresponding view.

    Update

    Based on your edit: you're redirecting to a different action (the Edit [HttpGet] one), so obviously ViewBag.SuccessBody is not defined there. Why not just pass a bool? editSuccess parameter to your [HttpGet] Edit method, indicating whether the edit was successful or not?

    [HttpGet]
    public ActionResult Edit(int id, bool? editSuccess)
    {
        if (editSuccess.HasValue) 
        {
             if (editSuccess)
             {
                 // edit was successful here
                ViewBag.SuccessBody = "Yay! :)";
             }
             else
             {
                // edit was unsuccessful here
                ViewBag.SuccessBody = "No! :(";
             }
        } 
        // other stuff
        return View();
    }
    

    Your [HttpPost] action then becomes:

    [HttpPost]
    public ActionResult Edit(ArticleEditViewModel model)
    {
        if (ModelState.IsValid)
        {
            // ...
            RedirectToAction("Edit", new { id = product.Id, editSuccess = true });
        }
        else
        {
            // ...
        }
    }
    

    Using this approach you can specify when the edit might have failed as well, by setting editSuccess to false. If you're simply interested in passing whatever value back to the view, then skip all the editSuccess parts and simply return ViewBag.SuccessBody from the [HttpGet] action, instead of the [HttpPost] one.

    Aside: Obviously, as editSuccess is optional and you're only setting ViewBag.SuccessBody to something when editSuccess actually has a value, you can do this check in the view to determine whether to output something or not in the HTML:

    @if (!string.IsNullOrEmpty(ViewBag.SuccessBody)) 
    { 
        // not empty, do something
    }