I have a site, where I load a list of images (thumbnails) from the database. The problem is that the images are displayed rather slowly, as fetching each thumbnail with Url.Action is rather time-consuming (when going through the whole MVC pipeline).
Therefore, I would like to load the images asynchronously with Ajax & JQUERY, while displaying the standard loading image (ajaxloag.info) for each image, until the image is loaded. A similar question has been raised here, but I need a more complete example, as I am very new to MVC and JQUERY.
Thanks in advance,
View (partialView)
// Foreach product, display the corresponding thumbnail
<% foreach (var p in Model)
{ %>
.
.
<img width="100" src="<%= Url.Action( "Thumbnail", "Products", new { productId = p.ID } ) %>" alt="" />
Controller
public ActionResult Thumbnail(string productId)
{
try
{
Guid pid = new Guid(productId);
byte[] thumbnailData = _productsRepository.GetProductThumbnail(pid);
if (thumbnailData != null)
{
return File(thumbnailData, "image/jpg");
}
else
{
return File(@"../Content/missingproduct.png", "image/jpg");
}
}
catch (Exception e)
{
throw e;
}
}
UPDATE - The parent view containing the Javascript
<script type="text/javascript">
$(document).ready(function()
{
getContentTab (1);
});
function getContentTab(index)
{
var criteria = {
categoryId : "<%: ViewBag.Header %>",
tabIndex: index,
searchString : "<%: ViewBag.SearchString %>"
};
var url='<%= Url.Content("~/Products/GetAjaxTab") %>'
var targetDiv = "#listContent";
var ajaxLoadUrl = '<%: Url.Content("/Content") %>/ajax-loader.gif';
var ajaxLoading = "<img id='ajax-loader' src='" + ajaxLoadUrl + "' align='left' height='28' width='28' />";
$(targetDiv).html("<div>" + ajaxLoading + " Loading...</div>");
tag in respect to the callback.
$.get(url, criteria, function(result)
{
$(targetDiv).html(result);
});
}
function AjaxStart()
{
$('#listContent').mask('Opdaterer');
}
function AjaxEnd()
{
$('#listContent').unmask();
}
$(function () {
$('.async').load(function () {
$(this).unbind('load');
this.src = $(this).attr('data-img-url');
alert('2');
});
});
//]]>
</script>
You could use HTML5 data-*
attributes:
<img width="100"
src="ajax-loader.gif"
class="async"
data-img-url="<%= Url.Action("Thumbnail", "Products", new { productId = p.ID }) %>"
/>
and then in a separate js file:
$(function() {
$('.async').load(function() {
$(this).unbind('load');
this.src = $(this).attr('data-img-url');
});
});
Also I would use editor/display templates instead of writing foreach
loops in the views:
<%= Html.DisplayForModel() %>
and in the corresponding display template you would put the image:
<%@ Control
Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<AppName.Models.Product>"
%>
<img width="100"
src="ajax-loader.gif"
class="async"
data-img-url="<%= Url.Action("Thumbnail", "Products", new { productId = Model.ID }) %>"
/>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With