ASP.NET MVC 3 - Partial View displayling as new page - asp.net-mvc-3

I have had look at a few post already here but I am none the wiser. I tried my first example of Ajax but to no avail. The Partial View is loaded into a separate page as opposed to changing the dom element in the current page.
The pupose is by clicking on the Refresh link in updates the "Last Activity Date" value of the current row only.
Please if there is an easy well of doing this can you also let me know?
View:
#model IEnumerable<RegistrationManager.User>
#{
ViewBag.Title = "Users";
}
#section scripts {
#Content.Script(Url, "jquery-unobtrusive-ajax.min.js")
}
<h2>Users</h2>
<table>
<tr>
<th>Email Address</th>
<th>Given Names</th>
<th>Surname</th>
<th>Last Activity Date</th>
<th>Refresh</th>
</tr>
#foreach (var item in Model)
{
string selectedRow = "";
if (ViewBag.UserId != null && item.UserId == ViewBag.UserId)
{
selectedRow = "selectedrow";
}
<tr class="#selectedRow" valign="top">
<td>
#item.UserName
</td>
<td>
#item.Profile.GivenNames
</td>
<td>
#item.Profile.Surname
</td>
<td>
<div id="#String.Format("LastActivityDate{0}", item.UserId)">#Html.Partial("_DateOnlyPartialView", item.LastActivityDate)</div>
</td>
<td>
#Ajax.ActionLink("Refresh", "Refresh",
new { UserId = item.UserId },
new AjaxOptions {
UpdateTargetId = "LastActivityDate" + item.UserId,
InsertionMode = InsertionMode.Replace,
HttpMethod = "GET"
})
</td>
</tr>
}
</table>
Conrtoller:
public PartialViewResult Refresh(Guid? UserId)
{
User user = _db.Users.Find(UserId);
user.RefreshLastActivityDate();
return PartialView("_DateOnlyPartialView", user.LastActivityDate);
}

Have you included/referenced all the necessary javascript files?
If you have UnobtrusiveJavaScriptEnabled then you'll need:
jQuery
jquery.unobtrusive-ajax.js
if you also use client side validation, you'll need;
jquery.validate.js
jquery.validate.unobtrusive.js
These files can all be found when you create a new MVC3 project.

Related

DropdownlistFor in a loop, null model on submit

I am having an issue with the values selected in multiple dropdownlistfor(s) being available in the controller when the form is submitted. The model is always blank. I know there are issues with mvc having dropdowns in loops but I thought I have solved for this. Let me know what you think.
View
#model DataDictionaryConversion.Models.FinalResults
#{ using (Html.BeginForm("SaveMapping", "Home", FormMethod.Post, null))
{
#Html.AntiForgeryToken()
<table class="table table-striped">
<thead>
<tr>
<th>Converted to Name</th>
<th>Your Project Name</th>
<th><input type="button"
onclick="checkAll()"/></th>
</tr>
</thead>
<tbody>
#{for (int x = 0; x < Model.DDObjects.Count(); x++)
{
var isSelection = false;
<tr>
<td class="filterable-cell">#Model.DDObjects[x].ObjectName</td>
<td class="filterable-cell">
#Html.DropDownList(Model.DDObjects[x].ObjectName, new
SelectList(Model.ProjectObjects, "ObjectName", "ObjectName"),
htmlAttributes: new { #id = "ddlObject", #class = "js-example-basic-single" })</td>
</td>
<td>
<input type="checkbox" id="NoValue-
#Model.DDObjects[x].ObjectName" name="NoValue-
#Model.DDObjects[x].ObjectName" onclick="byPassObject(this)" /> Object
Not
Used
</td>
</tr>
}
}
</tbody>
<tfoot>
<tr>
<td style="text-align:right; height:20px"><input
type="submit" class="btn btn-warning" value="Generate Conversion Mapping"
/></td>
</tr>
</tfoot>
</table>
}
}
Controller
[HttpPost]
public ActionResult SaveMapping([FromServices]ApplicationDbContext context, FinalResults model)
{
return View("Mapping");
}
Model
public class FinalResults
{
public IList<FinalObjectModel> ProjectObjects { get; set; }
public IList<Conversion_CSD_ObjectNameLearningModel> DDObjects {
get; set; }
FinalResults model is null
You're using Html.DropDownList. The first param there is a string, which should correspond with the name you're binding to. However, you're passing the value of Model.DDObjects[x].ObjectName, not literally something like "DDOjbects[0].ObjectName".
Instead, you should be using Html.DropDownListFor like so:
#Html.DropDownListFor(m => m.DDObjects[x].ObjectName, ...)
Then, the select list will be bound correctly.

Is there an #Html.ActionLink equivilent for HttpPost?

I have a table that I need to add links to. The links need to go to an HTTPPost actionResult on my controller. I have a huge list that the user needs to be allowed to click on the status, hit the controller and route to the appropriate page afterward. #Html.ActionLink is an HttpGet action. Is there an equivalent for a post?
<table class="table table-striped table-bordered">
<th>Ssn</th>
<th>State</th>
<th>File Uploaded Date</th>
<th>Claim Status</th>
#foreach (var currentClaim in Model.CurrentClaims)
{
<tr >
<td><span name="Ssn">#currentClaim.SSN</span></td>
<td>#currentClaim.StateName</td>
<td>#currentClaim.ClaimDate</td>
<td>#Html.ActionLink(#currentClaim.ClaimStatus, "SubmitClaim", "Claim", FormMethod.Post, new ClaimInputModel { SSN = currentClaim.SSN, StateId = currentClaim.StateId })</td>
</tr>
}
</table>
I tried using
#using("SubmitClaim", "Claim", FormMethod.Post, new ClaimInputModel { SSN = currentClaim.SSN, StateId = currentClaim.StateId })
{
<button type="submit" >xxx</button>
}
I get an HttpCompiler error with this.
You need to use the BeginForm() HtmlHelper that returns a MvcForm which implements IDisposable...
#using(Html.BeginForm("SubmitClaim", "Claim", FormMethod.Post, new { SSN = currentClaim.SSN, StateId = currentClaim.StateId }))
{
<button type="submit" >xxx</button>
}

How can I make a loop to repeat my method for each item?

there is my issue. In a controller, I have this method which export my view in a file when I click a button.
public ActionResult Export(string searchString, int searchOrder = 0)
{
var user = from m in db.Orders select m;
if (!String.IsNullOrEmpty(searchString))
{
user = user.Where(s => s.ClientID.Contains(searchString));
}
Response.AddHeader("Content-Type", "application/vnd.ms-excel");
return this.View(user);
}
My Index view :
#model IEnumerable<MyApp.Models.Order>
#{
ViewBag.Title = "Index";
}
<h2>Orders Historic</h2>
<div id="orderDiv">
#using (Html.BeginForm("Export", "Historic", FormMethod.Get))
{
<p>
Generate Order with ClientID :&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp
#Html.TextBox("searchString")
<input type="submit" value="GENEREMOI" />
</p>
}
</div>
And my Export view :
#model IEnumerable<KrysGroup.Models.Order>
<table cellpadding="3" cellspacing="3">
<tr>
<td width="12%" align="center">
Client Name/ID
</td>
<td width="15%" align="center">
N° Order
</td>
OTHER TD....
</tr>
#foreach (var item in Model)
{
TimeSpan result = DateTime.Now - item.OrderDate;
if (result.Days < 31)
{
<tr border="1" bgcolor="#Odd">
<td> #Html.DisplayFor(modelItem => item.Username) </td>
<td> #Html.DisplayFor(modelItem => item.OrderId) </td>
<td>
<ul style="list-style-type:none; padding:0; margin:0">
#if (item.OrderDetails != null)
{
foreach (var o in item.OrderDetails)
{
if (o.Pack == null)
{
<li> #Html.DisplayFor(modelItem => o.Product.Name) </li>
}
else
{
<li> <text>Pack</text> #Html.DisplayFor(modelItem => o.Pack.Name) </li>
}
}
}
</ul>
</td>
OTHER TD...
</table>
So, in my view, I inform in a textbox a ClientID and when I click the button, it export in a file all the fields in my table with this ClientID.
I would like to automate this action, that is to say I would like write a method or something for, when I click on the button, it executes this export() method for each clientId it meet in my table.
I hope I was clear enough, sorry for my english..
Thanks for your answers, links, tips whatever.
You can write a partial view typed to a list of Id's that loads when you click the button.
So in the controller you have a method converts what you want and returns a view that is typed to the conversion of your model.
In your main view you have a div that will be populated with a partial view after the click-event of the original button.
#Ajax.ActionLink("Name", "NameOfTheAction", "NameOfTheController",
new { id = itemId },
new AjaxOptions { HttpMethod = "Get", UpdateTargetId = "divInMainView", OnSuccess = "Do Something (js)" },
new { html-props })
How to populate is up to you, in your view

Parameters from view not getting to controller action method

I'm implementing Troy Goode's PagedList in one of my views (ASP.NET MVC 3 Razor). The challenge I'm having is when I click on a page number link, the request is routed to my HttpGet method, which just returns the empty page (ready for input).
My View Model:
public class SearchViewModel
{
public SelectList IndustrySelectList { get; set; }
public IPagedList<KeyValuePair<string, SearchResult>> SearchResults { get; set; }
public PagingInfo PagingInfo { get; set; }
}
Controller:
[HttpGet]
public ViewResult Search(string searchTerm = "")
{
SearchViewModel vm = new SearchViewModel
{
IndustrySelectList = new SelectList(_Industries.AsEnumerable(), "IndustryId", "IndustryName"),
PagingInfo = new PagingInfo
{
CurrentPage = 1,
ItemsPerPage = 25,
TotalItems = 0
}
};
return View(vm);
}
[HttpPost]
public ActionResult Search(string[] industries, string searchTerm = "", int page = 1)
{
SearchViewModel vm = null;
_url = "http://localhost/MasterNode/masternode.cgi?zoom_query={" + searchTerm + "}&zoom_xml=1&zoom_page={startPage?}&zoom_per_page=1000";
StringBuilder sb = new StringBuilder();
int pageSize = 5;
if (string.IsNullOrEmpty(searchTerm))
{
vm = new SearchViewModel
{
IndustrySelectList = new SelectList(_Industries.AsEnumerable(), "IndustryId", "IndustryName")
};
}
else
{
_request = new SearchRequest(SearchRequest.EnvironmentTypes.Development, "", _url, searchTerm, SearchRequest.SearchType.AllWords, 1000);
sb.Append(GetResults(_url));
_results = new Dictionary<string, SearchResult>();
ParseResults(sb);
GetDetailInformationForResults(searchTerm);
vm = new SearchViewModel
{
IndustrySelectList = new SelectList(_Industries.AsEnumerable(), "IndustryId", "IndustryName"),
SearchResults = _results.ToList<KeyValuePair<string, SearchResult>>().ToPagedList(1, 25),
PagingInfo = new PagingInfo
{
CurrentPage = page,
ItemsPerPage = pageSize,
TotalItems = _results.Count()
}
};
}
return View(vm);
}
View:
#model MultiView.OmniGuide.ViewModels.SearchViewModel
#using MultiView.OmniGuide.HtmlHelpers
#using PagedList
#using PagedList.Mvc
#{
ViewBag.Title = "Search";
}
<link href="/Content/PagedList.css" rel="stylesheet" type="text/css" />
#using (Html.BeginForm("Search", "Home"))
{
#Html.HiddenFor(c => c.IndustrySelectList)
#Html.HiddenFor(c => c.PagingInfo)
#Html.HiddenFor(c => c.SearchResults)
<table width="70%">
<tr>
<td colspan="2" style="background: #fff">
<input id="searchTerm" name="searchTerm" type="text" class="SearchBox" style="width: 450px" />
<input type="submit" class="SearchButton" value=" " />
</td>
</tr>
<tr align="left">
<td align="left" style="background: #fff">
#Html.ActionLink("MultiView corporate site", "Search")
</td>
</tr>
<tr>
<td colspan="1" align="center" style="width: 450px">
#{
Html.Telerik().PanelBar()
.Name("searchPanel")
.Items(title =>
{
title.Add()
.Text("Filter by Industry")
.Content(() =>
{
#Html.RenderPartial("_Industry", #Model);
});
})
.Render();
}
</td>
</tr>
<tr><td colspan="2"></td></tr>
</table>
<br />
if (Model.SearchResults != null)
{
<table width="70%">
<tr>
<th>
Company Image
</th>
<th class="tableHeader">
Company Name Here
</th>
<th class="tableHeader">
Website
</th>
</tr>
#foreach (KeyValuePair<string, MultiView.OmniGuide.Models.SearchResult> itm in Model.SearchResults)
{
<tr>
<td align="left" style="width: 15%">
#itm.Value.DetailedInfo.LogoURL
</td>
<td align="left" style="width: 60%">
<p style="text-align: left">
#itm.Value.DetailedInfo.DescriptionAbbreviated
<br />
</p>
#Html.AnchorLink(itm.Value.FoundURL, itm.Value.FoundURL)
</td>
<td style="width: 25%">
#itm.Value.FoundURL
</td>
</tr>
}
</table>
#Html.PagedListPager((IPagedList)Model.SearchResults, page => Url.Action("Search", "Home", new { page }))
}
}
When text is supplied in the input box and the button is clicked, the requested is routed to the HttpPost method. In looking at the request.form values, all expected data but paging information is present.
?HttpContext.Request.Form.AllKeys
{string[5]}
[0]: "IndustrySelectList"
[1]: "PagingInfo"
[2]: "SearchResults"
[3]: "searchTerm"
[4]: "industries"
Any help with this would be very much appreciated!
By clicking the button you are submitting the form which is why it is doing the httppost. The next page link is hitting the httpget correctly but you are not passing it any information to so that it knows what to get. The get needs other information, like what page you are wanting.
The page number links fire a GET request, so you'll need to make sure that your GET action can handle the full search as well, so will need to get the page number and industries array - using defaults for when those parameters aren't available.
e.g.
[HttpGet]
public ViewResult Search(string searchTerm = "", int page = 1,
string industries = "")
{
//.....
}
You'll need to modify the pager link like this to pass industries to the get action.
#Html.PagedListPager((IPagedList)Model.SearchResults, page => Url.Action("Search", "Home", new { page, industries = string.Join(",", Model.IndustrySelectList.Where( x => x.Selected).Select( x => x.Text)) }))
It's not clear to me from your code where the post action is getting string[] industries from, or what it is doing with it, but you will need some way of passing this same this to your get action, probably as a single string that is comma separated. The example I've provided assumed you are taken it from the select list on the viewmodel

error while trying to display view in asp.net mvc 3 app?

I am trying to display a list in a View, how to fix this error?
The model item passed into the dictionary is of type
'System.Data.Objects.ObjectQuery1[System.Linq.IGrouping2[System.Int32,mvc3Post.Models.Contact]]',
but this dictionary requires a model item of type
'System.Collections.Generic.IEnumerable`1[mvc3Post.Models.Contact]'.
controller:
public ActionResult Index()
{
AdventureWorksEntities db = new AdventureWorksEntities();
var result = from soh in db.SalesOrderHeaders
join co in db.Contacts
on soh.ContactID equals co.ContactID
orderby co.FirstName
group co by co.ContactID into g
select g;
return View(result.AsEnumerable());
}
view:
#model IEnumerable<mvc3Post.Models.Contact>
#{
ViewBag.Title = "Index";
}
<h2>
Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
NameStyle
</th>
<th>
Title
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.NameStyle)
</td>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.ContactID }) |
#Html.ActionLink("Details", "Details", new { id = item.ContactID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.ContactID })
</td>
</tr>
}
</table>
Updated now that I see the controller method:
You might need to transform your LINQ result set into a list or something (e.g., contacts.ToList()) more concrete.
Another alternative might be to create a root object for your page's list object to live on. I find it a little easier to follow and maintain if each View has a corresponding Model class that represents it's entire state.
I think either route will resolve your issue though. I think that the latter is probably the better way if I had to recommend one vs the other.

Resources