jojacafe
9/9/2016 - 10:43 AM

Image manager - gallery Drag and drop https://css-tricks.com/drag-and-drop-file-uploading/

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&hellip;</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>
}