MDL-31901: Changing interface of file picker, use renderers:
- Filepicker window is now resizable and draggable; - filepicker&renderer: removed id substitution from renderer, replaced it with classes (better readability); - filepicker: allowed tree and table view for search results; - filepicker: fixed small bug with displaying external link checkbox - filepicker: display additional information about file in select window, repository returns more formatted information
This commit is contained in:
@@ -74,9 +74,11 @@ $string['createinstance'] = 'Create a repository instance';
|
||||
$string['createrepository'] = 'Create a repository instance';
|
||||
$string['createxxinstance'] = 'Create "{$a}" instance';
|
||||
$string['date'] = 'Date';
|
||||
$string['datecreated'] = 'Created';
|
||||
$string['deleted'] = 'Repository deleted';
|
||||
$string['deleterepository'] = 'Delete this repository';
|
||||
$string['detailview'] = 'View details';
|
||||
$string['dimensions'] = 'Dimensions';
|
||||
$string['disabled'] = 'Disabled';
|
||||
$string['download'] = 'Download';
|
||||
$string['downloadfolder'] = 'Download all';
|
||||
|
||||
@@ -439,7 +439,7 @@ class page_requirements_manager {
|
||||
case 'core_filepicker':
|
||||
$module = array('name' => 'core_filepicker',
|
||||
'fullpath' => '/repository/filepicker.js',
|
||||
'requires' => array('base', 'node', 'node-event-simulate', 'json', 'async-queue', 'io-base', 'io-upload-iframe', 'io-form', 'yui2-menu', 'yui2-treeview', 'yui2-dragdrop', 'panel', 'cookie', 'datatable', 'datatable-sort'),
|
||||
'requires' => array('base', 'node', 'node-event-simulate', 'json', 'async-queue', 'io-base', 'io-upload-iframe', 'io-form', 'yui2-menu', 'yui2-treeview', 'yui2-dragdrop', 'panel', 'cookie', 'datatable', 'datatable-sort', 'resize-plugin', 'dd-plugin', 'resize-constrain'),
|
||||
// TODO check if those all are really required
|
||||
'strings' => array(array('add', 'repository'), array('back', 'repository'), array('cancel', 'moodle'), array('close', 'repository'),
|
||||
array('cleancache', 'repository'), array('copying', 'repository'), array('date', 'repository'), array('downloadsucc', 'repository'),
|
||||
|
||||
+155
-128
@@ -65,10 +65,34 @@ M.core_filepicker.show = function(Y, options) {
|
||||
M.core_filepicker.instances[options.client_id].show();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Add new file picker to current instances
|
||||
*/
|
||||
M.core_filepicker.init = function(Y, options) {
|
||||
/** help function to extract width/height style as a number, not as a string */
|
||||
Y.Node.prototype.getStylePx = function(attr) {
|
||||
var style = this.getStyle(attr);
|
||||
if (''+style == '0' || ''+style == '0px') {
|
||||
return 0;
|
||||
}
|
||||
var matches = style.match(/^([\d\.]+)px$/)
|
||||
if (matches && parseFloat(matches[1])) {
|
||||
return parseFloat(matches[1]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** if condition is met, the class is added to the node, otherwise - removed */
|
||||
Y.Node.prototype.addClassIf = function(className, condition) {
|
||||
if (condition) {
|
||||
this.addClass(className);
|
||||
} else {
|
||||
this.removeClass(className);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
if (options.templates);
|
||||
for (var templid in options.templates) {
|
||||
this.templates[templid] = options.templates[templid];
|
||||
@@ -377,20 +401,14 @@ M.core_filepicker.init = function(Y, options) {
|
||||
}
|
||||
},
|
||||
view_files: function() {
|
||||
if (this.active_repo.issearchresult) {
|
||||
// list view is desiged to display treeview
|
||||
// it is not working well with search result
|
||||
this.view_as_icons();
|
||||
this.viewbar_set_enabled(true);
|
||||
this.print_path();
|
||||
if (this.viewmode == 2) {
|
||||
this.view_as_list();
|
||||
} else if (this.viewmode == 3) {
|
||||
this.view_as_table();
|
||||
} else {
|
||||
this.viewbar_set_enabled(true);
|
||||
this.print_path();
|
||||
if (this.viewmode == 2) {
|
||||
this.view_as_list();
|
||||
} else if (this.viewmode == 3) {
|
||||
this.view_as_table();
|
||||
} else {
|
||||
this.view_as_icons();
|
||||
}
|
||||
this.view_as_icons();
|
||||
}
|
||||
},
|
||||
treeview_dynload: function(node, cb) {
|
||||
@@ -541,18 +559,10 @@ M.core_filepicker.init = function(Y, options) {
|
||||
filenamediv.setContent(filename);
|
||||
var imgdiv = element.one('.fp-thumbnail');
|
||||
var set_width = function(node, width) {
|
||||
var widthmatches = node.getStyle('minWidth').match(/^(\d+)px$/)
|
||||
if (widthmatches && parseInt(widthmatches[1])>width) {
|
||||
width = parseInt(widthmatches[1]);
|
||||
}
|
||||
node.setStyle('width', '' + width + 'px')
|
||||
node.setStyle('width', '' + Math.max(width, node.getStylePx('minWidth')) + 'px')
|
||||
}
|
||||
var set_height = function(node, height) {
|
||||
var heightmatches = node.getStyle('minHeight').match(/^(\d+)px$/)
|
||||
if (heightmatches && parseInt(heightmatches[1])>height) {
|
||||
height = parseInt(heightmatches[1]);
|
||||
}
|
||||
node.setStyle('height', '' + height + 'px')
|
||||
node.setStyle('height', '' + Math.max(height, node.getStylePx('minHeight')) + 'px')
|
||||
}
|
||||
var width = node.thumbnail_width ? node.thumbnail_width : 90;
|
||||
var height = node.thumbnail_height ? node.thumbnail_height : 90;
|
||||
@@ -656,75 +666,90 @@ M.core_filepicker.init = function(Y, options) {
|
||||
this.selectui.show();
|
||||
var client_id = this.options.client_id;
|
||||
var selectnode = this.fpnode.one('.fp-select');
|
||||
var return_types = this.options.repositories[this.active_repo.id].return_types;
|
||||
selectnode.removeClass('loading');
|
||||
selectnode.one('#newname-'+client_id).set('value', args.title);
|
||||
selectnode.one('#text-author-'+client_id).set('value', this.options.author);
|
||||
selectnode.one('.fp-saveas input').set('value', args.title);
|
||||
selectnode.one('.fp-setauthor input').set('value', this.options.author);
|
||||
|
||||
var imgnode = Y.Node.create('<img/>').set('src', args.thumbnail)
|
||||
selectnode.one('#img-'+client_id).setContent('').appendChild(imgnode);
|
||||
selectnode.one('.fp-thumbnail').setContent('').appendChild(imgnode);
|
||||
|
||||
selectnode.one('#linkexternal-'+client_id).set('checked', ''); // default to unchecked
|
||||
if ((this.options.externallink && this.options.env == 'editor' && this.options.return_types != 1)) {
|
||||
// enable checkbox 'Link external'
|
||||
selectnode.one('#linkexternal-'+client_id).set('disabled', '');
|
||||
selectnode.all('#linkexternal-'+client_id+',#wrap-linkexternal-'+client_id).removeClass('uneditable')
|
||||
selectnode.one('.fp-linkexternal input').set('checked', ''); // default to unchecked
|
||||
if ((this.options.externallink && this.options.env == 'editor' && return_types == 3)) {
|
||||
// support both internal and external links, enable checkbox 'Link external'
|
||||
selectnode.one('.fp-linkexternal input').set('disabled', '');
|
||||
selectnode.all('.fp-linkexternal').removeClass('uneditable')
|
||||
} else {
|
||||
// disable checkbox 'Link external'
|
||||
selectnode.one('#linkexternal-'+client_id).set('disabled', 'disabled');
|
||||
selectnode.all('#linkexternal-'+client_id+',#wrap-linkexternal-'+client_id).addClass('uneditable')
|
||||
if (this.options.return_types == 1) {
|
||||
selectnode.one('.fp-linkexternal input').set('disabled', 'disabled');
|
||||
selectnode.all('.fp-linkexternal').addClass('uneditable')
|
||||
if (return_types == 1) {
|
||||
// support external links only
|
||||
selectnode.one('#linkexternal-'+client_id).set('checked', 'checked');
|
||||
selectnode.one('.fp-linkexternal input').set('checked', 'checked');
|
||||
}
|
||||
}
|
||||
|
||||
if (args.hasauthor) {
|
||||
selectnode.one('#text-author-'+client_id).set('disabled', 'disabled');
|
||||
selectnode.all('#text-author-'+client_id+',#wrap-text-author-'+client_id).addClass('uneditable')
|
||||
selectnode.one('.fp-setauthor input').set('disabled', 'disabled');
|
||||
selectnode.all('.fp-setauthor').addClass('uneditable')
|
||||
} else {
|
||||
selectnode.one('#text-author-'+client_id).set('disabled', '');
|
||||
selectnode.all('#text-author-'+client_id+',#wrap-text-author-'+client_id).removeClass('uneditable')
|
||||
selectnode.one('.fp-setauthor input').set('disabled', '');
|
||||
selectnode.all('.fp-setauthor').removeClass('uneditable')
|
||||
}
|
||||
|
||||
if (!args.haslicense) {
|
||||
// the license of the file
|
||||
this.populate_licenses_select(selectnode.one('#select-license-'+client_id));
|
||||
selectnode.one('#wrap-select-license-'+client_id).set('disabled', '');
|
||||
selectnode.all('#select-license-'+client_id+'#wrap-select-license-'+client_id).removeClass('uneditable');
|
||||
selectnode.one('.fp-setlicense select').set('disabled', '');
|
||||
selectnode.one('.fp-setlicense').removeClass('uneditable');
|
||||
} else {
|
||||
selectnode.one('#wrap-select-license-'+client_id).set('disabled', 'disabled');
|
||||
selectnode.all('#select-license-'+client_id+'#wrap-select-license-'+client_id).addClass('uneditable');
|
||||
selectnode.one('.fp-setlicense select').set('disabled', 'disabled');
|
||||
selectnode.one('.fp-setlicense').addClass('uneditable');
|
||||
}
|
||||
|
||||
selectnode.one('form #filesource-'+client_id).set('value', args.source);
|
||||
|
||||
// display static information about a file (when known)
|
||||
var attrs = ['datemodified','datecreated','size','license','author','dimensions'];
|
||||
for (var i in attrs) {
|
||||
if (selectnode.one('.fp-'+attrs[i])) {
|
||||
var value = (args[attrs[i]+'_f']) ? args[attrs[i]+'_f'] : (args[attrs[i]] ? args[attrs[i]] : '');
|
||||
selectnode.one('.fp-'+attrs[i]).addClassIf('fp-unknown', ''+value == '')
|
||||
.one('.fp-value').setContent(value);
|
||||
}
|
||||
}
|
||||
},
|
||||
setup_select_file: function() {
|
||||
var client_id = this.options.client_id;
|
||||
var selectnode = this.fpnode.one('.fp-select');
|
||||
var getfile = selectnode.one('#fp-confirm-'+client_id);
|
||||
var getfile = selectnode.one('.fp-select-confirm');
|
||||
// bind labels with corresponding inputs
|
||||
selectnode.all('.fp-saveas,.fp-linkexternal,.fp-setauthor,.fp-setlicense').each(function (node) {
|
||||
node.all('label').set('for', node.one('input,select').generateID());
|
||||
});
|
||||
this.populate_licenses_select(selectnode.one('.fp-setlicense select'));
|
||||
// register event on clicking submit button
|
||||
getfile.on('click', function(e) {
|
||||
e.preventDefault();
|
||||
var client_id = this.options.client_id;
|
||||
var scope = this;
|
||||
var repository_id = this.active_repo.id;
|
||||
var title = selectnode.one('#newname-'+client_id).get('value');
|
||||
var title = selectnode.one('.fp-saveas input').get('value');
|
||||
var filesource = selectnode.one('form #filesource-'+client_id).get('value');
|
||||
var params = {'title':title, 'source':filesource, 'savepath': this.options.savepath};
|
||||
var license = selectnode.one('#select-license-'+client_id);
|
||||
var license = selectnode.one('.fp-setlicense select');
|
||||
if (license) {
|
||||
params['license'] = license.get('value');
|
||||
Y.Cookie.set('recentlicense', license.get('value'));
|
||||
}
|
||||
var author = selectnode.one('#text-author-'+client_id);
|
||||
if (author){
|
||||
params['author'] = author.get('value');
|
||||
}
|
||||
params['author'] = selectnode.one('.fp-setauthor input').get('value');
|
||||
|
||||
if (this.options.externallink && this.options.env == 'editor') {
|
||||
// in editor, images are stored in '/' only
|
||||
params.savepath = '/';
|
||||
// when image or media button is clicked
|
||||
if ( this.options.return_types != 1 ) {
|
||||
var linkexternal = selectnode.one('#linkexternal-'+client_id);
|
||||
var return_types = this.options.repositories[this.active_repo.id].return_types;
|
||||
if ( return_types != 1 ) {
|
||||
var linkexternal = selectnode.one('.fp-linkexternal input');
|
||||
if (linkexternal && linkexternal.get('checked')) {
|
||||
params['linkexternal'] = 'yes';
|
||||
}
|
||||
@@ -775,7 +800,7 @@ M.core_filepicker.init = function(Y, options) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}, this);
|
||||
var cancel = selectnode.one('#fp-cancel-'+client_id);
|
||||
var cancel = selectnode.one('.fp-select-cancel');
|
||||
cancel.on('click', function(e) {
|
||||
e.preventDefault();
|
||||
this.selectui.hide();
|
||||
@@ -815,24 +840,9 @@ M.core_filepicker.init = function(Y, options) {
|
||||
},
|
||||
render: function() {
|
||||
var client_id = this.options.client_id;
|
||||
var nodecontent = M.core_filepicker.templates.generallayout.
|
||||
replace(/\{TOOLBARID}/g, 'fp-tb-'+client_id).
|
||||
replace(/\{TOOLBACKID}/g, 'fp-tb-back-'+client_id).
|
||||
replace(/\{TOOLSEARCHID}/g, 'fp-tb-search-'+client_id).
|
||||
replace(/\{TOOLREFRESHID}/g, 'fp-tb-refresh-'+client_id).
|
||||
replace(/\{TOOLLOGOUTID}/g, 'fp-tb-logout-'+client_id).
|
||||
replace(/\{TOOLMANAGEID}/g, 'fp-tb-manage-'+client_id).
|
||||
replace(/\{TOOLHELPID}/g, 'fp-tb-help-'+client_id);
|
||||
this.fpnode = Y.Node.create(nodecontent).set('id', 'filepicker-'+client_id);
|
||||
var fpselectnode = Y.Node.create(M.core_filepicker.templates.selectlayout.
|
||||
replace(/\{IMGID}/g, 'img-'+client_id).
|
||||
replace(/\{NEWNAMEID}/g, 'newname-'+client_id).
|
||||
replace(/\{LINKEXTID}/g, 'linkexternal-'+client_id).
|
||||
replace(/\{AUTHORID}/g, 'text-author-'+client_id).
|
||||
replace(/\{LICENSEID}/g, 'select-license-'+client_id).
|
||||
replace(/\{BUTCONFIRMID}/g, 'fp-confirm-'+client_id).
|
||||
replace(/\{BUTCANCELID}/g, 'fp-cancel-'+client_id)
|
||||
);
|
||||
this.fpnode = Y.Node.create(M.core_filepicker.templates.generallayout).
|
||||
set('id', 'filepicker-'+client_id);
|
||||
var fpselectnode = Y.Node.create(M.core_filepicker.templates.selectlayout);
|
||||
Y.one(document.body).appendChild(this.fpnode);
|
||||
this.fpnode.appendChild(fpselectnode);
|
||||
this.mainui = new Y.Panel({
|
||||
@@ -842,10 +852,25 @@ M.core_filepicker.init = function(Y, options) {
|
||||
centered : true,
|
||||
modal : true,
|
||||
visible : false,
|
||||
render : true,
|
||||
plugins : [Y.Plugin.Drag]
|
||||
render : true
|
||||
});
|
||||
// allow to move the panel dragging it by it's header:
|
||||
this.mainui.plug(Y.Plugin.Drag,{handles:['.yui3-widget-hd']});
|
||||
// Check if CSS for the node sets min-max width/height and therefore if panel shall be resizable:
|
||||
var resizeconstraints = {
|
||||
minWidth: this.fpnode.getStylePx('minWidth')?this.fpnode.getStylePx('minWidth'):this.fpnode.getStylePx('width'),
|
||||
minHeight: this.fpnode.getStylePx('minHeight')?this.fpnode.getStylePx('minHeight'):this.fpnode.getStylePx('height'),
|
||||
maxWidth: this.fpnode.getStylePx('maxWidth')?this.fpnode.getStylePx('maxWidth'):this.fpnode.getStylePx('width'),
|
||||
maxHeight: this.fpnode.getStylePx('maxHeight')?this.fpnode.getStylePx('maxHeight'):this.fpnode.getStylePx('height'),
|
||||
preserveRatio: false
|
||||
};
|
||||
if (resizeconstraints.minWidth < resizeconstraints.maxWidth ||
|
||||
resizeconstraints.minHeight < resizeconstraints.maxHeight) {
|
||||
this.mainui.plug(Y.Plugin.Resize)
|
||||
this.mainui.resize.plug(Y.Plugin.ResizeConstrained, resizeconstraints);
|
||||
}
|
||||
this.mainui.show();
|
||||
// create panel for selecting a file (initially hidden)
|
||||
this.selectui = new Y.Panel({
|
||||
srcNode : fpselectnode,
|
||||
zIndex : 600000,
|
||||
@@ -1121,35 +1146,33 @@ M.core_filepicker.init = function(Y, options) {
|
||||
create_upload_form: function(data) {
|
||||
var client_id = this.options.client_id;
|
||||
var id = data.upload.id+'_'+client_id;
|
||||
var str = M.core_filepicker.templates.uploadform.
|
||||
replace(/\{UPLOADFORMID}/g, id).
|
||||
replace(/\{INPUTFILEID}/g, id+'_file').
|
||||
replace(/\{NEWNAMEID}/g, 'newname-'+client_id).
|
||||
replace(/\{AUTHORID}/g, 'author-'+client_id).
|
||||
replace(/\{LICENSEID}/g, 'license-'+client_id).
|
||||
replace(/\{BUTUPLOADID}/g, id+'_action');
|
||||
this.fpnode.one('.fp-content').setContent(str);
|
||||
var content = this.fpnode.one('.fp-content');
|
||||
content.setContent(M.core_filepicker.templates.uploadform);
|
||||
|
||||
Y.all('#'+id+'_file').set('name', 'repo_upload_file');
|
||||
Y.all('#'+'newname-'+client_id).set('name', 'title');
|
||||
Y.all('#'+'author-'+client_id).set('name', 'author');
|
||||
Y.all('#'+'author-'+client_id).set('value', this.options.author);
|
||||
Y.all('#'+'license-'+client_id).set('name', 'license');
|
||||
this.populate_licenses_select(Y.one('#'+'license-'+client_id))
|
||||
Y.one('#'+id).appendChild(Y.Node.create('<input/>').
|
||||
content.all('.fp-file,.fp-saveas,.fp-setauthor,.fp-setlicense').each(function (node) {
|
||||
node.all('label').set('for', node.one('input,select').generateID());
|
||||
});
|
||||
content.one('form').set('id', id);
|
||||
content.one('.fp-file input').set('name', 'repo_upload_file');
|
||||
content.one('.fp-saveas input').set('name', 'title');
|
||||
content.one('.fp-setauthor input').setAttrs({name:'author', value:this.options.author});
|
||||
content.one('.fp-setlicense select').set('name', 'license');
|
||||
this.populate_licenses_select(content.one('.fp-setlicense select'))
|
||||
// append hidden inputs to the upload form
|
||||
content.one('form').appendChild(Y.Node.create('<input/>').
|
||||
setAttrs({type:'hidden',name:'itemid',value:this.options.itemid}));
|
||||
var types = this.options.accepted_types;
|
||||
for (var i in types) {
|
||||
Y.one('#'+id).appendChild(Y.Node.create('<input/>').
|
||||
content.one('form').appendChild(Y.Node.create('<input/>').
|
||||
setAttrs({type:'hidden',name:'accepted_types[]',value:types[i]}));
|
||||
}
|
||||
|
||||
var scope = this;
|
||||
Y.one('#'+id+'_action').on('click', function(e) {
|
||||
content.one('.fp-upload-btn').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
var license = Y.one('#license-'+client_id);
|
||||
var license = content.one('.fp-setlicense select');
|
||||
Y.Cookie.set('recentlicense', license.get('value'));
|
||||
if (!Y.one('#'+id+'_file').get('value')) {
|
||||
if (!content.one('.fp-file input').get('value')) {
|
||||
scope.print_msg(M.str.repository.nofilesattached, 'error');
|
||||
return false;
|
||||
}
|
||||
@@ -1185,7 +1208,8 @@ M.core_filepicker.init = function(Y, options) {
|
||||
/** setting handlers and labels for elements in toolbar. Called once during the initial render of filepicker */
|
||||
setup_toolbar: function() {
|
||||
var client_id = this.options.client_id;
|
||||
Y.one('#fp-tb-logout-'+client_id).on('click', function(e) {
|
||||
var toolbar = this.fpnode.one('.fp-toolbar');
|
||||
toolbar.one('.fp-tb-logout').one('a,button').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
if (!this.active_repo.nologin) {
|
||||
this.hide_header();
|
||||
@@ -1198,14 +1222,15 @@ M.core_filepicker.init = function(Y, options) {
|
||||
}, true);
|
||||
}
|
||||
}, this);
|
||||
Y.one('#fp-tb-refresh-'+client_id).on('click', function(e) {
|
||||
toolbar.one('.fp-tb-refresh').one('a,button').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
if (!this.active_repo.norefresh) {
|
||||
this.list();
|
||||
}
|
||||
}, this);
|
||||
Y.one('#fp-tb-search-'+client_id).
|
||||
toolbar.one('.fp-tb-search form').
|
||||
set('method', 'POST').
|
||||
set('id', 'fp-tb-search-'+client_id).
|
||||
on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
if (!this.active_repo.nosearch) {
|
||||
@@ -1220,31 +1245,32 @@ M.core_filepicker.init = function(Y, options) {
|
||||
}
|
||||
}, this);
|
||||
|
||||
// it does not matter what kind of element is {TOOLMANAGEID}, we create a dummy <a>
|
||||
// it does not matter what kind of element is .fp-tb-manage, we create a dummy <a>
|
||||
// element and use it to open url on click event
|
||||
var managelnk = Y.Node.create('<a/>').
|
||||
setAttrs({id:'fp-tb-manage-'+client_id+'-link', target:'_blank'}).
|
||||
setStyle('display', 'none');
|
||||
Y.one('#fp-tb-'+client_id).append(managelnk);
|
||||
Y.one('#fp-tb-manage-'+client_id).on('click', function(e) {
|
||||
e.preventDefault();
|
||||
managelnk.simulate('click')
|
||||
});
|
||||
toolbar.append(managelnk);
|
||||
toolbar.one('.fp-tb-manage').one('a,button').
|
||||
on('click', function(e) {
|
||||
e.preventDefault();
|
||||
managelnk.simulate('click')
|
||||
});
|
||||
|
||||
// same with {TOOLHELPID}
|
||||
// same with .fp-tb-help
|
||||
var helplnk = Y.Node.create('<a/>').
|
||||
setAttrs({id:'fp-tb-help-'+client_id+'-link', target:'_blank'}).
|
||||
setStyle('display', 'none');
|
||||
Y.one('#fp-tb-'+client_id).append(helplnk);
|
||||
Y.one('#fp-tb-help-'+client_id).on('click', function(e) {
|
||||
e.preventDefault();
|
||||
helplnk.simulate('click')
|
||||
});
|
||||
toolbar.append(helplnk);
|
||||
toolbar.one('.fp-tb-manage').one('a,button').
|
||||
on('click', function(e) {
|
||||
e.preventDefault();
|
||||
helplnk.simulate('click')
|
||||
});
|
||||
},
|
||||
hide_header: function() {
|
||||
var client_id = this.options.client_id;
|
||||
if (Y.one('#fp-tb-'+client_id)) {
|
||||
Y.one('#fp-tb-'+client_id).addClass('empty');
|
||||
if (this.fpnode.one('.fp-toolbar')) {
|
||||
this.fpnode.one('.fp-toolbar').addClass('empty');
|
||||
}
|
||||
if (this.pathbar) {
|
||||
this.pathbar.setContent('').addClass('empty');
|
||||
@@ -1259,23 +1285,26 @@ M.core_filepicker.init = function(Y, options) {
|
||||
var client_id = this.options.client_id;
|
||||
this.hide_header();
|
||||
this.print_paging();
|
||||
this.print_path();
|
||||
var toolbar = this.fpnode.one('.fp-toolbar');
|
||||
if (!toolbar) { return; }
|
||||
|
||||
var enable_tb_control = function(elementid, enabled) {
|
||||
if (!enabled) {
|
||||
Y.all('#'+elementid+',#wrap-'+elementid).addClass('disabled').removeClass('enabled')
|
||||
} else {
|
||||
Y.all('#'+elementid+',#wrap-'+elementid).removeClass('disabled').addClass('enabled')
|
||||
Y.one('#fp-tb-'+client_id).removeClass('empty');
|
||||
var enable_tb_control = function(node, enabled) {
|
||||
if (!node) { return; }
|
||||
node.addClassIf('disabled', !enabled).addClassIf('enabled', enabled)
|
||||
if (enabled) {
|
||||
toolbar.removeClass('empty');
|
||||
}
|
||||
}
|
||||
|
||||
// TODO 'back' permanently disabled for now. Note, flickr_public uses 'Logout' for it!
|
||||
enable_tb_control('fp-tb-back-'+client_id, false);
|
||||
enable_tb_control(toolbar.one('.fp-tb-back'), false);
|
||||
|
||||
// search form
|
||||
enable_tb_control('fp-tb-search-'+client_id, !r.nosearch);
|
||||
enable_tb_control(toolbar.one('.fp-tb-search'), !r.nosearch);
|
||||
if(!r.nosearch) {
|
||||
Y.all('#fp-tb-search-'+client_id).setContent('');
|
||||
var searchform = toolbar.one('.fp-tb-search form');
|
||||
searchform.setContent('');
|
||||
this.request({
|
||||
scope: this,
|
||||
action:'searchform',
|
||||
@@ -1283,7 +1312,7 @@ M.core_filepicker.init = function(Y, options) {
|
||||
callback: function(id, obj, args) {
|
||||
if (obj.repo_id == scope.active_repo.id && obj.form) {
|
||||
// if we did not jump to another repository meanwhile
|
||||
Y.all('#fp-tb-search-'+scope.options.client_id).setContent(obj.form);
|
||||
searchform.setContent(obj.form);
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
@@ -1291,24 +1320,22 @@ M.core_filepicker.init = function(Y, options) {
|
||||
|
||||
// refresh button
|
||||
// weather we use cache for this instance, this button will reload listing anyway
|
||||
enable_tb_control('fp-tb-refresh-'+client_id, !r.norefresh);
|
||||
enable_tb_control(toolbar.one('.fp-tb-refresh'), !r.norefresh);
|
||||
|
||||
// login button
|
||||
enable_tb_control('fp-tb-logout-'+client_id, !r.nologin);
|
||||
enable_tb_control(toolbar.one('.fp-tb-logout'), !r.nologin);
|
||||
if(!r.nologin) {
|
||||
var label = r.logouttext?r.logouttext:M.str.repository.logout;
|
||||
Y.one('#fp-tb-logout-'+client_id).setContent(label)
|
||||
toolbar.one('.fp-tb-logout').one('a,button').setContent(label)
|
||||
}
|
||||
|
||||
// manage url
|
||||
enable_tb_control('fp-tb-manage-'+client_id, r.manage);
|
||||
enable_tb_control(toolbar.one('.fp-tb-manage'), r.manage);
|
||||
Y.one('#fp-tb-manage-'+client_id+'-link').set('href', r.manage);
|
||||
|
||||
// help url
|
||||
enable_tb_control('fp-tb-help-'+client_id, r.help);
|
||||
enable_tb_control(toolbar.one('.fp-tb-help'), r.help);
|
||||
Y.one('#fp-tb-help-'+client_id+'-link').set('href', r.help);
|
||||
|
||||
this.print_path();
|
||||
},
|
||||
get_page_button: function(page) {
|
||||
var r = this.active_repo;
|
||||
|
||||
+26
-18
@@ -1793,37 +1793,45 @@ abstract class repository {
|
||||
}
|
||||
$len = count($listing['list']);
|
||||
for ($i=0; $i<$len; $i++) {
|
||||
if (isset($listing['list'][$i]['size'])) {
|
||||
$listing['list'][$i]['size'] = (int)$listing['list'][$i]['size'];
|
||||
$listing['list'][$i]['size_f'] = display_size($listing['list'][$i]['size']);
|
||||
$file = & $listing['list'][$i];
|
||||
if (isset($file['size'])) {
|
||||
$file['size'] = (int)$file['size'];
|
||||
$file['size_f'] = display_size($file['size']);
|
||||
}
|
||||
if (isset($file['license']) &&
|
||||
get_string_manager()->string_exists($file['license'], 'license')) {
|
||||
$file['license_f'] = get_string($file['license'], 'license');
|
||||
}
|
||||
if (isset($file['image_width']) && isset($file['image_height'])) {
|
||||
$file['dimensions'] = $file['image_width'].'x'.$file['image_height'];
|
||||
}
|
||||
foreach (array('date', 'datemodified', 'datecreated') as $key) {
|
||||
if (!isset($listing['list'][$i][$key]) && isset($listing['list'][$i]['date'])) {
|
||||
$listing['list'][$i][$key] = $listing['list'][$i]['date'];
|
||||
if (!isset($file[$key]) && isset($file['date'])) {
|
||||
$file[$key] = $file['date'];
|
||||
}
|
||||
if (isset($listing['list'][$i][$key])) {
|
||||
if (isset($file[$key])) {
|
||||
// must be UNIX timestamp
|
||||
$listing['list'][$i][$key] = (int)$listing['list'][$i][$key];
|
||||
if (!$listing['list'][$i][$key]) {
|
||||
unset($listing['list'][$i][$key]);
|
||||
$file[$key] = (int)$file[$key];
|
||||
if (!$file[$key]) {
|
||||
unset($file[$key]);
|
||||
} else {
|
||||
$listing['list'][$i][$key.'_f'] = userdate($listing['list'][$i][$key], get_string('strftimedatetime', 'langconfig'));
|
||||
$listing['list'][$i][$key.'_f_s'] = userdate($listing['list'][$i][$key], get_string('strftimedatetimeshort', 'langconfig'));
|
||||
$file[$key.'_f'] = userdate($file[$key], get_string('strftimedatetime', 'langconfig'));
|
||||
$file[$key.'_f_s'] = userdate($file[$key], get_string('strftimedatetimeshort', 'langconfig'));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isset($listing['list'][$i]['type']) && !array_key_exists('children', $listing['list'][$i]) && isset($listing['list'][$i]['title'])) {
|
||||
$mimetype = mimeinfo('type', $listing['list'][$i]['title']);
|
||||
if (!isset($file['type']) && !array_key_exists('children', $file) && isset($file['title'])) {
|
||||
$mimetype = mimeinfo('type', $file['title']);
|
||||
if (get_string_manager()->string_exists($mimetype, 'mimetypes')) {
|
||||
$mimetype = get_string($mimetype, 'mimetypes');
|
||||
}
|
||||
$listing['list'][$i]['type'] = $mimetype;
|
||||
$file['type'] = $mimetype;
|
||||
}
|
||||
if (!isset($listing['list'][$i]['icon']) && isset($listing['list'][$i]['title'])) {
|
||||
if (array_key_exists('children', $listing['list'][$i])) {
|
||||
$listing['list'][$i]['icon'] = $OUTPUT->pix_url('f/folder')->out(false);
|
||||
if (!isset($file['icon']) && isset($file['title'])) {
|
||||
if (array_key_exists('children', $file)) {
|
||||
$file['icon'] = $OUTPUT->pix_url('f/folder')->out(false);
|
||||
} else {
|
||||
$listing['list'][$i]['icon'] = $OUTPUT->pix_url('f/'.mimeinfo('icon', $listing['list'][$i]['title']))->out(false);
|
||||
$file['icon'] = $OUTPUT->pix_url('f/'.mimeinfo('icon', $file['title']))->out(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+78
-70
@@ -36,7 +36,9 @@ class core_repository_renderer extends plugin_renderer_base {
|
||||
* Template for FilePicker with general layout (not QuickUpload).
|
||||
*
|
||||
* Must have one top element containing everything else (recommended <div class="file-picker">),
|
||||
* CSS for this element must define width and height of the filepicker window;
|
||||
* CSS for this element must define width and height of the filepicker window. Or CSS must
|
||||
* define min-width, max-width, min-height and max-height and in this case the filepicker
|
||||
* window will be resizeable;
|
||||
*
|
||||
* Element with class 'fp-viewbar' will have the class 'enabled' or 'disabled' when view mode
|
||||
* can be changed or not;
|
||||
@@ -59,23 +61,18 @@ class core_repository_renderer extends plugin_renderer_base {
|
||||
* The content of element with class 'fp-path-folder-name' will be substituted with folder name;
|
||||
* Parent element will receive class 'empty' when there are no folders to be displayed;
|
||||
*
|
||||
* Element with id {TOOLBARID} will have class 'empty' if all 'Search', 'Login', 'Refresh' and
|
||||
* 'Logout' are unavailable for this repo;
|
||||
* Element with id {TOOLBACKID} will hold the click event for going back to Login form;
|
||||
* Element (<form>!) with id {TOOLSEARCHID} is responsible for search inside the repo (if
|
||||
* repository provides this functionality), it must have one input-text field;
|
||||
* Element with id {TOOLREFRESHID} will hold the click event for refreshing current view;
|
||||
* Element with id {TOOLLOGOUTID} will hold the click event for logout (the content of the
|
||||
* element will be substituted with logout string provided by repository or default
|
||||
* M.str.repository.logout if not specified);
|
||||
* Element with id {TOOLMANAGEID} will hold the click event for opening new window to manage
|
||||
* repository files;
|
||||
* Element with id {TOOLHELPID} will hold the click event for opening new window for help;
|
||||
* Elements with ids {TOOLBACKID}, {TOOLSEARCHID}, {TOOLREFRESHID}, {TOOLLOGOUTID},
|
||||
* {TOOLMANAGEID}, {TOOLHELPID} and also optional elements width ids wrap-{TOOLBACKID},
|
||||
* wrap-{TOOLSEARCHID}, wrap-{TOOLREFRESHID}, wrap-{TOOLLOGOUTID}, wrap-{TOOLMANAGEID} and
|
||||
* wrap-{TOOLHELPID} will have class 'enabled' or 'disabled' when applicable or not for
|
||||
* the current repository view;
|
||||
* Element with class 'fp-toolbar' will have class 'empty' if all 'Back', 'Search', 'Refresh',
|
||||
* 'Logout', 'Manage' and 'Help' are unavailable for this repo;
|
||||
*
|
||||
* Inside fp-toolbar there are expected elements with classes fp-tb-back, fp-tb-search,
|
||||
* fp-tb-refresh, fp-tb-logout, fp-tb-manage and fp-tb-help. Each of them will have
|
||||
* class 'enabled' or 'disabled' if particular repository has this functionality.
|
||||
* Element with class 'fp-tb-search' must contain empty form inside, it's contents will
|
||||
* be substituted with the search form returned by repository (in the most cases it
|
||||
* is generated with template core_repository_renderer::repository_default_searchform);
|
||||
* Other elements must have either <a> or <button> element inside, it will hold onclick
|
||||
* event for corresponding action; labels for fp-tb-back and fp-tb-logout may be
|
||||
* replaced with those specified by repository;
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -96,16 +93,16 @@ class core_repository_renderer extends plugin_renderer_base {
|
||||
</ul>
|
||||
</div>
|
||||
<div style="width:480px;height:400px;display:inline-block;vertical-align:top;">
|
||||
<div class="fp-toolbar" id="{TOOLBARID}" style="background:yellow">
|
||||
<div id="wrap-{TOOLBACKID}"><a id="{TOOLBACKID}">'.get_string('back', 'repository').'</a></div>
|
||||
<div id="wrap-{TOOLSEARCHID}">
|
||||
<div class="{!}fp-toolbar">
|
||||
<div class="{!}fp-tb-back"><a>'.get_string('back', 'repository').'</a></div>
|
||||
<div class="{!}fp-tb-search">
|
||||
<img src="'.$this->pix_url('a/search').'" />
|
||||
<form id="{TOOLSEARCHID}"></form>
|
||||
<form/>
|
||||
</div>
|
||||
<div id="wrap-{TOOLREFRESHID}"><a id="{TOOLREFRESHID}"><img src="'.$this->pix_url('a/refresh').'" />'.get_string('refresh', 'repository').'</a></div>
|
||||
<div id="wrap-{TOOLLOGOUTID}"><img src="'.$this->pix_url('a/logout').'" /><a id="{TOOLLOGOUTID}"></a></div>
|
||||
<div id="wrap-{TOOLMANAGEID}"><a id="{TOOLMANAGEID}"><img src="'.$this->pix_url('a/setting').'" /> '.get_string('manageurl', 'repository').'</a></div>
|
||||
<div id="wrap-{TOOLHELPID}"><a id="{TOOLHELPID}"><img src="'.$this->pix_url('a/help').'" /> '.get_string('help').'</a></div>
|
||||
<div class="{!}fp-tb-refresh"><a><img src="'.$this->pix_url('a/refresh').'" />'.get_string('refresh', 'repository').'</a></div>
|
||||
<div class="{!}fp-tb-logout"><img src="'.$this->pix_url('a/logout').'" /><a></a></div>
|
||||
<div class="{!}fp-tb-manage"><a><img src="'.$this->pix_url('a/setting').'" /> '.get_string('manageurl', 'repository').'</a></div>
|
||||
<div class="{!}fp-tb-help"><a><img src="'.$this->pix_url('a/help').'" /> '.get_string('help').'</a></div>
|
||||
</div>
|
||||
<div class="{!}fp-paging" style="background:pink"></div>
|
||||
<div class="fp-pathbar" style="background:#ddffdd">
|
||||
@@ -169,18 +166,21 @@ class core_repository_renderer extends plugin_renderer_base {
|
||||
* All content must be enclosed in an element with class 'fp-select', CSS for this class
|
||||
* must define width and height of the window;
|
||||
*
|
||||
* Image will be added as content to the element with id {IMGID};
|
||||
* Thumbnail image will be added as content to the element with class 'fp-thumbnail';
|
||||
*
|
||||
* Inside the window <form> element must be present and contain followng input fields:
|
||||
* {NEWNAMEID} (input-text)
|
||||
* {LINKEXTID} (input-checkbox)
|
||||
* {AUTHORID} (input-text)
|
||||
* {LICENSEID} (select, will be populated with available options)
|
||||
* {BUTCONFIRMID} (will hold onclick event)
|
||||
* {BUTCANCELID} (will hold onclick event)
|
||||
* Inside the window the elements with the following classnames must be present:
|
||||
* 'fp-saveas', 'fp-linkexternal', 'fp-setauthor', 'fp-setlicense'. Inside each of them must have
|
||||
* one input element (or select in case of fp-setlicense). They may also have labels.
|
||||
* The elements will be assign with class 'uneditable' and input/select element will become
|
||||
* disabled if they are not applicable for the particular file;
|
||||
*
|
||||
* Elements with ids 'wrap-{LINKEXTID}', 'wrap-{AUTHORID}' and 'wrap-{LICENSEID}' may be
|
||||
* assigned with class 'uneditable' if not applicable for particular repository;
|
||||
* There may be present elements with classes 'fp-datemodified', 'fp-datecreated', 'fp-size',
|
||||
* 'fp-license', 'fp-author'. They will receive additional class 'fp-unknown' if information
|
||||
* is unavailable. If there is information available, the content of embedded element
|
||||
* with class 'fp-value' will be substituted with the value;
|
||||
*
|
||||
* Elements with classes 'fp-select-confirm' and 'fp-select-cancel' will hold corresponding
|
||||
* onclick events;
|
||||
*
|
||||
* When confirm button is pressed and file is being selected, the top element receives
|
||||
* additional class 'loading'. It is removed when response from server is received.
|
||||
@@ -194,20 +194,27 @@ class core_repository_renderer extends plugin_renderer_base {
|
||||
<p>'.get_string('loading', 'repository').'</p>
|
||||
</div>
|
||||
<form>
|
||||
<p id="{IMGID}"></p>
|
||||
<p class="{!}fp-thumbnail"></p>
|
||||
<table width="100%">
|
||||
<tr><td class="mdl-right"><label for="{NEWNAMEID}">'.get_string('saveas', 'repository').'</label>:</td>
|
||||
<td class="mdl-left"><input type="text" id="{NEWNAMEID}" /></td></tr>
|
||||
<tr id="wrap-{LINKEXTID}"><td></td>
|
||||
<td class="mdl-left"><input type="checkbox" id="{LINKEXTID}" value="" /><label for="{LINKEXTID}">'.get_string('linkexternal', 'repository').'</label></td></tr>
|
||||
<tr id="wrap-{AUTHORID}"><td class="mdl-right"><label for="{AUTHORID}">'.get_string('author', 'repository').'</label>:</td>
|
||||
<td class="mdl-left"><input id="{AUTHORID}" type="text" /></td></tr>
|
||||
<tr id="wrap-{LICENSEID}"><td class="mdl-right"><label for="{LICENSEID}">'.get_string('chooselicense', 'repository').'</label>:</td>
|
||||
<td class="mdl-left"><select id="{LICENSEID}"></select></td></tr>
|
||||
<tr class="{!}fp-saveas"><td class="mdl-right"><label>'.get_string('saveas', 'repository').'</label>:</td>
|
||||
<td class="mdl-left"><input type="text"/></td></tr>
|
||||
<tr class="{!}fp-linkexternal"><td></td>
|
||||
<td class="mdl-left"><input type="checkbox"/><label>'.get_string('linkexternal', 'repository').'</label></td></tr>
|
||||
<tr class="{!}fp-setauthor"><td class="mdl-right"><label>'.get_string('author', 'repository').'</label>:</td>
|
||||
<td class="mdl-left"><input type="text" /></td></tr>
|
||||
<tr class="{!}fp-setlicense"><td class="mdl-right"><label>'.get_string('chooselicense', 'repository').'</label>:</td>
|
||||
<td class="mdl-left"><select></select></td></tr>
|
||||
</table>
|
||||
<p><button id="{BUTCONFIRMID}" >'.get_string('getfile', 'repository').'</button>
|
||||
<button id="{BUTCANCELID}" >'.get_string('cancel').'</button></p>
|
||||
</form></div>';
|
||||
<p><button class="{!}fp-select-confirm" >'.get_string('getfile', 'repository').'</button>
|
||||
<button class="{!}fp-select-cancel" >'.get_string('cancel').'</button></p>
|
||||
</form>
|
||||
<div class="{!}fp-datemodified">'.get_string('lastmodified', 'moodle').': <span class="fp-value"/></div>
|
||||
<div class="{!}fp-datecreated">'.get_string('datecreated', 'repository').': <span class="fp-value"/></div>
|
||||
<div class="{!}fp-size">'.get_string('size', 'repository').': <span class="fp-value"/></div>
|
||||
<div class="{!}fp-license">'.get_string('license', 'moodle').': <span class="fp-value"/></div>
|
||||
<div class="{!}fp-author">'.get_string('author', 'repository').': <span class="fp-value"/></div>
|
||||
<div class="{!}fp-dimensions">'.get_string('dimensions', 'repository').': <span class="fp-value"/></div>
|
||||
</div>';
|
||||
return preg_replace('/\{\!\}/', '', $rv);
|
||||
}
|
||||
|
||||
@@ -215,42 +222,43 @@ class core_repository_renderer extends plugin_renderer_base {
|
||||
* Content to display when user chooses 'Upload file' repository (will be nested inside
|
||||
* element with class 'fp-content').
|
||||
*
|
||||
* Must contain form (enctype="multipart/form-data" method="POST") with id {UPLOADFORMID}
|
||||
* The elements with the following ids are obligatory:
|
||||
* {INPUTFILEID} (input-file)
|
||||
* {NEWNAMEID} (input-text)
|
||||
* {AUTHORID} (input-text)
|
||||
* {LICENSEID} (select, will be populated with available options)
|
||||
* {BUTUPLOADID} (any element type, will hold onclick event)
|
||||
* Must contain form (enctype="multipart/form-data" method="POST")
|
||||
*
|
||||
* The elements with the following classnames must be present:
|
||||
* 'fp-file', 'fp-saveas', 'fp-setauthor', 'fp-setlicense'. Inside each of them must have
|
||||
* one input element (or select in case of fp-setlicense). They may also have labels.
|
||||
*
|
||||
* Element with class 'fp-upload-btn' will hold onclick event for uploading the file;
|
||||
*
|
||||
* Please note that some fields may be hidden using CSS if this is part of quickupload form
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function js_template_uploadform() {
|
||||
return '<div class="fp-upload-form mdl-align">
|
||||
<form id="{UPLOADFORMID}" enctype="multipart/form-data" method="POST">
|
||||
$rv = '<div class="fp-upload-form mdl-align">
|
||||
<form enctype="multipart/form-data" method="POST">
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td class="mdl-right"><label for="{INPUTFILEID}">'.get_string('attachment', 'repository').'</label>:</td>
|
||||
<td class="mdl-left"><input type="file" id="{INPUTFILEID}" /></td>
|
||||
<tr class="{!}fp-file">
|
||||
<td class="mdl-right"><label>'.get_string('attachment', 'repository').'</label>:</td>
|
||||
<td class="mdl-left"><input type="file"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="mdl-right"><label for="{NEWNAMEID}">'.get_string('saveas', 'repository').'</label>:</td>
|
||||
<td class="mdl-left"><input type="text" id="{NEWNAMEID}" /></td>
|
||||
<tr class="{!}fp-saveas">
|
||||
<td class="mdl-right"><label>'.get_string('saveas', 'repository').'</label>:</td>
|
||||
<td class="mdl-left"><input type="text"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="mdl-right"><label for="{AUTHORID}">'.get_string('author', 'repository').'</label>:</td>
|
||||
<td class="mdl-left"><input type="text" id="{AUTHORID}" /></td>
|
||||
<tr class="{!}fp-setauthor">
|
||||
<td class="mdl-right"><label>'.get_string('author', 'repository').'</label>:</td>
|
||||
<td class="mdl-left"><input type="text"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="mdl-right"><label for="{LICENSEID}">'.get_string('chooselicense', 'repository').'</label>:</td>
|
||||
<td class="mdl-left"><select id="{LICENSEID}" /></td>
|
||||
<tr class="{!}fp-setlicense">
|
||||
<td class="mdl-right"><label>'.get_string('chooselicense', 'repository').'</label>:</td>
|
||||
<td class="mdl-left"><select/></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<div class="fp-upload-btn"><button id="{BUTUPLOADID}">'.get_string('upload', 'repository').'</button></div>
|
||||
<div><button class="{!}fp-upload-btn">'.get_string('upload', 'repository').'</button></div>
|
||||
</div> ';
|
||||
return preg_replace('/\{\!\}/', '', $rv);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user