I have a weird situation. I am working on extending some 3rd party code and this is done by writing our own provider and then configuring the system to use ours instead of the base provider that came with the code. I have the provider(s) working just fine but when I call it from within a JS block, it is not passing the GUID in the JS call. Both the GUID and Response parameters are coming back WAY screwed up!
The main points to look at are:
function addImage(fileName, fileSize, fileType, guid, response) in the ASCX file
addImage('unk', 'unk', 'unk', '<%: myGuid %>', '<%: fullPath %>'); also in the ASCX file
I put in comments in the below code for where to look (// ************* HERE **** HERE **** HERE ************* //)
Our AJAXImageUploader.ascx code:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<List<RainWorx.FrameWorx.DTO.Media.Media>>" %>
<!--<form enctype="multipart/form-data" method="post">-->
<%:Html.GlobalResource("UploadImages")%> (<%:Html.GlobalResource("MaxImagesInformational", SiteClient.Settings["MaxImagesPerItem"]) %>) - <%:Html.GlobalResource("ImageFees",
Html.SiteCurrency(AccountingClient.GetAllFeeProperties().Where(fp => fp.Processor.Equals("RainWorx.FrameWorx.Providers.Fee.Standard.ImageCount") &&
fp.Event.Name.Equals((string)ViewData["Event"]) &&
fp.ListingType.Name.Equals((string)ViewData["ListingType"]) &&
fp.Name.Equals("FirstImage")).Single().Amount),
Html.SiteCurrency(AccountingClient.GetAllFeeProperties().Where(fp => fp.Processor.Equals("RainWorx.FrameWorx.Providers.Fee.Standard.ImageCount") &&
fp.Event.Name.Equals((string)ViewData["Event"]) &&
fp.ListingType.Name.Equals((string)ViewData["ListingType"]) &&
fp.Name.Equals("AdditionalImages")).Single().Amount)
)%>
<input type="file" id="photo" name="photo" />
<!--</form> -->
<script type="text/javascript">
// ************* HERE **** HERE **** HERE ************* //
// ************* HERE **** HERE **** HERE ************* //
function addImage(fileName, fileSize, fileType, guid, response) {
var thumbnails = $("div#sortablethumbnails");
var newSpan = $("<span class='imagecontainer'/>").appendTo(thumbnails);
var newImg = $("<img/>").appendTo(newSpan).attr("src", guid + response);
$("<input type='hidden' name='media_guid_" + guid + "'/>").appendTo(newSpan).attr("value", guid);
$("<input type='hidden' name='media_ordr_" + guid + "'/>").appendTo(newSpan).attr("class", "order");
$("<a href='#' class='deleteimage'><img src='Content/images/General/Delete.png' alt='<%:Html.GlobalResource("RemoveImage") %>' style='margin-left: -30px;' /></a>").appendTo(newSpan);
RefreshOrder();
}
$(document).ready(function() {
$("#photo").makeAsyncUploader({
upload_url: $.url('Listing/AsyncUpload'),
flash_url: 'Content/swf/swfupload.swf',
button_image_url: 'Content/images/blankButton.png',
disableDuringUpload: 'INPUT[type="submit"]',
button_text: '<%:Html.GlobalResource("ChooseImages") %>'
});
$("div#sortablethumbnails").html($("input#ThumbnailRendererState").val());
});
</script>
<script type="text/javascript">
$(document).ready(function() {
$("div#sortablethumbnails").sortable({
opacity: 0.7,
revert: false,
scroll: true,
tolerance: 'pointer',
update: function(event, ui) {
RefreshOrder();
}
});
$("div#sortablethumbnails").disableSelection();
$("a.deleteimage").live("click", function() {
$(this).parent().remove();
RefreshOrder();
return false;
});
<% if (Model != null)
{
//var imageList = Model.Where(a => a.Context == "UploadListingImage").ToList();
var imageList = Model.Where(m => m.Type.Equals("D4I.Providers.MediaLoader.DateHashedURI_AWS")).ToList();
if(imageList.Count > 0)
{
//Get Workflow
Dictionary<string, string> workflowParams = CommonClient.GetAttributeData("MediaAsset.Workflow", "UploadListingImage");
//Load Media
IMediaLoader mediaLoader = RainWorx.FrameWorx.Unity.UnityResolver.Get<IMediaLoader>(workflowParams["Loader"]);
Dictionary<string, string> loaderProviderSettings = CommonClient.GetAttributeData(mediaLoader.TypeName, "UploadListingImage");
foreach (Media media in imageList)
{
string fullPath = mediaLoader.Load(loaderProviderSettings, media, "ThumbCrop");
string myGuid = media.GUID.ToString();
%>
// ************* HERE **** HERE **** HERE ************* //
// ************* HERE **** HERE **** HERE ************* //
addImage('unk', 'unk', 'unk', '<%: myGuid %>', '<%: fullPath %>');
<%
}
}
} %>
});
// function AddImage(src) {
// $("div#sortablethumbnails").append("<span class='imagecontainer'><img src='" + src + "' /><span class='order'></span><a href='#' class='deleteimage'>Delete</a></span>");
// RefreshOrder();
// }
function RefreshOrder() {
var images = $(".imagecontainer");
for (var x = 0; x < images.length; x++) {
$(".imagecontainer .order:eq(" + x + ")").val(x);
}
}
</script>
<%-- <input type=button id=debuginfo value="Debug Info" />--%>
<div id=sortablethumbnails></div>
}
%>
The results:
<span class="imagecontainer">
<img src="http://s3.amazonaws.com/deal4it/dev/ListingImage/20120106/096b341f-2e7c-4ef1-b969-37a62a877e67_thumbcrop.jpg">
<input type="hidden" name="media_guid_http://s3.amazonaws.com/deal4it/dev/" value="http://s3.amazonaws.com/deal4it/dev/">
<input type="hidden" name="media_ordr_http://s3.amazonaws.com/deal4it/dev/" class="order" value="2">
<a href="#" class="deleteimage">
<img src="Content/images/General/Delete.png" alt="Remove Image" style="margin-left: -30px;">
</a>
</span>
Our Loader looks like:
namespace D4I.Providers.MediaLoader
{
public class DateHashedURI_AWS : RainWorx.FrameWorx.Providers.MediaLoader.IMediaLoader
{
public string Load(Dictionary<string, string> providerSettings, Media media, string variationName)
{
Variation variation = media.Variations[variationName];
string path = String.Format("{0:yyyy}{0:MM}{0:dd}", variation.Asset.DateStamp);
if (providerSettings.Count < 6)
providerSettings = DefaultProviderSettings;
return Amazon.GetMediaUrl(path: path
, fileName: variation.Asset.Reference
, providerSettings: providerSettings
, context: media.Context);
}
public Dictionary<string, string> DefaultProviderSettings
{
get
{
Dictionary<string, string> retVal = new Dictionary<string, string>();
// deleted values are our AWS login info //
return retVal;
}
}
public bool VerifyProviderSettings(Dictionary<string, string> providerSettings)
{
return (DefaultProviderSettings.Keys.Except(providerSettings.Keys).Count() <= 0);
}
public string TypeName
{
get { return "D4I.Providers.MediaLoader.DateHashedURI_AWS"; }
}
}
}
The call to make the return value looks like:
public static string GetMediaUrl(string path, string fileName, string context, Dictionary<string, string> providerSettings = null)
{
// Initialize the AWS API...
_providerSettings = providerSettings;
Initialize();
string absoluteURL = String.Format("{0}/{1}/{2}/{3}/{4}/{5}", BaseURL, BucketName, RootFolder.StripSlashes(), context.FixContext(), path, fileName);
Uri uri = new Uri(absoluteURL);
return uri.AbsoluteUri;
}
I can step through every bit of code and see it working just fine except the code in AJAXImageUploader.ascx. I even tried putting the C# code found inside the JS block in the ASCX where I could break on it and I still cannot get to it. In all other cases I can confirm that the media.GUID is in fact a valid GUID and that the Load() function returns a valid URI string for the image on AWS.
Any ideas how to track this down??
Found out that the SWF that the source company wrote contains a call to a JS file that does further changes to data pieces after a successful upload. I got the data I need from RainWorx and voila - it all started working correctly. I love the lack of viable documentation on these hidden gems! < grumble />
Related
I am about to integrate svg-edit to an ASP.NET MVC project.
Is there anyone who has a recommendation or tutorial on how to begin with?
Thank you.
I am answering my own question.
After a research, I recommend deploying the whole SVG-EDIT lib into mvc architecture, then modify the embed api as following:
This is my Partial View and JS file that call the embed api and put it into the iframe within the partial view:
document.write("<script type='text/javascript' src='~/Scripts/svg-edit/embedapi.js'></script>");
// Make sure to add the embedapi into the html file, becuase the intialization function runs actually in that file, all this call does is basically to take the iframe from html and inialize the api within that tag.
$(document).ready(function () {
// jquery selectro
$("#LoadSVG").click(function () {
$("#svg").append($('<iframe src="/Scripts/svg-edit/svg-editor.html" width="900px" height="600px" id="svgedit"></iframe>'));
});
});
#Scripts.Render("~/bundles/KSage")
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<header>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
</header>
<input id="LoadSVG" type="button" value="LoadSVG" />
<input id="CloseSVG" type="button" value="CloseSVG" />
<input id="save" type="button" value="save" onclick="save()">
<input id="Add" type="button" value="AddNewTag!" onclick="AddNewElemnt()" />
<input id="LoadExample" type="button" value ="LoadExample" onclick="LoadExample()"/>
<body id ="mainBody">
<p id="svg"></p>
<p id="DivData"></p>
<p id="TestId"></p>
<p id="SavedData"></p>
</body>
</html>
Here I have a save and load functions ready for the module: There is so much work to do in order to perfect the algorithm, but since this was just a test project to figure out the possibility of integrating the module into the environment I put enough effort to understand that share the knowledge with the community:
Here is my cshtml file:
#Scripts.Render("~/bundles/KSage")
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<header>
</header>
<input id="LoadSVG" type="button" value="LoadSVG" />
<input id="CloseSVG" type="button" value="CloseSVG" />
<input id="save" type="button" value="save" onclick="save()">
<input id="Add" type="button" value="AddNewTag!" onclick="AddNewElemnt()" />
<input id="LoadExample" type="button" value ="LoadExample" onclick="LoadExample()"/>
<body id ="mainBody">
<p id="svg"></p>
<p id="DivData"></p>
<p id="TestId"></p>
<p id="SavedData"></p>
</body>
</html>
Here is the js file:
document.write("<script type='text/javascript' src='~/Scripts/svg-edit/embedapi.js'></script>");
document.write("<script src='~/Scripts/jquery-1.10.2.js'></script>");
$(document).ready(function () {
// jquery selectro
$("#LoadSVG").click(function () {
$("#svg").append($('<iframe src="/Scripts/svg-edit/svg-editor.html" width="900px" height="600px" id="svgedit"></iframe>'));
});
});
$(document).ready(function () {
// jquery selectro
$("#save1").click(function () {
$("#DivData").append("<b>Appended text</b>");
});
});
$(document).ready(function(){
$("#CloseSVG").click(function () {
$("#svg").hide();
});
});
function HandleSvgData(data,error) {
if (error) {
alert('Error:' + error);
} else {
$('#DivData').append(data);
alert(data);
}
}
function handleSvgData(data, error) {
alert("handling Data");
if (error) {
alert('error ' + error);
} else {
alert('Congratulations. Your SVG string is back in the host page, do with it what you will\n\n' + data);
}
}
function save1() {
alert("saving");
// svgCanvas.getSvgString()(handleSvgData);
$("#svgedit").append($('This is the test classed appended after DivDat'));
}
function AddNewElemnt()
{
var newElement = document.createElement("Test");
var newNode = document.createTextNode("This is my new node!");
newElement.appendChild(newNode);
var referenceElement = document.getElementById("mainBody");
var tagInsert = document.getElementById("TestId");
referenceElement.insertBefore(newElement, tagInsert);
// alert("added");
}
function Postt(data) {
}
function Post(data) {
var mainBody = document.getElementById("mainBody");
var SvgDataId = prompt("give me primary id");
var SvgUser = prompt("give me UserName");
var form = document.createElement("form");
form.setAttribute("id", "PostData");
form.setAttribute("action", "/SvgDatas/Create");
form.setAttribute("method", "post");
mainBody.appendChild(form);
var PostData = document.getElementById("PostData");
var InputSvgDataId = document.createElement("input");
InputSvgDataId.setAttribute("name", "SvgDataId");
InputSvgDataId.setAttribute("value", SvgDataId);
PostData.appendChild(InputSvgDataId);
var InputSvgUser = document.createElement("input");
InputSvgUser.setAttribute("name", "SvgUser");
InputSvgUser.setAttribute("value", SvgUser);
PostData.appendChild(InputSvgUser);
var InputData = document.createElement("input");
InputData.setAttribute("name", "Data");
InputData.setAttribute("value", data);
PostData.appendChild(InputData);
form.submit();
}
function save() {
var doc, mainButton,
frame = document.getElementById('svgedit');
svgCanvas = new EmbeddedSVGEdit(frame);
// Hide main button, as we will be controlling new, load, save, etc. from the host document
doc = frame.contentDocument || frame.contentWindow.document;
mainButton = doc.getElementById('main_button');
mainButton.style.display = 'none';
// get data
svgCanvas.getSvgString()(function handleSvgData(data, error) {
if (error) {
alert('error ' + error);
} else {
alert('Congratulations. Your SVG string is back in the host page, do with it what you will\n\n' + data);
Post(data);
}
});
}
/*
function BuidUrl(SVGUser) {
var uri = prompt("Give me url where the serach function lives, if empty then I will use Razor syntax to call within MVC architescture");
if (uri)
return uri;
else {
var urlHelper = ('http://localhost:53546/SvgDatas/Search?id='+SVGUser);
return urlHelper;
}
}
*/
function returnedData_IntializeEditor(data, status) {
if ((data != null) && (status == "success")) {
var frame = document.getElementById('svgedit');
svgCanvas = new EmbeddedSVGEdit(frame);
doc = frame.contentDocument || frame.contentWindow.document;
mainButton = doc.getElementById('main_button');
tool_Bottum = doc.getElementById("#tool_button");
mainButton.style.display = 'none';
// Open Data into the frame
// var svgexample = '<svg width="640" height="480" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><g><title>Layer 1<\/title><rect stroke-width="5" stroke="#000000" fill="#FF0000" id="svg_1" height="35" width="51" y="35" x="32"/><ellipse ry="15" rx="24" stroke-width="5" stroke="#000000" fill="#0000ff" id="svg_2" cy="60" cx="66"/><\/g><\/svg>';
svgCanvas.setSvgString(data.Data);
} else {
$("#svg").append("<li>There is not such a data available in the database!</li>");
}
}
function LoadExample() {
var SVGUser = prompt("Enter the SVG ID");
$.getJSON("http://localhost:53546/SvgDatas/Search?id=" + SVGUser, returnedData_IntializeEditor );
}
This is the model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace IntegrationOfSVG.Models
{
public class SvgData
{
public string SvgDataId { get; set; }
public string SvgUser { get; set; }
public string Data { get; set; }
}
}
Thank you SVG-EDIT community for the great tool.
Next I am planning to add a view mode to this module that opens the data from a sequal server and if the mode is admin, lets the user to edit the existing data. I will keep this posted updated.
1- One way is to remove the tools from the client side, but it has a certain limitation that is the fact that css does not adjust a
function RemoveTools() {
var frame = document.getElementsByClassName("iFrameHtmlTag")[0];
doc = frame.contentWindow.document;
if (doc != null) {
var Tools = [
'tools_top', 'tools_left', 'tools_bottom', 'sidepanels', 'main_icon', 'rulers', 'sidepanels', 'canvashadow'];
for (i=0; i<Tools.length;i++)
{
doc.getElementById(Tools[i]).style.display = "none";
}
} else
alert("Doc was null");
};
$(document).ready(function () {
$("#hide").click(function () {
RemoveTools();
});
});
It is an effective way, but there should be a better method to view the object with few parameters also to readjust the size of the window. I will continue with that topic too.
I am facing problem here as in phonegap image is uploaded to the server once u select a picture.I don't want to upload image before submitting form. Image is uploaded automatically to server which is something i don't want.I want to upload image with the form, where form contains many more fields which is required to send along with image. What are the possible ways to submit with form?
<!DOCTYPE HTML >
<html>
<head>
<title>Registration Form</title>
<script type="text/javascript" charset="utf-8" src="phonegap-1.2.0.js"></script>
<script type="text/javascript" charset="utf-8">
// Wait for PhoneGap to load
document.addEventListener("deviceready", onDeviceReady, false);
// PhoneGap is ready
function onDeviceReady() {
// Do cool things here...
}
function getImage() {
// Retrieve image file location from specified source
navigator.camera.getPicture(uploadPhoto, function(message) {
alert('get picture failed');
},{
quality: 50,
destinationType: navigator.camera.DestinationType.FILE_URI,
sourceType: navigator.camera.PictureSourceType.PHOTOLIBRARY
});}
function uploadPhoto(imageURI) {
var options = new FileUploadOptions();
options.fileKey="file";
options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1);
options.mimeType="image/jpeg";
var params = new Object();
params.value1 = "test";
params.value2 = "param";
options.params = params;
options.chunkedMode = false;
var ft = new FileTransfer();
ft.upload(imageURI, "http://yourdomain.com/upload.php", win, fail, options);
}
function win(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
alert(r.response);
}
function fail(error) {
alert("An error has occurred: Code = " = error.code);
}
</script>
</head>
<body>
<form id="regform">
<button onclick="getImage();">select Avatar<button>
<input type="text" id="firstname" name="firstname" />
<input type="text" id="lastname" name="lastname" />
<input type="text" id="workPlace" name="workPlace" class="" />
<input type="submit" id="btnSubmit" value="Submit" />
</form>
</body>
</html>
Create two functions you can call separately. One function for just getting the image, and another function to upload the image.
You can do something like below.
<!DOCTYPE html>
<html>
<head>
<title>Submit form</title>
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<script type="text/javascript" charset="utf-8">
var pictureSource; // picture source
var destinationType; // sets the format of returned value
// Wait for device API libraries to load
//
document.addEventListener("deviceready",onDeviceReady,false);
// device APIs are available
//
function onDeviceReady() {
pictureSource = navigator.camera.PictureSourceType;
destinationType = navigator.camera.DestinationType;
}
// Called when a photo is successfully retrieved
//
function onPhotoURISuccess(imageURI) {
// Show the selected image
var smallImage = document.getElementById('smallImage');
smallImage.style.display = 'block';
smallImage.src = imageURI;
}
// A button will call this function
//
function getPhoto(source) {
// Retrieve image file location from specified source
navigator.camera.getPicture(onPhotoURISuccess, onFail, { quality: 50,
destinationType: destinationType.FILE_URI,
sourceType: source });
}
function uploadPhoto() {
//selected photo URI is in the src attribute (we set this on getPhoto)
var imageURI = document.getElementById('smallImage').getAttribute("src");
if (!imageURI) {
alert('Please select an image first.');
return;
}
//set upload options
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = imageURI.substr(imageURI.lastIndexOf('/')+1);
options.mimeType = "image/jpeg";
options.params = {
firstname: document.getElementById("firstname").value,
lastname: document.getElementById("lastname").value,
workplace: document.getElementById("workplace").value
}
var ft = new FileTransfer();
ft.upload(imageURI, encodeURI("http://some.server.com/upload.php"), win, fail, options);
}
// Called if something bad happens.
//
function onFail(message) {
console.log('Failed because: ' + message);
}
function win(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
//alert("Response =" + r.response);
console.log("Sent = " + r.bytesSent);
}
function fail(error) {
alert("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
</script>
</head>
<body>
<form id="regform">
<button onclick="getPhoto(pictureSource.PHOTOLIBRARY);">Select Photo:</button><br>
<img style="display:none;width:60px;height:60px;" id="smallImage" src="" />
First Name: <input type="text" id="firstname" name="firstname"><br>
Last Name: <input type="text" id="lastname" name="lastname"><br>
Work Place: <input type="text" id="workplace" name="workPlace"><br>
<input type="button" id="btnSubmit" value="Submit" onclick="uploadPhoto();">
</form>
</body>
</html>
You're already sending custom fields in your example.
var params = new Object();
params.value1 = "test";
params.value2 = "param";
options.params = params;
Just populate params with your form fields.
I also faced same problem, but I have done using two server side calls on one click. In this, in first call submit data and get its id in callback using JSON then upload image using this id. On server side updated data and image using this id.
$('#btn_Submit').on('click',function(event) {
event.preventDefault();
if(event.handled !== true)
{
var ajax_call = serviceURL;
var str = $('#frm_id').serialize();
$.ajax({
type: "POST",
url: ajax_call,
data: str,
dataType: "json",
success: function(response){
//console.log(JSON.stringify(response))
$.each(response, function(key, value) {
if(value.Id){
if($('#vImage').attr('src')){
var imagefile = imageURI;
$('#vImage').attr('src', imagefile);
/* Image Upload Start */
var ft = new FileTransfer();
var options = new FileUploadOptions();
options.fileKey="vImage";
options.fileName=imagefile.substr(imagefile.lastIndexOf('/')+1);
options.mimeType="image/jpeg";
var params = new Object();
params.value1 = "test";
params.value2 = "param";
options.params = params;
options.chunkedMode = false;
ft.upload(imagefile, your_service_url+'&Id='+Id+'&mode=upload', win, fail, options);
/* Image Upload End */
}
}
});
}
}).done(function() {
$.mobile.hidePageLoadingMsg();
})
event.handled = true;
}
return false;
});
On server side using PHP
if($_GET['type'] != "upload"){
// Add insert logic code
}else if($_GET['type'] == "upload"){
// Add logic for image
if(!empty($_FILES['vImage']) ){
// Copy image code and update data
}
}
I could not get these plugins to upload a file with the other answers.
The problem seemed to stem from the FileTransfer plugin, which states:
fileURL: Filesystem URL representing the file on the device or a data URI.
But that did not appear to work properly for me. Instead I needed to use the File plugin to create a temporary file using the data uri to get me a blob object: in their example, writeFile is a function which takes a fileEntry (returned by createFile) and dataObj (blob). Once the file is written, its path can be retrieved and passed to the FileTransfer instance. Seems like an awful lot of work, but at least it's now uploading.
I have an MVC2 application where I am trying to use the Fine-Uploader plugin. When I run through my code behind, it saves the file that I uploaded. However, what get's displayed back in the browser is Upload Failed. I'm not sure what I'm missing here. My code is below:
Code behind:
public void UploadFiles()
{
try
{
if (Request.Files.Count > 0)
{
foreach (string file in Request.Files)
{
HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase;
if (hpf.ContentLength == 0)
{
continue;
}
string filename = Path.GetFileName(hpf.FileName);
string path = Path.Combine(Server.MapPath(ConfigurationManager.AppSettings["AttachmentPath"]), filename);
hpf.SaveAs(path);
}
}
}
catch (Exception e)
{
//Do something
}
}
Master page:
<script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
<script src="<%=Url.Content("~/Scripts/jquery.fineuploader-3.5.0.js") %>" type="text/javascript"></script>
<script src="<%=Url.Content("~/Scripts/jquery.fineuploader-3.5.0.min.js") %>" type="text/javascript"></script>
Markup page:
<div id="manual-fine-uploader"></div>
<div id="triggerUpload" class="btn btn-primary" style="margin-top: 10px;">
<i class="icon-upload icon-white"></i> Upload now
</div>
<script type="text/javascript">
$(document).ready(function () {
var manualuploader = new qq.FineUploader({
element: $('#manual-fine-uploader')[0],
request: {
endpoint: 'Home/UploadFiles'
},
autoUpload: false,
text: {
uploadButton: '<i class="icon-plus icon-white"></i> Select Files'
}
});
$('#triggerUpload').click(function () {
manualuploader.uploadStoredFiles();
});enter code here
});
</script>
Fine Uploader expects a valid JSON response indicating whether the upload succeeded or not.
A successful upload response must have:
{ "success": true }
for Fine Uploader to know that it worked. You can add whatever else you want to your response, but without indicating 'success' Fine Uploader will think that the upload failed.
What I would do is add a return to your UploadFiles function. Somewhat like:
public UploadResult UploadFiles()
{
try
{
// ... save file and other things
}
catch (Exception ex)
{
// failsauce :(
return new UploadResult(false);
}
// success :)
return new UploadResult(true);
}
Where UploadResult is much like:
public class UploadResult
{
// This is important!
public const string ResponseContentType = "text/plain";
public FineUploaderResult(bool success)
{
_success = success;
}
public override void ExecuteResult(ControllerContext context)
{
// Here we create the JSON Response object,
// set the correct content-type, and finally
// it gets built with the correct success flag.
var response = context.HttpContext.Response;
response.ContentType = ResponseContentType;
response.Write(BuildResponse());
}
public string BuildResponse()
{
var response = new JObject();
response["success"] = _success;
// ... maybe set some other data in the response JSON
return response.ToString();
}
}
There is an example using ASP.NET MVC C# up on the server examples repository that may provide some assistance.
Also, on the development branch there is a server-side README which indicates exactly what constitutes a valid JSON response for Fine Uploader.
Does anyone has a clean suggestion of instantiate this jquery's useful library.
I need to submit files and manage the Json response from the server.
I always get none json response within the Js code. I have reviewed some articles mentioning it but the code doesn't fit to the purpose.
The situation is: I achieve the submition and saving in the database but the Json response never arrives.
Thanks in advance.
This is my view code:
<script type="text/javascript">
$("#formUplImg").fileupload({
dataType: "json",
url:'#Url.Action("CreateJson","ProductImage")',
done: function (e, data) {
alert(data.StatusMessage);
}
});
</script>
#using (Html.BeginForm("CreateJson", "ProductImage", FormMethod.Post, new { id = "formUplImg", enctype = "multipart/form-data", #class = "jqtransform" }))
{
#Html.ValidationSummary(true)
<div class="rowElem">
<input type="file" id="Content" name="Content" />
</div>
<div class="rowElem">
#Html.ValidationMessageFor(item => item.Content)
</div>
<div class="rowElem">#Html.JQueryUI().Button("Guardar imagen", ButtonElement.Button, ButtonType.Submit, new { id = "guardar_imagen" })</div>
}
This is my controller action code:
[HttpPost]
public ContentResult CreateJson(UploadedFileInfo fileInfo)
{
try
{
if (fileInfo.Content == null)
throw new Exception("Hubo problemas con el envĂo. Seleccione un archivo a subir");
var file = new TempDocument
{
CreatedBy = User.Identity.Name,
CreationTime = DateTime.Now,
FileName = fileInfo.Content.FileName,
MimeType = fileInfo.Content.ContentType,
Size = fileInfo.Content.ContentLength,
Content = new byte[fileInfo.Content.ContentLength]//Image content to save
};
fileInfo.Content.InputStream.Read(file.Content, 0, fileInfo.Content.ContentLength);//Reading image content into ProductImage object
DocumentsManager.StorePendingDocuments.Add(file);
DocumentsManager.SaveTempDocuments();//Store each document uploaded to: TempDocument Table
TempData["SuccessMsg"] = "The image was saved successfully";
var json = new JavaScriptSerializer().Serialize(new { Success = true, StatusMessage = "El objeto fue insertado correctamente" });
return Content(json, "application/json");
}
catch (Exception exception)
{
TempData["ErrorMsg"] = exception.Message;
var json = new JavaScriptSerializer().Serialize(new { Success = false, StatusMessage = exception.Message });
return Content(json, "application/json");
}
}
Use return type of Action as ActionResult and use:
`return Json(new { Result = "Success" });`
So that on success you will get Json object containing result value.
I am using Valums ajax file-upload plugins for multi file-upload using asp.net mvc 3.
Views
#using (Html.BeginForm("Upload", "AjaxUpload", FormMethod.Post, new { name = "form1", #id="form1" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Upload Wav File</legend>
<div class="editor-label">
#Html.Label("Select Active Date Time")
</div>
<div>
<input type="text" id="active" value="#DateTime.Now" />
</div>
<div class="editor-label">
#Html.Label("Select Language")
</div>
<div>
#Html.DropDownList("Language1", (SelectList)ViewBag.lang)
</div>
<div class="editor-label">
#Html.Label("Select Category")
</div>
<div>
#Html.DropDownList("ParentCategoryID", ViewBag.ParentCategoryID as SelectList)
</div>
<br />
<div id="file-uploader">
<noscript>
<p>Please enable JavaScript to use file uploader.</p>
</noscript>
</div>
</fieldset>
}
Scripts
<script type="text/javascript">
var uploader = new qq.FileUploader
({
element: document.getElementById('file-uploader'),
onSubmit: function () {
uploader.setParams({
param1: document.getElementById("Language1").value,
param2: document.getElementById("ParentCategoryID").value,
param3: document.getElementById("active").value
});
},
action: '#Url.Action("upload")', // put here a path to your page to handle uploading
allowedExtensions: ['jpg', 'jpeg', 'png', 'gif'], // user this if you want to upload only pictures
sizeLimit: 4000000, // max size, about 4MB
minSizeLimit: 0, // min size
debug: true
});
</script>
Controller Action
[HttpPost]
public ActionResult Upload(HttpPostedFileBase qqfile, string param1, string param2, string param3)
{
var filenam = DateTime.Now.ToString("yyyyMMddhhmmss") + param1 + param2 + Request["qqfile"];
var filename = filenam.Replace(" ", "_");
var filepath = Path.Combine(Server.MapPath("~/App_Data/Uploads"), Path.GetFileName(filename));
if (param2 != null || param2 != "")
{
var wav = new PlayWav
{
Name = filename,
CategoryID = int.Parse(param2),
UserID = repository.GetUserID(HttpContext.User.Identity.Name),
LanguageID = int.Parse(param1),
UploadDateTime = DateTime.Now,
ActiveDateTime = DateTime.Parse(param3),
FilePath = filepath
};
db.AddToPlayWavs(wav);
if (qqfile != null)
{
qqfile.SaveAs(filepath);
db.SaveChanges();
return Json(new { success = true }, "text/html");
}
else
{
if (!string.IsNullOrEmpty(filepath))
{
using (var output = System.IO.File.Create(filepath))
{
Request.InputStream.CopyTo(output);
}
db.SaveChanges();
return Json(new { success = true });
}
}
}
return Json(new { success = false });
}
Problems Explaination
I have Upload controller action where I have rename the filename for uploaded file and it is working fine. The problem here is that after file is uploaded, file name displayed the name of original file name and also show the file size. But I want to display the file name which is re-named and the value which is selected in dropdown box list and datetime value submitted from form fields and it's file size is ok. I have no idea how could I modify those content which is displayed after file-upload is completed.
First the new file name is to be returned to clienside as,
assuming filename to be shown is already yielded in the following line,
var filenam = DateTime.Now.ToString("yyyyMMddhhmmss")
+ param1 + param2 + Request["qqfile"];
this needs to be sent to client side,
return Json(new { success = true, filename });
client side code changes, notice the onCompleted event handler, its job is to replace the original filename with the new one received from server.
<script type="text/javascript">
var uploader = new qq.FileUploader
({
element: document.getElementById('file-uploader'),
onSubmit: function () {
uploader.setParams({
param1: document.getElementById("Language1").value,
param2: document.getElementById("ParentCategoryID").value,
param3: document.getElementById("active").value
});
},
onComplete: function (id, fileName, responseJson) {
$(this.element).find('.qq-upload-list li[qqFileId=' + id + ']').find('.qq-upload-file').html(responseJson.filename);
},
action: '#Url.Action("upload")', // put here a path to your page to handle uploading
allowedExtensions: ['jpg', 'jpeg', 'png', 'gif'], // user this if you want to upload only pictures
sizeLimit: 4000000, // max size, about 4MB
minSizeLimit: 0, // min size
debug: true
});
</script>
hope this helps.
EDIT:
qqFileId attribute in the li element is the only associating link bitween the informative li item and uploaded files.
Though the qqFileId is not visible in firebug dom structure, in the console executing the following command shows the id,
$('.qq-upload-list li:last').attr('qqFileId')
if ie browser is causing you the problem it might be because of,
find('.qq-upload-list li[qqFileId=' + id + ']')
and can be changed as
onComplete: function (id, fileName, responseJson) {
$(this.element).find('.qq-upload-list li').each(function () {
if($(this).attr('qqFileId')==id)
$(this).find('.qq-upload-file').html(responseJson.filename);
});
}