Rebuild image based UI for FileUpload form widget
This commit is contained in:
parent
99146294aa
commit
887b959156
|
|
@ -1,7 +1,9 @@
|
|||
<?php namespace Backend\FormWidgets;
|
||||
|
||||
use Str;
|
||||
use Lang;
|
||||
use Input;
|
||||
use Response;
|
||||
use Validator;
|
||||
use System\Models\File;
|
||||
use ApplicationException;
|
||||
|
|
@ -9,7 +11,14 @@ use Backend\Classes\FormField;
|
|||
use Backend\Classes\FormWidgetBase;
|
||||
use ValidationException;
|
||||
use Exception;
|
||||
use Lang;
|
||||
|
||||
/*
|
||||
Requirements for this new uploader
|
||||
|
||||
- Fluid single image
|
||||
- Prevent uploading of PHP files, etc
|
||||
- Avatar mode
|
||||
*/
|
||||
|
||||
/**
|
||||
* File upload field
|
||||
|
|
@ -88,7 +97,7 @@ class FileUpload extends FormWidgetBase
|
|||
public function render()
|
||||
{
|
||||
$this->prepareVars();
|
||||
return $this->makePartial('container');
|
||||
return $this->makePartial('fileupload');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -103,6 +112,7 @@ class FileUpload extends FormWidgetBase
|
|||
$this->vars['imageHeight'] = $this->imageHeight;
|
||||
$this->vars['imageWidth'] = $this->imageWidth;
|
||||
$this->vars['acceptedFileTypes'] = $this->getAcceptedFileTypes(true);
|
||||
$this->vars['cssDimensions'] = $this->getCssDimensions();
|
||||
}
|
||||
|
||||
protected function getFileList()
|
||||
|
|
@ -142,6 +152,25 @@ class FileUpload extends FormWidgetBase
|
|||
return $mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the CSS dimensions for the uploaded image,
|
||||
* uses auto where no dimension is provided.
|
||||
* @return string
|
||||
*/
|
||||
protected function getCssDimensions()
|
||||
{
|
||||
$cssDimensions = '';
|
||||
$cssDimensions .= ($this->imageWidth)
|
||||
? 'width: '.$this->imageWidth.'px;'
|
||||
: 'width: auto;';
|
||||
|
||||
$cssDimensions .= ($this->imageHeight)
|
||||
? 'height: '.$this->imageHeight.'px;'
|
||||
: 'height: auto;';
|
||||
|
||||
return $cssDimensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the specified accepted file types, or the default
|
||||
* based on the mode. Image mode will return:
|
||||
|
|
@ -240,6 +269,7 @@ class FileUpload extends FormWidgetBase
|
|||
public function onLoadAttachmentConfig()
|
||||
{
|
||||
if (($file_id = post('file_id')) && ($file = File::find($file_id))) {
|
||||
$file = $this->decorateFileAttributes($file);
|
||||
$this->vars['file'] = $file;
|
||||
return $this->makePartial('config_form');
|
||||
}
|
||||
|
|
@ -258,8 +288,7 @@ class FileUpload extends FormWidgetBase
|
|||
$file->description = post('description');
|
||||
$file->save();
|
||||
|
||||
$file->thumb = $file->getThumb($this->imageWidth, $this->imageHeight, $this->thumbOptions);
|
||||
return ['item' => $file->toArray()];
|
||||
return ['displayName' => $file->title ?: $file->file_name];
|
||||
}
|
||||
|
||||
throw new ApplicationException('Unable to find file, it may no longer exist');
|
||||
|
|
@ -330,15 +359,17 @@ class FileUpload extends FormWidgetBase
|
|||
|
||||
$fileRelation->add($file, $this->sessionKey);
|
||||
|
||||
$result = $this->decorateFileAttributes($file);
|
||||
$file = $this->decorateFileAttributes($file);
|
||||
|
||||
$result = ['id' => $file->id, 'thumb' => $file->thumb];
|
||||
Response::json($result, 200)->send();
|
||||
|
||||
}
|
||||
catch (Exception $ex) {
|
||||
$result = json_encode(['error' => $ex->getMessage()]);
|
||||
Response::json($ex->getMessage(), 400)->send();
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
die($result);
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,146 +1,22 @@
|
|||
.field-fileupload .attachment-input {
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
width: 10px;
|
||||
opacity: 0;
|
||||
}
|
||||
.field-fileupload .attachment-item {
|
||||
position: relative;
|
||||
}
|
||||
.field-fileupload .image-multi ul,
|
||||
.field-fileupload .file-multi ul {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.field-fileupload .image-multi ul:before,
|
||||
.field-fileupload .file-multi ul:before,
|
||||
.field-fileupload .image-multi ul:after,
|
||||
.field-fileupload .file-multi ul:after {
|
||||
content: " ";
|
||||
display: table;
|
||||
}
|
||||
.field-fileupload .image-multi ul:after,
|
||||
.field-fileupload .file-multi ul:after {
|
||||
clear: both;
|
||||
}
|
||||
.field-fileupload .image-multi ul li,
|
||||
.field-fileupload .file-multi ul li {
|
||||
list-style: none;
|
||||
.field-fileupload .upload-button {
|
||||
display: block;
|
||||
float: left;
|
||||
margin-right: 35px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.field-fileupload .file-multi .attachment-item,
|
||||
.field-fileupload .file-single.attachment-item {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
.field-fileupload .active-image,
|
||||
.field-fileupload .active-file {
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border: 1px solid #e0e0e0;
|
||||
background: white;
|
||||
position: relative;
|
||||
outline: none;
|
||||
overflow: hidden;
|
||||
padding: 5px;
|
||||
}
|
||||
.field-fileupload .active-image .caption,
|
||||
.field-fileupload .active-file .caption {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
font-size: 11px;
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
color: #999;
|
||||
padding: 2px 5px;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.field-fileupload .active-image img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.field-fileupload .active-file {
|
||||
padding: 0;
|
||||
}
|
||||
.field-fileupload .active-file .file-icon {
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
.field-fileupload .active-file .file-icon i {
|
||||
font-size: 64px;
|
||||
color: #444;
|
||||
}
|
||||
.field-fileupload .active-file .file-icon b {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 10px;
|
||||
color: #FFF;
|
||||
display: block;
|
||||
width: 100%;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
text-align: center;
|
||||
text-indent: 12px;
|
||||
}
|
||||
.field-fileupload .uploader-toolbar {
|
||||
-webkit-transition: opacity 0.2s;
|
||||
transition: opacity 0.2s;
|
||||
height: 100%;
|
||||
background: #e0e0e0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -20px;
|
||||
width: 20px;
|
||||
}
|
||||
.field-fileupload .uploader-toolbar h3,
|
||||
.field-fileupload .uploader-toolbar p {
|
||||
display: none;
|
||||
}
|
||||
.field-fileupload .uploader-toolbar a {
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
padding: 3px 0 0 7px;
|
||||
color: #999;
|
||||
font-size: 15px;
|
||||
margin-left: -4px;
|
||||
text-align: center;
|
||||
}
|
||||
.field-fileupload .uploader-toolbar a:hover {
|
||||
color: #666;
|
||||
}
|
||||
.field-fileupload .uploader-toolbar a.uploader-file-link {
|
||||
display: none;
|
||||
}
|
||||
.field-fileupload .no-attachment {
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border: 2px dotted #e0e0e0;
|
||||
border: 2px dotted rgba(0, 0, 0, 0.1);
|
||||
position: relative;
|
||||
outline: none;
|
||||
}
|
||||
.field-fileupload .no-attachment table {
|
||||
.field-fileupload .upload-button table {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
.field-fileupload .no-attachment table td {
|
||||
.field-fileupload .upload-button table td {
|
||||
line-height: 16px;
|
||||
font-size: 11px;
|
||||
vertical-align: middle;
|
||||
height: 100%;
|
||||
}
|
||||
.field-fileupload .no-attachment table td:before {
|
||||
.field-fileupload .upload-button table td:before {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
display: block;
|
||||
|
|
@ -148,55 +24,108 @@
|
|||
color: rgba(0, 0, 0, 0.1);
|
||||
vertical-align: middle;
|
||||
}
|
||||
.field-fileupload .no-attachment table td span {
|
||||
.field-fileupload .upload-button table td span {
|
||||
display: block;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
.field-fileupload .no-attachment:hover {
|
||||
/*background: #ffffdd;*/
|
||||
border: 2px dotted rgba(0, 0, 0, 0.1);
|
||||
.field-fileupload .upload-button:hover {
|
||||
border: 2px dotted rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.field-fileupload .no-attachment:focus {
|
||||
border: 2px solid #ccc;
|
||||
.field-fileupload .upload-button:hover table td:before {
|
||||
color: #5cb85c;
|
||||
color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.field-fileupload .upload-button:focus {
|
||||
border: 2px solid rgba(0, 0, 0, 0.3);
|
||||
background: transparent;
|
||||
}
|
||||
.field-fileupload .uploader-progress {
|
||||
.field-fileupload .upload-button:focus table td:before {
|
||||
color: #5cb85c;
|
||||
color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.field-fileupload .upload-object {
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
position: relative;
|
||||
top: -7px;
|
||||
}
|
||||
.field-fileupload .uploader-progress {
|
||||
margin: 0 2px;
|
||||
visibility: hidden;
|
||||
outline: none;
|
||||
overflow: hidden;
|
||||
height: 5px;
|
||||
margin-bottom: 20px;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 2px;
|
||||
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
.field-fileupload .uploader-progress .progress-bar {
|
||||
line-height: 5px;
|
||||
color: #ffffff;
|
||||
background-color: #ccc;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
.field-fileupload .upload-object img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.field-fileupload .loading img,
|
||||
.field-fileupload .loading .file-icon {
|
||||
opacity: 0.5;
|
||||
filter: alpha(opacity=50);
|
||||
.field-fileupload .upload-object .icon-container {
|
||||
display: table;
|
||||
opacity: .6;
|
||||
}
|
||||
.field-fileupload .loading .uploader-loading {
|
||||
background-image: url(../../../../assets/images/loader-transparent.svg);
|
||||
.field-fileupload .upload-object .icon-container i {
|
||||
color: #95a5a6;
|
||||
display: inline-block;
|
||||
}
|
||||
.field-fileupload .upload-object .icon-container div {
|
||||
display: table-cell;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.field-fileupload .upload-object .icon-container.image > div.icon-wrapper {
|
||||
display: none;
|
||||
}
|
||||
.field-fileupload .upload-object h4 {
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
color: #2b3e50;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
line-height: 150%;
|
||||
margin: 15px 0 5px 0;
|
||||
padding-right: 0;
|
||||
-webkit-transition: padding 0.1s;
|
||||
transition: padding 0.1s;
|
||||
position: relative;
|
||||
}
|
||||
.field-fileupload .upload-object h4 a {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
display: none;
|
||||
}
|
||||
.field-fileupload .upload-object p.size {
|
||||
font-size: 12px;
|
||||
color: #95a5a6;
|
||||
}
|
||||
.field-fileupload .upload-object p.size strong {
|
||||
font-weight: 400;
|
||||
}
|
||||
.field-fileupload .upload-object .meta .drag-handle {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
cursor: move;
|
||||
}
|
||||
.field-fileupload .upload-object .info h4 a,
|
||||
.field-fileupload .upload-object .meta a.drag-handle {
|
||||
color: #2b3e50;
|
||||
display: none;
|
||||
font-size: 15px;
|
||||
text-decoration: none;
|
||||
}
|
||||
.field-fileupload .upload-object .icon-container {
|
||||
position: relative;
|
||||
}
|
||||
.field-fileupload .upload-object .icon-container:after {
|
||||
background-image: url('../../../../../system/assets/ui/images/loader-transparent.svg');
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
margin-top: -22.5px;
|
||||
margin-top: -20px;
|
||||
margin-left: -20px;
|
||||
display: block;
|
||||
background-size: 40px 40px;
|
||||
|
|
@ -204,124 +133,231 @@
|
|||
-webkit-animation: spin 1s linear infinite;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
.field-fileupload .loading .no-attachment {
|
||||
cursor: default;
|
||||
border: 2px solid #ccc;
|
||||
.field-fileupload .upload-object.is-success .icon-container:after {
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.3s ease;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
.field-fileupload .loading .no-attachment table td:before {
|
||||
.field-fileupload .upload-object.is-error .icon-container:after {
|
||||
content: "";
|
||||
background: none;
|
||||
font-family: FontAwesome;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
text-decoration: inherit;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
*margin-right: .3em;
|
||||
content: "\f071";
|
||||
-webkit-animation: none;
|
||||
animation: none;
|
||||
font-size: 40px;
|
||||
color: #ab2a1c;
|
||||
margin-top: -30px;
|
||||
margin-left: -20px;
|
||||
text-shadow: 2px 2px 0 #fff;
|
||||
}
|
||||
.field-fileupload .upload-object.is-success {
|
||||
cursor: pointer;
|
||||
}
|
||||
.field-fileupload .upload-object.is-success .icon-container {
|
||||
opacity: 1;
|
||||
}
|
||||
.field-fileupload .upload-object.is-success .progress-bar {
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.3s ease;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
.field-fileupload .upload-object.is-error {
|
||||
cursor: pointer;
|
||||
}
|
||||
.field-fileupload .upload-object.is-error .icon-container {
|
||||
opacity: .5;
|
||||
}
|
||||
.field-fileupload .upload-object.is-error .info h4 {
|
||||
color: #ab2a1c;
|
||||
}
|
||||
.field-fileupload .upload-object.is-error .info h4 a {
|
||||
display: none;
|
||||
}
|
||||
.field-fileupload .loading .uploader-progress {
|
||||
visibility: visible;
|
||||
.field-fileupload .upload-object.is-error .meta {
|
||||
display: none;
|
||||
}
|
||||
.field-fileupload.is-sortable li.placeholder {
|
||||
.field-fileupload.is-sortable {
|
||||
position: relative;
|
||||
border: 2px dotted #e0e0e0;
|
||||
}
|
||||
.field-fileupload.is-sortable li.dragged {
|
||||
.field-fileupload.is-sortable .upload-placeholder {
|
||||
position: relative;
|
||||
border: 1px dotted #e0e0e0 !important;
|
||||
}
|
||||
.field-fileupload.is-sortable .upload-object.dragged {
|
||||
position: absolute;
|
||||
opacity: 0.5;
|
||||
filter: alpha(opacity=50);
|
||||
z-index: 2000;
|
||||
}
|
||||
.field-fileupload.is-sortable li.dragged .uploader-toolbar {
|
||||
.field-fileupload.is-sortable .upload-object.dragged .uploader-toolbar {
|
||||
display: none;
|
||||
}
|
||||
.field-fileupload .no-data {
|
||||
background: #f6f6f6;
|
||||
border: 1px solid #e0e0e0;
|
||||
color: #555555;
|
||||
font-size: 13px;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
padding: 10px;
|
||||
body:not(.no-select) .field-fileupload .upload-object:hover h4 a {
|
||||
display: block;
|
||||
}
|
||||
.form-sidebar .field-fileupload .image-multi {
|
||||
margin-right: -5px;
|
||||
body:not(.no-select) .field-fileupload .upload-object:hover .meta .drag-handle {
|
||||
display: block;
|
||||
}
|
||||
.form-sidebar .field-fileupload .image-multi ul li {
|
||||
margin-right: 5px;
|
||||
margin-bottom: 5px;
|
||||
@media (max-width: 1024px) {
|
||||
.field-fileupload .upload-object h4 a {
|
||||
display: block !important;
|
||||
}
|
||||
.field-fileupload .upload-object .meta .drag-handle {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
html:not(.touch) .image-multi ul li,
|
||||
html:not(.touch) .file-multi ul li {
|
||||
margin-right: 15px;
|
||||
.field-fileupload.style-image-multi .upload-button,
|
||||
.field-fileupload.style-image-multi .upload-object {
|
||||
margin: 0 10px 10px 0;
|
||||
}
|
||||
html:not(.touch) .field-fileupload .attachment-item .uploader-toolbar {
|
||||
top: 0;
|
||||
left: 0;
|
||||
.field-fileupload.style-image-multi .upload-button {
|
||||
width: 76px;
|
||||
height: 76px;
|
||||
}
|
||||
.field-fileupload.style-image-multi .upload-files-container {
|
||||
margin-left: 90px;
|
||||
}
|
||||
.field-fileupload.style-image-multi .upload-object {
|
||||
background: #fff;
|
||||
border: 1px solid #ecf0f1;
|
||||
width: 260px;
|
||||
}
|
||||
.field-fileupload.style-image-multi .upload-object .progress-bar {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: white;
|
||||
opacity: 0;
|
||||
filter: alpha(opacity=0);
|
||||
-webkit-transition: all 0.3s ease;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
html:not(.touch) .field-fileupload .attachment-item .uploader-toolbar a {
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
padding: 0 0 5px 6px;
|
||||
font-size: 16px;
|
||||
color: #808b93;
|
||||
margin-left: 5px;
|
||||
}
|
||||
html:not(.touch) .field-fileupload .attachment-item .uploader-toolbar a:before {
|
||||
margin-right: 0;
|
||||
}
|
||||
html:not(.touch) .field-fileupload .attachment-item .uploader-toolbar a:hover {
|
||||
color: #0181b9;
|
||||
}
|
||||
html:not(.touch) .field-fileupload .attachment-item .uploader-toolbar a.uploader-remove {
|
||||
overflow: hidden;
|
||||
height: 5px;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 2px;
|
||||
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 1px;
|
||||
font-size: 13px;
|
||||
bottom: 10px;
|
||||
left: 0;
|
||||
}
|
||||
html:not(.touch) .field-fileupload .attachment-item .uploader-toolbar a.uploader-remove:hover {
|
||||
color: #c73f26;
|
||||
.field-fileupload.style-image-multi .upload-object .progress-bar .upload-progress {
|
||||
float: left;
|
||||
width: 0%;
|
||||
height: 100%;
|
||||
line-height: 5px;
|
||||
color: #ffffff;
|
||||
background-color: #5fb6f5;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
-webkit-transition: width 0.6s ease;
|
||||
transition: width 0.6s ease;
|
||||
}
|
||||
html:not(.touch) .field-fileupload .attachment-item .uploader-toolbar a.uploader-config,
|
||||
html:not(.touch) .field-fileupload .attachment-item .uploader-toolbar a.uploader-file-link {
|
||||
display: inline-block;
|
||||
.field-fileupload.style-image-multi .upload-object .icon-container {
|
||||
border-right: 1px solid #f6f8f9;
|
||||
float: left;
|
||||
width: 75px;
|
||||
height: 75px;
|
||||
}
|
||||
html:not(.touch) .field-fileupload .attachment-item .uploader-toolbar div.controls {
|
||||
.field-fileupload.style-image-multi .upload-object .icon-container i {
|
||||
font-size: 35px;
|
||||
}
|
||||
.field-fileupload.style-image-multi .upload-object .info {
|
||||
margin-left: 90px;
|
||||
}
|
||||
.field-fileupload.style-image-multi .upload-object .info h4 {
|
||||
padding-right: 15px;
|
||||
}
|
||||
.field-fileupload.style-image-multi .upload-object .info h4 a {
|
||||
right: 15px;
|
||||
}
|
||||
.field-fileupload.style-image-multi .upload-object .meta {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 0 15px 0 90px;
|
||||
}
|
||||
html:not(.touch) .field-fileupload .attachment-item .uploader-toolbar h3,
|
||||
html:not(.touch) .field-fileupload .attachment-item .uploader-toolbar p {
|
||||
.field-fileupload.style-image-multi .upload-object .meta a.drag-handle {
|
||||
bottom: 15px;
|
||||
}
|
||||
.field-fileupload.style-image-multi .upload-object.upload-placeholder {
|
||||
height: 75px;
|
||||
background-color: transparent;
|
||||
}
|
||||
.field-fileupload.style-image-multi .upload-object.upload-placeholder:after {
|
||||
opacity: 0;
|
||||
}
|
||||
body:not(.no-select) .field-fileupload.style-image-multi .upload-object:hover {
|
||||
background: #4da7e8 !important;
|
||||
}
|
||||
body:not(.no-select) .field-fileupload.style-image-multi .upload-object:hover i,
|
||||
body:not(.no-select) .field-fileupload.style-image-multi .upload-object:hover p.size {
|
||||
color: #ecf0f1;
|
||||
}
|
||||
body:not(.no-select) .field-fileupload.style-image-multi .upload-object:hover h4 {
|
||||
color: white;
|
||||
}
|
||||
body:not(.no-select) .field-fileupload.style-image-multi .upload-object:hover .icon-container {
|
||||
border-right-color: #4da7e8 !important;
|
||||
}
|
||||
body:not(.no-select) .field-fileupload.style-image-multi .upload-object:hover h4 {
|
||||
padding-right: 35px !important;
|
||||
}
|
||||
@media (max-width: 1280px) {
|
||||
.field-fileupload.style-image-multi .upload-object {
|
||||
width: 230px;
|
||||
}
|
||||
}
|
||||
@media (max-width: 1024px) {
|
||||
.field-fileupload.style-image-multi .upload-button {
|
||||
width: 100%;
|
||||
}
|
||||
.field-fileupload.style-image-multi .upload-files-container {
|
||||
margin-left: 0;
|
||||
}
|
||||
.field-fileupload.style-image-multi .upload-object {
|
||||
margin-right: 0;
|
||||
display: block;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
.field-fileupload.style-image-single.is-populated .upload-button {
|
||||
display: none;
|
||||
}
|
||||
.field-fileupload.style-image-single .upload-object .icon-container {
|
||||
border: 1px solid #f6f8f9;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.field-fileupload.style-image-single .upload-object .progress-bar {
|
||||
display: block;
|
||||
padding: 15px 13px 0;
|
||||
color: #7e8c8d;
|
||||
margin-top: 0;
|
||||
line-height: 140%;
|
||||
}
|
||||
html:not(.touch) .field-fileupload .attachment-item .uploader-toolbar h3 {
|
||||
word-wrap: break-word;
|
||||
font-weight: 700;
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
html:not(.touch) .field-fileupload .attachment-item .uploader-toolbar p {
|
||||
font-size: 11px;
|
||||
padding-top: 0;
|
||||
white-space: normal;
|
||||
position: absolute;
|
||||
top: 35px;
|
||||
bottom: 20px;
|
||||
width: 100%;
|
||||
opacity: 0.8;
|
||||
filter: alpha(opacity=80);
|
||||
overflow: hidden;
|
||||
height: 5px;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 2px;
|
||||
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 0;
|
||||
}
|
||||
html:not(.touch) .field-fileupload .attachment-item .uploader-toolbar p abbr {
|
||||
border-bottom: none;
|
||||
.field-fileupload.style-image-single .upload-object .progress-bar .upload-progress {
|
||||
float: left;
|
||||
width: 0%;
|
||||
height: 100%;
|
||||
line-height: 5px;
|
||||
color: #ffffff;
|
||||
background-color: #5fb6f5;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
-webkit-transition: width 0.6s ease;
|
||||
transition: width 0.6s ease;
|
||||
}
|
||||
html:not(.touch) .field-fileupload .attachment-item:hover .uploader-toolbar {
|
||||
opacity: 1;
|
||||
filter: alpha(opacity=100);
|
||||
.field-fileupload.style-image-single .upload-object .meta {
|
||||
position: absolute;
|
||||
bottom: 65px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 0 15px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,147 +3,128 @@
|
|||
*
|
||||
* Data attributes:
|
||||
* - data-control="fileupload" - enables the file upload plugin
|
||||
* - data-upload-link="a.link" - reference to a trigger to open the file browser window
|
||||
* - data-upload-input="input" - a file typed html input, this input name will determine the postback variable
|
||||
* - data-loading-class="loading" - this class is added to the container when file is uploading
|
||||
* - data-progress-bar=".bar" - reference to a progress bar, it's width is modified when file is uploading
|
||||
* - data-unique-id="XXX" - an optional identifier for multiple uploaders on the same page, this value will
|
||||
* appear in the postback variable called X_OCTOBER_FILEUPLOAD
|
||||
* - data-item-template - a Mustache template to render each item with
|
||||
* - data-template - a Dropzone.js template to use for each item
|
||||
* - data-error-template - a popover template used to show an error
|
||||
* - data-sort-handler - AJAX handler for sorting postbacks
|
||||
* - data-config-handler - AJAX handler for configuration popup
|
||||
*
|
||||
* JavaScript API:
|
||||
* $('div').fileUploader()
|
||||
*
|
||||
* Dependancies:
|
||||
* - blueimp File Upload (blueimp/jQuery-File-Upload)
|
||||
* - Dropzone.js
|
||||
*/
|
||||
+function ($) { "use strict";
|
||||
|
||||
var Base = $.oc.foundation.base,
|
||||
BaseProto = Base.prototype
|
||||
|
||||
// FILEUPLOAD CLASS DEFINITION
|
||||
// ============================
|
||||
|
||||
var FileUpload = function(element, options) {
|
||||
this.options = options
|
||||
this.$el = $(element)
|
||||
this.editor = null
|
||||
this.dataCache = null
|
||||
this.locked = false
|
||||
this.dropzone = null
|
||||
var self = this
|
||||
var FileUpload = function (element, options) {
|
||||
this.$el = $(element)
|
||||
this.options = options || {}
|
||||
|
||||
/*
|
||||
* Validate requirements
|
||||
*/
|
||||
this.isMulti = this.$el.hasClass('is-multi');
|
||||
this.templateHtml = $('#' + this.options.itemTemplate).html()
|
||||
this.uploadLink = $(this.options.uploadLink, this.$el)
|
||||
$.oc.foundation.controlUtils.markDisposable(element)
|
||||
Base.call(this)
|
||||
this.init()
|
||||
}
|
||||
|
||||
FileUpload.prototype = Object.create(BaseProto)
|
||||
FileUpload.prototype.constructor = FileUpload
|
||||
|
||||
FileUpload.prototype.init = function() {
|
||||
if (this.options.isMulti === null) {
|
||||
this.options.isMulti = this.$el.hasClass('is-multi')
|
||||
}
|
||||
|
||||
this.$el.one('dispose-control', this.proxy(this.dispose))
|
||||
this.$uploadButton = $('.upload-button', this.$el)
|
||||
this.$filesContainer = $('.upload-files-container', this.$el)
|
||||
this.uploaderOptions = {}
|
||||
|
||||
this.$el.on('click', '.upload-object.is-success', this.proxy(this.onClickSuccessObject))
|
||||
this.$el.on('click', '.upload-object.is-error', this.proxy(this.onClickErrorObject))
|
||||
this.$el.on('click', '.upload-remove-button', this.proxy(this.onRemoveObject))
|
||||
|
||||
this.bindUploader()
|
||||
if (this.$el.hasClass('is-sortable')) {
|
||||
this.bindSortable()
|
||||
}
|
||||
}
|
||||
|
||||
FileUpload.prototype.dispose = function() {
|
||||
this.$el.off('click', '.upload-object.is-error', this.proxy(this.onClickErrorObject))
|
||||
this.$el.off('dispose-control', this.proxy(this.dispose))
|
||||
this.$el.removeData('oc.fileUpload')
|
||||
|
||||
this.$el = null
|
||||
this.$uploadButton = null
|
||||
this.$filesContainer = null
|
||||
this.uploaderOptions = null
|
||||
|
||||
// In some cases options could contain callbacks,
|
||||
// so it's better to clean them up too.
|
||||
this.options = null
|
||||
|
||||
BaseProto.dispose.call(this)
|
||||
}
|
||||
|
||||
//
|
||||
// Uploading
|
||||
//
|
||||
|
||||
FileUpload.prototype.bindUploader = function() {
|
||||
this.uploaderOptions = {
|
||||
url: this.options.url,
|
||||
paramName: this.options.paramName,
|
||||
clickable: this.$uploadButton.get(0),
|
||||
previewsContainer: this.$filesContainer.get(0),
|
||||
maxFiles: !this.options.isMulti ? 1 : null
|
||||
}
|
||||
|
||||
if (this.options.fileTypes) {
|
||||
this.uploaderOptions.acceptedFiles = this.options.fileTypes
|
||||
}
|
||||
|
||||
if (this.options.template) {
|
||||
this.uploaderOptions.previewTemplate = $(this.options.template).html()
|
||||
}
|
||||
|
||||
if (this.options.uniqueId) {
|
||||
this.options.extraData = $.extend({}, this.options.extraData, { X_OCTOBER_FILEUPLOAD: this.options.uniqueId })
|
||||
}
|
||||
|
||||
/*
|
||||
* Populate found images
|
||||
*/
|
||||
var populated = this.$el.data('populatedData')
|
||||
if (populated)
|
||||
$.each(populated, function(index, item){ self.renderItem(item) })
|
||||
this.dropzone = new Dropzone(this.$el.get(0), this.uploaderOptions)
|
||||
this.dropzone.on('error', this.proxy(this.onUploadFail))
|
||||
this.dropzone.on('success', this.proxy(this.onUploadComplete))
|
||||
this.dropzone.on('sending', this.proxy(this.onUploadSending))
|
||||
this.dropzone.on('addedfile', this.proxy(this.evalIsPopulated))
|
||||
}
|
||||
|
||||
/*
|
||||
* Bind the uploader
|
||||
*/
|
||||
this.bindUploader()
|
||||
FileUpload.prototype.onUploadFail = function(file, error) {
|
||||
var $preview = $(file.previewElement)
|
||||
$preview.addClass('is-error')
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the progress bar
|
||||
*/
|
||||
this.progressBar = $(this.options.progressBar, this.$el).find('>.progress-bar')
|
||||
FileUpload.prototype.onUploadComplete = function(file, response) {
|
||||
var $preview = $(file.previewElement),
|
||||
$img = $('.image img', $preview)
|
||||
|
||||
/*
|
||||
* Bind remove link
|
||||
*/
|
||||
this.$el.on('click', this.options.removeLink, function(){
|
||||
var item = $(this).closest('.attachment-item')
|
||||
$(this).on('ajaxDone', function() {
|
||||
self.removeItem(item)
|
||||
})
|
||||
self.toggleLoading(true, item)
|
||||
})
|
||||
$preview.addClass('is-success')
|
||||
|
||||
/*
|
||||
* When configuration form is saved, refresh the item
|
||||
*/
|
||||
this.$el.on('popupComplete', this.options.configLink, function(event, element, modal){
|
||||
var popupEl = $(this),
|
||||
currentItem = popupEl.closest('.attachment-item')
|
||||
|
||||
modal.on('ajaxDone', 'button[type=submit]', function(e, context, data){
|
||||
popupEl.popup('hide')
|
||||
if (data.error) alert(data.error)
|
||||
else self.renderItem(data.item, currentItem)
|
||||
self.toggleLoading(false, currentItem)
|
||||
|
||||
}).on('ajaxPromise', 'button[type=submit]', function(){
|
||||
popupEl.popup('visible', false)
|
||||
self.toggleLoading(true, currentItem)
|
||||
})
|
||||
})
|
||||
|
||||
/*
|
||||
* Sortable items
|
||||
*/
|
||||
if (this.$el.hasClass('is-sortable')) {
|
||||
var placeholderEl = $('<li class="placeholder"/>').css({
|
||||
width: this.options.imageWidth,
|
||||
height: this.options.imageHeight
|
||||
})
|
||||
|
||||
this.$el.find('ul, ol').sortable({
|
||||
itemSelector: 'li:not(.attachment-uploader)',
|
||||
vertical: false,
|
||||
tolerance: -100,
|
||||
placeholder: placeholderEl,
|
||||
onDrop: function ($item, container, _super) {
|
||||
_super($item, container)
|
||||
self.onSortAttachments()
|
||||
},
|
||||
distance: 10
|
||||
})
|
||||
if (response.id) {
|
||||
$preview.data('id', response.id)
|
||||
$('.upload-remove-button', $preview).data('request-data', { file_id: response.id })
|
||||
$img.attr('src', response.thumb)
|
||||
}
|
||||
}
|
||||
|
||||
FileUpload.prototype.bindUploader = function() {
|
||||
var self = this
|
||||
|
||||
/*
|
||||
* Build uploader options
|
||||
*/
|
||||
var uploaderOptions = {
|
||||
url: this.options.url,
|
||||
clickable: this.uploadLink.get(0),
|
||||
paramName: this.options.paramName,
|
||||
previewsContainer: $('<div />').get(0),
|
||||
maxFiles: !this.isMulti ? 1 : null,
|
||||
method: 'POST'
|
||||
}
|
||||
|
||||
if (this.options.fileTypes) {
|
||||
uploaderOptions.acceptedFiles = this.options.fileTypes
|
||||
}
|
||||
|
||||
/*
|
||||
* Bind uploader
|
||||
*/
|
||||
this.dropzone = new Dropzone(this.$el.get(0), uploaderOptions)
|
||||
this.dropzone.on('error', $.proxy(self.onUploadFail, self))
|
||||
this.dropzone.on('success', $.proxy(self.onUploadComplete, self))
|
||||
this.dropzone.on('uploadprogress', $.proxy(self.onUploadProgress, self))
|
||||
this.dropzone.on('thumbnail', $.proxy(self.onUploadThumbnail, self))
|
||||
this.dropzone.on('sending', function(file, xhr, formData) {
|
||||
self.addExtraFormData(formData)
|
||||
self.onUploadStart()
|
||||
})
|
||||
|
||||
FileUpload.prototype.onUploadSending = function(file, xhr, formData) {
|
||||
this.addExtraFormData(formData)
|
||||
}
|
||||
|
||||
FileUpload.prototype.addExtraFormData = function(formData) {
|
||||
|
|
@ -161,44 +142,30 @@
|
|||
}
|
||||
}
|
||||
|
||||
FileUpload.prototype.removeItem = function(item) {
|
||||
if (this.isMulti) {
|
||||
item.closest('li').fadeOut(500, function(){
|
||||
item.remove()
|
||||
//
|
||||
// Sorting
|
||||
//
|
||||
|
||||
FileUpload.prototype.bindSortable = function() {
|
||||
var
|
||||
self = this,
|
||||
placeholderEl = $('<div class="upload-object upload-placeholder"/>').css({
|
||||
width: this.options.imageWidth,
|
||||
height: this.options.imageHeight
|
||||
})
|
||||
}
|
||||
else {
|
||||
item.find('.active-image, .active-file, .uploader-toolbar').remove()
|
||||
this.uploadLink.show()
|
||||
this.toggleLoading(false, item)
|
||||
|
||||
// Reset the file counter
|
||||
this.dropzone.removeAllFiles()
|
||||
}
|
||||
}
|
||||
|
||||
FileUpload.prototype.renderItem = function(item, replaceItem) {
|
||||
|
||||
var newItem = $(Mustache.to_html(this.templateHtml, item))
|
||||
|
||||
if (this.isMulti) {
|
||||
if (replaceItem)
|
||||
replaceItem.closest('li').replaceWith(newItem)
|
||||
else
|
||||
this.uploadLink.closest('li').before(newItem)
|
||||
|
||||
$('p', newItem).ellipsis()
|
||||
return newItem
|
||||
}
|
||||
else {
|
||||
if (replaceItem)
|
||||
this.removeItem(replaceItem)
|
||||
|
||||
this.uploadLink.hide().before(newItem)
|
||||
|
||||
$('p', newItem).ellipsis()
|
||||
return newItem.closest('.attachment-item')
|
||||
}
|
||||
this.$filesContainer.sortable({
|
||||
itemSelector: 'div.upload-object.is-success',
|
||||
nested: false,
|
||||
tolerance: -100,
|
||||
placeholder: placeholderEl,
|
||||
handle: '.drag-handle',
|
||||
onDrop: function ($item, container, _super) {
|
||||
_super($item, container)
|
||||
self.onSortAttachments()
|
||||
},
|
||||
distance: 10
|
||||
})
|
||||
}
|
||||
|
||||
FileUpload.prototype.onSortAttachments = function() {
|
||||
|
|
@ -209,9 +176,9 @@
|
|||
*/
|
||||
var orderData = {}
|
||||
|
||||
this.$el.find('.attachment-item:not(.attachment-uploader)')
|
||||
this.$el.find('.upload-object.is-success')
|
||||
.each(function(index){
|
||||
var id = $(this).data('attachment-id')
|
||||
var id = $(this).data('id')
|
||||
orderData[id] = index + 1
|
||||
})
|
||||
|
||||
|
|
@ -221,83 +188,89 @@
|
|||
}
|
||||
}
|
||||
|
||||
FileUpload.prototype.onUploadStart = function() {
|
||||
this.locked = true
|
||||
this.toggleLoading(true, this.progressBar.closest('.attachment-item'))
|
||||
//
|
||||
// User interaction
|
||||
//
|
||||
|
||||
this.options.onStart && this.options.onStart()
|
||||
FileUpload.prototype.onRemoveObject = function(ev) {
|
||||
var self = this,
|
||||
$object = $(ev.target).closest('.upload-object')
|
||||
|
||||
$(ev.target)
|
||||
.closest('.upload-remove-button')
|
||||
.one('ajaxPromise', function(){
|
||||
$object.removeClass('is-success')
|
||||
})
|
||||
.one('ajaxDone', function(){
|
||||
$object.remove()
|
||||
self.evalIsPopulated()
|
||||
})
|
||||
.request()
|
||||
|
||||
ev.stopPropagation()
|
||||
}
|
||||
|
||||
FileUpload.prototype.onUploadThumbnail = function(file, thumbUrl) {
|
||||
// Provides a thumbnail preview, could be useful
|
||||
// but not used at this point in time.
|
||||
FileUpload.prototype.onClickSuccessObject = function(ev) {
|
||||
var $target = $(ev.target).closest('.upload-object')
|
||||
|
||||
$target.popup({
|
||||
handler: this.options.configHandler,
|
||||
extraData: { file_id: $target.data('id') }
|
||||
})
|
||||
|
||||
$target.one('popupComplete', function(event, element, modal){
|
||||
|
||||
modal.one('ajaxDone', 'button[type=submit]', function(e, context, data) {
|
||||
if (data.displayName) {
|
||||
$('[data-dz-name]', $target).text(data.displayName)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
FileUpload.prototype.onUploadComplete = function(file, data) {
|
||||
if (data.error)
|
||||
return this.onUploadFail(null, data.error)
|
||||
FileUpload.prototype.onClickErrorObject = function(ev) {
|
||||
var
|
||||
self = this,
|
||||
$target = $(ev.target).closest('.upload-object'),
|
||||
errorMsg = $('[data-dz-errormessage]', $target).text(),
|
||||
$template = $(this.options.errorTemplate)
|
||||
|
||||
this.options.onComplete && this.options.onComplete()
|
||||
$target.ocPopover({
|
||||
content: Mustache.render($template.html(), { errorMsg: errorMsg }),
|
||||
modal: true,
|
||||
highlightModalTarget: true,
|
||||
placement: 'top',
|
||||
fallbackPlacement: 'left',
|
||||
containerClass: 'popover-danger'
|
||||
})
|
||||
|
||||
var newItem = this.renderItem(data)
|
||||
|
||||
newItem.css({ opacity: 0 })
|
||||
.animate({ opacity: 1}, 500)
|
||||
|
||||
this.resetAll()
|
||||
var $container = $target.data('oc.popover').$container
|
||||
$container.one('click', '[data-remove-file]', function() {
|
||||
$target.data('oc.popover').hide()
|
||||
$target.remove()
|
||||
self.evalIsPopulated()
|
||||
})
|
||||
}
|
||||
|
||||
FileUpload.prototype.onUploadFail = function(file, error) {
|
||||
alert('Error uploading file: ' + error)
|
||||
this.options.onFail && this.options.onFail()
|
||||
this.resetAll()
|
||||
}
|
||||
//
|
||||
// Helpers
|
||||
//
|
||||
|
||||
FileUpload.prototype.onUploadProgress = function(file, progress, bytesSent) {
|
||||
this.progressBar.css('width', progress + '%')
|
||||
}
|
||||
|
||||
FileUpload.prototype.resetAll = function() {
|
||||
this.toggleLoading(false, this.progressBar.closest('.attachment-item'))
|
||||
this.locked = false
|
||||
}
|
||||
|
||||
FileUpload.prototype.toggleLoading = function(isLoading, el) {
|
||||
var self = this
|
||||
|
||||
if (!this.options.loadingClass)
|
||||
return
|
||||
|
||||
if (!el)
|
||||
el = this.$el
|
||||
|
||||
if (isLoading) {
|
||||
el.addClass(this.options.loadingClass)
|
||||
} else {
|
||||
el.removeClass(this.options.loadingClass)
|
||||
}
|
||||
|
||||
this.progressBar.css('width', '0')
|
||||
FileUpload.prototype.evalIsPopulated = function() {
|
||||
this.$el.toggleClass('is-populated', !!$('.upload-object', this.$filesContainer).length)
|
||||
}
|
||||
|
||||
FileUpload.DEFAULTS = {
|
||||
url: window.location,
|
||||
configHandler: null,
|
||||
sortHandler: null,
|
||||
uniqueId: null,
|
||||
extraData: {},
|
||||
sortHandler: null,
|
||||
loadingClass: 'loading',
|
||||
removeLink: '.uploader-remove',
|
||||
uploadLink: '.uploader-link',
|
||||
configLink: '.uploader-config',
|
||||
progressBar: '.uploader-progress',
|
||||
onComplete: null,
|
||||
onStart: null,
|
||||
onFail: null,
|
||||
imageWidth: 100,
|
||||
imageHeight: 100,
|
||||
paramName: 'file_data',
|
||||
fileTypes: null,
|
||||
itemTemplate: null,
|
||||
paramName: 'file_data'
|
||||
template: null,
|
||||
errorTemplate: null,
|
||||
isMulti: null
|
||||
}
|
||||
|
||||
// FILEUPLOAD PLUGIN DEFINITION
|
||||
|
|
|
|||
|
|
@ -0,0 +1,319 @@
|
|||
.uploader-object-active() {
|
||||
background: @fileupload-object-active-bg !important;
|
||||
|
||||
i, p.size {
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
h4 {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.icon-container {
|
||||
border-right-color: @fileupload-object-active-bg !important;
|
||||
}
|
||||
}
|
||||
|
||||
.uploader-progress-bar() {
|
||||
display: block;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
height: @fileupload-progress-bar-height;
|
||||
background-color: @fileupload-progress-bar-bg;
|
||||
border-radius: @border-radius-base;
|
||||
.box-shadow(inset 0 1px 2px rgba(0,0,0,.1));
|
||||
|
||||
.upload-progress {
|
||||
float: left;
|
||||
width: 0%;
|
||||
height: 100%;
|
||||
line-height: @fileupload-progress-bar-height;
|
||||
color: @fileupload-progress-bar-color;
|
||||
background-color: #5fb6f5;
|
||||
.box-shadow(none);
|
||||
.transition(width .6s ease);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Shared
|
||||
//
|
||||
|
||||
.field-fileupload {
|
||||
|
||||
//
|
||||
// Upload button
|
||||
//
|
||||
|
||||
.upload-button {
|
||||
display: block;
|
||||
float: left;
|
||||
border: 2px dotted rgba(0,0,0,.1);
|
||||
position: relative;
|
||||
outline: none;
|
||||
table {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table td {
|
||||
line-height: 16px;
|
||||
font-size: 11px;
|
||||
vertical-align: middle;
|
||||
height: 100%;
|
||||
|
||||
&:before {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
display: block;
|
||||
font-size: 22px;
|
||||
color: rgba(0,0,0,.1);
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
span {
|
||||
display: block;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border: 2px dotted rgba(0,0,0,.2);
|
||||
|
||||
table td:before {
|
||||
color: @brand-success;
|
||||
color: rgba(0,0,0,.2);
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border: 2px solid rgba(0,0,0,.3);
|
||||
background: transparent;
|
||||
|
||||
table td:before {
|
||||
color: @brand-success;
|
||||
color: rgba(0,0,0,.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Uploaded item
|
||||
//
|
||||
|
||||
.upload-object {
|
||||
|
||||
.border-radius(3px);
|
||||
position: relative;
|
||||
outline: none;
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.icon-container {
|
||||
display: table;
|
||||
opacity: .6;
|
||||
|
||||
i {
|
||||
color: #95a5a6;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
div {
|
||||
display: table-cell;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-container.image {
|
||||
> div.icon-wrapper {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
color: #2b3e50;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
line-height: 150%;
|
||||
margin: 15px 0 5px 0;
|
||||
padding-right: 0;
|
||||
.transition(padding 0.1s);
|
||||
|
||||
position: relative;
|
||||
|
||||
a {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
p.size {
|
||||
font-size: 12px;
|
||||
color: #95a5a6;
|
||||
strong { font-weight: 400; }
|
||||
}
|
||||
|
||||
.meta {
|
||||
.drag-handle {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
cursor: move;
|
||||
}
|
||||
}
|
||||
|
||||
.info h4 a,
|
||||
.meta a.drag-handle {
|
||||
color: #2b3e50;
|
||||
display: none;
|
||||
font-size: 15px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Loading State
|
||||
//
|
||||
|
||||
.upload-object {
|
||||
.icon-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.icon-container:after {
|
||||
background-image: url('../../../../../system/assets/ui/images/loader-transparent.svg');
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
margin-top: -20px;
|
||||
margin-left: -20px;
|
||||
display: block;
|
||||
background-size: 40px 40px;
|
||||
background-position: 50% 50%;
|
||||
.animation(spin 1s linear infinite);
|
||||
}
|
||||
|
||||
&.is-success {
|
||||
.icon-container:after {
|
||||
opacity: 0;
|
||||
.transition(opacity .3s ease);
|
||||
}
|
||||
}
|
||||
|
||||
// Replaces the loader with an error symbol
|
||||
&.is-error {
|
||||
.icon-container:after {
|
||||
content: "";
|
||||
background: none;
|
||||
.icon(@exclamation-triangle);
|
||||
.animation(none);
|
||||
font-size: 40px;
|
||||
color: #ab2a1c;
|
||||
margin-top: -30px;
|
||||
margin-left: -20px;
|
||||
text-shadow: 2px 2px 0 #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Success state
|
||||
//
|
||||
|
||||
.upload-object.is-success {
|
||||
cursor: pointer;
|
||||
.icon-container {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
opacity: 0;
|
||||
.transition(opacity .3s ease);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Error State
|
||||
//
|
||||
|
||||
.upload-object.is-error {
|
||||
cursor: pointer;
|
||||
|
||||
.icon-container {
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.info h4 {
|
||||
color: #ab2a1c;
|
||||
a {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.meta {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Sortable
|
||||
//
|
||||
|
||||
&.is-sortable {
|
||||
position: relative;
|
||||
|
||||
.upload-placeholder {
|
||||
position: relative;
|
||||
border: 1px dotted #e0e0e0 !important;
|
||||
}
|
||||
|
||||
.upload-object.dragged {
|
||||
position: absolute;
|
||||
.opacity(.5);
|
||||
z-index: 2000;
|
||||
.uploader-toolbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Media
|
||||
//
|
||||
|
||||
body:not(.no-select) {
|
||||
.field-fileupload {
|
||||
.upload-object:hover {
|
||||
h4 a { display: block; }
|
||||
.meta .drag-handle { display: block; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.field-fileupload {
|
||||
.upload-object {
|
||||
h4 a { display: block !important; }
|
||||
.meta .drag-handle { display: block !important; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
//
|
||||
// Multi Image
|
||||
//
|
||||
|
||||
.field-fileupload.style-image-multi {
|
||||
.upload-button,
|
||||
.upload-object {
|
||||
margin: 0 10px 10px 0;
|
||||
}
|
||||
|
||||
.upload-button {
|
||||
width: 76px;
|
||||
height: 76px;
|
||||
}
|
||||
|
||||
.upload-files-container {
|
||||
margin-left: 90px;
|
||||
}
|
||||
|
||||
.upload-object {
|
||||
background: #fff;
|
||||
border: 1px solid #ecf0f1;
|
||||
width: 260px;
|
||||
|
||||
.progress-bar {
|
||||
.uploader-progress-bar();
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.icon-container {
|
||||
border-right: 1px solid #f6f8f9;
|
||||
float: left;
|
||||
width: 75px;
|
||||
height: 75px;
|
||||
|
||||
i {
|
||||
font-size: 35px;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
margin-left: 90px;
|
||||
|
||||
h4 {
|
||||
padding-right: 15px;
|
||||
a {
|
||||
right: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.meta {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 0 15px 0 90px;
|
||||
|
||||
a.drag-handle {
|
||||
bottom: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
&.upload-placeholder {
|
||||
height: 75px;
|
||||
background-color: transparent;
|
||||
&:after { opacity: 0; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Media
|
||||
//
|
||||
|
||||
body:not(.no-select) {
|
||||
.field-fileupload.style-image-multi {
|
||||
.upload-object:hover {
|
||||
.uploader-object-active();
|
||||
h4 { padding-right: 35px !important; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1280px) {
|
||||
.field-fileupload.style-image-multi {
|
||||
.upload-object {
|
||||
width: 230px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.field-fileupload.style-image-multi {
|
||||
.upload-button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.upload-files-container {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.upload-object {
|
||||
margin-right: 0;
|
||||
display: block;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// Single Image
|
||||
//
|
||||
|
||||
.field-fileupload.style-image-single {
|
||||
&.is-populated {
|
||||
.upload-button {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.upload-object {
|
||||
.icon-container {
|
||||
border: 1px solid #f6f8f9;
|
||||
background: rgba(255,255,255,.5);
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
.uploader-progress-bar();
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.meta {
|
||||
position: absolute;
|
||||
bottom: 65px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 0 15px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,367 +1,11 @@
|
|||
@import "../../../../assets/less/core/boot.less";
|
||||
|
||||
@fileupload-progress-bar-height: 5px;
|
||||
@fileupload-progress-bar-color: #fff;
|
||||
@fileupload-progress-bar-bg: #f5f5f5;
|
||||
@fileupload-inactive-icon: #808b93;
|
||||
@fileupload-object-active-bg: #4da7e8;
|
||||
|
||||
.field-fileupload {
|
||||
|
||||
.attachment-input {
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
width: 10px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.attachment-item {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.image-multi, .file-multi {
|
||||
ul {
|
||||
padding: 0; margin: 0;
|
||||
.clearfix;
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
float: left;
|
||||
margin-right: 35px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.file-multi .attachment-item, .file-single.attachment-item {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.active-image, .active-file {
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border: 1px solid #e0e0e0;
|
||||
background: white;
|
||||
position: relative;
|
||||
outline: none;
|
||||
overflow: hidden;
|
||||
padding: 5px;
|
||||
|
||||
.caption {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
font-size: 11px;
|
||||
background: rgba(0,0,0,.05);
|
||||
color: #999;
|
||||
padding: 2px 5px;
|
||||
width: 100%;
|
||||
.text-overflow();
|
||||
}
|
||||
}
|
||||
|
||||
.active-image {
|
||||
img { width: 100%; height: 100%; }
|
||||
}
|
||||
|
||||
.active-file {
|
||||
padding: 0;
|
||||
.file-icon {
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
i {
|
||||
font-size: 64px;
|
||||
color: #444;
|
||||
}
|
||||
b {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 10px;
|
||||
color: #FFF;
|
||||
display: block;
|
||||
width: 100%;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
text-align: center;
|
||||
text-indent: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.uploader-toolbar {
|
||||
.transition(opacity .2s);
|
||||
height: 100%;
|
||||
background: #e0e0e0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -20px;
|
||||
width: 20px;
|
||||
|
||||
h3, p {
|
||||
display: none;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
padding: 3px 0 0 7px;
|
||||
color: #999;
|
||||
font-size: 15px;
|
||||
margin-left: -4px;
|
||||
text-align: center;
|
||||
&:hover { color: #666; }
|
||||
|
||||
&.uploader-file-link {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-attachment {
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border: 2px dotted #e0e0e0;
|
||||
position: relative;
|
||||
outline: none;
|
||||
table {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table td {
|
||||
line-height: 16px;
|
||||
font-size: 11px;
|
||||
vertical-align: middle;
|
||||
height: 100%;
|
||||
|
||||
&:before {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
display: block;
|
||||
font-size: 22px;
|
||||
color: rgba(0,0,0,.1);
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
span {
|
||||
display: block;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
/*background: #ffffdd;*/
|
||||
border: 2px dotted rgba(0,0,0,.1);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border: 2px solid #ccc;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.uploader-progress {
|
||||
position: relative;
|
||||
top: -(@fileupload-progress-bar-height + 2);
|
||||
}
|
||||
|
||||
//
|
||||
// Loading
|
||||
//
|
||||
|
||||
.uploader-progress {
|
||||
margin: 0 2px;
|
||||
visibility: hidden;
|
||||
overflow: hidden;
|
||||
height: @fileupload-progress-bar-height;
|
||||
margin-bottom: @line-height-computed;
|
||||
background-color: @progress-bg;
|
||||
border-radius: @border-radius-base;
|
||||
.box-shadow(inset 0 1px 2px rgba(0,0,0,.1));
|
||||
.progress-bar {
|
||||
line-height: @fileupload-progress-bar-height;
|
||||
color: @progress-bar-color;
|
||||
background-color: #ccc;
|
||||
.box-shadow(none);
|
||||
}
|
||||
}
|
||||
|
||||
.loading {
|
||||
img, .file-icon {
|
||||
.opacity(.5);
|
||||
}
|
||||
.uploader-loading {
|
||||
background-image: url(../../../../assets/images/loader-transparent.svg);
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
margin-top: -(20px + @fileupload-progress-bar-height / 2);
|
||||
margin-left: -20px;
|
||||
display: block;
|
||||
background-size: 40px 40px;
|
||||
background-position: 50% 50%;
|
||||
.animation(spin 1s linear infinite);
|
||||
}
|
||||
.no-attachment {
|
||||
cursor: default;
|
||||
border: 2px solid #ccc;
|
||||
table td:before { display: none; }
|
||||
}
|
||||
.uploader-progress {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Sortable
|
||||
//
|
||||
|
||||
&.is-sortable {
|
||||
|
||||
li.placeholder {
|
||||
position: relative;
|
||||
border: 2px dotted #e0e0e0;
|
||||
}
|
||||
|
||||
li.dragged {
|
||||
position: absolute;
|
||||
.opacity(.5);
|
||||
z-index: 2000;
|
||||
.uploader-toolbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-data {
|
||||
background: #f6f6f6;
|
||||
border: 1px solid #e0e0e0;
|
||||
color: #555555;
|
||||
font-size: 13px;
|
||||
.box-sizing(border-box);
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.form-sidebar {
|
||||
.field-fileupload {
|
||||
.image-multi {
|
||||
margin-right: -5px;
|
||||
ul li {
|
||||
margin-right: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Desktop Friendly
|
||||
//
|
||||
|
||||
html:not(.touch) {
|
||||
|
||||
.image-multi, .file-multi {
|
||||
ul li { margin-right: 15px; }
|
||||
}
|
||||
|
||||
.field-fileupload {
|
||||
.attachment-item {
|
||||
.uploader-toolbar {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: white;
|
||||
.opacity(0);
|
||||
.transition(all .3s ease);
|
||||
|
||||
a {
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
padding: 0 0 5px 6px;
|
||||
font-size: 16px;
|
||||
color: @fileupload-inactive-icon;
|
||||
margin-left: 5px;
|
||||
|
||||
&:before {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #0181b9;
|
||||
}
|
||||
|
||||
&.uploader-remove {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 1px;
|
||||
font-size: 13px;
|
||||
|
||||
&:hover {
|
||||
color: #c73f26;
|
||||
}
|
||||
}
|
||||
|
||||
&.uploader-config,
|
||||
&.uploader-file-link {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
div.controls {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
h3, p {
|
||||
display: block;
|
||||
padding: 15px 13px 0;
|
||||
color: #7e8c8d;
|
||||
margin-top: 0;
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
h3 {
|
||||
word-wrap: break-word;
|
||||
font-weight: 700;
|
||||
font-size: 12px;
|
||||
.text-overflow();
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 11px;
|
||||
padding-top: 0;
|
||||
white-space: normal;
|
||||
position: absolute;
|
||||
top: 35px;
|
||||
bottom: 20px;
|
||||
width: 100%;
|
||||
.opacity(0.8);
|
||||
|
||||
abbr {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.uploader-toolbar {
|
||||
.opacity(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@import "fileupload.base.less";
|
||||
@import "fileupload.imagemulti.less";
|
||||
@import "fileupload.imagesingle.less";
|
||||
|
|
|
|||
|
|
@ -2,24 +2,32 @@
|
|||
<input type="hidden" name="file_id" value="<?= $file->id ?>" />
|
||||
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="popup">×</button>
|
||||
<h4 class="modal-title"><?= e(trans('backend::lang.fileupload.attachment')) ?>: <?= $file->file_name ?></h4>
|
||||
<!--<button type="button" class="close" data-dismiss="popup">×</button>-->
|
||||
<a href="<?= $file->path ?>" target="_blank">
|
||||
<img
|
||||
src="<?= $file->path ?>"
|
||||
class="img-responsive center-block"
|
||||
alt=""
|
||||
title="<?= e(trans('backend::lang.fileupload.attachment')) ?>: <?= e($file->file_name) ?>" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p><?= e(trans('backend::lang.fileupload.help')) ?></p>
|
||||
|
||||
<div class="form-group">
|
||||
<label><?= e(trans('backend::lang.fileupload.title_label')) ?></label>
|
||||
<input
|
||||
type="text"
|
||||
name="title"
|
||||
class="form-control"
|
||||
value="<?= $file->title ?>"
|
||||
placeholder="<?= e(trans('backend::lang.fileupload.title_label')) ?>"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><?= e(trans('backend::lang.fileupload.description_label')) ?></label>
|
||||
<textarea name="description" class="form-control"><?= $file->description ?></textarea>
|
||||
<textarea
|
||||
name="description"
|
||||
placeholder="<?= e(trans('backend::lang.fileupload.description_label')) ?>"
|
||||
class="form-control"><?= $file->description ?></textarea>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -28,9 +36,9 @@
|
|||
type="submit"
|
||||
class="btn btn-primary"
|
||||
data-request="<?= $this->getEventHandler('onSaveAttachmentConfig') ?>"
|
||||
data-stripe-load-indicator>
|
||||
data-popup-load-indicator>
|
||||
<?= e(trans('backend::lang.form.save')) ?>
|
||||
</button>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-default"
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
<div id="<?= $this->getId('container') ?>">
|
||||
<?= $this->makePartial('fileupload') ?>
|
||||
</div>
|
||||
|
|
@ -1,83 +1,81 @@
|
|||
<div
|
||||
id="<?= $this->getId() ?>"
|
||||
class="field-fileupload is-multi <?= count($fileList) ? 'has-attachments' : '' ?> is-sortable"
|
||||
class="field-fileupload style-image-multi is-sortable is-multi"
|
||||
data-control="fileupload"
|
||||
data-unique-id="<?= $this->getId() ?>"
|
||||
data-template="#<?= $this->getId('template') ?>"
|
||||
data-error-template="#<?= $this->getId('errorTemplate') ?>"
|
||||
data-sort-handler="<?= $this->getEventHandler('onSortAttachments') ?>"
|
||||
data-image-width="<?= $imageWidth ?>"
|
||||
data-image-height="<?= $imageHeight ?>"
|
||||
<?php if ($acceptedFileTypes): ?>data-file-types="<?= $acceptedFileTypes ?>"<?php endif ?>
|
||||
data-item-template="<?= $this->getId('template') ?>">
|
||||
data-config-handler="<?= $this->getEventHandler('onLoadAttachmentConfig') ?>"
|
||||
data-unique-id="<?= $this->getId() ?>"
|
||||
<?php if ($acceptedFileTypes): ?>data-file-types="<?= $acceptedFileTypes ?>"<?php endif ?>>
|
||||
|
||||
<div class="image-multi">
|
||||
<ul>
|
||||
<!-- Add New Image -->
|
||||
<li class="attachment-item attachment-uploader <?php if ($this->previewMode): ?>hidden<?php endif ?>" style="width: <?= $imageWidth.'px' ?>; height: <?= $imageHeight.'px' ?>">
|
||||
<a href="javascript:;" class="uploader-link no-attachment">
|
||||
<table><tr><td class="oc-<?= $emptyIcon ?>"></td></tr></table>
|
||||
</a>
|
||||
<!-- Upload Button -->
|
||||
<a href="javascript:;" class="upload-button">
|
||||
<table><tr><td class="oc-<?= $emptyIcon ?>"></td></tr></table>
|
||||
</a>
|
||||
|
||||
<div class="uploader-progress">
|
||||
<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
<!-- Existing files -->
|
||||
<div class="upload-files-container">
|
||||
<?php foreach ($fileList as $file): ?>
|
||||
<div class="upload-object is-success" data-id="<?= $file->id ?>">
|
||||
<div class="icon-container image">
|
||||
<img src="<?= $file->thumb ?>" />
|
||||
</div>
|
||||
<div class="uploader-loading"></div>
|
||||
</li>
|
||||
</ul>
|
||||
<?php if ($this->previewMode && !count($fileList)): ?>
|
||||
<div class="no-data" style="height: <?= $imageHeight.'px' ?>"><?= e(trans($this->previewNoFilesMessage)) ?></div>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
|
||||
<!-- Populated Image -->
|
||||
<script type="text/template" id="<?= $this->getId('template') ?>">
|
||||
<li>
|
||||
<div
|
||||
class="attachment-item"
|
||||
data-attachment-id="{{id}}"
|
||||
style="width: <?= $imageWidth.'px' ?>; height: <?= $imageHeight.'px' ?>">
|
||||
|
||||
<a href="{{path}}" target="_blank" class="active-image">
|
||||
<img src="{{thumb}}" alt="" class="attachment-image" />
|
||||
</a>
|
||||
<div class="uploader-toolbar">
|
||||
<h3>
|
||||
<abbr title="{{#title}}{{title}}{{/title}}{{^title}}{{file_name}}{{/title}}">
|
||||
{{#title}}{{title}}{{/title}}{{^title}}{{file_name}}{{/title}}
|
||||
</abbr>
|
||||
</h3>
|
||||
{{#description}}
|
||||
<p><abbr title="{{description}}">{{description}}</abbr></p>
|
||||
{{/description}}
|
||||
|
||||
<?php if (!$this->previewMode): ?>
|
||||
<div class="info">
|
||||
<h4 class="filename">
|
||||
<span data-dz-name><?= $file->title ?: $file->disk_name ?></span>
|
||||
<a
|
||||
href="javascript:;"
|
||||
class="uploader-remove oc-icon-times"
|
||||
class="upload-remove-button"
|
||||
data-request="<?= $this->getEventHandler('onRemoveAttachment') ?>"
|
||||
data-request-data="file_id: {{id}}"></a>
|
||||
<?php endif ?>
|
||||
|
||||
<div class="controls">
|
||||
<?php if (!$this->previewMode): ?>
|
||||
<a
|
||||
href="javascript:;"
|
||||
class="uploader-config oc-icon-cog"
|
||||
data-control="popup"
|
||||
data-handler="<?= $this->getEventHandler('onLoadAttachmentConfig') ?>"
|
||||
data-request-data="file_id: {{id}}"></a>
|
||||
<?php endif ?>
|
||||
|
||||
<a
|
||||
href="{{path}}"
|
||||
class="uploader-file-link oc-icon-paperclip"
|
||||
target="_blank"></a>
|
||||
</div>
|
||||
data-request-confirm="Are you sure?"
|
||||
data-request-data="file_id: <?= $file->id ?>"
|
||||
><i class="icon-times"></i></a>
|
||||
</h4>
|
||||
<p class="size"><?= e($file->sizeToString()) ?></p>
|
||||
</div>
|
||||
<div class="meta">
|
||||
<a href="javascript:;" class="drag-handle"><i class="icon-bars"></i></a>
|
||||
</div>
|
||||
<div class="uploader-loading"></div>
|
||||
</div>
|
||||
</li>
|
||||
</script>
|
||||
|
||||
<!-- Existing images -->
|
||||
<script> $('#<?= $this->getId() ?>').data('populatedData', <?= $fileList ?>); </script>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Template for new files -->
|
||||
<script type="text/template" id="<?= $this->getId('template') ?>">
|
||||
<div class="upload-object dz-preview dz-file-preview">
|
||||
<div class="icon-container image">
|
||||
<img data-dz-thumbnail />
|
||||
</div>
|
||||
<div class="info">
|
||||
<h4 class="filename">
|
||||
<span data-dz-name></span>
|
||||
<a
|
||||
href="javascript:;"
|
||||
class="upload-remove-button"
|
||||
data-request="<?= $this->getEventHandler('onRemoveAttachment') ?>"
|
||||
data-request-confirm="Are you sure?"
|
||||
><i class="icon-times"></i></a>
|
||||
</h4>
|
||||
<p class="size" data-dz-size></p>
|
||||
</div>
|
||||
<div class="meta">
|
||||
<a href="javascript:;" class="drag-handle"><i class="icon-bars"></i></a>
|
||||
<div class="progress-bar"><span class="upload-progress" data-dz-uploadprogress></span></div>
|
||||
<div class="error-message"><span data-dz-errormessage></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<!-- Error template -->
|
||||
<script type="text/template" id="<?= $this->getId('errorTemplate') ?>">
|
||||
<div class="popover-head">
|
||||
<h3>Upload error</h3>
|
||||
<p>{{errorMsg}}</p>
|
||||
<button type="button" class="close" data-dismiss="popover" aria-hidden="true">×</button>
|
||||
</div>
|
||||
<div class="popover-body">
|
||||
<button class="btn btn-danger" data-remove-file>Remove file</button>
|
||||
</div>
|
||||
</script>
|
||||
|
|
@ -1,75 +1,81 @@
|
|||
<div
|
||||
id="<?= $this->getId() ?>"
|
||||
class="field-fileupload <?= $singleFile ? 'has-attachments' : '' ?>"
|
||||
class="field-fileupload style-image-single <?= $singleFile ? 'is-populated' : '' ?>"
|
||||
data-control="fileupload"
|
||||
data-template="#<?= $this->getId('template') ?>"
|
||||
data-error-template="#<?= $this->getId('errorTemplate') ?>"
|
||||
data-config-handler="<?= $this->getEventHandler('onLoadAttachmentConfig') ?>"
|
||||
data-unique-id="<?= $this->getId() ?>"
|
||||
data-image-width="<?= $imageWidth ?>"
|
||||
data-image-height="<?= $imageHeight ?>"
|
||||
<?php if ($acceptedFileTypes): ?>data-file-types="<?= $acceptedFileTypes ?>"<?php endif ?>
|
||||
data-item-template="<?= $this->getId('template') ?>">
|
||||
<?php if ($acceptedFileTypes): ?>data-file-types="<?= $acceptedFileTypes ?>"<?php endif ?>>
|
||||
|
||||
<div
|
||||
class="image-single attachment-item"
|
||||
data-attachment-id="<?= $singleFile ? $singleFile->id : '' ?>"
|
||||
style="width: <?= $imageWidth.'px' ?>; height: <?= $imageHeight.'px' ?>">
|
||||
<!-- Add New Image -->
|
||||
<a
|
||||
href="javascript:;"
|
||||
style="<?= $cssDimensions ?>"
|
||||
class="upload-button">
|
||||
<table><tr><td class="oc-<?= $emptyIcon ?>"></td></tr></table>
|
||||
</a>
|
||||
|
||||
<!-- Add New Image -->
|
||||
<a
|
||||
href="javascript:;"
|
||||
class="uploader-link no-attachment"
|
||||
<?php if ($singleFile): ?>style="display:none"<?php endif ?>>
|
||||
<table><tr><td class="oc-<?= $emptyIcon ?>"></td></tr></table>
|
||||
</a>
|
||||
|
||||
<div class="uploader-progress">
|
||||
<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
<div class="uploader-loading"></div>
|
||||
<!-- Existing file -->
|
||||
<div class="upload-files-container">
|
||||
<?php if ($singleFile): ?>
|
||||
<div class="upload-object is-success" data-id="<?= $singleFile->id ?>">
|
||||
<div class="icon-container image">
|
||||
<img src="<?= $singleFile->thumb ?>" />
|
||||
</div>
|
||||
<div class="info">
|
||||
<h4 class="filename">
|
||||
<span data-dz-name><?= $singleFile->title ?: $singleFile->disk_name ?></span>
|
||||
<a
|
||||
href="javascript:;"
|
||||
class="upload-remove-button"
|
||||
data-request="<?= $this->getEventHandler('onRemoveAttachment') ?>"
|
||||
data-request-confirm="Are you sure?"
|
||||
data-request-data="file_id: <?= $singleFile->id ?>"
|
||||
><i class="icon-times"></i></a>
|
||||
</h4>
|
||||
<p class="size"><?= e($singleFile->sizeToString()) ?></p>
|
||||
</div>
|
||||
<div class="meta"></div>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
|
||||
<!-- Populated Image -->
|
||||
<script type="text/template" id="<?= $this->getId('template') ?>">
|
||||
</div>
|
||||
|
||||
<a href="{{path}}" target="_blank" class="active-image">
|
||||
<img src="{{thumb}}" alt="" class="attachment-image" />
|
||||
</a>
|
||||
<div class="uploader-toolbar">
|
||||
<h3>
|
||||
<abbr title="{{#title}}{{title}}{{/title}}{{^title}}{{file_name}}{{/title}}">
|
||||
{{#title}}{{title}}{{/title}}{{^title}}{{file_name}}{{/title}}
|
||||
</abbr>
|
||||
</h3>
|
||||
{{#description}}
|
||||
<p><abbr title="{{description}}">{{description}}</abbr></p>
|
||||
{{/description}}
|
||||
|
||||
<?php if (!$this->previewMode): ?>
|
||||
<!-- Template for new file -->
|
||||
<script type="text/template" id="<?= $this->getId('template') ?>">
|
||||
<div class="upload-object dz-preview dz-file-preview">
|
||||
<div class="icon-container image">
|
||||
<img data-dz-thumbnail style="<?= $cssDimensions ?>" />
|
||||
</div>
|
||||
<div class="info">
|
||||
<h4 class="filename">
|
||||
<span data-dz-name></span>
|
||||
<a
|
||||
href="javascript:;"
|
||||
class="uploader-remove oc-icon-times"
|
||||
class="upload-remove-button"
|
||||
data-request="<?= $this->getEventHandler('onRemoveAttachment') ?>"
|
||||
data-request-data="file_id: {{id}}"></a>
|
||||
<?php endif ?>
|
||||
|
||||
<div class="controls">
|
||||
<?php if (!$this->previewMode): ?>
|
||||
<a
|
||||
href="javascript:;"
|
||||
class="uploader-config oc-icon-cog"
|
||||
data-control="popup"
|
||||
data-handler="<?= $this->getEventHandler('onLoadAttachmentConfig') ?>"
|
||||
data-request-data="file_id: {{id}}"></a>
|
||||
<?php endif ?>
|
||||
<a
|
||||
href="{{path}}"
|
||||
class="uploader-file-link oc-icon-paperclip"
|
||||
target="_blank"></a>
|
||||
</div>
|
||||
data-request-confirm="Are you sure?"
|
||||
><i class="icon-times"></i></a>
|
||||
</h4>
|
||||
<p class="size" data-dz-size></p>
|
||||
</div>
|
||||
<div class="meta">
|
||||
<div class="progress-bar"><span class="upload-progress" data-dz-uploadprogress></span></div>
|
||||
<div class="error-message"><span data-dz-errormessage></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
</script>
|
||||
|
||||
<!-- Existing images -->
|
||||
<script> $('#<?= $this->getId() ?>').data('populatedData', <?= $fileList ?>); </script>
|
||||
|
||||
</div>
|
||||
<!-- Error template -->
|
||||
<script type="text/template" id="<?= $this->getId('errorTemplate') ?>">
|
||||
<div class="popover-head">
|
||||
<h3>Upload error</h3>
|
||||
<p>{{errorMsg}}</p>
|
||||
<button type="button" class="close" data-dismiss="popover" aria-hidden="true">×</button>
|
||||
</div>
|
||||
<div class="popover-body">
|
||||
<button class="btn btn-danger" data-remove-file>Remove file</button>
|
||||
</div>
|
||||
</script>
|
||||
Loading…
Reference in New Issue