Image manager - gallery Drag and drop https://css-tricks.com/drag-and-drop-file-uploading/
#file-upload {
margin: 40px 0 20px 0;
}
.box
{
font-family: Roboto, sans-serif;
color: #0f3c4b;
font-size: 1.4rem; /* 20 */
background-color: #c8dadf;
position: relative;
padding: 20px;
text-align: center;
}
.box.has-advanced-upload
{
outline: 2px dashed #92b0b3;
outline-offset: -10px;
-webkit-transition: outline-offset .15s ease-in-out, background-color .15s linear;
transition: outline-offset .15s ease-in-out, background-color .15s linear;
}
.box.is-dragover
{
outline-offset: -20px;
outline-color: #c8dadf;
background-color: #fff;
}
.box__dragndrop,
.box__icon
{
display: none;
}
.box.has-advanced-upload .box__dragndrop
{
display: inline;
}
.box.has-advanced-upload .box__icon
{
width: 100%;
height: 60px;
fill: #92b0b3;
display: block;
margin: 10px 0 20px;
}
.box.is-uploading .box__input,
.box.is-success .box__input,
.box.is-error .box__input
{
visibility: hidden;
}
.box__uploading,
.box__success,
.box__error,
.box__restart
{
display: none;
}
.box.is-uploading .box__uploading,
.box.is-success .box__success,
.box.is-error .box__error,
.box.is-success .box__restart,
.box.is-error .box__restart
{
display: block;
position: absolute;
top: 50%;
right: 0;
left: 0;
-webkit-transform: translateY( -50% );
transform: translateY( -50% );
}
.box__uploading
{
font-style: italic;
}
.box__success
{
-webkit-animation: appear-from-inside .25s ease-in-out;
animation: appear-from-inside .25s ease-in-out;
}
@-webkit-keyframes appear-from-inside
{
from { -webkit-transform: translateY( -50% ) scale( 0 ); }
75% { -webkit-transform: translateY( -50% ) scale( 1.1 ); }
to { -webkit-transform: translateY( -50% ) scale( 1 ); }
}
@keyframes appear-from-inside
{
from { transform: translateY( -50% ) scale( 0 ); }
75% { transform: translateY( -50% ) scale( 1.1 ); }
to { transform: translateY( -50% ) scale( 1 ); }
}
.box__restart
{
margin-top: 30px;
font-size: 80%;
cursor: pointer;
}
.box__restart:focus,
.box__restart:hover
{
color: #39bfd3;
}
.box__file
{
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}
.box__file + label
{
max-width: 80%;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
display: inline-block;
overflow: hidden;
}
.box__file + label:hover strong,
.box__file:focus + label strong,
.box__file.has-focus + label strong
{
color: #39bfd3;
}
.box__file:focus + label,
.box__file.has-focus + label
{
outline: 1px dotted #000;
outline: -webkit-focus-ring-color auto 5px;
}
.box__button
{
display: block;
}
.box__button
{
font-weight: 700;
color: #e5edf1;
background-color: #39bfd3;
display: none;
padding: 8px 16px;
margin: 40px auto 0;
}
.box__button:hover,
.box__button:focus
{
background-color: #0f3c4b;
}
#file-upload #gallery {
/*margin-top: 20px;*/
}
#file-upload #gallery:after {
content: '';
display: block;
clear: both;
}
#file-upload #gallery .img-box{
float: left;
display: flex;
justify-content: center;
height: 100px;
width: 104px;
overflow: hidden;
margin: 5px;
border: 1px solid #ccc;
transition: all 0.4s ease;
}
#file-upload #gallery .img-box:hover{
opacity: 0.5;
cursor: pointer;
}
#file-upload #gallery .img-box:hover:after{
content: "X";
position: absolute;
color: #fff;
font-size: 64px;
-webkit-transform: scale(0.5,0.4);
-moz-transform: scale(0.5,0.4);
-ms-transform: scale(0.5,0.4);
-o-transform: scale(0.5,0.4);
transform: scale(0.5,0.4);
}
<div id="file-upload">
<div class="form-horizontal">
<div class="form-group ">
<label class="control-label col-md-2">@LanguageResources.Admin_DirectOwner_Gallery</label>
<div class="col-md-10 floatRight">
<form class="box" method="post" action="/Manage/FileUpload" enctype="multipart/form-data">
<div class="box__input">
<svg class="box__icon" xmlns="http://www.w3.org/2000/svg" width="50" height="43" viewBox="0 0 50 43"><path d="M48.4 26.5c-.9 0-1.7.7-1.7 1.7v11.6h-43.3v-11.6c0-.9-.7-1.7-1.7-1.7s-1.7.7-1.7 1.7v13.2c0 .9.7 1.7 1.7 1.7h46.7c.9 0 1.7-.7 1.7-1.7v-13.2c0-1-.7-1.7-1.7-1.7zm-24.5 6.1c.3.3.8.5 1.2.5.4 0 .9-.2 1.2-.5l10-11.6c.7-.7.7-1.7 0-2.4s-1.7-.7-2.4 0l-7.1 8.3v-25.3c0-.9-.7-1.7-1.7-1.7s-1.7.7-1.7 1.7v25.3l-7.1-8.3c-.7-.7-1.7-.7-2.4 0s-.7 1.7 0 2.4l10 11.6z" /></svg>
<input class="box__file" type="file" name="files[]" id="file" data-multiple-caption="{count} @LanguageResources.Admin_DirectOwner_FileUploadFilesSelected" multiple accept="image/*" />
<label for="file"><strong>@LanguageResources.Admin_DirectOwner_FileUploadChooseFile</strong><span class="box__dragndrop"> @LanguageResources.Admin_DirectOwner_FileUploadDragIt</span></label>
<button class="box__button" type="submit">@LanguageResources.Admin_DirectOwner_FileUploadUpload</button>
</div>
<div class="box__uploading">@LanguageResources.Admin_DirectOwner_FileUploadUploading…</div>
<div class="box__success">@LanguageResources.Admin_DirectOwner_FileUploadDone</div>
<div class="box__error">@LanguageResources.Admin_DirectOwner_FileUploadError <span></span></div>
<div class="box__restart">@LanguageResources.Admin_DirectOwner_FileUploadRestart</div>
@Html.HiddenFor(model => model.Id)
</form>
</div>
</div>
</div>
<div class="form-horizontal">
<div class="form-group">
<label class="control-label col-md-2"></label>
<div id="gallery" class="col-md-10">
</div>
</div>
</div>
<script type="text/javascript">
'use strict';
; (function (document, window, index) {
// feature detection for drag&drop upload
var isAdvancedUpload = function () {
var div = document.createElement('div');
return (('draggable' in div) || ('ondragstart' in div && 'ondrop' in div)) && 'FormData' in window && 'FileReader' in window;
}();
// applying the effect for every form
var forms = document.querySelectorAll('.box');
Array.prototype.forEach.call(forms, function (form) {
var input = form.querySelector('input[type="file"]'),
label = form.querySelector('label'),
errorMsg = form.querySelector('.box__error span'),
restart = form.querySelectorAll('.box__restart'),
droppedFiles = false,
showFiles = function (files) {
label.textContent = files.length > 1 ? (input.getAttribute('data-multiple-caption') || '').replace('{count}', files.length) : files[0].name;
},
triggerFormSubmit = function () {
//var event = document.createEvent('HTMLEvents');
//event.initEvent('submit', true, false);
//form.dispatchEvent(event);
runUpload();
};
// letting the server side to know we are going to make an Ajax request
var ajaxFlag = document.createElement('input');
ajaxFlag.setAttribute('type', 'hidden');
ajaxFlag.setAttribute('name', 'ajax');
ajaxFlag.setAttribute('value', 1);
form.appendChild(ajaxFlag);
// automatically submit the form on file select
input.addEventListener('change', function (e) {
showFiles(e.target.files);
triggerFormSubmit();
});
// drag&drop files if the feature is available
if (isAdvancedUpload) {
form.classList.add('has-advanced-upload'); // letting the CSS part to know drag&drop is supported by the browser
['drag', 'dragstart', 'dragend', 'dragover', 'dragenter', 'dragleave', 'drop'].forEach(function (event) {
form.addEventListener(event, function (e) {
// preventing the unwanted behaviours
e.preventDefault();
e.stopPropagation();
});
});
['dragover', 'dragenter'].forEach(function (event) {
form.addEventListener(event, function () {
form.classList.add('is-dragover');
});
});
['dragleave', 'dragend', 'drop'].forEach(function (event) {
form.addEventListener(event, function () {
form.classList.remove('is-dragover');
});
});
form.addEventListener('drop', function (e) {
droppedFiles = e.dataTransfer.files; // the files that were dropped
showFiles(droppedFiles);
triggerFormSubmit();
});
}
//form.addEventListener('submit', function (e) {
function runUpload() {
// preventing the duplicate submissions if the current one is in progress
if (form.classList.contains('is-uploading')) return false;
var _validFileExtensions = [".jpg", ".jpeg", ".png"];
var blnValid = false;
if (!droppedFiles) {
for (var j = 0; j < _validFileExtensions.length; j++) {
var sCurExtension = _validFileExtensions[j];
if (input.value.substr(input.value.length - sCurExtension.length, sCurExtension.length).toLowerCase() == sCurExtension.toLowerCase()) {
blnValid = true;
break;
}
}
if (!blnValid) {
input.value = '';
droppedFiles = false;
form.classList.add('is-error');
return false;
}
}
form.classList.remove('is-error', 'is-success');
form.classList.add('is-uploading');
form.classList.remove('is-error');
if (isAdvancedUpload) // ajax file upload for modern browsers
{
//e.preventDefault();
// gathering the form data
var ajaxData = new FormData(form);
if (droppedFiles) {
Array.prototype.forEach.call(droppedFiles, function (file) {
if (((file.size / 1028) / 1028) < 4) {
for (var j = 0; j < _validFileExtensions.length; j++) {
var sCurExtension = _validFileExtensions[j];
if (file.name.substr(file.name.length - sCurExtension.length, sCurExtension.length).toLowerCase() == sCurExtension.toLowerCase()) {
blnValid = true;
break;
}
}
if (!blnValid) {
input.value = '';
droppedFiles = false;
form.classList.remove('is-uploading');
form.classList.add('is-error');
throw new Error("Error!");
}
ajaxData.append(file.name, file);
} else {
input.value = '';
droppedFiles = false;
form.classList.remove('is-uploading');
form.classList.add('is-error')
errorMsg.textContent = "**File max size is 4 mb**: " + file.name;
throw new Error("Error!");
}
});
}
// ajax request
var ajax = new XMLHttpRequest();
ajax.open(form.getAttribute('method'), form.getAttribute('action'), true);
ajax.setRequestHeader("X-Requested-With", "XMLHttpRequest");
ajax.onload = function () {
form.classList.remove('is-uploading');
var data = JSON.parse(ajax.responseText);
if (ajax.status >= 200 && ajax.status < 400) {
form.classList.add(data.success == true ? 'is-success' : 'is-error');
if (!data.success) errorMsg.textContent = data.error;
var inputsId = document.querySelectorAll('form input[name="Id"]');
inputsId[0].value = data.property;
inputsId[1].value = data.property;
var countFilesUpload = droppedFiles ? droppedFiles.length : 1;
loadFileUpload(countFilesUpload, inputsId[0].value);
}
else alert('Error. ' + data.message + '!');
input.value = '';
droppedFiles = false;
};
ajax.onerror = function () {
form.classList.remove('is-uploading');
alert('Error. Please, try again!');
input.value = '';
droppedFiles = false;
};
ajax.send(ajaxData);
}
else // fallback Ajax solution upload for older browsers
{
var iframeName = 'uploadiframe' + new Date().getTime(),
iframe = document.createElement('iframe');
$iframe = $('<iframe name="' + iframeName + '" style="display: none;"></iframe>');
iframe.setAttribute('name', iframeName);
iframe.style.display = 'none';
document.body.appendChild(iframe);
form.setAttribute('target', iframeName);
iframe.addEventListener('load', function () {
var data = JSON.parse(iframe.contentDocument.body.innerHTML);
form.classList.remove('is-uploading');
form.classList.add(data.success == true ? 'is-success' : 'is-error');
form.removeAttribute('target');
if (!data.success) errorMsg.textContent = data.error;
iframe.parentNode.removeChild(iframe);
});
}
return false;
}
//});
// restart the form if has a state of error/success
Array.prototype.forEach.call(restart, function (entry) {
entry.addEventListener('click', function (e) {
e.preventDefault();
form.classList.remove('is-error', 'is-success');
label.innerHTML = '<strong>Choose a file</strong><span class="box__dragndrop"> or drag it here (4 mb/file max)</span>.';
input.click();
});
});
// Firefox focus bug fix for file input
input.addEventListener('focus', function () { input.classList.add('has-focus'); });
input.addEventListener('blur', function () { input.classList.remove('has-focus'); });
});
}(document, window, 0));
</script>
</div>
@model chilliIS.propertyMallorca.Web.Areas.Admin.Models.DirectOwnerProperty
@using LanguageResources
@{
ViewBag.Title = LanguageResources.Admin_DirectOwner_AddProperty;
Layout = "~/Views/Shared/_AdminLayout.cshtml";
}
<h2>@LanguageResources.Admin_DirectOwner_CreateProperty</h2>
@Html.Partial("~/Areas/Admin/Views/Shared/_FileUpload.cshtml", Model)
@using (Html.BeginRouteForm("Admin_Properties_DirectOwner_Create_Post", null, FormMethod.Post))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
@Html.HiddenFor(model => model.Id)
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Desc, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Desc, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Desc, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Price, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-2">
@Html.EditorFor(model => model.Price, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Price, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.HidePrice, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-2">
@Html.EditorFor(model => model.HidePrice)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Bedrooms, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-2">
@Html.EditorFor(model => model.Bedrooms, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Bedrooms, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Bathrooms, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-2">
@Html.EditorFor(model => model.Bathrooms, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Bathrooms, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.TerraceM2, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-2">
@Html.EditorFor(model => model.TerraceM2, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.TerraceM2, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.ConstructedAreaSizeM2, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-2">
@Html.EditorFor(model => model.ConstructedAreaSizeM2, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.ConstructedAreaSizeM2, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Type, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-2">
@Html.DropDownListFor(model => model.Type, Model.TypeList, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Location, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-2">
@Html.DropDownListFor(model => model.Location, Model.LocationList, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.SaleFrequency, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-2">
@Html.DropDownListFor(model => model.SaleFrequency, Model.SaleFrequencyList, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.LanguageProperty, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-2">
@Html.DropDownListFor(model => model.LanguageProperty, Model.LanguagePropertyList, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.ListingStatus, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.ListingStatus)
</div>
</div>
@Html.HiddenFor(model => model.AssetPath)
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="@LanguageResources.Admin_DirectOwner_CreateProperty" class="btn btn-default orange-btn" />
@Html.ActionLink(LanguageResources.Admin_Members_Cancel, "DirectOwnerProperties", null, new { @class = "btn btn-default orange-btn" })
</div>
</div>
</div>
}
@Html.Partial("_UsersFooter")
@section scripts {
<script type="text/javascript">
$(document).ready(function () {
loadFileUpload(0, @Model.Id.ToString());
});
function updateTotalFile() {
// Count elements
var imgages = $('#gallery .img-box');
var countFiles = imgages.eq(imgages.length - 1).data('code');
var inputCountFiles = $('input[name=totalFiles]');
if (countFiles == undefined) { countFiles = 0 };
if (inputCountFiles.length == 0) {
var form = document.querySelector('.box');
var ajaxFlag = document.createElement('input');
ajaxFlag.setAttribute('type', 'hidden');
ajaxFlag.setAttribute('name', 'totalFiles');
ajaxFlag.setAttribute('value', countFiles);
form.appendChild(ajaxFlag);
} else {
inputCountFiles.val(countFiles);
}
}
function loadFileUpload(multi, propertyId) {
var data = {
multi: multi,
propertyId: propertyId
}
$.ajax({
type: "POST",
url: '/Manage/FileLoad',
data: data,
async: true
})
.done(function (msg) {
var wp = $('#gallery');
var html = "";
var listFile = $.parseJSON(msg.list);
if (listFile.length > 0) {
if (!!wp.html().trim()) {
html = wp.html();
}
for (i in listFile) {
html += listFile[i];
}
wp.html(html);
wp.slideDown();
$(".img-box").click(function (e) {
var that = $(this);
var eq = that.data("code");
data = {
element: eq,
propertyId: propertyId
}
$.ajax({
type: "POST",
url: '/Manage/FileDelete',
data: data
})
.done(function (msg) {
if (msg.success) {
that.remove();
updateTotalFile();
}
});
});
} else {
wp.slideUp();
}
updateTotalFile();
return false;
});
}
</script>
}