How to dynamically create partial views - asp.net-mvc-3

I have a table in my database called Programs. I want to display a tab for each program .I am trying to create a partial view to do this and then I want to include the partial view to every view that will need to have those tabs. My partial view looks like below.
<div id="tabs">
<ul>
<li id="HomeTab">#Html.ActionLink("Dashboard", "Index", "Home")</li>
<li id="Program1Tab">#Html.ActionLink("Program1", "Index", "Program")</li>
<li id="Program2Tab">#Html.ActionLink("Program2", "Index", "Program")</li>
</ul>
</div>
I am hoping to dynamically create the tabs using something like
#foreach (var ptype in Model)
{
<li id=\"#ptype.Name\"Tab>#Html.ActionLink(ptype.Name, "Index", "Project")</li>
}
however I am wondering how I can load the tabs without using a controller. Can I use a helper class/method to directly access the model bypassing the controller?
update:
I also tried by creating a helper method
namespace MyProject.Helpers
{
public class ProgramTypes
{
public static List<ProgramType> ProgramTypesList()
{
MyDbContext db = new myDbContext();
return db.ProgramTypes.ToList<Programtype>();
}
}
}
and then accessing them using
#foreach (var ptype in MyProject.Helpers.ProgramTypes.ProgramTypesList())
however i am not sure if this is the correct thing to do.

The best solution is - passing collection of programs to your view
#model IQueyrable<Program>
<div id="tabs">
<ul>
#foreach (var ptype in Model)
{
<li>#Html.RenderPartial("ProgramTab", ptype)</li>
}
</ul>
</div>
so you have to create another partial view where you will display program details.
If you want organize this like tabs you should use something like jquery tabs
you don't have to use actionlink just RenderPartial or RenderAction

Related

Partial view in NET 6

i am lost with NET6.
I created this partial view _MenuNav.cshtml :
#model IEnumerable<CateringMilano.Models.Menu>
#foreach (var item in Model)
{
<div>
<a alt="#item.MenuTitle)">#item.MenuName</a>
<b>#item.MenuTitle</b>
</div>
}
and the cod in my controller is :
// GET: /Menus/_MenuNav/
public ActionResult _MenuNav(string menuPosition)
{
// Get my db
var model = _context.Menu.Include(m => m.ChildMenuSub) as IQueryable<Menu>;
model = model.Where(p => p.MenuPosition == menuPosition);
// Send your collection of Mreations to the View
return PartialView(model);
}
and in the last project with net 4 i use to write the following code in the principal view in order to call my partial view :
#Html.Action("_MenuNav", "Menus", new { menuPosition = "Menu" })
but it looks like it does not work anymore this with NET6
Do you know how to rewrite my code in order to get the same result?
you must be mixing view components with partial views. Partial view were always used like this
<div id="partialName">
<partial name="_PartialName" />
</div>
with model
<partial name="_PartialName" model="Model.MyInfo" />
or for async
<div id="partialName">
#await Html.PartialAsync("_PartialName")
</div>
and the most popular way to update parital view is using ajax
And you can check my answer about viewcomponents here
https://stackoverflow.com/a/69698058/11392290

How to get model from Partial View in MVC

I have a main Index view from which I call view called Create, into which I pass type of the widget I want to create as a string.
Index view:
<i class="fa fa-image"></i> Create Image Widget -
<i class="fa fa-file-text"></i> Create Text Widget
Create Action:
public ActionResult Create(string wType)
{
ViewBag.wType = wType;
return View();
}
the type is then passed into view via ViewBag.wType and this is evaluated in the Create View
Create view:
#using (Html.BeginForm())
{
<section class="row">
#{
if (ViewBag.wType == "image")
{
Html.RenderPartial("~/Views/WidgetEditor/_CreateImageWidget.cshtml");
}
else if (ViewBag.wType == "text")
{
Html.RenderPartial("~/Views/WidgetEditor/_CreateTextWidget.cshtml");
}
}
</section>
}
and depending on this, appropriate partial view is loaded.
Partial views have different models so when the form is submitted, I do not know how which model is passed back. The one from _CreateImageWidget or _CreateTextWidget.
If the HttpPost controller look like this
[HttpPost]
public ActionResult Create(DisplayWidgetImageViewModel imageModel, DisplayWidgetTextViewModel textModel)
{
return new ViewResult();
}
I will get populated imageModel if _CreateImageWidget partial is chosen and textMode if _CreateTextWidget partial is chosen.
This is acceptable it the number of widgets types does not change, but this is not the case.
Is there a way to get somehow specific model from a partial view and know/find out which one it is or am I doing this completely wrong way?
You can create multiple forms in single page. You can also use different action methods per partial:
#using (Html.BeginForm("Action", "Controller")) {
Html.RenderPartial("~/Views/WidgetEditor/_CreateImageWidget.cshtml")
}
You all this without having to use Ajax.
I have used this answer to solve my problem: determine-the-model-of-a-partial-view-from-the-controller-within-mvc
there are also several other link with more resources.

To call a page on click of an ActionLink in the same View

i am developing an application in MVC3..
I have several links on the leftside and on click of the link the page should be displayed on the right side
I have made a table.
in the First Column the links are displayed like this:
<ul>
#foreach (var item in Model)
{
<li>#Html.ActionLink(item.HobbyName, "Hobbies")</li>
}
and in the second column i need to display information about the links when it is clicked but i am not understanding hw shud i do that..
Like What shud i write in the Controller to fetch those views in this column.
Please Help me
Use Ajax.ActionLink instead of Html.Actionlink and set update target id in Ajax Options to the div you want to update. Example
<ul>
#foreach(var item in Model)
{
<li>
#Ajax.ActionLink(item.HobbyName, "Hobbies",
new AjaxOptions { UpdateTargetId = "divHobyList" })
</li>
}
</ul>
<div id="divHobyList">
here will load hobbies
</div>

Nested edit templates in mvc razor

I have seen many versions of this question but the answers always turn into "you don't need to do that" and never an answer.
I have a list of attributes about a product that I want to show in an unordered list with checkboxes to select particular attributes.
In My Model:
public List<ProductAttribute> ProductAttributes {get;set;}
in my Create.cshtml:
<div Class="ProductAttributes">
#Html.EditorFor(m => m.ProductAttributes, "ProductAttributeSelectorList")
</div>
In my ProductAttributeSelectorList.cshtml:
#model List<Models.DisplayLocationAttribute>
<div class="AttributeSelector">
<ul>
#foreach (var item in Model)
{
<li>
#Html.EditorFor(_ => item, "EditLocationAttributeList")
</li>
}
</ul>
</div>
And finally, in my EditLocationAttributeList.cshtml
#model Models.DisplayLocationAttribute
#Html.HiddenFor(m => m.Id)
#Html.CheckBoxFor(m => m.IsSelected)
<a href="#" alt="#Model.Description" >#Model.Name</a>
This all displays on the page perfectly I can style it like I want with CSS, but when the submit returns, my model.ProductAttributes collection is null.
I know I can bind directly to the EditLocationAttributeList and it will display and return a populated model.ProductAttributes if I use this:
#Html.EditorFor(m => m.ProductAttributes, "EditLocationAttributeList")
but now I do not have the unordered list that I would like to have. I could treat the template like an Item Template and have the line item tags embeded in that template but that seems smelly to have a template that is tightly coupled to another template.
Any Ideas?
Thanks in advance,
Tal
model.ProductAttributes is null, because the DefaultModelBinder is not able to reference each DisplayLocationAttribute back to the ProductAttribute property of your model. The simplest solution is to name your list elements as an array, so that for example each IsSelected element is named in the style ProductAttributes[n].IsSelected.
Add the following to ProductAttributeSelectorList.cshtml:
#model List<Models.DisplayLocationAttribute>
#{
var i = 0;
}
<div class="AttributeSelector">
<ul>
#foreach (var item in Model)
{
this.ViewData.TemplateInfo.HtmlFieldPrefix = "ProductAttributes[" +
i.ToString() + "]";
i++;
<li>
#Html.EditorFor(_ => item, "EditLocationAttributeList")
</li>
}
</ul>
</div>
#{
this.ViewData.TemplateInfo.HtmlFieldPrefix = "";
}
This will give you an indexed array, which the DefaultModelBinder will be able to associate to ProductAttributes. However, it builds a hard dependency to the name ProductAttributes. You can get around the hard dependency by several methods, such as passing the property name in the ViewBag.

MVC 3 Rendering 2-Level Menu as Partial View

I would like to implement a 2-level parent/child menu in my MVC 3 site such as
Company
- Background
- Contact
I have implemented a single, parent level menu as a PartialView like so ...
<div id="menu" class="block">
<ul id="menuItems">
foreach (var item in Model)
{
<li id="#item.Id">#Html.ActionLink(item.Name, item.Action,item.Controller)</li>
}
</ul>
</div>
and then included it on my MasterPage ...
#{Html.RenderAction("MainMenu", "Menu");}
The problem is that I would like to render a second child-menu based on the menu item selected at the parent level. This involves passing the Id of the parent into the controller action that returns the menu model. I'm not sure how I can pass this parent Id into the controller action. Can anyone provide any insights into this? I'm using MVC3 & Razor.
You may want to check out MvcSiteMapProvider which handles multilevel menu and sitemaps.
Looks like you're using Razor and while I'm not super familiar with that I'll take a shot at it. Basically you're going to pass a new object that has a single property of "id" to the MainMenu view. That will create another menu. Your MainMenu action should take an optional parameter of id.
public ActionResult MainMenu(int? id = null) {
...
}
Here is what your new list item would look like.
<li id="#item.Id">#Html.ActionLink(item.Name, item.Action,item.Controller)
#{Html.RenderAction("MainMenu", "Menu", new { id = item.Id });}
</li>

Resources