Ajaxified link in MVC3/JQuery not working in IE8 (missing header) - asp.net-mvc-3

Consider the following code (it is based on a default EMPTY MVC3 project created in visual web developer express 2010sp1):
_Layout.cshtml:
<!DOCTYPE html>
<html>
<head>
<title>#ViewBag.Title</title>
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
</head>
<body>
<div id="header">header</div>
<div id="main">#RenderBody()</div>
</body>
</html>
Index method of HomeController:
public ActionResult Index()
{
if (Request.IsAjaxRequest())
{
ViewBag.Message = "partial";
return PartialView();
}
else
{
ViewBag.Message = "full";
return View();
}
}
Index.cshtml:
<script type="text/javascript">
$(function () {
$('#myLink').click(function () {
$.post(this.href, function (result) {
$('#main').html(result);
alert(result);
});
return false;
//$('#main').load(this.href);
//return false;
});
});
</script>
HomeController index. #ViewBag.Message
#Html.ActionLink("Index", "Index", new { controller = "Home" }, new { id = "myLink" } );
The problem is that in IE8 when the myLink link is clicked, it doesn't update the main div with only the partial html from Index.cshtml but the complete html including the layout. Ofcourse it works fine in FF, I mean why shouldn't it right? It seems Request.IsAjaxRequest() always evaluates to false in IE8. I understand that it is a result of a header X-Requested-With not being attached to a request in IE8. I don't have a lot of experience with web development -- is this a common issue and what is the (best) way to solve this?
UPDATE:
Yesterday I got it working normally in IE8, but when I tried it again this morning, the same problem was back. Now I don't think it has anything to do with the settings in IE8 anymore as I restored the settings to the default values. I tried examining the request with the fiddler tool. In order for me to be able to capture the traffic from localhost with fiddler, I added a period to the address: http://localhost.:3157/. So now the error occurs only when I use http://localhost.:3157/ (with period) and it works normally when I use http://localhost:3157/ (without period). I additionally tested the behavior in Chrome, Opera and Safari -- the ajax link works normally in these browsers. Note that I can get it working normally in IE8 when I attach a query parameter to the ajax link like so:
#Html.ActionLink("Index", "Index", new { controller = "Home", param = "param" }, new { id = "myLink" } )
I don't really want to do this. I'm running low on ideas here. I'm probably missing something that is blatantly obvious to a seasoned web developer =] Anybody recognize these symptoms?

You probably want to use the .live() method instead of .click():
$('#myLink').live('click', function () {
...
return false;
});
because you are replacing the DOM in the AJAX callback (the #main) which contains the link so you are killing the event handler you have assigned.
Also you have a typo in the jquery script inclusion in the <head>. You are missing a closing > after type="text/javascript":
<script src="#Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
So here's a complete working example:
_Layout.cshtml:
<!DOCTYPE html>
<html>
<head>
<title>#ViewBag.Title</title>
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
</head>
<body>
<div id="header">header</div>
<div id="main">#RenderBody()</div>
</body>
</html>
HomeController:
public class HomeController : Controller
{
public ActionResult Index()
{
if (Request.IsAjaxRequest())
{
ViewBag.Message = "partial";
return PartialView();
}
else
{
ViewBag.Message = "full";
return View();
}
}
}
Index.cshtml:
<script type="text/javascript">
$(function () {
$('#myLink').click(function () {
$.post(this.href, function (result) {
$('#main').html(result);
});
return false;
});
});
</script>
HomeController index. #ViewBag.Message
#Html.ActionLink("Index", "Index", new { controller = "Home" }, new { id = "myLink" } )

add
jQuery.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
}
});
to make sure the correct header is attached.

Related

Trying to load a partial view with Ajax.ActionLink

After reading a few other posts on here I've got this far with attempting to load a partial view on the click of a link (the text link may actually change to be an image once I get past this proof of concept stage). The problem is I am being directed to the partial view on click instead of it populating a div within the view I am clicking the link on:
The layout:
<script src="#Url.Content("~/scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
The View:
#Ajax.ActionLink("Item 1 Ajax", "Details", "Portfolio", new { name = "test" }, new AjaxOptions
{
HttpMethod = "Post",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "row1Content",
OnComplete = "portfolioItemLoaded"
})
<div id="row1content"></div>
<script type="text/javascript">
function portfolioItemLoaded() {
alert("Done");
}
</script>
The controller:
public class PortfolioController : Controller
{
public ActionResult Details(string name)
{
return PartialView(name);
}
}
The partial (obviously named test.cshtml):
<p>Item 1 test</p>
Have I missed something obvious? It's the first time I have attempted to use AJAX in MVC, so there might be a school boy error or two.
I am planning on having several different Ajax Action Links that call different partial views, hence the reason I am passing the name in to the controller.
Code fixed
Do you wanna try this, you have a better control, if error, etc....
HTML with helper
#Html.ActionLink("Item 1 Ajax", "Details", "Portfolio", Nothing, New With {.Id = "myLink"})
JavaScript
<script type="text/javascript">
$(document).ready(function() {
$('#myLink').click(getIt);
});
function getIt() {
$.ajax({
type: "POST",
url: $(this).attr('href'),
error: function () {
//show error handler
},
success: function (r) {
$('#row1content').html(r);
}
});
return false;
}
</script>

google maps + asp .net mvc 3 not working

I am teaching myself asp .net mvc 3. I read this tutorial: http://www.codeproject.com/Articles/148949/ASP-NET-MVC-3-the-Razor-View-Engine-and-Google-Map and several other such posts. However, I have not been able to get google map running on my application. what am I doing wrong?
View:
#section Scripts_head {
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
}
<script type="text/javascript">
function initialize() {
var latlng = new google.maps.LatLng(40.716948, -74.003563);
var options = { zoom: 14, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP };
var map = new google.maps.Map(document.getElementById("map"), options);
}
$(function () {
initialize();
});
</script>
<div id="map" style="width:80%; height:80%"></div>
I have also tried putting the div over the script tag.
Layout Page:
<head>
...
#RenderSection("Scripts_head", false)
</head>
Controller:
public class MapController : Controller
{
//
// GET: /Map/
public ActionResult Index()
{
return View();
}
}
If you dont have errors, then its probably sizing of your div "map". Here is your code extracted and working in JsFiddle:
http://jsfiddle.net/GNwU8/3/
Give you map div an absolute size. You have:
<div id="map" style="width:80%; height:80%"></div>
...but that is 80% of what?
instead try:
<div id="map" style="width:400px; height:300px"></div>

mvc3 jquery mobile how to use Html.BeginForm

I have already written an entire site in MVC3. I am trying to build the mobile version with Jquery Mobile. I haven't changed my controller code, except to add a check for whether or not it should return a mobile page. I have the following in the document head of my mobile logon page:
<head>
<title>Mobile Logon</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0-alpha.1/jquery.mobile-1.2.0-alpha.1.min.css" />
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
$(document).bind("mobileinit", function(){
$.extend( $.mobile , {
ajaxEnabled: false
});
});
<script src="http://code.jquery.com/mobile/1.2.0-alpha.1/jquery.mobile-1.2.0-alpha.1.min.js"></script>
</head>
I have a page with a header and content. In the content, I want to let the user redirect to the register form. the following seems to work:
<form action="Register" method="get" data-ajax="false">
<button type="submit" value="Register for an account"></button>
</form>
This does not work: (the url seems correct in the browser, but all that loads is a blank, white page)
#using(Html.BeginForm("Register", "Account", FormMethod.Get, null ))
{
<button type="submit" value="Register for an account"></button>
}
When I look in the page source, I notice two differences: The first one gives a form tag with
action="Register"
while the second gives a form tag with
action="Account/Register"
The other difference is the "data-ajax=false" in the form tag.
Questions:
Am I able to use #Html.BeginForm() with Jquery Mobile? If not, how do I redirect to a different controller?
How come my code in the head section doesn't turn off the default ajax behavior of Jquery Mobile? (I tried using the form tag above without data-ajax=false, and I got the same blank, white screen as the #Html.BeginForm gave me).
EDIT: here is my logon controller code (Account controller)
public ActionResult LogOn()
{
//return View();
return SelectView("Logon", null);
}
private ActionResult SelectView(string viewName, object model, string outputType = "html")
{
if (outputType.ToLower() == "json")
{
return Json(model, JsonRequestBehavior.AllowGet);
}
else
{
#if MOBILE
return View(viewName + ".Mobile", model);
#else
if (Request.Browser.IsMobileDevice)
{
return View(viewName + ".Mobile", model);
}
else
{
return View(viewName, model);
}
#endif
}
}
here is my Register controller code: (Account controller)
public ActionResult Register(string returnUrl = "")
{
//if no return url supplied, use referrer url.
//Protect against endless loop by checking for empty referrer.
if (String.IsNullOrEmpty(returnUrl) && Request.UrlReferrer != null && Request.UrlReferrer.ToString().Length > 0)
{
return RedirectToAction("Register", new { returnUrl = Request.UrlReferrer.ToString() });
}
return View();
}

jquery File Upload (blueimp) - IE9 doesn't support multiple file selection?

I'm using jquery file upload plugin per blueimp and IE9 is not allowing multiple file selection per the following code (below) or the demo:
http://blueimp.github.com/jQuery-File-Upload/
Can somebody provide a workaround or insight?
View:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="#Url.Content("~/Scripts/jquery.ui.widget.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.iframe-transport.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.fileupload.js")" type="text/javascript"></script>
<input id="fileupload" type="file" name="files" multiple="multiple"/>
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(IEnumerable<HttpPostedFileBase> files)
{
foreach (var file in files)
{
var filename = Path.Combine(Server.MapPath("~/App_Data"), file.FileName);
file.SaveAs(filename);
}
return View();
}
}
For Internet Explorer, you need a flash fallback, plupload does this.

"UpdatePanel" in Razor (mvc 3)

Is there something like UpdatePanel (in ASPX) for Razor?
I want to refresh data (e.g. table, chart, ...) automaticly every 30 seconds.
Similar to clicking the following link every 30 seconds:
#Ajax.ActionLink("Refresh", "RefreshItems", new AjaxOptions() {
UpdateTargetId = "ItemList",
HttpMethod = "Post"})
Edit:
I may should add that the action link renders a partial view.
Code in cshtml:
<div id="ItemList">
#Html.Partial("_ItemList", Model)
</div>
Code in Controller:
[HttpPost]
public ActionResult RefreshItems() {
try {
// Fill List/Model
...
// Return Partial
return PartialView("_ItemList", model);
}
catch (Exception ex) {
return RedirectToAction("Index");
}
}
It would be create if the PartielView could refresh itself.
You can try something similar to the following using Jquery (have not tested though)
<script type="text/javascript">
$(document).ready(function() {
setInterval(function()
{
// not sure what the controller name is
$.post('<%= Url.Action("Refresh", "RefreshItems") %>', function(data) {
// Update the ItemList html element
$('#ItemList').html(data);
});
}
, 30000);
});
</script>
The above code should be placed in the containing page i.e. not the partial view page. Bear in mind that the a partial view is not a complete html page.
My initial guess is that this script can be placed in the partial and modified as follows. Make sure that the ajax data type is set to html.
<script type="text/javascript">
setInterval(function()
{
// not sure what the controller name is
$.post('<%= Url.Action("Refresh", "RefreshItems") %>', function(data) {
// Update the ItemList html element
$('#ItemList').html(data);
});
}
, 30000);
</script>
Another alternative is to store the javascript in a separate js file and use the Jquery getScript function in ajax success callback.
Well, if you don't need the AJAX expierience than use the HTML tag:
<meta http-equiv=”refresh” content=”30; URL=http://www.programmingfacts.com”>
go here: http://www.programmingfacts.com/auto-refresh-page-after-few-seconds-using-javascript/
If someone wants the complete code for a selfupdating partial view have a look!
Code of the Controller:
[HttpPost]
public ActionResult RefreshSelfUpdatingPartial() {
// Setting the Models Content
// ...
return PartialView("_SelfUpdatingPartial", model);
}
Code of the Partial (_SelfUpdatingPartial.cshtml):
#model YourModelClass
<script type="text/javascript">
setInterval(function () {
$.post('#Url.Action("RefreshSelfUpdatingPartial")', function (data) {
$('#SelfUpdatingPartialDiv').html(data);
}
);
}, 20000);
</script>
// Div
<div id="SelfUpdatingPartialDiv">
// Link to Refresh per Click
<p>
#Ajax.ActionLink("Aktualisieren", "RefreshFlatschels", new AjaxOptions() {
UpdateTargetId = "FlatschelList",
HttpMethod = "Post", InsertionMode = InsertionMode.Replace
})
</p>
// Your Code
// ...
</div>
Code to integrate the Partial in the "Main"-View (ViewWithSelfupdatingPartial.cs):
#Html.Partial("_FlatschelOverview", Model)
The <meta refresh ..> tag in HTML will work for you. Its the best option
Traditional controls don't works in ASP MVC
You could do it using Jquery timers http://plugins.jquery.com/project/timers
Other option could be to use the Delay function
In your target is as simple as refresh the whole page, this SO link will be of your interest: Auto refresh in ASP.NET MVC
Hope It Helps.

Resources