To call a page on click of an ActionLink in the same View - asp.net-mvc-3

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>

Related

Update partial view after edit

I have the following index:
<div id='addProduct'>
#{ Html.RenderPartial("Create", new BoringStore.Models.Product()); }
</div>
<div id='productList'>
#{ Html.RenderPartial("ProductListControl", Model.Products); }
</div>
The partial Create view contains an invisible div which is used to create a new product.
After doing so the partial view ProductListControl is updated.
Now I want to do so with an edit function.
Problem: It's not possible to integrate the edit page while loading the index because at this moment I don't know which product the user wants to edit.
My thought:
I'd like to call my existing edit view in an jquery modal (not the problem) so the user can perform changes.
After saving the modal is closed (still not the problem- I could handle this) and the ProductListControl is updated (here's my problem ... :().
How am I able to do so?
I've seen some tutorials but I'd like to keep it as clean & easy as possible.
Most of them are using dom manipulating and get feedback from the server (controller) by a JsonResult.
If possible I'd like to stick to the razor syntax, no pure JavaScript or jquery and if possible I'd like to avoid JsonResults.
One way might be to use the Ajax.BeginForm for your create product view.
The Ajax.BeginForm accepts a number of AjaxOptions, one being the UpdateTargetId (your DOM id, in this case your productlist div), more info here.
Then in your product controller code you can return a partial view, with the product list. So for example:
Index.cshtml
#using (Ajax.BeginForm("AjaxSave", "Product", new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "productList", InsertionMode = InsertionMode.Replace }))
{
// your form
<p>
<input type="submit" value="Save" />
</p>
}
...
<div id="productList">...
</div>
ProductController.cs
[HttpGet]
public ActionResult AjaxSave(Product product)
{
if (ModelState.IsValid)
{
// save products etc..
}
var allProducts = _productService.GetAllProducts();
return PartialView("ProductListControl", allProducts);
}
There is a nice article on about this here.

How to dynamically create partial views

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

MVC Ajax action Link copies itself and appends, how do i fix

I am using ordered list design to to make my twitter app to view the tweets. Every Time I call the ajax insert, it puts puts another copy of the ajax link on the page . I am just trying to get the next set of tweets from the controller and inserting them so it lines up. I have tried moving the tags around and but the additional ajax buttons keep showing up.
Thinking it was a css problem i stripped it all out. Wasnt the issue. I will have to reformat my list again to put the closing and openning tags before and after the code block.
I just tried to putting it in a partial view and I put the ajax code in the layout.
Ajax Action Link
#Ajax.ActionLink("Update Tweets", "Index", "Home",
new AjaxOptions
{
UpdateTargetId = "TweetBox",
InsertionMode = InsertionMode.InsertBefore,
HttpMethod = "Get",
})
Partial View
<div id="TweetBox">
<div class="TwitterMessageBox">
<ol>
<li class="TweetLineBody">
#foreach (var item in Model)
{
#Html.Hidden(item.StatusId, item.StatusId)
<div class="TwitProfileImage">
<img src=#Url.Content(item.ImageUrl) alt="#item.ScreenName" />
</div>
<div class="TwitRealName">
#item.User
</div>
<div class="TwitNickName">
#MvcHtmlString.Create(#Html.Namify(#item.ScreenName))
</div>
<div class="TweetText">
#MvcHtmlString.Create(#item.Tweet)</div>
<div class="TweetTime">
#Html.RelativeDate(#item.Created)</div>
<div class="TweetRating">
Rating</div>
}
</li>
</ol>
</div>
</div>
The Controller is just a basic Enumerable List on the Home/ Index
This is the behavior
Lets say you have an ajax call that gets data from a controller action. It inserts before on a targetid thats a div id.
The initial view is perfect
AJAX UPDATE HTML LINK // You click it to get the controller invoke the ajax and get the data
Tweet 1
Tweet 2
etc = its perfect and aligned
You click the Ajax action link in your webpage, It goes out and gets the data but adds a second like like this
AJAX UPDATE HTML LINK
AJAX UPDATE HTML LINK
Tweet 1
Tweet 2 // alignment is still perfect but you have the 2nd ajax links
Now click the ajax link a 3rd time
// alignment is still perfect but you have the 2nd ajax link at top and one sandwiched
AJAX UPDATE HTML LINK
AJAX UPDATE HTML LINK
Tweet 1
Tweet 2
// alignment is still perfect but you have the 2nd ajax link at top and one sandwiched
Plus the Tweets results
AJAX UPDATE HTML LINK
Tweet 1
Tweet 2 // alignment is still perfect but you have the 2nd ajax links at the top and a 3rd List is inserted betweet 2/3
Controller Code per request:
public class HomeController : Controller
{
//
// GET: /Home/
private TwitterContext twitterCtx;
public ActionResult Index()
{
twitterCtx = new TwitterContext();
List<TweetViewModel> friendTweets = (from tweet in twitterCtx.Status
where tweet.Type == StatusType.Public
select new TweetViewModel
{
ImageUrl = tweet.User.ProfileImageUrl,
UserId = tweet.UserID,
User = tweet.User.Name,
ScreenName = tweet.User.Identifier.ScreenName,
StatusId = tweet.StatusID,
Tweet = HomeController.AddWebAndTwitterLinks(tweet.Text),
Created = tweet.CreatedAt
})
.ToList();
return View(friendTweets);
}
My Desired Behavior is 1 ajax link to call the controller and the data inserts
Without seeing all the code, I can only assume you don't have your views sorted out. Your controller appears to be returning the full Index view. If you put your tweet box into a partial view, your ajax action needs to be returning that partial view.

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