My application has been implemeted using MVC 3, .net.
I am trying to generate an excel file at the click of a button.
The call to the controller action is made using Ajax.
My main problem is: During the file generation i am trying to display an image on the screen to let the user know of the ingoing operation. I can very well display the image but i cannot hide it after the operation is completed. The codei am using is :
Javascript code:
$("input.DownloadExcelReport").click(function (e) {
e.preventDefault();
var parameter = -- code to fetch parameter value;
var outputViewUrl = (the url is created here);
showLoading(); -- This function displays the image
window.location.href = outputViewUrl;
});
Controller Action code:
public ActionResult DownExcelReportForAssortment(Guid parameter)
{
try
{
//the contents for the file generation are fetched here..
// Write contents to excel file
if (memoryStream != null)
{
var documentName = "Report.xls";
byte[] byteArrary = memoryStream.ToArray();
return File(byteArrary, "application/vnd.ms-excel", documentName);
}
}
catch (Exception ex)
{
LogManager.LogException(ex);
}
}
I do not return a Json result to the calling javascript method where i can write the code to hide the image.
I am returning a file which can be saved by the user and the action is completed.
Can somone please suggect/help me of how can i hide the image once the file generation operation is complete?
Appreciate the help...
You may checkout the following article and put this into action. So we start by defining a controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult DownExcelReportForAssortment(Guid parameter, string tokenId)
{
// Simulate some heavy work to fetch the report
Thread.Sleep(5000);
// we fake it
byte[] byteArray = System.IO.File.ReadAllBytes(#"c:\test.xls");
var cookie = new HttpCookie("fileDownloadToken", tokenId);
Response.AppendCookie(cookie);
return File(byteArray, "application/vnd.ms-excel", "report.xls");
}
}
and in the view:
#Html.ActionLink(
"download report",
"DownExcelReportForAssortment",
"Home",
new { parameter = Guid.NewGuid(), tokenId = "__token__" },
new { #class = "download" }
)
Now the last step is to include the jquery.cookie plugin:
<script type="text/javascript" src="#Url.Content("~/scripts/jquery.cookie.js")"></script>
and write a script to subscribe to the click event of the anchor and track the download progress:
$(function () {
var fileDownloadCheckTimer;
$('.download').click(function () {
var token = new Date().getTime();
$(this).attr('href', function () {
return this.href.replace('__token__', token);
});
// Show the download spinner
$('body').append('<span id="progress">Downloading ...</span>');
// Start polling for the cookie
fileDownloadCheckTimer = window.setInterval(function () {
var cookieValue = $.cookie('fileDownloadToken');
if (cookieValue == token) {
window.clearInterval(fileDownloadCheckTimer);
$.cookie('fileDownloadToken', null);
// Hide the download spinner
$('#progress').remove();
}
}, 1000);
});
});
Related
I have a layout page inside which i have a table with delete button
when i press a delete button it is showing some thing like .
my ajex option is like.
#{
AjaxOptions xPost = new AjaxOptions();
xPost.HttpMethod = "POST";
xPost.Confirm = "Do you wish to submit this form ?";
xPost.OnBegin = "OnBegin";
xPost.OnComplete = "OnComplete";
xPost.OnFailure = "OnFailure";
xPost.OnSuccess = "OnSuccess";
xPost.LoadingElementDuration = 1000;
xPost.LoadingElementId = "divProgress";
xPost.UpdateTargetId = "divResponse";
xPost.InsertionMode = InsertionMode.Replace;
}
and on delete i am subbmiting the form to a controll like
public ActionResult Delete(int id)
{
ContactPersonManager.Delete(id);
return RedirectToAction("List");
}
As you are using ajax, you could return the URL from your action and have it redirected in javascript:
Controller
public ActionResult Delete(int id)
{
ContactPersonManager.Delete(id);
return Json(new { success = true, redirecturl = Url.Action("List") });
}
Then add something like this to your OnSuccess handler in javascript:
Javascript
function anOnSuccessFunction (data)
{
if (data.success == true)
{
window.location = data.redirecturl;
}
}
Markup
Make sure you point your Ajax options to the javascript function.
xPost.OnSuccess = "anOnSuccessFunction";
How to upload the image in asp.net mvc4.images save in local folder,images path name save to database.
I would say use Valum's AJAX File Uploader
here is how I'd done that
[HttpGet]
public ActionResult PictureUpload()
{
return View();
}
[HttpPost]
public ActionResult PictureUpload( string qqfile)
{
var path = Server.MapPath("~/App_data/Files/");
var file = string.Empty;
try
{
var stream = Request.InputStream;
if (String.IsNullOrEmpty(Request["qqfile"]))
{
// IE
HttpPostedFileBase postedFile = Request.Files[0];
if (postedFile != null) stream = postedFile.InputStream;
file = Path.Combine(path, qqfile);
}
else
{
//Webkit, Mozilla
file = Path.Combine(path, qqfile);
}
var buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
System.IO.File.WriteAllBytes(file, buffer);
}
catch (Exception ex)
{
return Json(new { success = false, message = ex.Message }, "application/json");
}
return Json(new { success = true }, "text/html");
}
**THIS GIVEN HTML and Javascript need uploaderjs file and css file from Valums website **
Index
<div id="file-uploader">
<noscript>
<p>Please enable JavaScript to use file uploader.</p>
<!-- or put a simple form for upload here -->
</noscript>
</div>
<script src="~/Scripts/fileuploader.js"></script>
<script type="text/javascript">
var uploader = new qq.FileUploader({
// pass the dom node (ex. $(selector)[0] for jQuery users)
element: document.getElementById('file-uploader'),
// path to server-side upload script
action: '/FileUpload/File',
onComplete: function(data) {
alert(data);
},
});
</script>
Hope this will help
I am using MVC3 and evopdf (http://www.evopdf.com/) to create a pdf when user clicks on a print button.
I have the initial view that contains a form and print button and a 2nd view specifically designed for printing.
Clicking on the print button calls javascript to submit the form, which calls the print action.
What I would like to happen is that once the print button has been clicked, a "processing" message is displayed.
Once the pdf has been generated I would like the message to be removed.
This is the javascript (I have not included all of my javascript as there are parts that are not relevant)
$(document).ready(function () {
$(".btn").click(function () {
var delay = 10;
$("#AjaxDelay").val(delay);
$.blockUI();
$('#printForm').submit();
});
$('#printForm').submit(function () {
$.blockUI();
$.ajax({
url: this.action,
type: this.method,
success: function (data) {
$.unblockUI();
//I need to open the pdf in appropriate app, adobe pdf viewer or similar
},
failure:function(data) {
alert("error");
$.unblockUI();
}
});
return false;
});
});
The form
#using (Html.BeginForm("PrintView", "Index", new { format = "pdf/", id = Model.ID, AjaxDelay = Model.AjaxDelay }, FormMethod.Get, new { id="printForm" }))
{
#Html.HiddenFor(m=>m.AjaxDelay)
<button type="button" class="btn print" >Print</button>
}
IndexController
public ActionResult PrintView(int id)
{
var model = GetData(id);
return View(model);
}
This is my HttpHandler
public void ProcessRequest(HttpContext context)
{
if (!context.Request.IsAuthenticated) return;
ProducePDF(context, "pdf title", 20);
}
private void ProducePDF(HttpContext context, string title,int delay)
{
var pdfConverter = GetPdfConverter();
// set the license key
pdfConverter.LicenseKey = "licence key here";
pdfConverter.JavaScriptEnabled = true;
var pdfBytes = pdfConverter.GetPdfBytesFromUrl(context.Request.Url.ToString().Replace(".pdf/", ""));
// send the PDF document as a response to the browser for download
var response = HttpContext.Current.Response;
response.Clear();
response.AddHeader("Content-Type", "application/pdf");
response.AddHeader("Content-Disposition", String.Format("attachment; filename=" + title + ".pdf; size={0}", pdfBytes.Length));
response.BinaryWrite(pdfBytes);
response.End();
}
Thanks.
I found a solution that uses the jquery cookie plugin and appending a cookie to the response as described in this stackoverflow article.
Hide image using Javascript after controller action is complete MVC3
I did have to make a small change in that I had to specify the path when removing the cookie.
I've just introduced SSL to my MVC website. I made the whole default AccountContorller use it. It works fine unless I'm currently on http page and try to log on with ajax (the logon action is vredirected to httpS). This popup logon window doesn't even show up.
For the controller a used a custom attribute:
public class RequireSSL : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.ActionDescriptor.IsDefined(typeof(NoSSL), true) ||
filterContext.ActionDescriptor.IsDefined(typeof(OptionalSSL), true))
{
base.OnActionExecuting(filterContext);
return;
}
HttpRequestBase req = filterContext.HttpContext.Request;
HttpResponseBase res = filterContext.HttpContext.Response;
//Check if we're secure or not and if we're on the local box
if (!req.IsSecureConnection && (!req.IsLocal || Properties.Settings.Default.UseSSLForLocalRequests))
{
var builder = new UriBuilder(req.Url)
{
Scheme = Uri.UriSchemeHttps,
Port = Properties.Settings.Default.HttpsPort,
};
res.Redirect(builder.Uri.ToString());
}
base.OnActionExecuting(filterContext);
}
}
How can I make it work?
EDIT
The whole rest was generated by MVC. (Project with built in authentications)
That's the link.
#Html.ActionLink(#Labels.LogOn, "LogOn", "Account", routeValues: null, htmlAttributes: new { id = "logonLink", data_dialog_title = "Identification" })
JS somehow hooks into that link and performs ajax logon . Probably with this code: (JajaxLogin.js - also out of the box)
/// <reference path="jquery-1.6.2.js" />
/// <reference path="jquery.validate.js" />
$(function () {
// Cache for dialogs
var dialogs = {};
var getValidationSummaryErrors = function ($form) {
// We verify if we created it beforehand
var errorSummary = $form.data('validation-summary-errors');
if (!errorSummary) {
errorSummary = $('<div class="validation-summary-errors"><span>Please correct the errors and try again.</span><ul></ul></div>')
.insertBefore($form);
// Remember that we created it
$form.data('validation-summary-errors', errorSummary);
}
return errorSummary;
};
var formSubmitHandler = function (e) {
var $form = $(this);
// We check if jQuery.validator exists on the form
if (!$form.valid || $form.valid()) {
$.post($form.attr('action'), $form.serializeArray())
.done(function (json) {
json = json || {};
// In case of success, we redirect to the provided URL or the same page.
if (json.success) {
location = json.redirect || location.href;
} else if (json.errors) {
var errorSummary = getValidationSummaryErrors($form);
var items = $.map(json.errors, function (error) {
return '<li>' + error + '</li>';
}).join('');
var ul = errorSummary
.find('ul')
.empty()
.append(items);
}
});
}
// Prevent the normal behavior since we opened the dialog
e.preventDefault();
};
var loadAndShowDialog = function (id, link, url) {
var separator = url.indexOf('?') >= 0 ? '&' : '?';
// Save an empty jQuery in our cache for now.
dialogs[id] = $();
// Load the dialog with the content=1 QueryString in order to get a PartialView
$.get(url + separator + 'content=1')
.done(function (content) {
dialogs[id] = $('<div class="modal-popup">' + content + '</div>')
.hide() // Hide the dialog for now so we prevent flicker
.appendTo(document.body)
.filter('div') // Filter for the div tag only, script tags could surface
.dialog({ // Create the jQuery UI dialog
title: link.data('dialog-title'),
modal: true,
resizable: true,
draggable: true,
width: link.data('dialog-width') || 300
})
.find('form') // Attach logic on forms
.submit(formSubmitHandler)
.end();
});
};
// List of link ids to have an ajax dialog
var links = ['logonLink', 'registerLink'];
$.each(links, function (i, id) {
$('#' + id).click(function (e) {
var link = $(this),
url = link.attr('href');
if (!dialogs[id]) {
loadAndShowDialog(id, link, url);
} else {
dialogs[id].dialog('open');
}
// Prevent the normal behavior since we use a dialog
e.preventDefault();
});
});
});
I can't work out what I'm doing wrong - I'm sure this used to work...:
<script type="text/javascript">
$("##containerId form").submit(function (event) {
event.preventDefault();
var form = $(this);
if (form.valid()) {
$.post(form.attr('action'), form.serialize(), function(data) {
$("##containerId").replaceWith(data.result);
}, "json");
}
});
</script>
I have a function that returns a view result as a string so I can return it as an object within the JSON response:
protected string RenderViewResultToString(ViewResultBase viewResult) {
using (var sw = new StringWriter()) {
if (string.IsNullOrEmpty(viewResult.ViewName))
viewResult.ViewName = ControllerContext.RouteData.GetRequiredString("action");
ViewEngineResult result = null;
if (viewResult.View == null) {
result = viewResult.ViewEngineCollection.FindPartialView(ControllerContext, viewResult.ViewName);
if (result.View == null)
throw new InvalidOperationException("Unable to find view. Searched in: " + string.Join(",", result.SearchedLocations));
viewResult.View = result.View;
}
var view = viewResult.View;
var viewContext = new ViewContext(ControllerContext, view, viewResult.ViewData, viewResult.TempData, sw);
view.Render(viewContext, sw);
if (result != null)
result.ViewEngine.ReleaseView(ControllerContext, view);
return sw.ToString();
}
}
So, in my controller I have:
[HttpPost, ValidateInput(false)]
public JsonResult Edit(/* stuff */) {
bool success = true;
try {
/* stuff */
} catch {
/* stuff */
success = false;
}
return Json(new { success, result = RenderViewResultToString(/* stuff - call to something that gives a ViewResult */) });
}
In Chrome, I get: "Resource interpreted as Document but transferred with MIME type application/json." and it renders the JSON in the browser as text.
In Firefox/IE, it prompts me to download a file.
What gives?
The form submission isn't getting suppressed. The messages you are getting are from an actual form submission to a page that returns JSON. If you check the browser address bar, you should see the URL is different.
If you run $("##containerId form") in the console, you should see that you're getting no results. "#" is an invalid character in a selector and needs to be escaped. $("#\\#containerId form") should work.