no selected value selectlist partial view asp.net mvc - asp.net-mvc

So I have a Edit view with a partial view. In this partial view I have a selectlist (or dropdownlist) which values come from a ViewBag. In the control I include the selected value but it just does'nt work.
public ActionResult Edit(int id = 0)
{
Customer c = db.Customer.Find(id);
ViewBag.CustomerGlobalQuality = new SelectList(db.GlobalQuality, "Id", "Quality", c.Skill.GlobalQuality);
return View(c);
}
and in the PARTIAL VIEW I have:
#Html.DropDownList("CustomerGlobalQuality")
#Html.ValidationMessageFor(model => model.Skill.GlobalQuality)
what did I miss? It usually works with normal views, so why not with a partial?

if your logic doesn't need partial view, do not include it in this case. Use those lines of code inside your edit chtml view. In your case debug it and see what are you realy sending to drop down list. I see that you included dropdown list dana in edit view. If you use partial view you must pass object to that view in controler.
public ActionResult PartialDDLData()
{
ViewBag.CustomerGlobalQuality = new SelectList(db.GlobalQuality, "Id", "Quality", c.Skill.GlobalQuality);
return Partial("_nameOfView",ViewBag.CustomerGlobalQuality);
}
and make sure your partial view is accessible in shared or controller view folder.

Related

Adding a dropdown list outside or RenderBody call

I have a .NET MVC project with Razor views and I would like to implement search functionality that consists of a dropdown list, a text box and a search button.
The problem is that I would like to implement this search snippet in my _Layout.cshtml file outside of the #RenderBody() call. This means that the search functionality would be accessible on every page (it would be located at the very top right corner).
I'm trying to find out what is a good way of implementing this. I can get it to work but it would involve adding same code (do get dropdown values) to all controllers and actions.
ViewBag.States = new SelectList(db.States, "Id", "Name");
Is there a better way to implement this? It feels very repetitive to do it this way.
You can have a child action method which returns the partial view needed for your header and call this action method in your layout.
Create a view model for the properties needed.
public class AllPageVm
{
public int SelectedItem { set; get; }
public List<SelectListItem> Items { set; get; }
}
Now create an action method in any of your controller. Mark this action method with ChildActionOnly decorator.
public class HomeController : Controller
{
[ChildActionOnly]
public ActionResult HeaderSearch()
{
var vm = new AllPageVm()
{
Items = db.States
.Select(a => new SelectListItem() {Value = a.Id.ToString(),
Text = a.Name})
.ToList()
};
return PartialView(vm);
}
Now in the HeaderSearch.cshtml partial view, you can render whatever markup you want for your search header. Here is a simple example to render the dropdown. You may update this part to include whatever markup you want (Ex : a form tag which has textbox, dropdown and the button etc)
#model AllPageVm
<div>
<label>Select one state</label>
#Html.DropDownListFor(a => a.SelectedItem, Model.Items, "Select")
</div>
Now in your layout, you can call this child action method
<div class="container body-content">
#Html.Action("HeaderSearch", "Home")
#RenderBody()
<hr/>
<footer>
<p>© #DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>
Make sure you are calling PartialView method from the HeaderSearch child action method instead of View method. If you call View method, it will recursively call the same method and you will get a StackOverflow exception

MVC: How to get controller to render partial view initiated from the view

In my MVC5 project I want to create a menu in a partial view. This menu is dynamic in the sense that it is built from content in my database. Thus I have a controller taking care of creating my menu and returning the menu model to my partial view:
public PartialViewResult GetMenu()
{
MenuStructuredModel menuStructuredModel = menuBusiness.GetStructuredMenu();
return PartialView("~/Views/Shared/MenuPartial", menuStructuredModel);
}
In my partial view called MenuPartial I want to use razor to iterate over my menu items, like:
#model MyApp.Models.Menu.MenuStructuredModel
<div class="list-group panel">
#foreach (var category in Model.ViewTypes[0].Categories)
{
#category.ShownName
}
</div>
Now the problem is the view in which I insert the partial view. If in the view I simply do:
#Html.Partial("MenuPartial")
It won't call the controller to populate the model with data first. What I want is to let the controller return the partial. But I don't know how to do this from the view. In pseudo code I would like to do something like:
#Html.RenderPartialFromController("/MyController/GetMenu")
Thanks to Stephen Muecke and Erick Cortorreal I got it to work.
This is what the controller should look like:
[ChildActionOnly]
public PartialViewResult GetMenu()
{
MenuStructuredModel menuStructuredModel = menuBusiness.GetStructuredMenu();
return PartialView("~/Views/Shared/MenuPartial", menuStructuredModel);
}
And it may called like:
#Html.Action("GetMenu", "Home")
(Hence GetMenu() is declared in the HomeController in my example).
The controller is now called (and the model is populated) prior to the partial view is rendered.
You should use: #Html.RenderAction or #Html.Action.

How to update #Html.DropDownList after post

In my MVC app, I need to update the values in a DropDownList after a post.
My view:
#{
IEnumerable<MyModel.MySelectItem> mylist= ViewBag.MyList;
}
#using (Ajax.BeginForm(...........)
{
#Html.DropDownList("myselection", mylist.ToSelectList(p => p.Description, p => p.Description), "Select Item")
....Other controls and a submit button are here...
}
My controller:
//Populate list in Index()
ViewBag.MyList = myGeneratedList;
return View();
When the view is initially displayed, the DropDownList is populated with the correct values.
Here is the post method:
public ActionResult GetData()
{
ActionResult result = null;
//Query data...
ViewBag.MyList = myNEWGeneratedList;
//Need to display a table of results and update DropDownList
var myTableResults = GetSomeData();
result = PartialView("_MyTableResultsView", myTableResults);
return results;
}
When the form posts back, the partial view displays it's results fine, but the DropDownList does NOT get updated.
How can I get the DropDownList in the view to update after a post?
Ajax.beginform will update a specific control based on the value of the UpdateTargetId parameter. If your dropdownlist is not within the target control, it will not be changed. If it is in the targeted control, it will be updated or overwritten with whatever is returned in your partial view.
If you want your dropdownlist to update outside of the returned partial view or UpdateTarget, you would most likely use javascript or jquery to update it client side.
Another option is to use HTML.beginform which will issue a full page postback (refresh everything), but your controller would need to be updated to return a view that contains the updated dropdownlist as well as the code in your current partial view.

Repeating view within a view in ASP MVC3

If I have an elaborate repeating layout which I would like to only define once, say some fancy grid of boxes, but the content of those boxes would vary both in view and model from grid to grid (but not within a grid), e.g. one page has a fancygrid of product summaries and another page has a fancygrid of category introductions. What's the most sensible pattern for implementing that MVC3?
You could use display templates. For example define a property on your view model that is of type Enumerable<SomeViewModel>:
public class MyViewModel
{
public IEnumerable<SomeViewModel> Models { get; set; }
}
and in the view use the DisplayFor helper:
#model MyViewModel
#Html.DisplayFor(x => x.Models)
then define a custom display template that will automatically be rendered for each element of the Models collection (~/Views/Shared/DisplayTemplates/SomeViewModel.cshtml):
#model SomeViewModel
<div>
#Html.DisplayFor(x => x.SomeProperty)
...
</div>
Templated helpers work by convention. By default it will first look in the ~/Views/CurrentController/DisplayTemplates folder and then in the ~/Views/Shared/DisplayTemplates folder for a template which is named the same way as the type of the collection property (SomeViewModel.cshtml).
You can move the repeating section into a partial view. Then that partial view can be reused anywhere
Action GenreMenu in Store Controller:
[ChildActionOnly]
public ActionResult GenreMenu()
{
var genres = storeDB.Genres.ToList();
return PartialView(genres);
}
in the View this will repeat the partial view three times:
#for (int i = 0; i < 3; i++)
{
Html.RenderAction("GenreMenu", "Store");
}

Set input column value in code in MVC

I created my first MVC application in ASP.NET today. I have a datetime column "CreatedAt" which should be filled by current date without being visible in the input form. But the generated code has this code:
<div class="editor-field">
#Html.EditorFor(model => model.CreatedAt)
#Html.ValidationMessageFor(model => model.CreatedAt)
</div>
It displays a textbox in input form. I don't want to display it, instead it should be set in code behind. How can I do that?
ASP.NET MVC doesn't have a concept of a 'code-behind'. Quite simply, you send data from your View, and it's processed in your Controller.
So if this is an action that POSTs, then we can send data back to the controller, and even better, we can keep that data 'hidden' from the textbox view.
In your view, you should replace that with the following line:
#Html.HiddenFor(m => m.CreatedAt, DateTime.Now);
Then when the model is POSTed to the controller, the CreatedAt property will have the DateTime.Now filled in.
When you POST something, it has to go to an Action Method:
public class MyController : Controller
{
//other stuff
[HttpPost]
public ActionResult Edit(Product product)
{
product.CreatedAt // should equal the DateTime.Now set when you created the View
}
}
or you could set it in the controller after it POSTs:
public class MyController : Controller
{
//other stuff
[HttpPost]
public ActionResult Edit(Product product)
{
product.CreatedAt = DateTime.Now;
}
}
You may run into issues with Html.Hidden in this context, if you do, make sure to use the work around in place.

Resources