1 // YUI3 File Picker module for moodle
2 // Author: Dongsheng Cai <dongsheng@moodle.com>
8 * this.rendered, it tracks if YUI Panel rendered
9 * this.api, stores the URL to make ajax request
10 * this.mainui, YUI Panel
11 * this.treeview, YUI Treeview
12 * this.viewbar, a button group to switch view mode
13 * this.viewmode, store current view mode
17 * this.options.client_id, the instance id
18 * this.options.contextid
20 * this.options.repositories, stores all repositories displaied in file picker
21 * this.options.formcallback
23 * Active repository options
26 * this.active_repo.nosearch
27 * this.active_repo.norefresh
28 * this.active_repo.nologin
29 * this.active_repo.help
30 * this.active_repo.manage
34 * this.filelist, cached filelist
37 * this.filepath, current path
38 * this.logindata, cached login form
41 M.core_filepicker = M.core_filepicker || {};
44 * instances of file pickers used on page
46 M.core_filepicker.instances = M.core_filepicker.instances || {};
47 M.core_filepicker.active_filepicker = null;
50 * Init and show file picker
52 M.core_filepicker.show = function(Y, options) {
53 if (!M.core_filepicker.instances[options.client_id]) {
54 M.core_filepicker.init(Y, options);
56 M.core_filepicker.instances[options.client_id].show();
60 * Add new file picker to current instances
62 M.core_filepicker.init = function(Y, options) {
63 var FilePickerHelper = function(options) {
64 FilePickerHelper.superclass.constructor.apply(this, arguments);
67 FilePickerHelper.NAME = "FilePickerHelper";
68 FilePickerHelper.ATTRS = {
73 Y.extend(FilePickerHelper, Y.Base, {
74 api: M.cfg.wwwroot+'/repository/repository_ajax.php',
76 initializer: function(options) {
77 this.options = options;
78 if (!this.options.savepath) {
79 this.options.savepath = '/';
83 destructor: function() {
86 request: function(args, redraw) {
87 var client_id = args.client_id;
88 var api = this.api + '?action='+args.action;
92 scope = args['scope'];
94 params['repo_id']=args.repository_id;
95 params['p'] = args.path?args.path:'';
96 params['page'] = args.page?args.page:'';
97 params['env']=this.options.env;
98 // the form element only accept certain file types
99 params['accepted_types']=this.options.accepted_types;
100 params['sesskey']=M.cfg.sesskey;
101 params['client_id'] = args.client_id;
102 params['filearea'] = this.options.filearea?this.options.filearea:'user_draft';
103 params['itemid'] = this.options.itemid?this.options.itemid:0;
104 params['maxbytes'] = this.options.maxbytes?this.options.maxbytes:-1;
105 if (args['params']) {
106 for (i in args['params']) {
107 params[i] = args['params'][i];
113 complete: function(id,o,p) {
114 var panel_id = '#panel-'+client_id;
121 data = Y.JSON.parse(o.responseText);
123 Y.one(panel_id).set('innerHTML', 'ERROR: '+M.str.repository.invalidjson);
127 if (data && data.e) {
128 Y.one(panel_id).set('innerHTML', 'ERROR: '+data.e);
131 args.callback(id,data,p);
139 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
140 'User-Agent': 'MoodleFilePicker/3.0'
142 data: build_querystring(params),
146 cfg.form = args.form;
154 build_tree: function(node, level) {
155 var client_id = this.options.client_id;
156 var dynload = this.active_repo.dynload;
158 node.title = '<i><u>'+node.title+'</u></i>';
162 //title:fp_lang.date+' '+node.date+fp_lang.size+' '+node.size,
164 source:node.source?node.source:'',
165 thumbnail:node.thumbnail,
166 path:node.path?node.path:[]
168 var tmpNode = new YAHOO.widget.TextNode(info, level, false);
169 //var tooltip = new YAHOO.widget.Tooltip(tmpNode.labelElId, {
170 //context:tmpNode.labelElId, text:info.title});
172 tmpNode.repo_id=node.repo_id;
174 tmpNode.repo_id=this.active_repo.id;
181 tmpNode.scope = this;
183 tmpNode.isLeaf = false;
184 tmpNode.client_id = client_id;
186 tmpNode.path = node.path;
190 for(var c in node.children) {
191 this.build_tree(node.children[c], tmpNode);
194 tmpNode.isLeaf = true;
197 view_files: function() {
198 this.viewbar.set('disabled', false);
199 if (this.viewmode == 1) {
200 this.view_as_icons();
201 } else if (this.viewmode ==2) {
204 this.view_as_icons();
207 treeview_dynload: function(node, cb) {
208 var scope = node.scope;
209 var client_id = scope.options.client_id;
210 var repository_id = scope.active_repo.id;
213 client_id: client_id,
214 repository_id: repository_id,
215 path:node.path?node.path:'',
216 page:node.page?args.page:'',
217 callback: function(id, obj, args) {
218 obj.issearchresult = false;
220 scope.viewbar.set('disabled', false);
221 scope.parse_repository_options(obj);
223 scope.build_tree(list[k], node);
229 view_as_list: function() {
231 var client_id = this.options.client_id;
232 var dynload = this.active_repo.dynload;
233 var list = this.filelist;
234 var panel_id = '#panel-'+client_id;
236 Y.one(panel_id).set('innerHTML', '');
239 var tree = Y.Node.create('<div id="treeview-'+client_id+'"></div>');
240 Y.one(panel_id).appendChild(tree);
241 this.treeview = new YAHOO.widget.TreeView('treeview-'+client_id);
243 this.treeview.setDynamicLoad(this.treeview_dynload, 1);
247 this.build_tree(list[k], this.treeview.getRoot());
250 this.treeview.subscribe('clickEvent', function(e){
253 fileinfo['title'] = e.node.data.filename;
254 fileinfo['source'] = e.node.data.source;
255 fileinfo['thumbnail'] = e.node.data.thumbnail;
256 scope.select_file(fileinfo);
259 this.treeview.draw();
261 view_as_icons: function() {
263 var client_id = this.options.client_id;
264 var list = this.filelist;
265 var panel_id = '#panel-'+client_id;
267 Y.one(panel_id).set('innerHTML', '');
271 var gridpanel = Y.Node.create('<div id="fp-grid-panel-'+client_id+'"></div>');
272 Y.one('#panel-'+client_id).appendChild(gridpanel);
276 var grid = document.createElement('DIV');
277 grid.className='fp-grid';
279 var title = document.createElement('DIV');
280 title.id = 'grid-title-'+client_id+'-'+String(count);
281 title.className = 'label';
282 if (node.shorttitle) {
283 node.title = node.shorttitle;
285 title.innerHTML += '<a href="###"><span>'+node.title+"</span></a>";
287 if(node.thumbnail_width){
288 grid.style.width = node.thumbnail_width+'px';
289 title.style.width = (node.thumbnail_width-10)+'px';
291 grid.style.width = title.style.width = '90px';
293 var frame = document.createElement('DIV');
294 frame.style.textAlign='center';
295 if(node.thumbnail_height){
296 frame.style.height = node.thumbnail_height+'px';
298 var img = document.createElement('img');
299 img.src = node.thumbnail;
300 if(node.thumbnail_alt) {
301 img.alt = node.thumbnail_alt;
303 if(node.thumbnail_title) {
304 img.title = node.thumbnail_title;
307 var link = document.createElement('A');
309 link.id = 'img-id-'+client_id+'-'+String(count);
312 //grid.innerHTML += '<p><a target="_blank" href="'+node.url+'">'+M.str.repository.preview+'</a></p>';
314 link.appendChild(img);
315 frame.appendChild(link);
316 grid.appendChild(frame);
317 grid.appendChild(title);
318 gridpanel.appendChild(grid);
320 var y_title = Y.one('#'+title.id);
321 var y_file = Y.one('#'+link.id);
322 var dynload = this.active_repo.dynload;
324 y_file.on('click', function(e, p) {
326 var params = {'path':p.path};
329 this.filelist = p.children;
333 y_title.on('click', function(e, p){
334 y_file.simulate('click');
338 fileinfo['title'] = list[k].title;
339 fileinfo['source'] = list[k].source;
340 fileinfo['thumbnail'] = list[k].thumbnail;
341 fileinfo['haslicense'] = list[k].haslicense?true:false;
342 fileinfo['hasauthor'] = list[k].hasauthor?true:false;
343 y_title.on('click', function(e, args) {
344 this.select_file(args);
346 y_file.on('click', function(e, args) {
347 this.select_file(args);
353 select_file: function(args) {
354 var client_id = this.options.client_id;
355 var thumbnail = Y.one('#fp-grid-panel-'+client_id);
357 thumbnail.setStyle('display', 'none');
359 var header = Y.one('#fp-header-'+client_id);
361 header.setStyle('display', 'none');
363 var footer = Y.one('#fp-footer-'+client_id);
365 footer.setStyle('display', 'none');
367 var path = Y.one('#path-'+client_id);
369 path.setStyle('display', 'none');
371 var panel = Y.one('#panel-'+client_id);
372 var form_id = 'fp-rename-form-'+client_id;
373 var html = '<div class="fp-rename-form" id="'+form_id+'">';
374 html += '<p><img src="'+args.thumbnail+'" /></p>';
375 html += '<p><label for="newname-'+client_id+'">'+M.str.repository.saveas+':</label>';
376 html += '<input type="text" id="newname-'+client_id+'" value="'+args.title+'" /></p>';
380 if (this.options.repositories[this.active_repo.id].return_types == 1) {
381 // support external links only
382 le_checked = 'checked';
383 le_style = ' style="display:none;"';
384 } else if(this.options.repositories[this.active_repo.id].return_types == 2) {
385 // support internal files only
386 le_style = ' style="display:none;"';
388 if (this.options.externallink && this.options.env == 'editor') {
389 html += '<p'+le_style+'><input type="checkbox" id="linkexternal-'+client_id+'" value="" '+le_checked+' />'+M.str.repository.linkexternal+'</p>';
392 if (!args.hasauthor) {
393 // the author of the file
394 html += '<p><label for="text-author">'+M.str.repository.author+' :</label>';
395 html += '<input id="text-author-'+client_id+'" type="text" name="author" value="'+this.options.author+'" />';
399 if (!args.haslicense) {
400 // the license of the file
401 var licenses = this.options.licenses;
402 html += '<p><label for="select-license-'+client_id+'">'+M.str.repository.chooselicense+' :</label>';
403 html += '<select name="license" id="select-license-'+client_id+'">';
404 for (var i in licenses) {
405 html += '<option value="'+licenses[i].shortname+'">'+licenses[i].fullname+'</option>';
407 html += '</select></p>';
410 html += '<p><input type="hidden" id="filesource-'+client_id+'" value="'+args.source+'" />';
411 html += '<input type="button" id="fp-confirm-'+client_id+'" value="'+M.str.repository.getfile+'" />';
412 html += '<input type="button" id="fp-cancel-'+client_id+'" value="'+M.str.moodle.cancel+'" /></p>';
415 var getfile_form = Y.Node.create(html);
416 panel.appendChild(getfile_form);
418 var getfile = Y.one('#fp-confirm-'+client_id);
419 getfile.on('click', function(e) {
420 var client_id = this.options.client_id;
422 var repository_id = this.active_repo.id;
423 var title = Y.one('#newname-'+client_id).get('value');
424 var filesource = Y.one('#filesource-'+client_id).get('value');
425 var params = {'title':title, 'source':filesource, 'savepath': this.options.savepath};
426 var license = Y.one('#select-license-'+client_id);
428 params['license'] = license.get('value');
430 var author = Y.one('#text-author-'+client_id);
432 params['author'] = author.get('value');
435 if (this.options.env == 'editor') {
436 // in editor, images are stored in '/' only
437 params.savepath = '/';
438 var linkexternal = Y.one('#linkexternal-'+client_id).get('checked');
440 params['linkexternal'] = 'yes';
442 } if (this.options.env == 'url') {
443 params['linkexternal'] = 'yes';
446 this.wait('download', title);
449 client_id: client_id,
450 repository_id: repository_id,
452 callback: function(id, obj, args) {
453 if (scope.options.editor_target && scope.options.env=='editor') {
454 scope.options.editor_target.value=obj.url;
455 scope.options.editor_target.onchange();
458 obj.client_id = client_id;
459 var formcallback_scope = null;
460 if (args.scope.options.magicscope) {
461 formcallback_scope = args.scope.options.magicscope;
463 formcallback_scope = args.scope;
465 scope.options.formcallback.apply(formcallback_scope, [obj]);
469 var elform = Y.one('#'+form_id);
470 elform.on('keydown', function(e) {
471 if (e.keyCode == 13) {
472 getfile.simulate('click');
476 var cancel = Y.one('#fp-cancel-'+client_id);
477 cancel.on('click', function(e) {
480 var treeview = Y.one('#treeview-'+client_id);
482 treeview.setStyle('display', 'none');
485 wait: function(type) {
486 var panel = Y.one('#panel-'+this.options.client_id);
487 panel.set('innerHTML', '');
489 var str = '<div style="text-align:center">';
491 str += '<img src="'+M.util.image_url('i/loading')+'" />';
492 str += '<p>'+M.str.repository.loading+'</p>';
494 str += '<img src="'+M.util.image_url('i/progressbar')+'" />';
495 str += '<p>'+M.str.repository.copying+' <strong>'+name+'</strong></p>';
499 panel.set('innerHTML', str);
505 var client_id = this.options.client_id;
506 var filepicker_id = 'filepicker-'+client_id;
507 var fpnode = Y.Node.create('<div class="file-picker" id="'+filepicker_id+'"></div>');
508 Y.one(document.body).appendChild(fpnode);
509 // render file picker panel
510 this.mainui = new YAHOO.widget.Panel(filepicker_id, {
515 monitorresize: false,
516 xy: [50, YAHOO.util.Dom.getDocumentScrollTop()+20]
519 this.mainui.beforeRenderEvent.subscribe(function() {
520 YAHOO.util.Event.onAvailable('layout-'+client_id, function() {
521 layout = new YAHOO.widget.Layout('layout-'+client_id, {
522 height: 480, width: 700,
524 {position: 'top', height: 32, resize: false,
525 body:'<div class="yui-buttongroup fp-viewbar" id="fp-viewbar-'+client_id+'"></div><div class="fp-searchbar" id="search-div-'+client_id+'"></div>', gutter: '2'},
526 {position: 'left', width: 200, resize: true, scroll:true,
527 body:'<ul class="fp-list" id="fp-list-'+client_id+'"></ul>', gutter: '0 5 0 2', minWidth: 150, maxWidth: 300 },
528 {position: 'center', body: '<div class="fp-panel" id="panel-'+client_id+'"></div>',
529 scroll: true, gutter: '0 2 0 0' }
536 this.mainui.setHeader('File Picker');
537 this.mainui.setBody('<div id="layout-'+client_id+'"></div>');
538 this.mainui.render();
539 this.rendered = true;
543 var view_icons = {label: M.str.repository.iconview, value: 't',
546 scope.view_as_icons();
550 var view_listing = {label: M.str.repository.listview, value: 'l',
553 scope.view_as_list();
557 this.viewbar = new YAHOO.widget.ButtonGroup({
558 id: 'btngroup-'+client_id,
561 container: 'fp-viewbar-'+client_id
563 this.viewbar.addButtons([view_icons, view_listing]);
564 // processing repository listing
565 var r = this.options.repositories;
566 Y.on('contentready', function(el) {
567 var list = Y.one(el);
570 var id = 'repository-'+client_id+'-'+count;
571 var link_id = id + '-link';
572 list.append('<li id="'+id+'"><a class="fp-repo-name" id="'+link_id+'" href="###">'+r[i].name+'</a></li>');
573 Y.one('#'+link_id).prepend('<img src="'+r[i].icon+'" width="16" height="16" /> ');
574 Y.one('#'+link_id).on('click', function(e, scope, repository_id) {
575 scope.repository_id = repository_id;
576 Y.all(el+' li a').setStyle('backgroundColor', 'transparent');
577 e.currentTarget.setStyle('backgroundColor', '#CCC');
578 this.list({'repo_id':repository_id});
579 }, this /*handler running scope*/, this/*second argument*/, r[i].id/*third argument of handler*/);
582 }, '#fp-list-'+client_id, this /* handler running scope */, '#fp-list-'+client_id /*first argument of handler*/);
584 parse_repository_options: function(data) {
585 this.filelist = data.list?data.list:null;
586 this.filepath = data.path?data.path:null;
587 this.active_repo = {};
588 this.active_repo.issearchresult = Boolean(data.issearchresult);
589 this.active_repo.dynload = data.dynload?data.dynload:false;
590 this.active_repo.pages = Number(data.pages?data.pages:null);
591 this.active_repo.page = Number(data.page?data.page:null);
592 this.active_repo.id = data.repo_id?data.repo_id:null;
593 this.active_repo.nosearch = data.nosearch?true:false;
594 this.active_repo.norefresh = data.norefresh?true:false;
595 this.active_repo.nologin = data.nologin?true:false;
596 this.active_repo.help = data.help?data.help:null;
597 this.active_repo.manage = data.manage?data.manage:null;
599 print_login: function(data) {
600 this.parse_repository_options(data);
601 var client_id = this.options.client_id;
602 var repository_id = data.repo_id;
603 var l = this.logindata = data.login;
605 var panel = Y.one('#panel-'+client_id);
606 var action = 'login';
607 if (data['login_btn_action']) {
608 action=data['login_btn_action'];
610 var form_id = 'fp-form-'+client_id;
611 var download_button_id = 'fp-form-download-button-'+client_id;
612 var search_button_id = 'fp-form-search-button-'+client_id;
613 var login_button_id = 'fp-form-login-button-'+client_id;
614 var popup_button_id = 'fp-form-popup-button-'+client_id;
616 var str = '<div class="fp-login-form">';
617 str += '<form id="'+form_id+'">';
619 str +='<table width="100%">';
622 if(l[k].type=='popup') {
625 str += '<td colspan="2"><p class="fp-popup">'+M.str.repository.popup+'</p>';
626 str += '<p class="fp-popup"><button id="'+popup_button_id+'">'+M.str.repository.login+'</button>';
629 }else if(l[k].type=='textarea') {
631 str += '<td colspan="2"><p><textarea id="'+l[k].id+'" name="'+l[k].name+'"></textarea></p></td>';
632 }else if(l[k].type=='select') {
634 str += '<td align="right"><label>'+l[k].label+':</label></td>';
635 str += '<td align="left"><select id="'+l[k].id+'" name="'+l[k].name+'">';
636 for (i in l[k].options) {
637 str += '<option value="'+l[k].options[i].value+'">'+l[k].options[i].label+'</option>';
639 str += '</select></td>';
644 var field_value = '';
646 label_id = ' for="'+l[k].id+'"';
647 field_id = ' id="'+l[k].id+'"';
650 str += '<td align="right" width="30%" valign="center">';
651 str += '<label'+label_id+'>'+l[k].label+'</label> </td>';
653 str += '<td width="30%"></td>';
656 field_value = ' value="'+l[k].value+'"';
658 if(l[k].type=='radio'){
659 var list = l[k].value.split('|');
660 var labels = l[k].value_label.split('|');
661 str += '<td align="left">';
662 for(var item in list) {
663 str +='<input type="'+l[k].type+'"'+' name="'+l[k].name+'"'+
664 field_id+' value="'+list[item]+'" />'+labels[item]+'<br />';
668 str += '<td align="left">';
669 str += '<input type="'+l[k].type+'"'+' name="'+l[k].name+'"'+field_value+' '+field_id+' />';
679 var btn_label = data['login_btn_label']?data['login_btn_label']:M.str.repository.submit;
680 if (action != 'popup') {
681 str += '<p><input type="button" id="';
684 str += search_button_id;
687 str += download_button_id;
690 str += login_button_id;
693 str += '" value="'+btn_label+'" /></p>';
700 panel.set('innerHTML', str);
702 alert(e.toString()+M.str.quiz.xhtml);
705 // process login action
706 var login_button = Y.one('#'+login_button_id);
709 login_button.on('click', function(){
711 var data = this.logindata;
714 for (var k in data) {
715 if(data[k].type!='popup') {
716 var el = Y.one('[name='+data[k].name+']');
717 var type = el.get('type');
718 params[data[k].name] = '';
719 if(type == 'checkbox') {
720 params[data[k].name] = el.get('checked');
722 params[data[k].name] = el.get('value');
726 // start ajax request
732 'client_id': client_id,
733 'repository_id': repository_id,
734 'callback': function(id, o, args) {
735 scope.parse_repository_options(o);
744 var search_button = Y.one('#'+search_button_id);
746 search_button.on('click', function(){
747 var data = this.logindata;
750 for (var k in data) {
751 if(data[k].type!='popup') {
752 var el = document.getElementsByName(data[k].name)[0];
753 params[data[k].name] = '';
754 if(el.type == 'checkbox') {
755 params[data[k].name] = el.checked;
756 } else if(el.type == 'radio') {
757 var tmp = document.getElementsByName(data[k].name);
759 if (tmp[i].checked) {
760 params[data[k].name] = tmp[i].value;
764 params[data[k].name] = el.value;
771 client_id: client_id,
772 repository_id: repository_id,
773 form: {id: 'fp-form-'+scope.options.client_id,upload:false,useDisabled:true},
774 callback: function(id, o, args) {
775 o.issearchresult = true;
776 scope.parse_repository_options(o);
782 var download_button = Y.one('#'+download_button_id);
783 if (download_button) {
784 download_button.on('click', function(){
788 var popup_button = Y.one('#'+popup_button_id);
790 popup_button.on('click', function(e){
791 M.core_filepicker.active_filepicker = this;
792 window.open(loginurl, 'repo_auth', 'location=0,status=0,width=500,height=300');
796 var elform = Y.one('#'+form_id);
797 elform.on('keydown', function(e) {
798 if (e.keyCode == 13) {
801 search_button.simulate('click');
804 login_button.simulate('click');
812 search: function(args) {
813 var data = this.logindata;
816 for (var k in data) {
817 if(data[k].type!='popup') {
818 var el = document.getElementsByName(data[k].name)[0];
819 params[data[k].name] = '';
820 if(el.type == 'checkbox') {
821 params[data[k].name] = el.checked;
822 } else if(el.type == 'radio') {
823 var tmp = document.getElementsByName(data[k].name);
825 if (tmp[i].checked) {
826 params[data[k].name] = tmp[i].value;
830 params[data[k].name] = el.value;
837 client_id: client_id,
838 repository_id: repository_id,
839 form: {id: 'fp-form-'+scope.options.client_id,upload:false,useDisabled:true},
840 callback: function(id, o, args) {
841 o.issearchresult = true;
842 scope.parse_repository_options(o);
847 list: function(args) {
853 args.repo_id = scope.active_repo.id;
857 client_id: scope.options.client_id,
858 repository_id: args.repo_id,
859 path:args.path?args.path:'',
860 page:args.page?args.page:'',
861 callback: function(id, obj, args) {
863 scope.viewbar.set('disabled', true);
864 scope.print_login(obj);
865 } else if (obj.upload) {
866 scope.viewbar.set('disabled', true);
867 scope.parse_repository_options(obj);
868 scope.create_upload_form(obj);
870 } else if (obj.iframe) {
872 } else if (obj.list) {
873 obj.issearchresult = false;
874 scope.viewbar.set('disabled', false);
875 scope.parse_repository_options(obj);
879 // TODO: Print message
884 create_upload_form: function(data) {
885 var client_id = this.options.client_id;
886 Y.one('#panel-'+client_id).set('innerHTML', '');
889 var id = data.upload.id+'_'+client_id;
890 var str = '<div id="'+id+'_div" class="fp-upload-form">';
891 str += '<form id="'+id+'" method="POST">';
892 str += '<table border=1>';
894 str += '<label for="'+id+'_file">'+data.upload.label+': </label></td>';
895 str += '<td><input type="file" id="'+id+'_file" name="repo_upload_file" />';
896 str += '<input type="hidden" name="itemid" value="'+this.options.itemid+'" /></tr>';
898 str += '<td><label>'+M.str.repository.author+': </label></td>';
899 str += '<td><input type="text" name="author" value="'+this.options.author+'" /></td>';
902 str += '<td>'+M.str.repository.chooselicense+': </td>';
904 var licenses = this.options.licenses;
905 str += '<select name="license" id="select-license-'+client_id+'">';
906 for (var i in licenses) {
907 str += '<option value="'+licenses[i].shortname+'">'+licenses[i].fullname+'</option>';
911 str += '</tr></table>';
913 str += '<div class="fp-upload-btn"><button id="'+id+'_action">'+M.str.repository.upload+'...</button></div>';
915 var upload_form = Y.Node.create(str);
916 Y.one('#panel-'+client_id).appendChild(upload_form);
918 Y.one('#'+id+'_action').on('click', function(e) {
920 Y.use('io-upload-iframe', function() {
924 client_id: client_id,
925 params: {'savepath':scope.options.savepath},
926 repository_id: scope.active_repo.id,
927 form: {id: id, upload:true},
928 callback: function(id, o, args) {
929 if (scope.options.editor_target&&scope.options.env=='editor') {
930 scope.options.editor_target.value=o.url;
931 scope.options.editor_target.onchange();
934 o.client_id = client_id;
935 var formcallback_scope = null;
936 if (args.scope.options.magicscope) {
937 formcallback_scope = args.scope.options.magicscope;
939 formcallback_scope = args.scope;
941 scope.options.formcallback.apply(formcallback_scope, [o]);
947 print_header: function() {
948 var r = this.active_repo;
950 var client_id = this.options.client_id;
951 var repository_id = this.active_repo.id;
952 var panel = Y.one('#panel-'+client_id);
953 var str = '<div id="fp-header-'+client_id+'">';
954 str += '<div class="fp-toolbar" id="repo-tb-'+client_id+'"></div>';
956 var head = Y.Node.create(str);
957 panel.appendChild(head);
958 //if(this.active_repo.pages < 8){
959 this.print_paging('header');
963 var toolbar = Y.one('#repo-tb-'+client_id);
966 var html = '<a href="###"><img src="'+M.util.image_url('a/search')+'" /> '+M.str.repository.search+'</a>';
967 var search = Y.Node.create(html);
968 search.on('click', function() {
972 repository_id: repository_id,
973 callback: function(id, obj, args) {
974 var scope = args.scope;
975 var client_id = scope.options.client_id;
976 var repository_id = scope.active_repo.id;
977 var container = document.getElementById('fp-search-dlg');
979 container.innerHTML = '';
980 container.parentNode.removeChild(container);
982 var container = document.createElement('DIV');
983 container.id = 'fp-search-dlg';
985 var dlg_title = document.createElement('DIV');
986 dlg_title.className = 'hd';
987 dlg_title.innerHTML = 'filepicker';
989 var dlg_body = document.createElement('DIV');
990 dlg_body.className = 'bd';
992 var sform = document.createElement('FORM');
993 sform.method = 'POST';
994 sform.id = "fp-search-form";
995 sform.innerHTML = obj.form;
997 dlg_body.appendChild(sform);
998 container.appendChild(dlg_title);
999 container.appendChild(dlg_body);
1000 Y.one(document.body).appendChild(container);
1001 var search_dialog= null;
1002 function dialog_handler() {
1003 scope.viewbar.set('disabled', false);
1007 client_id: client_id,
1008 repository_id: repository_id,
1009 form: {id: 'fp-search-form',upload:false,useDisabled:true},
1010 callback: function(id, o, args) {
1011 scope.parse_repository_options(o);
1015 search_dialog.cancel();
1018 search_dialog = new YAHOO.widget.Dialog("fp-search-dlg", {
1019 postmethod: 'async',
1025 constraintoviewport : true,
1028 text:M.str.repository.submit,
1029 handler:dialog_handler,
1032 text:M.str.moodle.cancel,
1038 search_dialog.render();
1039 search_dialog.show();
1043 toolbar.appendChild(search);
1045 // weather we use cache for this instance, this button will reload listing anyway
1047 var html = '<a href="###"><img src="'+M.util.image_url('a/refresh')+'" /> '+M.str.repository.refresh+'</a>';
1048 var refresh = Y.Node.create(html);
1049 refresh.on('click', function() {
1052 toolbar.appendChild(refresh);
1055 var html = '<a href="###"><img src="'+M.util.image_url('a/logout')+'" /> '+M.str.repository.logout+'</a>';
1056 var logout = Y.Node.create(html);
1057 logout.on('click', function() {
1060 client_id: client_id,
1061 repository_id: repository_id,
1063 callback: function(id, obj, args) {
1064 scope.viewbar.set('disabled', true);
1065 scope.print_login(obj);
1069 toolbar.appendChild(logout);
1073 var mgr = document.createElement('A');
1074 mgr.href = r.manage;
1075 mgr.target = "_blank";
1076 mgr.innerHTML = '<img src="'+M.util.image_url('a/setting')+'" /> '+M.str.repository.manageurl;
1077 toolbar.appendChild(mgr);
1080 var help = document.createElement('A');
1082 help.target = "_blank";
1083 help.innerHTML = '<img src="'+M.util.image_url('a/help')+'" /> '+M.str.repository.help;
1084 toolbar.appendChild(help);
1087 // only show in icons view
1088 if (this.viewmode == 1) {
1092 get_page_button: function(page) {
1093 var r = this.active_repo;
1095 if (page == r.page) {
1096 css = 'class="cur_page" ';
1098 var str = '<a '+css+'href="###" id="repo-page-'+page+'">';
1101 print_paging: function(html_id) {
1102 var client_id = this.options.client_id;
1104 var r = this.active_repo;
1108 str += '<div class="fp-paging" id="paging-'+html_id+'-'+client_id+'">';
1109 str += this.get_page_button(1)+'1</a> ';
1112 var ex = (span-1)/2;
1114 if (r.page+ex>=r.pages) {
1120 var max = r.page+ex;
1124 // won't display upper boundary
1125 if (r.page >= span) {
1127 for(var i=r.page-ex; i<max; i++) {
1128 str += this.get_page_button(i);
1133 // this very first elements
1134 for(var i = 2; i < max; i++) {
1135 str += this.get_page_button(i);
1141 // won't display upper boundary
1143 str += this.get_page_button(r.pages)+r.pages+'</a>';
1145 str += this.get_page_button(max)+max+'</a>';
1146 str += ' ... '+this.get_page_button(r.pages)+r.pages+'</a>';
1151 var a = Y.Node.create(str);
1152 Y.one('#fp-header-'+client_id).appendChild(a);
1154 Y.all('#fp-header-'+client_id+' .fp-paging a').each(
1155 function(node, id) {
1156 node.on('click', function(e) {
1157 var id = node.get('id');
1158 var re = new RegExp("repo-page-(\\d+)", "i");
1159 var result = id.match(re);
1161 args.page = result[1];
1162 if (scope.active_repo.issearchresult) {
1166 client_id: client_id,
1167 repository_id: r.id,
1168 params: {'page':result[1]},
1169 callback: function(id, o, args) {
1170 o.issearchresult = true;
1171 scope.parse_repository_options(o);
1183 print_path: function() {
1184 var client_id = this.options.client_id;
1185 if (this.viewmode == 2) {
1188 var panel = Y.one('#panel-'+client_id);
1189 var p = this.filepath;
1190 if (p && p.length!=0) {
1191 var path = Y.Node.create('<div id="path-'+client_id+'" class="fp-pathbar"></div>');
1192 panel.appendChild(path);
1193 for(var i = 0; i < p.length; i++) {
1194 var link_path = p[i].path;
1195 var link = document.createElement('A');
1197 link.innerHTML = p[i].name;
1198 link.id = 'path-node-'+client_id+'-'+i;
1199 var sep = Y.Node.create('<span>/</span>');
1200 path.appendChild(link);
1201 path.appendChild(sep);
1202 Y.one('#'+link.id).on('click', function(Y, path){
1203 this.list({'path':path});
1212 if (this.rendered) {
1213 var panel = Y.one('#panel-'+this.options.client_id);
1214 panel.set('innerHTML', '');
1220 launch: function() {
1225 M.core_filepicker.instances[options.client_id] = new FilePickerHelper(options);