MVC3 with Ajax - return data not "plugged" to the right spot - ajax

I'm trying to get started with Ajax on MVC
In my main view I have the following code:
#Ajax.ActionLink("Click here to get the data","LoadData",
new AjaxOptions
{
UpdateTargetId = "dataPanel",
InsertionMode = InsertionMode.InsertAfter,
HttpMethod="GET"
})
<div id="dataPanel">
</div>
I created the controller's action as below:
public PartialViewResult LatestReview()
{
var myData = GetMyData();
return PartialView("_PartialData", myData);
}
_PartialData is defined as below:
#model MyApp.Models.Data
<div>
#if (Model == null)
{
<p>There is no data yet</p>
}
else
{
<p>
#Model.Body
</p>
}
</div>
But when I click the link, my data (rendered in the _PartialData) is loaded fully in browser, replacing the source page (so not inside the dataPanel div)
When I look at original page source (before clicking the ajax link) It see the ajax actions define as below:
<a data-ajax="true" data-ajax-method="GET" data-ajax-mode="after" data-ajax-update="#dataPanel" href="/Home/LoadData">Click here to get the data</a>
<div id="dataPanel">
</div>
What am I doing wrong?
Thanks

I suspect that you forgot to include the jquery unobtrusive ajax script to your page:
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
It is this script that makes sense of all Ajax.* helper in ASP.NET MVC 3. Without it they generate standard markup with HTML5 data-* attributes which are used by the script.

Related

ASP.NET MVC4 PartialView Not Being Rendered Inside Parent View

I'm trying to filter a list of entities and update the partial view on the page with the filtered data. The partial view is returning the correct model with the filtered data, but is not being rendered inside the parent page. Instead it is being rendered in "body" element of an empty HTML page. I've found many topics on this but even though I appear to be following their directions, I'm still having no luck. A fresh set of eyes from the community here may be a huge help.
#model PennLighting.ViewModels.LinecardViewModel
#{
ViewBag.Title = "Linecard";
}
<div class="linecard-head">
#using (Ajax.BeginForm("Index",
new AjaxOptions
{
UpdateTargetId = "linecard"
}))
{
#Html.EditorFor(model => model.Categories)
<div class="buttons">
<input type="submit" name="btnFilter" value="Filter" />
<input type="submit" name="btnShowAll" value="Show All" />
</div>
}
</div>
<div id="linecard">
#Html.Partial("Linecard")
</div>
#section Scripts
{
#Scripts.Render("~/bundles/jqueryval")
}
public ActionResult Index()
{
var viewModel = new LinecardViewModel();
viewModel.Categories = db.Categories
.OrderBy(c => c.Name).ToList();
viewModel.Manufacturers = db.Manufacturers
.OrderBy(m => m.Name).ToList();
return View(viewModel);
}
public ActionResult Index(string btnFilter, string[] selectedCategories)
{
var viewModel = new LinecardViewModel();
var selectedMfrs = new List<Manufacturer>();
if (btnFilter != null && selectedCategories != null)
{
var categoryIds = selectedCategories.Select(c => int.Parse(c)).ToArray();
if (categoryIds != null)
{
selectedMfrs = db.Manufacturers
.Where(m => m.Categories.Any(c => categoryIds.Contains(c.ID)))
.OrderBy(m => m.Name).ToList();
}
}
else
selectedMfrs = db.Manufacturers.OrderBy(m => m.Name).ToList();
viewModel.Manufacturers = selectedMfrs;
return PartialView("Linecard", viewModel);
}
<!DOCTYPE html>
<html>
<head>
<title>#ViewBag.Title</title>
#Styles.Render("~/Content/themes/base/css", "~/Content/css")
</head>
<body>
<div id="container" class="round-bottom">
<div id="header">
<div id="header-left">
<div id="logo">
<a href="#Url.Content("~/")">
<img src="#Url.Content("~/Content/Images/logo.png")" alt="Penn Lighting Associates" /></a>
</div>
</div>
<div id="header-right">
<ul class="nav">
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li>#Html.ActionLink("About", "Index", "About")</li>
<li>#Html.ActionLink("Linecard", "Index", "Linecard")</li>
<li>#Html.ActionLink("Events", "Index", "Events")</li>
<li>#Html.ActionLink("Gallery", "Index", "Gallery")</li>
<li>#Html.ActionLink("Contact", "Index", "Contact")</li>
<li><a href="http://oasis.pennlighting.com:81/OASIS/desk/index.jsp" target="_blank">
Customer Login</a></li>
</ul>
</div>
</div>
<div id="main">
#RenderBody()
</div>
</div>
<div id="footer">
<p>
Copyright © 2008 Penn Lighting Associates</p>
</div>
#Scripts.Render("~/bundles/jquery")
#RenderSection("scripts",false)
</body>
</html>
So what am I missing? Thanks!
You cannot have 2 actions on the same controller with the same name accessible on the same HTTP verb. You might want to decorate your Index contorller action that is invoked with an AJAX call and returns a partial with the [HttpPost] attribute:
[HttpPost]
public ActionResult Index(string btnFilter, string[] selectedCategories)
{
...
}
Without seeing more of your solution, it's a bit fuzzy, but I believe you want to still return the Index and pass the model data into the Partial in your view. The way you are doing it would return only the partial view, which is why you're getting those results.
So in the filtered index:
return View(viewModel)
And in the index view, pass the data to the partial, which I assume without seeing has the right model association to display.
UPDATE
If you're looking to dynamically pull a subset of data and leave the rest untouched, then do an AJAX POST with the filter information to the action specified for the partial view. Take the data results and place them in the Linecard div.
There are many ways to send the data (bundle by JSON, serialize form, individual data points). Here are some examples:
http://brandonatkinson.blogspot.com/2011/01/using-jquery-and-aspnet-mvc-to-submit.html
MVC ajax json post to controller action method
The problem was that my jqueryval bundle was missing the jquery.unobtrusive-ajax.js file. My code works as is once that was included.

How to use Ajax to update RenderBody() section with VS 2012 Internet Template?

I've looked at few examples where Ajax can be used to update divs or other elements with ids. I have not been able to find an example that uses Ajax with Razor views to help me with the following.
My page is a standard Menu at the top, body in the middle, and a footer. There is no real need to update the header and footer each time. In fact, my page only requires a section of the Body to be updated based on menu clicks and actionlinks on the page. I'm testing this with the Internet Template that is created using VS 2012 if that helps such that I do not have to clutter this request with a bunch of code snippets. I am using Razor views and C# for coding preferences.
So, given the default _Layout.cshtml file, how would I load the About page i.e. RenderBody() section via Ajax? I've tried adding Ajax.BeginForm(...) to my _Layout.cshtml file around one div with an UpdateTargetId that matches a div that I wrapped around the RenderBody() call, returned a partial view from my controller, but that's not quite right. What I get is my partial view only. (The About page with no menu, footer, etc. just the code on the About page)
Would someone kindly share a link that demonstrates this functionality or kindly share the code that does what I desire i.e. swap index view with about view without a full page refresh? Some explanation of what I'm missing would be nice, but I'm sure I could deduce from a solid example where I went awry. As always, your time is much appreciated.
EDIT: Using Jasen's suggestion
_Layout.cshtml
<nav>
<ul id="menu">
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li>#Ajax.ActionLink("About", "About", "Home", null, new AjaxOptions { HttpMethod = "get", UpdateTargetId = "body" }, new { })</li>
<li>#Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
</nav>
....
Inside my div id="body"
#RenderSection("featured", required: false)
<section class="content-wrapper main-content clear-fix">
#RenderBody()
</section>
.....
HomeController.cs
public ActionResult About()
{
ViewBag.Message = "Your app description page.";
return PartialView();
}
......
Here is a simple example with jquery. The About partial gets injected into the div with id="body".
<button>About</button>
<div id="body"></div>
$(function () {
$("button").on("click", function(e) {
$.get("Home/About").done(function(result) {
$("#body").html(result);
});
});
));
Controller Action
[HttpGet]
public ActionResult About()
{
return PartialView("About");
}
About.cshtml
#{ Layout = null }
<h2>Home/About</h2>
<p>Blah... </p>
Edit: Maybe a better example is to use a link instead
#Html.ActionLink("About", "About", "Home", null, new { #class="menu-button" })
<div id="body"></div>
$(function () {
$(".menu-button").on("click", function(e) {
e.preventDefault();
var url = $(this).attr("href");
$.get(url).done(function(result) {
$("#body").html(result);
});
});
});
Edit: Without jquery you want to use Ajax.ActionLink() instead of Ajax.BeginForm()
#Ajax.ActionLink("About", "About", "Home", null, new AjaxOptions { HttpMethod = "get", UpdateTargetId = "body" }, new { })
<div id="body"></div>
In your HomeController.cs
public PartialViewResult About()
{
ViewBag.Message = "Your app description page.";
return PartialView();
}
In your _Layout.cshtml do not forget to import:
<script src="~/Content/Scripts/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="~/Content/Scripts/jquery.unobtrusive-ajax.min.js" type="text/javascript"></script>

partial view display with targeted div in MVC3 Razor view engine

My Controller Action is:
public ActionResult PVInPage()
{
return View();
}
public ActionResult ViewPage2()
{
return PartialView();
}
My Main View:
#using (Html.BeginForm("ViewPage2", "PartialViewInPage"))
{
<input type="submit" value="Call Page Two" />
}
<div id="DisplayPartilView">
#*display partial view *#
</div>
My Partial view Is :
#{
ViewBag.Title = "View Page 2";
}
<div style="width:500px; height:200px; background-color:Gray" >
<h1> This is my Partial view </h1>
</div>
Now I want to do : when i click submit button in my main view then my partial view arise in
My main view inner div with id="DisplayPartilView".
Thanks for response
If you want to load data/html into a page without navigating to a different page you need to use Ajax.
ASP.Net MVC provides a set of helpers to work with Ajax (they are all use jQuery.Ajax under the hood so you can always drop back to one level and write your ajax calls by hand).
But in your case the Ajax.BeginForm provides everything what you need:
So change your main view to:
#using (Ajax.BeginForm("ViewPage2", "PartialViewInPage",
new AjaxOptions() { UpdateTargetId = "DisplayPartilView" }))
{
<input type="submit" value="Call Page Two" />
}
<div id="DisplayPartilView">
#*display partial view *#
</div>
And to make it work you need to reference the following script in your main view or in your layout file after jQuery:
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
#using (Html.BeginForm("ViewPage2", "PartialViewInPage"))
will refresh page, that's why you need ajax
.serialize() to get data from all inputs and .ajax() to make post request, then set partial:
$('#DisplayPartilView').html(response);
In my project i am doing like this it's below
this is my button which is i click then my partial view load in my div like this
<script type="text/javascript">
$(function () {
$("#btnLode").click(function () {
$("#LodeForm").load("/City/ShowAllState", function () {
alert("Your page loaded Successfully !!!!!!!");
});
});
});
</script>
<div id="LodeForm">
</div>
and this is another solution for this problem
#using (Ajax.BeginForm("SearchCountry", "City",
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "Get",
LoadingElementId = "ajax-loader",
UpdateTargetId = "CountryListID",
}))
{
<input type="submit" value="search Country" data-autocomplete-source="#Url.Action("SearchCountry", "City")" />
}
<div id="CountryListID">
</div>
i think this will help you

MVC4 - Ajax.BeginForm and Partial view gives 'undefined'

I'm working on an activity booking and I'm having trouble using ajax.beginform with a partial view. When I click submit, it just goes to a new page and there is an 'undefined' in the top left corner. I have "../../Scripts/jquery.unobtrusive-ajax.min.js" in my layout page. What I want to do is when the user submits the form, the div "AjaxTest" gets updated with the partial view and the form is under the search results.
Here is what I have so far (I took out all the structure and styling so its easier to read):
Main View - Activities
#model Project.Models.ActivityModel
<div id="AjaxTest"></div>
#using (Ajax.BeginForm(new AjaxOptions
{
UpdateTargetId = "AjaxTest",
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST"
}))
{
#Html.ValidationSummary(true)
#Html.TextBoxFor(x => x.Activity_CityName)
<div class="editor-label">
<strong>#Html.LabelFor(x => x.Activity_StartDate)</strong>
</div>
<div class="editor-field">
<input id="checkin" type="text" name="Activity_StartDate" />
</div>
#Html.TextBoxFor(x => x.Activity_EndDate)
#Html.DropDownListFor(x => x.Activity_NumAdults, AdultNum)
#Html.DropDownListFor(x => x.Activity_NumChildren)
#Html.DropDownListFor(x => x.Activity_ChildAge1, ChildAge)
#Html.DropDownListFor(x => x.Activity_ChildAge2, ChildAge)
#Html.DropDownListFor(x => x.Activity_ChildAge3, ChildAge)
<div class="submitbutton">
<input data-inline="true"type="submit" id="activity_search" value="Search" />
</div>
}
Controller
[HttpPost]
public ActionResult Activities(ActivityModel activitysubmission) {
return PartialView("PartialActivities_Success", activitysubmission);
}
Partial View - PartialActivities_Success
#model Project.Models.ActivityModel
<p>City: #Model.Activity_CityName</p>
<p>StartDate: #Model.Activity_StartDate</p>
<p>EndDate: #Model.Activity_EndDate</p>
<div>
<p><strong>Ticket</strong></p>
<p>Number of Adults: #Model.Activity_NumAdults</p>
<p>Number of Children: #Model.Activity_NumChildren</p>
<p>Child 1 age: #Model.Activity_ChildAge1</p>
<p>Child 2 age: #Model.Activity_ChildAge2</p>
<p>Child 3 age: #Model.Activity_ChildAge3</p>
</div>
Scripts in Layout Page
<script src="../../Scripts/jquery.unobtrusive-ajax.min.js" type="text/javascript"> </script>
<script src="../../Scripts/xdate.js" type="text/javascript"></script>
<script src="../../Scripts/xdate.i18n.js" type="text/javascript"></script>
<script src="#System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Scripts/js")"></script>
<script>
$(document).bind("mobileinit", function() {
// As of Beta 2, jQuery Mobile's Ajax navigation does not work in all cases (e.g.,
// when navigating from a mobile to a non-mobile page, or when clicking "back"
// after a form post), hence disabling it.
$.mobile.ajaxEnabled = true; // originally false.
});
</script>
I noticed one mistake in the code. Your div has an id Ajaxtest but the parameter you are passing to BeginRequest is AjaxTest the T is capital
Are you using MVC 4? I would make sure that UnobtrusiveJavaScriptEnabled is set to true in your WebConfig file. I believe it is by default, though. The only other thing I can think of is to verify that you have your other jQuery files and that they're being loaded in the right order. If you load your unobrusive jQuery file before the main one then it won't work.
You haven't specified which action to call when posting the Ajax form. Try changing it to this:
#using (Ajax.BeginForm("Activities", new AjaxOptions
{
UpdateTargetId = "AjaxTest",
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST"
}))

ASP.NET MVC 2 Use Ajax to reload a UserControl

is it possible to use Ajax with ASP.NET MVC 2 to reload a user control, pass along a new Model and have it update all the values that make use of this model without refreshing the rest of the site content?
Yes, and here is one way to do so:
You can call an action on a controller from ajax (jquery is what I use) and get the result. To pass data up you provide parameter values to the $.ajax() call and rendering back you just render a partial with whatever viewmodel is appropriate to your partial.
To get the content displayed you just take the HTML result passed back to your $.ajax() call and, most commonly, replace the contents of a div with your HTML result.
I got it working!
I have the following code in the Controller:
[Authorize, HttpPost]
public ActionResult UpdateDinner(FormCollection formValues)
{
if (Request.IsAjaxRequest())
{
Dinner Dinner = DinnerRepository.GetDinner(Convert.ToInt32(formValues["Date"]));
return PartialView("DeclaratieWidget", Dinner);
}
}
I have this code in my View:
<script src="<%= AppPathHelper.Url(Request.ApplicationPath, "/Scripts/MicrosoftAjax.debug.js") %>" type="text/javascript"></script>
<script src="<%= AppPathHelper.Url(Request.ApplicationPath, "/Scripts/MicrosoftMvcAjax.debug.js") %>" type="text/javascript"></script>
<% using (Ajax.BeginForm("UpdateDinner", new AjaxOptions { UpdateTargetId = "Dinner" }))
{ %>
<select id="Date" name="Date">
<option value="<%= Dinner.Dinner_ID %>"><%= Dinner.Date.ToString("dddd d MMMM") %></option>
</select>
<input type="submit" value="Delete" />
<div id="avondeten">
<% Html.RenderPartial("DeclaratieWidget", Model.Dinners[0]); %>
</div>
It works perfectly this way! :D

Resources