https://github.com/TheKalin/jQuery-File-Upload.MVC5
Helper Class / Models
public class FilesHelperDB
{dbImageGalleryEntities1 _dbContext = new dbImageGalleryEntities1();
String DeleteURL = null;
String DeleteType = null;
String StorageRoot = null;
String UrlBase = null;
String tempPath = null;
//ex:"~/Files/something/";
String serverMapPath = null;
public FilesHelperDB(String DeleteURL, String DeleteType, String StorageRoot, String UrlBase, String tempPath, String serverMapPath)
{
this.DeleteURL = DeleteURL;
this.DeleteType = DeleteType;
this.StorageRoot = StorageRoot;
this.UrlBase = UrlBase;
this.tempPath = tempPath;
this.serverMapPath = serverMapPath;
}
public void DeleteFiles(String pathToDelete)
{
string path = HostingEnvironment.MapPath(pathToDelete);
System.Diagnostics.Debug.WriteLine(path);
if (Directory.Exists(path))
{
DirectoryInfo di = new DirectoryInfo(path);
foreach (FileInfo fi in di.GetFiles())
{
System.IO.File.Delete(fi.FullName);
System.Diagnostics.Debug.WriteLine(fi.Name);
}
di.Delete(true);
}
}
public String DeleteFile(String file)
{
System.Diagnostics.Debug.WriteLine("DeleteFile");
// var req = HttpContext.Current;
System.Diagnostics.Debug.WriteLine(file);
String fullPath = Path.Combine(StorageRoot, file);
System.Diagnostics.Debug.WriteLine(fullPath);
System.Diagnostics.Debug.WriteLine(System.IO.File.Exists(fullPath));
String thumbPath = "/" + file + "80x80.jpg";
String partThumb1 = Path.Combine(StorageRoot, "thumbs");
String partThumb2 = Path.Combine(partThumb1, file + "80x80.jpg");
System.Diagnostics.Debug.WriteLine(partThumb2);
System.Diagnostics.Debug.WriteLine(System.IO.File.Exists(partThumb2));
if (System.IO.File.Exists(fullPath))
{
//delete thumb
if (System.IO.File.Exists(partThumb2))
{
System.IO.File.Delete(partThumb2);
}
System.IO.File.Delete(fullPath);
String succesMessage = "Ok";
return succesMessage;
}
String failMessage = "Error Delete";
return failMessage;
}
public JsonFiles GetFileList()
{
var r = new List<ViewDataUploadFilesResult>();
String fullPath = Path.Combine(StorageRoot);
List<string> imgNameDB =(from a in _dbContext.tblImages where (a.isDelete == 1) select a.ImageName).ToList();
if (Directory.Exists(fullPath))
{
DirectoryInfo dir = new DirectoryInfo(fullPath);
foreach (FileInfo file in dir.GetFiles())
{
if(imgNameDB.Contains(file.Name))
{
string imgId = file.Name.Substring(3);
int indexOfDot = imgId.LastIndexOf('.');
imgId = imgId.Substring(0, indexOfDot);
int SizeInt = unchecked((int)file.Length);
r.Add(UploadResult(imgId,file.Name, SizeInt, file.FullName));
}
}
}
JsonFiles files = new JsonFiles(r);
return files;
}
public void UploadAndShowResults(HttpContextBase ContentBase, List<ViewDataUploadFilesResult> resultList)
{
var httpRequest = ContentBase.Request;
System.Diagnostics.Debug.WriteLine(Directory.Exists(tempPath));
String fullPath = Path.Combine(StorageRoot);
Directory.CreateDirectory(fullPath);
// Create new folder for thumbs
Directory.CreateDirectory(fullPath + "/thumbs/");
foreach (String inputTagName in httpRequest.Files)
{
var headers = httpRequest.Headers;
var file = httpRequest.Files[inputTagName];
System.Diagnostics.Debug.WriteLine(file.FileName);
if (string.IsNullOrEmpty(headers["X-File-Name"]))
{
UploadWholeFile(ContentBase, resultList);
}
else
{
UploadPartialFile(headers["X-File-Name"], ContentBase, resultList);
}
}
}
public int fetchID()
{
int n=0;
try
{
n = _dbContext.tblImages.Max(p => p.ImageId);
}
catch(Exception ex) { }
return n;
}
private void UploadWholeFile(HttpContextBase requestContext, List<ViewDataUploadFilesResult> statuses)
{
int n = fetchID() + 1;
var request = requestContext.Request;
for (int i = 0; i < request.Files.Count; i++)
{
var file = request.Files[i];
//Change filename as per sequence
string extension1 = Path.GetExtension(file.FileName);
var filename1 = "img"+ n.ToString() + extension1;
//Save image to DB
tblImage img1 = new tblImage()
{
ImageName = filename1,
isDelete = 1,
AdddDate = DateTime.UtcNow
};
_dbContext.tblImages.Add(img1);
int imgID = _dbContext.SaveChanges();
String pathOnServer = Path.Combine(StorageRoot);
var fullPath = Path.Combine(pathOnServer, filename1);
file.SaveAs(fullPath);
//Create thumb
string[] imageArray = file.FileName.Split('.');
if (imageArray.Length != 0)
{
String extansion = imageArray[imageArray.Length - 1].ToLower();
if (extansion != "jpg" && extansion != "png" && extansion != "jpeg") //Do not create thumb if file is not an image
{
}
else
{
var ThumbfullPath = Path.Combine(pathOnServer, "thumbs");
//String fileThumb = file.FileName + ".80x80.jpg";
String fileThumb = "img" + n.ToString() + "80x80.jpg";
var ThumbfullPath2 = Path.Combine(ThumbfullPath, fileThumb);
using (MemoryStream stream = new MemoryStream(System.IO.File.ReadAllBytes(fullPath)))
{
var thumbnail = new WebImage(stream).Resize(80, 80);
thumbnail.Save(ThumbfullPath2, "jpg");
}
}
}
statuses.Add(UploadResult(img1.ImageId.ToString(),filename1, file.ContentLength, filename1));
}
}
private void UploadPartialFile(string fileName, HttpContextBase requestContext, List<ViewDataUploadFilesResult> statuses)
{
var request = requestContext.Request;
if (request.Files.Count != 1) throw new HttpRequestValidationException("Attempt to upload chunked file containing more than one fragment per request");
var file = request.Files[0];
var inputStream = file.InputStream;
String patchOnServer = Path.Combine(StorageRoot);
var fullName = Path.Combine(patchOnServer, Path.GetFileName(file.FileName));
var ThumbfullPath = Path.Combine(fullName, Path.GetFileName(file.FileName + "80x80.jpg"));
ImageHandler handler = new ImageHandler();
var ImageBit = ImageHandler.LoadImage(fullName);
handler.Save(ImageBit, 80, 80, 10, ThumbfullPath);
using (var fs = new FileStream(fullName, FileMode.Append, FileAccess.Write))
{
var buffer = new byte[1024];
var l = inputStream.Read(buffer, 0, 1024);
while (l > 0)
{
fs.Write(buffer, 0, l);
l = inputStream.Read(buffer, 0, 1024);
}
fs.Flush();
fs.Close();
}
statuses.Add(UploadResult("",file.FileName, file.ContentLength, file.FileName));
}
public ViewDataUploadFilesResult UploadResult(string imgId1,String FileName, int fileSize, String FileFullPath)
{
String getType = System.Web.MimeMapping.GetMimeMapping(FileFullPath);
var result = new ViewDataUploadFilesResult()
{
imgId = imgId1,
name = FileName,
size = fileSize,
type = getType,
url = UrlBase + FileName,
deleteUrl = DeleteURL + imgId1,
thumbnailUrl = CheckThumb(getType, FileName),
deleteType = DeleteType,
};
return result;
}
public String CheckThumb(String type, String FileName)
{
var splited = type.Split('/');
if (splited.Length == 2)
{
string extansion = splited[1].ToLower();
if (extansion.Equals("jpeg") || extansion.Equals("jpg") || extansion.Equals("png") || extansion.Equals("gif"))
{
String thumbnailUrl = UrlBase + "thumbs/" + Path.GetFileNameWithoutExtension(FileName) + "80x80.jpg";
return thumbnailUrl;
}
else
{
if (extansion.Equals("octet-stream")) //Fix for exe files
{
return "/Content/Free-file-icons/48px/exe.png";
}
if (extansion.Contains("zip")) //Fix for exe files
{
return "/Content/Free-file-icons/48px/zip.png";
}
String thumbnailUrl = "/Content/Free-file-icons/48px/" + extansion + ".png";
return thumbnailUrl;
}
}
else
{
return UrlBase + "/thumbs/" + Path.GetFileNameWithoutExtension(FileName) + "80x80.jpg";
}
}
public List<String> FilesList()
{
List<String> Filess = new List<String>();
string path = HostingEnvironment.MapPath(serverMapPath);
System.Diagnostics.Debug.WriteLine(path);
if (Directory.Exists(path))
{
DirectoryInfo di = new DirectoryInfo(path);
foreach (FileInfo fi in di.GetFiles())
{
Filess.Add(fi.Name);
System.Diagnostics.Debug.WriteLine(fi.Name);
}
}
return Filess;
}
}
public class ImageHandler
{/// <summary>
/// Method to resize, convert and save the image.
/// </summary>
/// <param name="image">Bitmap image.</param>
/// <param name="maxWidth">resize width.</param>
/// <param name="maxHeight">resize height.</param>
/// <param name="quality">quality setting value.</param>
/// <param name="filePath">file path.</param>
public void Save(Bitmap image, int maxWidth, int maxHeight, int quality, string filePath)
{
// Get the image's original width and height
int originalWidth = image.Width;
int originalHeight = image.Height;
// To preserve the aspect ratio
float ratioX = (float)maxWidth / (float)originalWidth;
float ratioY = (float)maxHeight / (float)originalHeight;
float ratio = Math.Min(ratioX, ratioY);
// New width and height based on aspect ratio
int newWidth = (int)(originalWidth * ratio);
int newHeight = (int)(originalHeight * ratio);
// Convert other formats (including CMYK) to RGB.
Bitmap newImage = new Bitmap(newWidth, newHeight, PixelFormat.Format24bppRgb);
// Draws the image in the specified size with quality mode set to HighQuality
using (Graphics graphics = Graphics.FromImage(newImage))
{
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.DrawImage(image, 0, 0, newWidth, newHeight);
}
// Get an ImageCodecInfo object that represents the JPEG codec.
ImageCodecInfo imageCodecInfo = this.GetEncoderInfo(ImageFormat.Jpeg);
// Create an Encoder object for the Quality parameter.
System.Drawing.Imaging.Encoder encoder = System.Drawing.Imaging.Encoder.Quality;
// Create an EncoderParameters object.
EncoderParameters encoderParameters = new EncoderParameters(1);
// Save the image as a JPEG file with quality level.
EncoderParameter encoderParameter = new EncoderParameter(encoder, quality);
encoderParameters.Param[0] = encoderParameter;
newImage.Save(filePath, imageCodecInfo, encoderParameters);
}
/// <summary>
/// Method to get encoder infor for given image format.
/// </summary>
/// <param name="format">Image format</param>
/// <returns>image codec info.</returns>
private ImageCodecInfo GetEncoderInfo(ImageFormat format)
{
return ImageCodecInfo.GetImageDecoders().SingleOrDefault(c => c.FormatID == format.Guid);
}
public static Bitmap LoadImage(string path)
{
var ms = new MemoryStream(File.ReadAllBytes(path));
GC.KeepAlive(ms);
return (Bitmap)Image.FromStream(ms);
}
public static Size GetThumbnailSize(Image original)
{
// Maximum size of any dimension.
const int maxPixels = 40;
// Width and height.
int originalWidth = original.Width;
int originalHeight = original.Height;
// Compute best factor to scale entire image based on larger dimension.
double factor;
if (originalWidth > originalHeight)
{
factor = (double)maxPixels / originalWidth;
}
else
{
factor = (double)maxPixels / originalHeight;
}
// Return thumbnail size.
return new Size((int)(originalWidth * factor), (int)(originalHeight * factor));
}
}
public class FilesViewModel {
public ViewDataUploadFilesResult[] Files { get; set; }}
Controller
public class HomeController : Controller {
dbImageGalleryEntities1 _dbContext = new dbImageGalleryEntities1();
FilesHelper filesHelper;
FilesHelperDB filesHelperDB;
String tempPath = "~/somefiles/";
String serverMapPath = "~/Files/somefiles/";
private string StorageRoot
{
get { return Path.Combine(HostingEnvironment.MapPath(serverMapPath)); }
}
private string UrlBase = "/Files/somefiles/";
String DeleteURL = "/Home/deleteImageDB/?Id=";
String DeleteType = "GET";
public HomeController()
{
filesHelper = new FilesHelper(DeleteURL, DeleteType, StorageRoot, UrlBase, tempPath, serverMapPath);
filesHelperDB = new FilesHelperDB(DeleteURL, DeleteType, StorageRoot, UrlBase, tempPath, serverMapPath);
}
public ActionResult Index()
{
return View();
}
public ActionResult addImagesToFile(string viewName)
{
JsonFiles ListOfFiles = filesHelper.GetFileList();
var model = new FilesViewModel()
{
Files = ListOfFiles.files
};
return PartialView(viewName);
}
[HttpPost]
public JsonResult UploadToFile()
{
var resultList = new List<ViewDataUploadFilesResult>();
var CurrentContext = HttpContext;
filesHelper.UploadAndShowResults(CurrentContext, resultList);
JsonFiles files = new JsonFiles(resultList);
bool isEmpty = !resultList.Any();
if (isEmpty)
{
return Json("Error ");
}
else
{
return Json(files);
}
}
public ActionResult ShowFromFile()
{
JsonFiles ListOfFiles = filesHelper.GetFileList();
var model = new FilesViewModel()
{
Files = ListOfFiles.files
};
return PartialView("_partialImageToFileGrid", model);
}
public ActionResult imageToDB(string viewName)
{
return View(viewName);
}
//public ActionResult addImagesToDB(string viewName)
//{
// return PartialView(viewName);
//}
[HttpPost]
public JsonResult UploadToDB()
{
var resultList = new List<ViewDataUploadFilesResult>();
var CurrentContext = HttpContext;
filesHelperDB.UploadAndShowResults(CurrentContext, resultList);
JsonFiles files = new JsonFiles(resultList);
//bool isEmpty = !resultList.Any();
//if (isEmpty)
//{
// return Json("Error ");
//}
//else
//{
// return Json(files);
//}
return Json("OK", JsonRequestBehavior.AllowGet);
}
public ActionResult ShowFromDB()
{
JsonFiles ListOfFiles = filesHelperDB.GetFileList();
var model = new FilesViewModel()
{
Files = ListOfFiles.files
};
return PartialView("_partialImageToDBGrid", model);
}
[HttpGet]
public ActionResult deleteImageDB(string Id)
{
try
{
int Id1 = int.Parse(Id);
var img1 = _dbContext.tblImages.FirstOrDefault(x => x.ImageId == Id1);
img1.isDelete = 0;
_dbContext.SaveChanges();
}
catch (Exception ex) { }
return Json("OK", JsonRequestBehavior.AllowGet);
}
public ActionResult createAlbum(string viewName)
{
return PartialView(viewName);
}
}
Views
_Layout.cshtml
<!DOCTYPE html><html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>
@Styles.Render("~/Content/css")
@Styles.Render("~/Content/jQuery-File-Upload")
@Styles.Render("~/Content/jQuery-File-Upload")
@Scripts.Render("~/bundles/modernizr")
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@Scripts.Render("~/bundles/jqueryval")
@Scripts.Render("~/bundles/jQuery-File-Upload")
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
</div>
</div>
</div>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© @DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>
@RenderSection("scripts", required: false)
</body>
</html>
_partialImageToDB.cshtml
@model ImageGallery.Models.FilesViewModel
<div class="container">
<div id="addImagesDB">
@Html.Partial("_partialImageToDBAdd")
</div>
</div>
<hr />
<div id="displayImagesDB">
@if (Model == null)
{
Html.RenderPartial("_partialImageToDBGrid", new ImageGallery.Models.FilesViewModel());
}
else
{
Html.RenderPartial("_partialImageToDBGrid", Model);
}
</div>
<script>
$(document).ready(function () {
$.ajax({
url: '@Url.Action("ShowFromDB", "Home")',
type: "GET",
success: function (data) {
$('#displayImagesDB').html(data);
},
error: function (e) {
}
});
});
</script>
_partialImageToDBAdd.cshtml
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<script>
var $form = null;
$(function () {
$form = $('#fileupload1').fileupload({
dataType: 'json'
});
});
// $('#fileupload1').addClass('fileupload-processing');
</script>
@Html.Partial("_FilesFromDB")
_partialImageToDBGrid.cshtml
@model ImageGallery.Models.FilesViewModel
@using ImageGallery.Helpers
<link href="~/Content/sweetalert.css" rel="stylesheet" />
<script src="~/Content/sweetalert.js"></script>
<style>
.abcd {
text-align: center;
float: left;
position: relative;
}
.abcd img {
border-radius: 25px;
background: #ffffff;
margin-left: 10px;
margin-top: 10px;
height: 100px;
width: 100px;
padding: 5px;
border: 1px solid rgb(232, 222, 189);
}
.abcd1 img {
border-radius: 25px;
background: #ffffff;
margin-left: 10px;
margin-top: 5px;
padding: 5px;
border: 1px solid rgb(232, 222, 189);
}
.closeIcon {
position: absolute;
cursor: pointer;
float: right;
right: -3px;
top: 3px;
background: rgba(0,0,0,0.5);
display: block;
height: 20px;
width: 20px;
z-index: 222;
color: white;
text-align: center;
line-height: 20px;
border-radius: 25px;
}
.image_gallery {
display: inline-block;
width: 154px;
}
</style>
<h2>Show</h2>
<div id="blueimp-gallery" class="blueimp-gallery blueimp-gallery-controls" data-filter=":even">
<div class="slides"></div>
<h3 class="title"></h3>
<a class="prev">‹</a>
<a class="next">›</a>
<a class="close">×</a>
<a class="play-pause"></a>
<ol class="indicator"></ol>
</div>
<div id="links">
@if (@Model.Files != null && @Model.Files.Length != 0)
{
foreach (ViewDataUploadFilesResult file in @Model.Files)
{
if (file.type.Equals("video/mp4"))
{
<div id="abcd" class='abcd'>
<a href="@file.url" title="@file.name" type="video/mp4" data-description="This is a movie."><img src="@file.thumbnailUrl" alt="@file.name"><i id="@file.imgId" class="glyphicon glyphicon-remove closeIcon"></i></a>
</div>
}
else
{
<div id="abcd" class='abcd'>
<a href="@file.url" title="@file.name" data-description="This is a image."><img src="@file.thumbnailUrl" alt="@file.name"><i id="@file.imgId" class="glyphicon glyphicon-remove closeIcon"></i></a>
</div>
}
}
}
else
{
<p>No files</p>
}
</div>
<script>
$("i").click(function () {
alert(this.id);
var obj = this;
var imgId = this.id;
swal({
title: "Are you sure?",
text: "You will not be able to recover this Image!",
type: "warning",
showCancelButton: true,
confirmButtonClass: "btn-danger",
confirmButtonText: "Yes, delete it!",
cancelButtonText: "No, cancel plx!",
closeOnConfirm: true,
closeOnCancel: false
},
function (isConfirm) {
if (isConfirm) {
$.get('@Url.Action("deleteImageDB", "Home")', { Id: imgId }, function (data) { });
$(obj).parent().parent().remove();
} else {
swal("Cancelled", "Your Record is safe :)", "error");
}
});
return false;
});
document.getElementById('links').onclick = function (event) {
event = event || window.event;
var target = event.target || event.srcElement,
link = target.src ? target.parentNode : target,
options = { index: link, event: event },
links = this.getElementsByTagName('a');
blueimp.Gallery(links, options);
};
</script>
_FilesFromDB.cshtml
<h2>jQuery File Upload</h2>
<form id="fileupload1" method="POST" enctype="multipart/form-data" data-url="@Url.Action("UploadToDB","Home")">
<div class="row fileupload-buttonbar">
<div class="col-lg-7">
<!-- The fileinput-button span is used to style the file input field as button -->
<span class="btn btn-success fileinput-button">
<i class="glyphicon glyphicon-plus"></i>
<span>Add files...</span>
<input type="file" name="files[]" multiple>
</span>
<button type="submit" class="btn btn-primary start">
<i class="glyphicon glyphicon-upload"></i>
<span>Start upload</span>
</button>
<button type="reset" class="btn btn-warning cancel">
<i class="glyphicon glyphicon-ban-circle"></i>
<span>Cancel upload</span>
</button>
<button type="button" class="btn btn-danger delete">
<i class="glyphicon glyphicon-trash"></i>
<span>Delete</span>
</button>
<input type="checkbox" class="toggle">
<!-- The global file processing state -->
<span class="fileupload-process"></span>
</div>
<!-- The global progress state -->
<div class="col-lg-5 fileupload-progress fade">
<!-- The global progress bar -->
<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100">
<div class="progress-bar progress-bar-success" style="width:0%;"></div>
</div>
<!-- The extended global progress state -->
<div class="progress-extended"> </div>
</div>
</div>
<!-- The global progress state -->
<div class="col-lg-5 fileupload-progress fade">
<!-- The global progress bar -->
<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100">
<div class="progress-bar progress-bar-success" style="width:0%;"></div>
</div>
<!-- The extended global progress state -->
<div class="progress-extended"> </div>
</div>
<!-- The table listing the files available for upload/download -->
<table role="presentation" class="table table-striped"><tbody class="files"></tbody></table>
</form>
<br>
<!-- The blueimp Gallery widget -->
<div id="blueimp-gallery" class="blueimp-gallery blueimp-gallery-controls" data-filter=":even">
<div class="slides"></div>
<h3 class="title"></h3>
<a class="prev">‹</a>
<a class="next">›</a>
<a class="close">×</a>
<a class="play-pause"></a>
<ol class="indicator"></ol>
</div>
<!-- The template to display files available for upload -->
<script id="template-upload" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
<tr class="template-upload fade">
<td>
<span class="preview"></span>
</td>
<td>
<p class="name">{%=file.name%}</p>
<strong class="error text-danger"></strong>
</td>
<td>
<p class="size">Processing...</p>
<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><div class="progress-bar progress-bar-success" style="width:0%;"></div></div>
</td>
<td>
{% if (!i && !o.options.autoUpload) { %}
<button class="btn btn-primary start" disabled>
<i class="glyphicon glyphicon-upload"></i>
<span>Start</span>
</button>
{% } %}
{% if (!i) { %}
<button class="btn btn-warning cancel">
<i class="glyphicon glyphicon-ban-circle"></i>
<span>Cancel</span>
</button>
{% } %}
</td>
</tr>
{% } %}
</script>
<!-- The template to display files available for download -->
<script id="template-download" type="text/x-tmpl">
@*{% for (var i=0, file; file=o.files[i]; i++) { %}
<tr class="template-download fade">
<td>
<span class="preview">
{% if (file.thumbnailUrl) { %}
<a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" data-gallery><img src="{%=file.thumbnailUrl%}"></a>
{% } %}
</span>
</td>
<td>
<p class="name">
{% if (file.url) { %}
<a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" {%=file.thumbnailUrl?'data-gallery':''%}>{%=file.name%}</a>
{% } else { %}
<span>{%=file.name%}</span>
{% } %}
</p>
{% if (file.error) { %}
<div><span class="label label-danger">Error</span> {%=file.error%}</div>
{% } %}
</td>
<td>
<span class="size">{%=o.formatFileSize(file.size)%}</span>
</td>
<td>
{% if (file.deleteUrl) { %}
<button class="btn btn-danger delete" data-type="{%=file.deleteType%}" data-url="{%=file.deleteUrl%}" {% if (file.deletewithcredentials) { %} data-xhr-fields='{"withCredentials":true}' {% } %}>
<i class="glyphicon glyphicon-trash"></i>
<span>Delete</span>
</button>
<input type="checkbox" name="delete" value="1" class="toggle">
{% } else { %}
<button class="btn btn-warning cancel">
<i class="glyphicon glyphicon-ban-circle"></i>
<span>Cancel</span>
</button>
{% } %}
</td>
</tr>
{% } %}*@
</script>