mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
Merge branch 'story/SSF-28'
This commit is contained in:
commit
448c5fd7b9
@ -115,7 +115,7 @@ form.small .field input.text, form.small .field textarea, form.small .field sele
|
|||||||
.field .chzn-container-single .chzn-single { height: 26px; line-height: 26px; /* not relative, as then we'd had to redo most of chzn */ font-size: 12px; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #efefef), color-stop(10%, #ffffff), color-stop(90%, #ffffff), color-stop(100%, #efefef)); background-image: -webkit-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: -moz-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: -o-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: -ms-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); }
|
.field .chzn-container-single .chzn-single { height: 26px; line-height: 26px; /* not relative, as then we'd had to redo most of chzn */ font-size: 12px; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #efefef), color-stop(10%, #ffffff), color-stop(90%, #ffffff), color-stop(100%, #efefef)); background-image: -webkit-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: -moz-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: -o-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: -ms-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); }
|
||||||
.field .chzn-container-single .chzn-single:hover, .field .chzn-container-single .chzn-single:focus, .field .chzn-container-single .chzn-single:active { text-decoration: none; outline: none; }
|
.field .chzn-container-single .chzn-single:hover, .field .chzn-container-single .chzn-single:focus, .field .chzn-container-single .chzn-single:active { text-decoration: none; outline: none; }
|
||||||
.field .chzn-container-single .chzn-single div { width: 24px; }
|
.field .chzn-container-single .chzn-single div { width: 24px; }
|
||||||
.field .chzn-container-single .chzn-single div b { background-position: 1px 4px; }
|
.field .chzn-container-single .chzn-single div b { background-position: 4px 0px; }
|
||||||
.field input.hasDatepicker { width: 50%; max-width: 96px; }
|
.field input.hasDatepicker { width: 50%; max-width: 96px; }
|
||||||
|
|
||||||
/** ---------------------------------------------------- Buttons ---------------------------------------------------- */
|
/** ---------------------------------------------------- Buttons ---------------------------------------------------- */
|
||||||
@ -304,7 +304,7 @@ body.cms { overflow: hidden; }
|
|||||||
.cms-content-tools td { border-bottom: 1px solid #ced7dc; padding: 7px 2px; font-size: 11px; }
|
.cms-content-tools td { border-bottom: 1px solid #ced7dc; padding: 7px 2px; font-size: 11px; }
|
||||||
|
|
||||||
/** CMS Batch actions */
|
/** CMS Batch actions */
|
||||||
.cms-content-batchactions, .cms-content-constructive-actions { float: right; }
|
.cms-content-constructive-actions { float: left; }
|
||||||
|
|
||||||
.cms-content-batchactions { float: right; position: relative; display: block; margin-right: 8px; }
|
.cms-content-batchactions { float: right; position: relative; display: block; margin-right: 8px; }
|
||||||
.cms-content-batchactions form > * { display: block; float: left; }
|
.cms-content-batchactions form > * { display: block; float: left; }
|
||||||
@ -385,7 +385,8 @@ form.member-profile-form #Permissions .optionset li { float: none; width: auto;
|
|||||||
.cms .ui-widget-overlay { background-color: #000; background-image: none; }
|
.cms .ui-widget-overlay { background-color: #000; background-image: none; }
|
||||||
|
|
||||||
.ui-dialog { background: url("../images/textures/bg_cms_main_content.png") repeat left top #f0f3f4; border: 3px solid #000 !important; border-radius: 8px; overflow: visible; padding: 0; }
|
.ui-dialog { background: url("../images/textures/bg_cms_main_content.png") repeat left top #f0f3f4; border: 3px solid #000 !important; border-radius: 8px; overflow: visible; padding: 0; }
|
||||||
.ui-dialog .ui-dialog-titlebar.ui-widget-header { font-size: 14px; background-color: #92a5b2; padding: 4px 4px 4px 16px; border-bottom: 2px solid #8399a7; -moz-border-radius: 0; -webkit-border-radius: 0; -o-border-radius: 0; -ms-border-radius: 0; -khtml-border-radius: 0; border-radius: 0; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ced7dc), color-stop(100%, #92a5b2)); background-image: -webkit-linear-gradient(#ced7dc, #92a5b2); background-image: -moz-linear-gradient(#ced7dc, #92a5b2); background-image: -o-linear-gradient(#ced7dc, #92a5b2); background-image: -ms-linear-gradient(#ced7dc, #92a5b2); background-image: linear-gradient(#ced7dc, #92a5b2); }
|
.ui-dialog .ui-dialog-titlebar.ui-widget-header { font-size: 14px; background-color: #92a5b2; padding: 4px 4px 4px 16px; border-bottom: 2px solid #8399a7; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ced7dc), color-stop(100%, #92a5b2)); background-image: -webkit-linear-gradient(#ced7dc, #92a5b2); background-image: -moz-linear-gradient(#ced7dc, #92a5b2); background-image: -o-linear-gradient(#ced7dc, #92a5b2); background-image: -ms-linear-gradient(#ced7dc, #92a5b2); background-image: linear-gradient(#ced7dc, #92a5b2); }
|
||||||
|
.ui-dialog.loading { background-image: url(../images/spinner.gif); background-position: 50% 50%; background-repeat: no-repeat; }
|
||||||
|
|
||||||
body.cms-dialog { overflow: auto; background: url("../images/textures/bg_cms_main_content.png") repeat left top #f0f3f4; }
|
body.cms-dialog { overflow: auto; background: url("../images/textures/bg_cms_main_content.png") repeat left top #f0f3f4; }
|
||||||
|
|
||||||
|
@ -261,172 +261,27 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class: a#profile-link
|
* Trigger dialogs with iframe based on the links href attribute (see ssui-core.js).
|
||||||
*
|
|
||||||
* Link for editing the profile for a logged-in member through a modal dialog.
|
|
||||||
*/
|
*/
|
||||||
$('.cms-container .profile-link').entwine({
|
$('.cms-container .ss-ui-dialog-link').entwine({
|
||||||
DialogPadding: 40,
|
UUID: null,
|
||||||
MaxHeight: 800,
|
|
||||||
MaxWidth: 800,
|
|
||||||
MinHeight: 120,
|
|
||||||
MinWidth: 120,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor: onmatch
|
|
||||||
*/
|
|
||||||
onmatch: function() {
|
onmatch: function() {
|
||||||
this.bind('click', function(e) {
|
this._super();
|
||||||
return self._openPopup();
|
this.setUUID(new Date().getTime());
|
||||||
});
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
$('body').append(
|
|
||||||
'<div id="ss-ui-dialog">'
|
|
||||||
+ '<iframe id="ss-ui-dialog-iframe" '
|
|
||||||
+ 'marginWidth="0" marginHeight="0" frameBorder="0" scrolling="auto">'
|
|
||||||
+ '</iframe>'
|
|
||||||
+ '</div>'
|
|
||||||
);
|
|
||||||
|
|
||||||
$('#ss-ui-dialog-iframe').bind('load', function(e) {
|
|
||||||
self._resize();
|
|
||||||
});
|
|
||||||
|
|
||||||
$(window).bind('resize', function() {
|
|
||||||
self._resize();
|
|
||||||
});
|
|
||||||
|
|
||||||
self.redraw();
|
|
||||||
},
|
},
|
||||||
|
onclick: function() {
|
||||||
|
this._super();
|
||||||
|
|
||||||
/**
|
var self = this, id = 'ss-ui-dialog-' + this.getUUID();
|
||||||
* Function: redraw
|
|
||||||
*
|
|
||||||
* Returns: void
|
|
||||||
*/
|
|
||||||
redraw: function() {
|
|
||||||
var self = this;
|
|
||||||
var useCookie = false;
|
|
||||||
var cookieVal = false;
|
|
||||||
|
|
||||||
if(useCookie && jQuery.cookie && jQuery.cookie('ss-ui-dialog')) {
|
var dialog = $('#' + id);
|
||||||
cookieVal = JSON.parse(jQuery.cookie('ss-ui-dialog'));
|
if(!dialog.length) {
|
||||||
|
dialog = $('<div class="ss-ui-dialog" id="' + id + '" />');
|
||||||
|
$('body').append(dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#ss-ui-dialog").dialog(jQuery.extend({
|
dialog.ssdialog({iframeUrl: this.attr('href'), autoOpen: true});
|
||||||
autoOpen: false,
|
|
||||||
bgiframe: true,
|
|
||||||
modal: true,
|
|
||||||
width: self._width(),
|
|
||||||
height: self._height(),
|
|
||||||
position: 'center',
|
|
||||||
|
|
||||||
resizeStop: function(e, ui) {
|
|
||||||
self._resize();
|
|
||||||
},
|
|
||||||
|
|
||||||
dragStop: function(e, ui) {
|
|
||||||
self._saveState();
|
|
||||||
},
|
|
||||||
// TODO i18n
|
|
||||||
title: 'Edit Profile'
|
|
||||||
}, cookieVal)).css('overflow', 'hidden');
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: _popupHeight
|
|
||||||
*
|
|
||||||
* Returns a value > minHeight < max height
|
|
||||||
* Returns: Int
|
|
||||||
*/
|
|
||||||
_height: function() {
|
|
||||||
var marginTop = parseInt($(this).css('margin-top').replace('px', ''));
|
|
||||||
var marginBottom = parseInt($(this).css('margin-bottom').replace('px', ''));
|
|
||||||
var body = $("body").height();
|
|
||||||
|
|
||||||
var height = body - (marginTop + marginBottom) - (this.getDialogPadding() * 2);
|
|
||||||
|
|
||||||
if(height > this.getMaxHeight())
|
|
||||||
return this.getMaxHeight();
|
|
||||||
else if(height < this.getMinHeight())
|
|
||||||
return this.getMinHeight();
|
|
||||||
|
|
||||||
return height;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: _popupWidth
|
|
||||||
*
|
|
||||||
* Returns: Int
|
|
||||||
*/
|
|
||||||
_width: function() {
|
|
||||||
var body = $("body").width();
|
|
||||||
var width = body - (this.getDialogPadding() * 2);
|
|
||||||
|
|
||||||
if(width > this.getMaxWidth())
|
|
||||||
return this.getMaxWidth();
|
|
||||||
else if(width < this.getMinWidth())
|
|
||||||
return this.getMinWidth();
|
|
||||||
|
|
||||||
return width;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: _openPopup
|
|
||||||
*/
|
|
||||||
_openPopup: function(e) {
|
|
||||||
$('#ss-ui-dialog-iframe').attr('src', this.attr('href'));
|
|
||||||
|
|
||||||
$("#ss-ui-dialog").dialog('open');
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: _resize
|
|
||||||
*/
|
|
||||||
_resize: function() {
|
|
||||||
var iframe = $('#ss-ui-dialog-iframe');
|
|
||||||
var container = $('#ss-ui-dialog');
|
|
||||||
|
|
||||||
container.dialog("option", "width", this._width());
|
|
||||||
container.dialog("option", "height", this._height());
|
|
||||||
container.dialog('option', 'position', 'center');
|
|
||||||
|
|
||||||
iframe.attr('width',
|
|
||||||
container.innerWidth()
|
|
||||||
- parseFloat(container.css('paddingLeft'))
|
|
||||||
- parseFloat(container.css('paddingRight'))
|
|
||||||
);
|
|
||||||
iframe.attr('height',
|
|
||||||
container.innerHeight()
|
|
||||||
- parseFloat(container.css('paddingTop'))
|
|
||||||
- parseFloat(container.css('paddingBottom'))
|
|
||||||
);
|
|
||||||
|
|
||||||
this._saveState();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function: _saveState
|
|
||||||
*/
|
|
||||||
_saveState: function() {
|
|
||||||
var container = $('#ss-ui-dialog');
|
|
||||||
|
|
||||||
// save size in cookie (optional)
|
|
||||||
if(jQuery.cookie && container.width() && container.height()) {
|
|
||||||
jQuery.cookie(
|
|
||||||
'ss-ui-dialog',
|
|
||||||
JSON.stringify({
|
|
||||||
width: parseInt(container.width(), 10),
|
|
||||||
height: parseInt(container.height(), 10)
|
|
||||||
}),
|
|
||||||
{ expires: 30, path: '/'}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -29,6 +29,81 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extends jQueryUI dialog with iframe abilities (and related resizing logic),
|
||||||
|
* and sets some CMS-wide defaults.
|
||||||
|
*/
|
||||||
|
$.widget("ssui.ssdialog", $.ui.dialog, {
|
||||||
|
options: {
|
||||||
|
// Custom properties
|
||||||
|
iframeUrl: '',
|
||||||
|
reloadOnOpen: true,
|
||||||
|
|
||||||
|
// Defaults
|
||||||
|
width: '80%',
|
||||||
|
height: 500,
|
||||||
|
position: 'center',
|
||||||
|
modal: true,
|
||||||
|
bgiframe: true,
|
||||||
|
autoOpen: false
|
||||||
|
},
|
||||||
|
_create: function() {
|
||||||
|
$.ui.dialog.prototype._create.call(this);
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
// Create iframe
|
||||||
|
var iframe = $('<iframe marginWidth="0" marginHeight="0" frameBorder="0" scrolling="auto"></iframe>');
|
||||||
|
iframe.bind('load', function(e) {
|
||||||
|
if($(this).attr('src') == 'about:blank') return;
|
||||||
|
|
||||||
|
$(this).show();
|
||||||
|
self._resizeIframe();
|
||||||
|
self.uiDialog.removeClass('loading');
|
||||||
|
}).hide();
|
||||||
|
this.element.append(iframe);
|
||||||
|
|
||||||
|
// Let the iframe handle its scrolling
|
||||||
|
this.element.css('overflow', 'hidden');
|
||||||
|
},
|
||||||
|
open: function() {
|
||||||
|
$.ui.dialog.prototype.open.call(this);
|
||||||
|
|
||||||
|
var self = this, iframe = this.element.children('iframe');
|
||||||
|
|
||||||
|
// Load iframe
|
||||||
|
if(!iframe.attr('src') || this.options.reloadOnOpen) {
|
||||||
|
iframe.hide();
|
||||||
|
iframe.attr('src', this.options.iframeUrl);
|
||||||
|
this.uiDialog.addClass('loading');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resize events
|
||||||
|
this.uiDialog.bind('resize.ssdialog', function() {self._resizeIframe();});
|
||||||
|
$(window).bind('resize.ssdialog', function() {self._resizeIframe();});
|
||||||
|
},
|
||||||
|
close: function() {
|
||||||
|
$.ui.dialog.prototype.close.call(this);
|
||||||
|
|
||||||
|
this.uiDialog.unbind('resize.ssdialog');
|
||||||
|
$(window).unbind('resize.ssdialog');
|
||||||
|
},
|
||||||
|
_resizeIframe: function() {
|
||||||
|
var el = this.element, iframe = el.children('iframe');
|
||||||
|
|
||||||
|
iframe.attr('width',
|
||||||
|
el.innerWidth()
|
||||||
|
- parseFloat(el.css('paddingLeft'))
|
||||||
|
- parseFloat(el.css('paddingRight'))
|
||||||
|
);
|
||||||
|
iframe.attr('height',
|
||||||
|
el.innerHeight()
|
||||||
|
- parseFloat(el.css('paddingTop'))
|
||||||
|
- parseFloat(el.css('paddingBottom'))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$.widget("ssui.titlebar", {
|
$.widget("ssui.titlebar", {
|
||||||
_create: function() {
|
_create: function() {
|
||||||
this.originalTitle = this.element.attr('title');
|
this.originalTitle = this.element.attr('title');
|
||||||
|
@ -894,10 +894,16 @@ form.member-profile-form {
|
|||||||
background-color: #92a5b2;
|
background-color: #92a5b2;
|
||||||
padding: $grid-vertical/2 $grid-horizontal/2 $grid-vertical/2 $grid-horizontal*2;
|
padding: $grid-vertical/2 $grid-horizontal/2 $grid-vertical/2 $grid-horizontal*2;
|
||||||
border-bottom: 2px solid #8399a7;
|
border-bottom: 2px solid #8399a7;
|
||||||
@include border-radius-top(4px);
|
// @include border-radius-top(4px);
|
||||||
@include border-radius-bottom(0px);
|
// @include border-radius-bottom(0px);
|
||||||
@include background-image(linear-gradient(#ced7dc, #92a5b2));
|
@include background-image(linear-gradient(#ced7dc, #92a5b2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.loading {
|
||||||
|
background-image: url(../images/spinner.gif);
|
||||||
|
background-position: 50% 50%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body.cms-dialog {
|
body.cms-dialog {
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<% control CurrentMember %>
|
<% control CurrentMember %>
|
||||||
<span>
|
<span>
|
||||||
<% _t('Hello','Hi') %>
|
<% _t('Hello','Hi') %>
|
||||||
<a href="{$AbsoluteBaseURL}admin/myprofile" class="profile-link">
|
<a href="{$AbsoluteBaseURL}admin/settings/myprofile" class="profile-link ss-ui-dialog-link">
|
||||||
<% if FirstName && Surname %>$FirstName $Surname<% else_if FirstName %>$FirstName<% else %>$Email<% end_if %>
|
<% if FirstName && Surname %>$FirstName $Surname<% else_if FirstName %>$FirstName<% else %>$Email<% end_if %>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
/** Core styles for the basic GridField form field without any specific style. @package sapphire @subpackage scss @todo Add radial gradient to default delete button state @todo Create SASS mixin-function to simply swap the from/to, to to/from colours in grsdient mixins? */
|
/** Core styles for the basic GridField form field without any specific style. @package sapphire @subpackage scss @todo Add radial gradient to default delete button state @todo Create SASS mixin-function to simply swap the from/to, to to/from colours in grsdient mixins? */
|
||||||
.cms fieldset.ss-gridfield > div { margin-bottom: 35px; }
|
.cms fieldset.ss-gridfield > div { margin-bottom: 35px; }
|
||||||
|
.cms fieldset.ss-gridfield[data-selectable] tr.ui-selected, .cms fieldset.ss-gridfield[data-selectable] tr.ui-selecting { background: #FFFAD6 !important; }
|
||||||
|
.cms fieldset.ss-gridfield[data-selectable] td { cursor: pointer; }
|
||||||
.cms table.ss-gridfield.field { box-shadow: none; padding: 0; margin: 20px 0 0 0; border-collapse: separate; border-bottom: 0 none; }
|
.cms table.ss-gridfield.field { box-shadow: none; padding: 0; margin: 20px 0 0 0; border-collapse: separate; border-bottom: 0 none; }
|
||||||
.cms table.ss-gridfield.field thead { color: #1d2224; background: transparent; }
|
.cms table.ss-gridfield.field thead { color: #1d2224; background: transparent; }
|
||||||
.cms table.ss-gridfield.field tbody { background: #FFF; }
|
.cms table.ss-gridfield.field tbody { background: #FFF; }
|
||||||
|
@ -30,7 +30,9 @@ class UploadField extends FileField {
|
|||||||
*/
|
*/
|
||||||
public static $allowed_actions = array(
|
public static $allowed_actions = array(
|
||||||
'upload',
|
'upload',
|
||||||
'handleItem'
|
'attach',
|
||||||
|
'handleItem',
|
||||||
|
'handleSelect',
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,6 +40,7 @@ class UploadField extends FileField {
|
|||||||
*/
|
*/
|
||||||
public static $url_handlers = array(
|
public static $url_handlers = array(
|
||||||
'item/$ID' => 'handleItem',
|
'item/$ID' => 'handleItem',
|
||||||
|
'select' => 'handleSelect',
|
||||||
'$Action!' => '$Action',
|
'$Action!' => '$Action',
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -293,6 +296,13 @@ class UploadField extends FileField {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getAttributes() {
|
||||||
|
return array_merge(
|
||||||
|
parent::getAttributes(),
|
||||||
|
array('data-selectdialog-url', $this->Link('select'))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function Field() {
|
public function Field() {
|
||||||
$record = $this->getRecord();
|
$record = $this->getRecord();
|
||||||
$name = $this->getName();
|
$name = $this->getName();
|
||||||
@ -329,6 +339,8 @@ class UploadField extends FileField {
|
|||||||
|
|
||||||
$config = array(
|
$config = array(
|
||||||
'url' => $this->Link('upload'),
|
'url' => $this->Link('upload'),
|
||||||
|
'urlSelectDialog' => $this->Link('select'),
|
||||||
|
'urlAttach' => $this->Link('attach'),
|
||||||
'acceptFileTypes' => '.+$',
|
'acceptFileTypes' => '.+$',
|
||||||
'maxNumberOfFiles' => $this->getConfig('allowedMaxFileNumber')
|
'maxNumberOfFiles' => $this->getConfig('allowedMaxFileNumber')
|
||||||
);
|
);
|
||||||
@ -392,6 +404,14 @@ class UploadField extends FileField {
|
|||||||
return Object::create('UploadField_ItemHandler', $this, $itemID);
|
return Object::create('UploadField_ItemHandler', $this, $itemID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param SS_HTTPRequest $request
|
||||||
|
* @return UploadField_ItemHandler
|
||||||
|
*/
|
||||||
|
public function handleSelect(SS_HTTPRequest $request) {
|
||||||
|
return Object::create('UploadField_SelectHandler', $this, $this->folderName);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action to handle upload of a single file
|
* Action to handle upload of a single file
|
||||||
*
|
*
|
||||||
@ -467,6 +487,34 @@ class UploadField extends FileField {
|
|||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add existing {@link File} records to the relationship.
|
||||||
|
*/
|
||||||
|
public function attach($request) {
|
||||||
|
if(!$request->isPOST()) return $this->httpError(403);
|
||||||
|
if(!$this->managesRelation()) return $this->httpError(403);
|
||||||
|
|
||||||
|
$return = array();
|
||||||
|
|
||||||
|
$files = DataList::create('File')->byIDs($request->postVar('ids'));
|
||||||
|
foreach($files as $file) {
|
||||||
|
$this->attachFile($file);
|
||||||
|
$file = $this->customiseFile($file);
|
||||||
|
$return[] = array(
|
||||||
|
'id' => $file->ID,
|
||||||
|
'name' => $file->getTitle() . '.' . $file->getExtension(),
|
||||||
|
'url' => $file->getURL(),
|
||||||
|
'thumbnail_url' => $file->UploadFieldThumbnailURL,
|
||||||
|
'edit_url' => $file->UploadFieldEditLink,
|
||||||
|
'size' => $file->getAbsoluteSize(),
|
||||||
|
'buttons' => $file->UploadFieldFileButtons
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$response = new SS_HTTPResponse(Convert::raw2json($return));
|
||||||
|
$response->addHeader('Content-Type', 'application/json');
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param File
|
* @param File
|
||||||
*/
|
*/
|
||||||
@ -741,3 +789,84 @@ class UploadField_ItemHandler extends RequestHandler {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class UploadField_SelectHandler extends RequestHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var UploadField
|
||||||
|
*/
|
||||||
|
protected $parent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var String
|
||||||
|
*/
|
||||||
|
protected $folderName;
|
||||||
|
|
||||||
|
public static $url_handlers = array(
|
||||||
|
'$Action!' => '$Action',
|
||||||
|
'' => 'index',
|
||||||
|
);
|
||||||
|
|
||||||
|
function __construct($parent, $folderName = null) {
|
||||||
|
$this->parent = $parent;
|
||||||
|
$this->folderName = $folderName;
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
function index() {
|
||||||
|
return $this->renderWith('CMSDialog');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $action
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function Link($action = null) {
|
||||||
|
return Controller::join_links($this->parent->Link(), '/select/', $action);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Form
|
||||||
|
*/
|
||||||
|
function Form() {
|
||||||
|
$action = new FormAction('doAttach', _t('UploadField.AttachFile', 'Attach file(s)'));
|
||||||
|
$action->addExtraClass('ss-ui-action-constructive');
|
||||||
|
return new Form(
|
||||||
|
$this,
|
||||||
|
'Form',
|
||||||
|
new FieldList($this->getListField()),
|
||||||
|
new FieldList($action)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return FormField
|
||||||
|
*/
|
||||||
|
protected function getListField() {
|
||||||
|
$folder = $this->getFolder();
|
||||||
|
$config = GridFieldConfig::create();
|
||||||
|
$config->addComponent(new GridFieldSortableHeader());
|
||||||
|
$config->addComponent(new GridFieldFilter());
|
||||||
|
$config->addComponent(new GridFieldDefaultColumns());
|
||||||
|
$config->addComponent(new GridFieldPaginator(10));
|
||||||
|
|
||||||
|
$field = new GridField('Files', false, $folder->stageChildren(), $config);
|
||||||
|
$field->setAttribute('data-selectable', true);
|
||||||
|
if($this->parent->getConfig('allowedMaxFileNumber') > 1) $field->setAttribute('data-multiselect', true);
|
||||||
|
|
||||||
|
return $field;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Folder
|
||||||
|
*/
|
||||||
|
function getFolder() {
|
||||||
|
return Folder::find_or_make($this->folderName);
|
||||||
|
}
|
||||||
|
|
||||||
|
function doAttach($data, $form) {
|
||||||
|
// TODO Only implemented via JS for now
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1,5 +1,17 @@
|
|||||||
jQuery(function($){
|
jQuery(function($){
|
||||||
|
|
||||||
|
$('fieldset.ss-gridfield').entwine({
|
||||||
|
getItems: function() {
|
||||||
|
return this.find('.ss-gridfield-item');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('fieldset.ss-gridfield *').entwine({
|
||||||
|
getGridField: function() {
|
||||||
|
return this.parents('fieldset.ss-gridfield:first');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$('fieldset.ss-gridfield .action').entwine({
|
$('fieldset.ss-gridfield .action').entwine({
|
||||||
onclick: function(e){
|
onclick: function(e){
|
||||||
var button = this;
|
var button = this;
|
||||||
@ -26,13 +38,6 @@ jQuery(function($){
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var removeFilterButtons = function() {
|
|
||||||
// Remove stuff
|
|
||||||
$('th').children('div').each(function(i,v) {
|
|
||||||
$(v).remove();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Upon focusing on a filter <input> element, move "filter" and "reset" buttons and display next to the current <input> element
|
* Upon focusing on a filter <input> element, move "filter" and "reset" buttons and display next to the current <input> element
|
||||||
* ToDo ensure filter-button state is maintained after filtering (see resetState param)
|
* ToDo ensure filter-button state is maintained after filtering (see resetState param)
|
||||||
@ -46,8 +51,10 @@ jQuery(function($){
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var eleInput = $(this);
|
var eleInput = $(this);
|
||||||
|
|
||||||
// Remove existing <div> and <button> elements in-lieu of cloning
|
// Remove existing <div> and <button> elements in-lieu of cloning
|
||||||
removeFilterButtons();
|
this.getGridField().find('th > div').each(function(i,v) {$(v).remove();});
|
||||||
|
|
||||||
var eleButtonSetFilter = $('#action_filter');
|
var eleButtonSetFilter = $('#action_filter');
|
||||||
var eleButtonResetFilter = $('#action_reset');
|
var eleButtonResetFilter = $('#action_reset');
|
||||||
// Retain current widths to ensure <th>'s don't shift widths
|
// Retain current widths to ensure <th>'s don't shift widths
|
||||||
@ -71,4 +78,43 @@ jQuery(function($){
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows selection of one or more rows in the grid field.
|
||||||
|
* Purely clientside at the moment.
|
||||||
|
*/
|
||||||
|
$('fieldset.ss-gridfield[data-selectable]').entwine({
|
||||||
|
/**
|
||||||
|
* @return {jQuery} Collection
|
||||||
|
*/
|
||||||
|
getSelectedItems: function() {
|
||||||
|
return this.find('.ss-gridfield-item.ui-selected');
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* @return {Array} Of record IDs
|
||||||
|
*/
|
||||||
|
getSelectedIDs: function() {
|
||||||
|
return $.map(this.getSelectedItems(), function(el) {return $(el).data('id');});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$('fieldset.ss-gridfield[data-selectable] .ss-gridfield-items').entwine({
|
||||||
|
onmatch: function() {
|
||||||
|
this._super();
|
||||||
|
|
||||||
|
// TODO Limit to single selection
|
||||||
|
this.selectable();
|
||||||
|
},
|
||||||
|
onunmatch: function() {
|
||||||
|
this._super();
|
||||||
|
this.selectable('destroy');
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
$('fieldset.ss-gridfield[data-multiselect] .ss-gridfield-item').entwine({
|
||||||
|
onclick: function() {
|
||||||
|
// this.siblings('selected');
|
||||||
|
this._super();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
@ -1,12 +1,12 @@
|
|||||||
(function($) {
|
(function($) {
|
||||||
$.widget('blueimpUIX.fileupload', $.blueimpUI.fileupload, {
|
$.widget('blueimpUIX.fileupload', $.blueimpUI.fileupload, {
|
||||||
_initTemplates: function() {
|
_initTemplates: function() {
|
||||||
this.options.templateContainer = document.createElement(
|
this.options.templateContainer = document.createElement(
|
||||||
this._files.prop('nodeName')
|
this._files.prop('nodeName')
|
||||||
);
|
);
|
||||||
this.options.uploadTemplate = window.tmpl(this.options.uploadTemplateName);
|
this.options.uploadTemplate = window.tmpl(this.options.uploadTemplateName);
|
||||||
this.options.downloadTemplate = window.tmpl(this.options.downloadTemplateName);
|
this.options.downloadTemplate = window.tmpl(this.options.downloadTemplateName);
|
||||||
},
|
},
|
||||||
_enableFileInputButton: function() {
|
_enableFileInputButton: function() {
|
||||||
$.blueimpUI.fileupload.prototype._enableFileInputButton.call(this);
|
$.blueimpUI.fileupload.prototype._enableFileInputButton.call(this);
|
||||||
this.element.find('.ss-uploadfield-addfile').show();
|
this.element.find('.ss-uploadfield-addfile').show();
|
||||||
@ -26,10 +26,15 @@
|
|||||||
});
|
});
|
||||||
$.entwine('ss', function($) {
|
$.entwine('ss', function($) {
|
||||||
$('div.ss-upload').entwine({
|
$('div.ss-upload').entwine({
|
||||||
|
|
||||||
|
Config: null,
|
||||||
|
|
||||||
onmatch: function() {
|
onmatch: function() {
|
||||||
var fileInput = this.find('input');
|
var fileInput = this.find('input');
|
||||||
var dropZone = this.find('.ss-uploadfield-dropzone');
|
var dropZone = this.find('.ss-uploadfield-dropzone');
|
||||||
var config = $.parseJSON(fileInput.data('config').replace(/'/g,'"'));
|
var config = $.parseJSON(fileInput.data('config').replace(/'/g,'"'));
|
||||||
|
|
||||||
|
this.setConfig(config);
|
||||||
this.fileupload($.extend(true,
|
this.fileupload($.extend(true,
|
||||||
{
|
{
|
||||||
formData: function(form) {
|
formData: function(form) {
|
||||||
@ -52,22 +57,22 @@
|
|||||||
emptyResult: ss.i18n._t('UploadField.EMPTYRESULT')
|
emptyResult: ss.i18n._t('UploadField.EMPTYRESULT')
|
||||||
},
|
},
|
||||||
send: function(e, data) {
|
send: function(e, data) {
|
||||||
if (data.context && data.dataType && data.dataType.substr(0, 6) === 'iframe') {
|
if (data.context && data.dataType && data.dataType.substr(0, 6) === 'iframe') {
|
||||||
// Iframe Transport does not support progress events.
|
// Iframe Transport does not support progress events.
|
||||||
// In lack of an indeterminate progress bar, we set
|
// In lack of an indeterminate progress bar, we set
|
||||||
// the progress to 100%, showing the full animated bar:
|
// the progress to 100%, showing the full animated bar:
|
||||||
data.total = 1;
|
data.total = 1;
|
||||||
data.loaded = 1;
|
data.loaded = 1;
|
||||||
$(this).data('fileupload').options.progress(e, data);
|
$(this).data('fileupload').options.progress(e, data);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
progress: function(e, data) {
|
progress: function(e, data) {
|
||||||
if (data.context) {
|
if (data.context) {
|
||||||
var value = parseInt(data.loaded / data.total * 100, 10) + '%';
|
var value = parseInt(data.loaded / data.total * 100, 10) + '%';
|
||||||
data.context.find('.ss-uploadfield-item-status').html((data.total == 1)?ss.i18n._t('UploadField.LOADING'):value);
|
data.context.find('.ss-uploadfield-item-status').html((data.total == 1)?ss.i18n._t('UploadField.LOADING'):value);
|
||||||
data.context.find('.ss-uploadfield-item-progressbarvalue').css('width', value);
|
data.context.find('.ss-uploadfield-item-progressbarvalue').css('width', value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
config,
|
config,
|
||||||
{
|
{
|
||||||
@ -82,6 +87,62 @@
|
|||||||
dropZone.show(); // drag&drop avaliable
|
dropZone.show(); // drag&drop avaliable
|
||||||
}
|
}
|
||||||
this._super();
|
this._super();
|
||||||
|
},
|
||||||
|
|
||||||
|
openSelectDialog: function() {
|
||||||
|
// Create dialog and load iframe
|
||||||
|
var self = this, config = this.getConfig(), dialogId = 'ss-uploadfield-dialog-' + this.attr('id'), dialog = jQuery('#' + dialogId);
|
||||||
|
if(!dialog.length) dialog = jQuery('<div class="ss-uploadfield-dialog" id="' + dialogId + '" />');
|
||||||
|
|
||||||
|
// Show dialog
|
||||||
|
dialog.ssdialog({iframeUrl: config['urlSelectDialog']});
|
||||||
|
|
||||||
|
// TODO Allow single-select
|
||||||
|
dialog.find('iframe').bind('load', function(e) {
|
||||||
|
var contents = $(this).contents(), gridField = contents.find('fieldset.ss-gridfield');
|
||||||
|
// TODO Fix jQuery custom event bubbling across iframes on same domain
|
||||||
|
// gridField.find('.ss-gridfield-items')).bind('selectablestop', function() {
|
||||||
|
// });
|
||||||
|
|
||||||
|
// Remove top margin (easier than including new selectors)
|
||||||
|
contents.find('table.ss-gridfield').css('margin-top', 0);
|
||||||
|
|
||||||
|
// Can't use live() in iframes...
|
||||||
|
contents.find('input[name=action_doAttach]').unbind('click.openSelectDialog').bind('click.openSelectDialog', function() {
|
||||||
|
// TODO Fix entwine method calls across iframe/document boundaries
|
||||||
|
var ids = $.map(gridField.find('.ss-gridfield-item.ui-selected'), function(el) {return $(el).data('id');});
|
||||||
|
if(ids && ids.length) self.attachFiles(ids);
|
||||||
|
|
||||||
|
dialog.ssdialog('close');
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
dialog.ssdialog('open');
|
||||||
|
},
|
||||||
|
attachFiles: function(ids) {
|
||||||
|
var self = this, config = this.getConfig();
|
||||||
|
$.post(
|
||||||
|
config['urlAttach'],
|
||||||
|
{'ids': ids},
|
||||||
|
function(data, status, xhr) {
|
||||||
|
var fn = self.fileupload('option', 'downloadTemplate');
|
||||||
|
self.find('.ss-uploadfield-files').append(fn({
|
||||||
|
files: data,
|
||||||
|
formatFileSize: function (bytes) {
|
||||||
|
if (typeof bytes !== 'number') return '';
|
||||||
|
if (bytes >= 1000000000) return (bytes / 1000000000).toFixed(2) + ' GB';
|
||||||
|
if (bytes >= 1000000) return (bytes / 1000000).toFixed(2) + ' MB';
|
||||||
|
return (bytes / 1000).toFixed(2) + ' KB';
|
||||||
|
},
|
||||||
|
options: self.fileupload('option')
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$('div.ss-upload *').entwine({
|
||||||
|
getUploadField: function() {
|
||||||
|
return this.parents('div.ss-upload:first');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$('div.ss-upload .ss-uploadfield-files .ss-uploadfield-item').entwine({
|
$('div.ss-upload .ss-uploadfield-files .ss-uploadfield-item').entwine({
|
||||||
@ -160,5 +221,11 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
$('div.ss-upload .ss-uploadfield-fromfiles').entwine({
|
||||||
|
onclick: function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.getUploadField().openSelectDialog();
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}(jQuery));
|
}(jQuery));
|
@ -31,9 +31,22 @@ $gf_border_radius: 7px;
|
|||||||
}
|
}
|
||||||
|
|
||||||
.cms {
|
.cms {
|
||||||
fieldset.ss-gridfield>div {
|
fieldset.ss-gridfield {
|
||||||
margin-bottom: 35px;
|
& > div {
|
||||||
|
margin-bottom: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-selectable] {
|
||||||
|
tr.ui-selected, tr.ui-selecting {
|
||||||
|
background: #FFFAD6 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
table.ss-gridfield.field {
|
table.ss-gridfield.field {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -375,6 +375,84 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testSelect() {
|
||||||
|
$this->loginWithPermission('ADMIN');
|
||||||
|
|
||||||
|
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
|
||||||
|
$file4 = $this->objFromFixture('File', 'file4');
|
||||||
|
$file5 = $this->objFromFixture('File', 'file5');
|
||||||
|
$fileSubfolder = $this->objFromFixture('File', 'file-subfolder');
|
||||||
|
$fileNoEdit = $this->objFromFixture('File', 'file-noedit');
|
||||||
|
|
||||||
|
$response = $this->get('UploadFieldTest_Controller/Form/field/ManyManyFiles/select/');
|
||||||
|
$this->assertFalse($response->isError());
|
||||||
|
|
||||||
|
// A bit too much coupling with GridField, but a full template overload would make things too complex
|
||||||
|
$parser = new CSSContentParser($response->getBody());
|
||||||
|
$items = $parser->getBySelector('.ss-gridfield-item');
|
||||||
|
$itemIDs = array_map(create_function('$el', 'return (int)$el["data-id"];'), $items);
|
||||||
|
$this->assertContains($file4->ID, $itemIDs, 'Contains file in assigned folder');
|
||||||
|
$this->assertNotContains($fileSubfolder->ID, $itemIDs, 'Does not contain file in subfolder');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testAttachHasOne() {
|
||||||
|
$this->loginWithPermission('ADMIN');
|
||||||
|
|
||||||
|
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
|
||||||
|
$file1 = $this->objFromFixture('File', 'file1');
|
||||||
|
$file2 = $this->objFromFixture('File', 'file2');
|
||||||
|
$file3AlreadyAttached = $this->objFromFixture('File', 'file3');
|
||||||
|
|
||||||
|
$response = $this->post(
|
||||||
|
'UploadFieldTest_Controller/Form/field/HasOneFile/attach',
|
||||||
|
array('ids' => array($file1->ID/* first file should be ignored */, $file2->ID))
|
||||||
|
);
|
||||||
|
$this->assertFalse($response->isError());
|
||||||
|
|
||||||
|
$record = DataObject::get_by_id($record->class, $record->ID, false);
|
||||||
|
$this->assertEquals($file2->ID, $record->HasOneFileID, 'Attaches new relations');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testAttachHasMany() {
|
||||||
|
$this->loginWithPermission('ADMIN');
|
||||||
|
|
||||||
|
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
|
||||||
|
$file1 = $this->objFromFixture('File', 'file1');
|
||||||
|
$file2 = $this->objFromFixture('File', 'file2');
|
||||||
|
$file3AlreadyAttached = $this->objFromFixture('File', 'file3');
|
||||||
|
|
||||||
|
$response = $this->post(
|
||||||
|
'UploadFieldTest_Controller/Form/field/HasManyFiles/attach',
|
||||||
|
array('ids' => array($file1->ID, $file2->ID))
|
||||||
|
);
|
||||||
|
$this->assertFalse($response->isError());
|
||||||
|
|
||||||
|
$record = DataObject::get_by_id($record->class, $record->ID, false);
|
||||||
|
$this->assertContains($file1->ID, $record->HasManyFiles()->column('ID'), 'Attaches new relations');
|
||||||
|
$this->assertContains($file2->ID, $record->HasManyFiles()->column('ID'), 'Attaches new relations');
|
||||||
|
$this->assertContains($file3AlreadyAttached->ID, $record->HasManyFiles()->column('ID'), 'Does not detach existing relations');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testAttachManyMany() {
|
||||||
|
$this->loginWithPermission('ADMIN');
|
||||||
|
|
||||||
|
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
|
||||||
|
$file1 = $this->objFromFixture('File', 'file1');
|
||||||
|
$file2 = $this->objFromFixture('File', 'file2');
|
||||||
|
$file5AlreadyAttached = $this->objFromFixture('File', 'file5');
|
||||||
|
|
||||||
|
$response = $this->post(
|
||||||
|
'UploadFieldTest_Controller/Form/field/ManyManyFiles/attach',
|
||||||
|
array('ids' => array($file1->ID, $file2->ID))
|
||||||
|
);
|
||||||
|
$this->assertFalse($response->isError());
|
||||||
|
|
||||||
|
$record = DataObject::get_by_id($record->class, $record->ID, false);
|
||||||
|
$this->assertContains($file1->ID, $record->ManyManyFiles()->column('ID'), 'Attaches new relations');
|
||||||
|
$this->assertContains($file2->ID, $record->ManyManyFiles()->column('ID'), 'Attaches new relations');
|
||||||
|
$this->assertContains($file5AlreadyAttached->ID, $record->ManyManyFiles()->column('ID'), 'Does not detach existing relations');
|
||||||
|
}
|
||||||
|
|
||||||
function testManagesRelation() {
|
function testManagesRelation() {
|
||||||
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
|
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
|
||||||
|
|
||||||
@ -541,6 +619,10 @@ class UploadFieldTest_Controller extends Controller implements TestOnly {
|
|||||||
$fieldDisabled->setRecord($record);
|
$fieldDisabled->setRecord($record);
|
||||||
$fieldDisabled = $fieldDisabled->performDisabledTransformation();
|
$fieldDisabled = $fieldDisabled->performDisabledTransformation();
|
||||||
|
|
||||||
|
$fieldSubfolder = new UploadField('SubfolderField');
|
||||||
|
$fieldSubfolder->setFolderName('UploadFieldTest/subfolder1');
|
||||||
|
$fieldSubfolder->setRecord($record);
|
||||||
|
|
||||||
$form = new Form(
|
$form = new Form(
|
||||||
$this,
|
$this,
|
||||||
'Form',
|
'Form',
|
||||||
@ -550,7 +632,8 @@ class UploadFieldTest_Controller extends Controller implements TestOnly {
|
|||||||
$fieldHasMany,
|
$fieldHasMany,
|
||||||
$fieldManyMany,
|
$fieldManyMany,
|
||||||
$fieldReadonly,
|
$fieldReadonly,
|
||||||
$fieldDisabled
|
$fieldDisabled,
|
||||||
|
$fieldSubfolder
|
||||||
),
|
),
|
||||||
new FieldList(
|
new FieldList(
|
||||||
new FormAction('submit')
|
new FormAction('submit')
|
||||||
@ -561,7 +644,8 @@ class UploadFieldTest_Controller extends Controller implements TestOnly {
|
|||||||
'HasManyFiles',
|
'HasManyFiles',
|
||||||
'ManyManyFiles',
|
'ManyManyFiles',
|
||||||
'ReadonlyField',
|
'ReadonlyField',
|
||||||
'DisabledField'
|
'DisabledField',
|
||||||
|
'SubfolderField'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
return $form;
|
return $form;
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
Folder:
|
Folder:
|
||||||
folder1:
|
folder1:
|
||||||
Name: UploadFieldTest
|
Name: UploadFieldTest
|
||||||
|
folder1-subfolder1:
|
||||||
|
Name: subfolder1
|
||||||
|
ParentID: =>Folder.folder1
|
||||||
File:
|
File:
|
||||||
file1:
|
file1:
|
||||||
Title: File1
|
Title: File1
|
||||||
@ -37,6 +40,11 @@ File:
|
|||||||
Name: nodelete.txt
|
Name: nodelete.txt
|
||||||
Filename: assets/UploadFieldTest/nodelete.txt
|
Filename: assets/UploadFieldTest/nodelete.txt
|
||||||
ParentID: =>Folder.folder1
|
ParentID: =>Folder.folder1
|
||||||
|
file-subfolder:
|
||||||
|
Title: file-subfolder.txt
|
||||||
|
Name: file-subfolder.txt
|
||||||
|
Filename: assets/UploadFieldTest/subfolder1/file-subfolder.txt
|
||||||
|
ParentID: =>Folder.folder1-subfolder1
|
||||||
UploadFieldTest_Record:
|
UploadFieldTest_Record:
|
||||||
record1:
|
record1:
|
||||||
Title: Record 1
|
Title: Record 1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user