call jquery script after file upload finished asp.net mvc 2 - c#

i am trying to display a jquery popup after a fileupload action? not sure how to code this?
<%= Html.BeginForm("Upload","Home",FormMethod.Post,new { enctype = "multipart/form-data" }) %>
<%{ %>
<input type="file" id="upload" name="upload" />
<button id="btnUpload">
upload</button>
<%} %>
<script type="text/javascript">
function SayFinished() {
alert('Finished');
}
</script>
[HttpPost]
public ActionResult Upload()
{
HttpPostedFileBase selectedFile = Request.Files["upload"];
if (selectedFile.ContentLength > 0 )
{
//do some processing call jquery script to open popup: SayFinished()
}
return View("Index");
}

The simplest way to do this is to return a view from your controller after the post that has an onload script.
On the new view, put the following javascript:
In the controller set the following after file uploaded
ViewData["FileUploaded"] = "true";
Then in the view set
<% if (!String.IsnullOrEmpty(ViewData["FileUploaded"]) && ViewData["FileUploaded"] == "true") { %>
<script type="text/javascript">
$(document).ready(function() {
SayFinished();
});
function SayFinished() {
alert('Finished');
}
</script>
<%} %>

You can use this plugins to upload file using jQuery, http://pixelcone.com/jquery/ajax-file-upload-script
Sorry for previous feedback with incorrect information.

Related

Mvc: show animated gif for progress while loading big excel file to database

I am loading a big excel file to the database. I want my users to see that there is an activity going on. I started but didn't know how to proceed.
My ActionResult Index method has two parameters. How do I define this in my javascript.
On the click of the submit button I want the animated image to show and then stop when processing is complete
I understand I have to hide the div somehow. Not sure how to do this.
Please assist. Here is my code below.
#model SampleTemplate.Models.ResultViewModel
#{
ViewBag.Title = "Index";
}
<h2>File upload section</h2>
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="uploadSection">
<div id="divloading">
<p style="position:absolute; top:30%; left:45%;color: Red;">
Excel file in process, please wait...<img src="../../Images/animated.gif" />
</p>
</div>
<div>
<p class="headerSection">Select script</p>
<p>
<select name = "genericId">
<option value="12.1">12_1_flat_goods</option>
<option value="12.2">12_2_mats_bm</option>
</select>
</p>
</div>
<div id="spacebetween">
<p class="headerSection">Path to source file: </p>
<p class="spacebelow"><input type="file" name="file" value="" /> </p>
<p><button id="submi" name="Submit" onclick="JavascriptFunction();">Submit</button></p>
</div>
</div>
}
<script type="text/javascript" language="javascript">
function JavascriptFunction() {
var url = '#Url.Action("","Home")';
$("#divLoading").show();
}
</script>
...Here is my method
[HttpPost]
public ActionResult Index(HttpPostedFileBase file, ResultViewModel resModel)
{
//code to upload excel file goes here. No need to show this.
}
I have used Knockout.js for this before, and found it to be really clean and simple.
Check it out here: http://knockoutjs.com/
Your page would look something like this:
Knockout ViewModel javascript file -
function TestViewModel() {
var self = this;
self.itemsToDisplay = ko.observableArray([]);
//this property can be used to hold the bool for when you first hit the upload button
self.uploadStarted = ko.observable(false); // when page is loaded, this is false
//this is a property that will hold the bool value to show/hide the gif after the upload has started
self.uploadCompleted = ko.observable(false); // when page is loaded this is false
ko.applyBindings(self);
};
Then back in your View -
(Note: You will need to reference the knockout.js script in your View)
<div data-bind="visible: !uploadCompleted() && uploadStarted()">
// your gif image reference will go here
// it will only be displayed when uploadCompleted is false and uploadStarted is true
</div>
<button type="button" id="uploadButton" name="Submit">Upload</button>
<script type="text/javascript">
var viewModel = new TestViewModel();
// make an ajax call to your controller method to upload your content
// on success set your loaded property to true to hide your gif
$('#uploadButton').click(function() {
viewModel.uploadStarted(true);
$j.ajax({
type: "POST",
url: "../home/Index",
data: ko.toJSON({ file: file, resModel: model}),
contentType: "application/json",
success: function (data) {
// your controller will return your values in data
// update your viewModel properties
viewModel.itemsToDisplay(data);
viewModel.uploadCompleted(true);
viewModel.uploadStarted(false);
}
});
});
</script>
Hope that helps.
Best of luck!

Request.Files[""] Keep returning null

Using uploadify to auto submit a users files, in my controller method Request.Files["Name"] keeps returning null but request.form isn't null, I can see the file in request.form when I set a breakpoint and debug it. Am I missing something? I'm testing this on mvc2 but i plan on using it on mvc4.
<link href="../../Content/uploadify.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="../../Scripts/jquery.uploadify.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$('#file_upload').uploadify({
'swf': '/Content/uploadify.swf',
'uploader': '/Home/UploadFile',
'auto': true
// Your options here
});
});
</script>
</head>
<body>
<%--<% using (Html.BeginForm("UploadFile", "Home", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{ %>--%>
<input type="file" name="file_upload" id="file_upload" style="margin-bottom: 0px" />
<%-- <% } %>--%>
Controller Method:
[HttpPost]
public ActionResult UploadFile(HttpPostedFileBase file)
{
var theFile = Request.Files["file_upload"];
return Json("Success", JsonRequestBehavior.AllowGet);
}
If I add a submit button and then submit it it will work though. I need to be auto though without a submit button.
IIRC Uploadify uses fileData as parameter. So:
var theFile = Request.Files["fileData"];
or even better:
[HttpPost]
public ActionResult UploadFile(HttpPostedFileBase fileData)
{
// The fileData parameter should normally contain the uploaded file
// so you don't need to be looking for it in Request.Files
return Json("Success", JsonRequestBehavior.AllowGet);
}
Of course if you are not happy with this name you could always customize it using the fileObjName setting.

upload file asp.net mvc 2

i am trying to execute a task after uploading a file. After the task is finished i would like to display some info. At the moment i have an Upload action that will fire after clicking the 'Do task' button which is not good. question :I would like to just trigger the 'Sometask' action and not the Uploadaction?
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<%= Html.BeginForm("Upload","Home",FormMethod.Post,new { enctype = "multipart/form-data" }) %>
<%{ %>
<%=Html.HiddenFor(model=>model.Filepath) %>
<input type="file" id="upload" name="upload" />
<button id="btnUpload">
upload</button>
<%} %>
<button id="btnTask">
Do Task</button>
<script type="text/javascript">
$(document).ready(function (event) {
$('#btnTask').click(function () {
$.post("/Home/Sometask",
{ filePath: $("#Filepath").val() },
function (data) {
alert(data);
});
event.preventDefault;
});
});
</script>
[HttpPost]
public ActionResult Upload()
{
HttpPostedFileBase selectedFile = Request.Files["upload"];
if (selectedFile.ContentLength > 0)
{
string filePath = Path.Combine(HttpContext.Server.MapPath("\\Uploads\\")
, Path.GetFileName(selectedFile.FileName));
selectedFile.SaveAs(filePath);
UploadModel model = new UploadModel();
model.Filepath = filePath;
return View("Index", model);
}
return View("Index");
}
public string Sometask(string Filepath)
{
Thread.Sleep(5000);
return "ready";
}
Is the Upload() method being called? Looking at the code, I would expect the Sometask() to be called but not the Upload() method. The jQuery code is calling .post when the button is clicked and that should eliminate the normal form posting. If Sometask() is not getting called, you many need to add [HttpPost] attribute to the Sometask() method.
Note that for security reasons files cannot be uploaded from Javascript.

Using Javascript inside a dynamically load UserControl in jQuery Ui Tabs

I need to insert some JavaScript code inside a UserControl that I load from an Ajax call via jQuery Ui Tabs. Let me explain...
This is my View (with jQuery loaded)
<script type="text/javascript">
$(document).ready(function () {
$("#tabs").tabs({
cache: false,
});
getContentTab (1);
});
function getContentTab(index) {
var url='<%= Url.Content("~/Home/getUserControl") %>/' + index;
var targetDiv = "#tabs-" + index;
$.get(url,null, function(result) {
$(targetDiv).html(result);
});
}
</script>
<div id="tabs">
<ul>
<li>Nunc tincidunt</li>
<li>Proin dolor</li>
<li>Aenean lacinia</li>
</ul>
<div id="tabs-1">
</div>
<div id="tabs-2">
</div>
<div id="tabs-3">
</div>
</div>
With these lines of code I call the Ajax function to load the content into a DIV.
This is the Action from the controller:
public ActionResult getUserControl(int num)
{
return PartialView("TestUC", num);
}
And this is the UserControl...
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
Number... <span id="testSpan"><%=Model.ToString() %></span>!!
<input type="button" value="Click me!!" onclick="message();" />
<script type="text/javascript">
function message(item) {
alert($("#testSpan").html());
}
</script>
The problem is that the message() function returns always 1 (instead of returning the correct number).
My question is... How should I add the script to my UserControl in order to have my code running correctly?
I'm just guessing here.
I guess your problem is that when a tab is loaded, it stays in the DOM even if you open another one (i.e. If the #1 is the default, it will remain loaded even if you click on the second one).
If this is happening, when you call the message function, there will be multiple elements with the id "testSpan", and the jQuery selector $("#testSpan") will return the first of them.
I suppose this is just some test code, but for this particular case I would go with adding the <%= Model.ToString() %> as an argument to the javascript function.
Again, I'm just guessing about the behavior of the jquery-ui tabs() function.
Regards
Try Adding script like this
<script type="text/javascript" defer="defer">
function message(item) {
alert($("#testSpan").html());
}
</script>

Whats the best way of using MVC + ajax (jquery) to load page content, aspx or ascx or both

I want to have a menu that when I click replaces the content of a "main" div with content from a mvc view. This works just fine if I use a .aspx page, but any master.page content is then doubled (like the and any css/js). If I do the same but uses a .ascx user control the content is loaded without the extras, but if any browser loads the menu item directly (ie search bot's or someone with JS disabled), the page is displayed without the master.page content.
The best solution I've found so far is to create the content as a .ascx page, then have a .aspx page load this if it's called directly from the menu link, while the ajax javascript would modify the link to use only the .ascx. This leads to a lot duplication though, as every user control needs it's own .aspx page.
I was wondering if there is any better way of doing this? Could for example the master.page hide everything that's not from the .aspx page if it was called with parameter ?ajax=true?
We've solved this by using a baseController class that all controllers inherit from, and using an override for OnActionExecuted:
/// <summary>
/// Changes the masterpage to a slim version in AjaxRequest
/// </summary>
/// <param name="filterContext"></param>
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
var action = filterContext.Result as ViewResult;
if (action != null && Request.IsAjaxRequest())
{
action.MasterName = "Ajax";
}
base.OnActionExecuted(filterContext);
}
The "Ajax" master page is a then a simple masterpage with only 1 contentPlaceHolder. This works fine as long as all aspx pages that can be called with ajax only uses this placeholder.
What about making an ActionMethod that changes what it renders depending on the type of http request it gets? So if it is an ajax request it would render the ascx but if it is not, then it can render the whole view (or redirect to another action that renders the whole view)?
something like
public ActionResult Section1()
{
if (Request.IsAjaxRequest())
{
return PartialView("section1.ascx");
}
return View("section.aspx");
}
and i guess section.aspx coud have inside a RenderPartial(section1.ascx) (so you dont do the page twice).
Here is an example of the method I use with great success:
In the View:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Namespace.Stuff>>" %>
<asp:Content ID="Content3" ContentPlaceHolderID="head" runat="server">
<script type="text/javascript">
$(document).ready(function(){
$("#optionsForm").submit(function() {
$("#loading").dialog('open');
$.ajax({
type: $("#optionsForm").attr("method"),
url: $("#optionsForm").attr("action"),
data: $("#optionsForm").serialize(),
success: function(data, textStatus, XMLHttpRequest) {
$("#reports").html(data); //replace the reports html.
$("#loading").dialog('close'); //hide loading dialog.
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
$("#loading").dialog('close'); //hide loading dialog.
alert("Yikers! The AJAX form post didn't quite go as planned...");
}
});
return false; //prevent default form action
});
});
</script>
</asp:Content>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<div id="someContent">
<% using (Html.BeginForm("Index", "Reports", FormMethod.Post, new{ id = "optionsForm" }))
{ %>
<fieldset class="fieldSet">
<legend>Date Range</legend>
From: <input type="text" id="startDate" name="startDate" value="<%=ViewData["StartDate"] %>" />
To: <input type="text" id="endDate" name="endDate" value="<%=ViewData["EndDate"] %>" />
<input type="submit" value="submit" />
</fieldset>
<%} %>
</div>
<div id="reports">
<%Html.RenderPartial("ajaxStuff", ViewData.Model); %>
</div>
<div id="loading" title="Loading..." ></div>
</asp:Content>
In the Controller:
public ActionResult Index(string startDate, string endDate)
{
var returnData = DoSomeStuff();
if (Request.IsAjaxRequest()) return View("ajaxStuff", returnData);
return View(returnData);
}

Categories

Resources