Merge branch 'MDL-31656-master-3' of git://git.luns.net.uk/moodle
[moodle.git] / lib / form / filemanager.js
1 // This file is part of Moodle - http://moodle.org/
2 //
3 // Moodle is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // Moodle is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
15 /**
16  *
17  * File Manager UI
18  * =====
19  * this.api, stores the URL to make ajax request
20  * this.currentpath
21  * this.filepicker_options
22  * this.movefile_dialog
23  * this.mkdir_dialog
24  * this.rename_dialog
25  * this.client_id
26  * this.filecount, how many files in this filemanager
27  * this.maxfiles
28  * this.maxbytes
29  *
30  * FileManager options:
31  * =====
32  * this.options.currentpath
33  * this.options.itemid
34  */
37 M.form_filemanager = {};
39 /**
40  * This fucntion is called for each file picker on page.
41  */
42 M.form_filemanager.init = function(Y, options) {
43     var FileManagerHelper = function(options) {
44         FileManagerHelper.superclass.constructor.apply(this, arguments);
45     };
46     FileManagerHelper.NAME = "FileManager";
47     FileManagerHelper.ATTRS = {
48         options: {},
49         lang: {}
50     };
52     Y.extend(FileManagerHelper, Y.Base, {
53         api: M.cfg.wwwroot+'/repository/draftfiles_ajax.php',
54         menus: {},
55         initializer: function(options) {
56             this.options = options;
57             if (options.mainfile) {
58                 this.enablemainfile = options.mainfile;
59             }
60             this.client_id = options.client_id;
61             this.currentpath = '/';
62             this.maxfiles = options.maxfiles;
63             this.maxbytes = options.maxbytes;
65             this.filepicker_options = options.filepicker?options.filepicker:{};
66             this.filepicker_options.client_id = this.client_id;
67             this.filepicker_options.context = options.context;
68             this.filepicker_options.maxfiles = this.maxfiles;
69             this.filepicker_options.maxbytes = this.maxbytes;
70             this.filepicker_options.env = 'filemanager';
71             this.filepicker_options.itemid = options.itemid;
73             if (options.filecount) {
74                 this.filecount = options.filecount;
75             } else {
76                 this.filecount = 0;
77             }
78             this.setup_buttons();
79             this.refresh(this.currentpath); // MDL-31113 get latest list from server
80         },
82         wait: function(client_id) {
83             var container = Y.one('#filemanager-'+client_id);
84             container.set('innerHTML', '');
85             var html = Y.Node.create('<ul id="draftfiles-'+client_id+'"></ul>');
86             container.appendChild(html);
87             var panel = Y.one('#draftfiles-'+client_id);
88             var name = '';
89             var str = '<div style="text-align:center">';
90             str += '<img src="'+M.util.image_url('i/loading_small')+'" />';
91             str += '</div>';
92             try {
93                 panel.set('innerHTML', str);
94             } catch(e) {
95                 alert(e.toString());
96             }
97         },
98         request: function(args, redraw) {
99             var api = this.api + '?action='+args.action;
100             var params = {};
101             var scope = this;
102             if (args['scope']) {
103                 scope = args['scope'];
104             }
105             params['sesskey'] = M.cfg.sesskey;
106             params['client_id'] = this.client_id;
107             params['filepath'] = this.currentpath;
108             params['itemid'] = this.options.itemid?this.options.itemid:0;
109             if (args['params']) {
110                 for (i in args['params']) {
111                     params[i] = args['params'][i];
112                 }
113             }
114             var cfg = {
115                 method: 'POST',
116                 on: {
117                     complete: function(id,o,p) {
118                         if (!o) {
119                             alert('IO FATAL');
120                             return;
121                         }
122                         var data = Y.JSON.parse(o.responseText);
123                         args.callback(id,data,p);
124                     }
125                 },
126                 arguments: {
127                     scope: scope
128                 },
129                 headers: {
130                     'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
131                     'User-Agent': 'MoodleFileManager/3.0'
132                 },
133                 data: build_querystring(params)
134             };
135             if (args.form) {
136                 cfg.form = args.form;
137             }
138             Y.io(api, cfg);
139             if (redraw) {
140                 this.wait(this.client_id);
141             }
142         },
143         filepicker_callback: function(obj) {
144             this.filecount++;
145             this.check_buttons();
146             this.refresh(this.currentpath);
147             if (typeof M.core_formchangechecker != 'undefined') {
148                 M.core_formchangechecker.set_form_changed();
149             }
150         },
151         check_buttons: function() {
152             var button_addfile  = Y.one("#btnadd-"+this.client_id);
153             if (this.filecount > 0) {
154                 Y.one("#btndwn-"+this.client_id).setStyle('display', 'inline');
155             }
156             if (this.filecount >= this.maxfiles && this.maxfiles!=-1) {
157                 button_addfile.setStyle('display', 'none');
158             }
159         },
160         refresh: function(filepath) {
161             var scope = this;
162             this.currentpath = filepath;
163             if (!filepath) {
164                 filepath = this.currentpath;
165             } else {
166                 this.currentpath = filepath;
167             }
168             this.request({
169                 action: 'list',
170                 scope: scope,
171                 params: {'filepath':filepath},
172                 callback: function(id, obj, args) {
173                     scope.filecount = obj.filecount;
174                     scope.check_buttons();
175                     scope.options = obj;
176                     scope.render(obj);
177                 }
178             }, true);
179         },
180         setup_buttons: function() {
181             var button_download = Y.one("#btndwn-"+this.client_id);
182             var button_create   = Y.one("#btncrt-"+this.client_id);
183             var button_addfile  = Y.one("#btnadd-"+this.client_id);
185             // setup 'add file' button
186             // if maxfiles == -1, the no limit
187             if (this.filecount >= this.maxfiles
188                     && this.maxfiles!=-1) {
189                 button_addfile.setStyle('display', 'none');
190             } else {
191                 button_addfile.on('click', function(e) {
192                     var options = this.filepicker_options;
193                     options.formcallback = this.filepicker_callback;
194                     // XXX: magic here, to let filepicker use filemanager scope
195                     options.magicscope = this;
196                     options.savepath = this.currentpath;
197                     M.core_filepicker.show(Y, options);
198                 }, this);
199             }
201             // setup 'make a folder' button
202             if (this.options.subdirs) {
203                 button_create.on('click',function(e) {
204                     var scope = this;
205                     // a function used to perform an ajax request
206                     function perform_action(e) {
207                         var foldername = Y.one('#fm-newname').get('value');
208                         if (!foldername) {
209                             return;
210                         }
211                         scope.request({
212                             action:'mkdir',
213                             params: {filepath:scope.currentpath, newdirname:foldername},
214                             callback: function(id, obj, args) {
215                                 var filepath = obj.filepath;
216                                 scope.mkdir_dialog.hide();
217                                 scope.refresh(filepath);
218                                 Y.one('#fm-newname').set('value', '');
219                                 if (typeof M.core_formchangechecker != 'undefined') {
220                                     M.core_formchangechecker.set_form_changed();
221                                 }
222                             }
223                         });
224                     }
225                     if (!Y.one('#fm-mkdir-dlg')) {
226                         var dialog = Y.Node.create('<div id="fm-mkdir-dlg"><div class="hd">'+M.str.repository.entername+'</div><div class="bd"><input type="text" id="fm-newname" /></div></div>');
227                         Y.one(document.body).appendChild(dialog);
228                         this.mkdir_dialog = new YAHOO.widget.Dialog("fm-mkdir-dlg", {
229                              width: "300px",
230                              visible: true,
231                              x:e.pageX,
232                              y:e.pageY,
233                              constraintoviewport : true
234                              });
236                     }
237                     var buttons = [ { text:M.str.moodle.ok, handler:perform_action, isDefault:true },
238                                   { text:M.str.moodle.cancel, handler:function(){this.cancel();}}];
240                     this.mkdir_dialog.cfg.queueProperty("buttons", buttons);
241                     this.mkdir_dialog.render();
242                     this.mkdir_dialog.show();
243                 }, this);
244             } else {
245                 button_create.setStyle('display', 'none');
246             }
248             // setup 'download this folder' button
249             // NOTE: popup window must be enabled to perform download process
250             button_download.on('click',function() {
251                 var scope = this;
252                 // perform downloaddir ajax request
253                 this.request({
254                     action: 'downloaddir',
255                     scope: scope,
256                     callback: function(id, obj, args) {
257                         if (obj) {
258                             scope.refresh(obj.filepath);
259                             var win = window.open(obj.fileurl, 'fm-download-folder');
260                             if (!win) {
261                                 alert(M.str.repository.popupblockeddownload);
262                             }
263                         } else {
264                             alert(M.str.repository.draftareanofiles);
265                         }
266                     }
267                 });
268             }, this);
269         },
270         empty_filelist: function(container) {
271             container.set('innerHTML', '<div class="mdl-align">'+M.str.repository.nofilesattached+'</div>'+this.upload_message());
272         },
273         upload_message: function() {
274             var div = '<div id="filemanager-uploadmessage'+this.client_id+'" style="display:none" class="dndupload-target">';
275             div += M.util.get_string('droptoupload', 'moodle');
276             div += '</div>';
277             return div;
278         },
279         render: function() {
280             var options = this.options;
281             var path = this.options.path;
282             var list = this.options.list;
283             var breadcrumb = Y.one('#fm-path-'+this.client_id);
284             // build breadcrumb
285             if (path) {
286                 // empty breadcrumb
287                 breadcrumb.set('innerHTML', '');
288                 var count = 0;
289                 for(var p in path) {
290                     var arrow = '';
291                     if (count==0) {
292                         arrow = Y.Node.create('<span>'+M.str.moodle.path + ': </span>');
293                     } else {
294                         arrow = Y.Node.create('<span> ▶ </span>');
295                     }
296                     count++;
298                     var pathid  = 'fm-path-node-'+this.client_id;
299                     pathid += ('-'+count);
301                     var crumb = Y.Node.create('<a href="###" id="'+pathid+'">'+path[p].name+'</a>');
302                     breadcrumb.appendChild(arrow);
303                     breadcrumb.appendChild(crumb);
305                     var args = {};
306                     args.requestpath = path[p].path;
307                     args.client_id = this.client_id;
308                     Y.one('#'+pathid).on('click', function(e, args) {
309                         var scope = this;
310                         var params = {};
311                         params['filepath'] = args.requestpath;
312                         this.currentpath = args.requestpath;
313                         this.request({
314                             action: 'list',
315                             scope: scope,
316                             params: params,
317                             callback: function(id, obj, args) {
318                                 scope.filecount = obj.filecount;
319                                 scope.check_buttons();
320                                 scope.options = obj;
321                                 scope.render(obj);
322                             }
323                         }, true);
324                     }, this, args);
325                 }
326             }
327             var template = Y.one('#fm-template');
328             var container = Y.one('#filemanager-' + this.client_id);
329             var listhtml = '';
331             // folder list items
332             var folder_ids = [];
333             var folder_data = {};
335             // normal file list items
336             var file_ids   = [];
337             var file_data  = {};
339             // archives list items
340             var zip_ids    = [];
341             var zip_data = {};
343             var html_ids = [];
344             var html_data = {};
346             file_data.itemid = folder_data.itemid = zip_data.itemid = options.itemid;
347             file_data.client_id = folder_data.client_id = zip_data.client_id = this.client_id;
349             var foldername_ids = [];
350             if (!list || list.length == 0) {
351                 // hide file browser and breadcrumb
352                 //container.setStyle('display', 'none');
353                 this.empty_filelist(container);
354                 if (!path || path.length <= 1) {
355                     breadcrumb.setStyle('display', 'none');
356                 }
357                 return;
358             } else {
359                 container.setStyle('display', 'block');
360                 breadcrumb.setStyle('display', 'block');
361             }
363             var count = 0;
364             for(var i in list) {
365                 count++;
366                 // the li html element
367                 var htmlid = 'fileitem-'+this.client_id+'-'+count;
368                 // link to file
369                 var fileid = 'filename-'+this.client_id+'-'+count;
370                 // file menu
371                 var action = 'action-'  +this.client_id+'-'+count;
373                 var html = template.get('innerHTML');
375                 html_ids.push('#'+htmlid);
376                 html_data[htmlid] = action;
378                 list[i].htmlid = htmlid;
379                 list[i].fileid = fileid;
380                 list[i].action = action;
382                 var url = "###";
384                 switch (list[i].type) {
385                     case 'folder':
386                         // click folder name
387                         foldername_ids.push('#'+fileid);
388                         // click folder menu
389                         folder_ids.push('#'+action);
390                         folder_data[action] = list[i];
391                         folder_data[fileid] = list[i];
392                         break;
393                     case 'file':
394                         file_ids.push('#'+action);
395                         // click file name
396                         file_ids.push('#'+fileid);
397                         file_data[action] = list[i];
398                         file_data[fileid] = list[i];
399                         if (list[i].url) {
400                             url = list[i].url;
401                         }
402                     break;
403                     case 'zip':
404                         zip_ids.push('#'+action);
405                         zip_ids.push('#'+fileid);
406                         zip_data[action] = list[i];
407                         zip_data[fileid] = list[i];
408                         if (list[i].url) {
409                             url = list[i].url;
410                         }
411                     break;
412                 }
413                 var fullname = list[i].fullname;
415                 if (list[i].sortorder == 1) {
416                     html = html.replace('___fullname___', '<strong><a title="'+fullname+'" href="'+url+'" id="'+fileid+'"><img src="'+list[i].icon+'" /> ' + fullname + '</a></strong>');
417                 } else {
418                     html = html.replace('___fullname___', '<a title="'+fullname+'" href="'+url+'" id="'+fileid+'"><img src="'+list[i].icon+'" /> ' + fullname + '</a>');
419                 }
420                 html = html.replace('___action___', '<span class="fm-menuicon" id="'+action+'"><img alt="▶" src="'+M.util.image_url('i/menu')+'" /></span>');
421                 html = '<li id="'+htmlid+'">'+html+'</li>';
422                 listhtml += html;
423             }
424             if (!Y.one('#draftfiles-'+this.client_id)) {
425                 var filelist = Y.Node.create('<ul id="draftfiles-'+this.client_id+'"></ul>');
426                 container.appendChild(filelist);
427             }
428             listhtml += this.upload_message();
429             Y.one('#draftfiles-'+this.client_id).set('innerHTML', listhtml);
431             // click normal file menu
432             Y.on('click', this.create_filemenu, file_ids, this, file_data);
433             Y.on('contextmenu', this.create_filemenu, file_ids, this, file_data);
434             // click folder menu
435             Y.on('click', this.create_foldermenu, folder_ids, this, folder_data);
436             Y.on('contextmenu', this.create_foldermenu, folder_ids, this, folder_data);
437             Y.on('contextmenu', this.create_foldermenu, foldername_ids, this, folder_data);
438             // click archievs menu
439             Y.on('click', this.create_zipmenu, zip_ids, this, zip_data);
440             Y.on('contextmenu', this.create_zipmenu, zip_ids, this, zip_data);
441             // click folder name
442             Y.on('click', this.enter_folder, foldername_ids, this, folder_data);
443         },
444         enter_folder: function(e, data) {
445             var node = e.currentTarget;
446             var file = data[node.get('id')];
447             this.refresh(file.filepath);
448         },
449         create_filemenu: function(e, data) {
450             e.preventDefault();
451             var options = this.options;
452             var node = e.currentTarget;
453             var file = data[node.get('id')];
454             var scope = this;
456             var menuitems = [
457                 {text: M.str.moodle.download, onclick:{fn:open_file_in_new_window, obj:file, scope:this}}
458                 ];
459             function setmainfile(type, ev, obj) {
460                 var file = obj[node.get('id')];
461                 //Y.one(mainid).set('value', file.filepath+file.filename);
462                 var params = {};
463                 params['filepath']   = file.filepath;
464                 params['filename']   = file.filename;
465                 this.request({
466                     action: 'setmainfile',
467                     scope: scope,
468                     params: params,
469                     callback: function(id, obj, args) {
470                         scope.refresh(scope.currentpath);
471                     }
472                 });
473             }
474             function open_file_in_new_window(type, ev, obj) {
475                 // We open in a new window rather than changing the current windows URL as we don't
476                 // want to navigate away from the page
477                 window.open(obj.url, 'fm-download-file');
478             }
479             if (this.enablemainfile && (file.sortorder != 1)) {
480                 var mainid = '#id_'+this.enablemainfile;
481                 var menu = {text: M.str.repository.setmainfile, onclick:{fn: setmainfile, obj:data, scope:this}};
482                 menuitems.push(menu);
483             }
484             this.create_menu(e, 'filemenu', menuitems, file, data);
485         },
486         create_foldermenu: function(e, data) {
487             e.preventDefault();
488             var scope = this;
489             var node = e.currentTarget;
490             var fileinfo = data[node.get('id')];
491             // an extra menu item for folder to zip it
492             function archive_folder(type,ev,obj) {
493                 var params = {};
494                 params['filepath']   = fileinfo.filepath;
495                 params['filename']   = '.';
496                 this.request({
497                     action: 'zip',
498                     scope: scope,
499                     params: params,
500                     callback: function(id, obj, args) {
501                         scope.refresh(obj.filepath);
502                     }
503                 });
504             }
505             var menuitems = [
506                 {text: M.str.editor.zip, onclick: {fn: archive_folder, obj: data, scope: this}},
507                 ];
508             this.create_menu(e, 'foldermenu', menuitems, fileinfo, data);
509         },
510         create_zipmenu: function(e, data) {
511             e.preventDefault();
512             var scope = this;
513             var node = e.currentTarget;
514             var fileinfo = data[node.get('id')];
516             function unzip(type, ev, obj) {
517                 var params = {};
518                 params['filepath'] = fileinfo.filepath;
519                 params['filename'] = fileinfo.fullname;
520                 this.request({
521                     action: 'unzip',
522                     scope: scope,
523                     params: params,
524                     callback: function(id, obj, args) {
525                         scope.refresh(obj.filepath);
526                     }
527                 });
528             }
529             var menuitems = [
530                 {text: M.str.moodle.download, url:fileinfo.url},
531                 {text: M.str.moodle.unzip, onclick: {fn: unzip, obj: data, scope: this}}
532                 ];
533             function setmainfile(type, ev, obj) {
534                 var file = obj[node.get('id')];
535                 //Y.one(mainid).set('value', file.filepath+file.filename);
536                 var params = {};
537                 params['filepath']   = file.filepath;
538                 params['filename']   = file.filename;
539                 this.request({
540                     action: 'setmainfile',
541                     scope: scope,
542                     params: params,
543                     callback: function(id, obj, args) {
544                         scope.refresh(scope.currentpath);
545                     }
546                 });
547             }
548             if (this.enablemainfile && (fileinfo.sortorder != 1)) {
549                 var mainid = '#id_'+this.enablemainfile;
550                 var menu = {text: M.str.repository.setmainfile, onclick:{fn: setmainfile, obj:data, scope:this}};
551                 menuitems.push(menu);
552             }
553             this.create_menu(e, 'zipmenu', menuitems, fileinfo, data);
554         },
555         create_menu: function(ev, menuid, menuitems, fileinfo, options) {
556             var position = [ev.pageX, ev.pageY];
557             var scope = this;
558             function remove(type, ev, obj) {
559                 var dialog_options = {};
560                 var params = {};
561                 dialog_options.message = M.str.repository.confirmdeletefile;
562                 dialog_options.scope = this;
563                 var filename = '';
564                 var filepath = '';
565                 if (fileinfo.type == 'folder') {
566                     params.filename = '.';
567                     params.filepath = fileinfo.filepath;
568                 } else {
569                     params.filename = fileinfo.fullname;
570                 }
571                 dialog_options.callbackargs = [params];
572                 dialog_options.callback = function(params) {
573                     this.request({
574                         action: 'delete',
575                         scope: this,
576                         params: params,
577                         callback: function(id, obj, args) {
578                             scope.filecount--;
579                             scope.refresh(obj.filepath);
580                             if (typeof M.core_formchangechecker != 'undefined') {
581                                 M.core_formchangechecker.set_form_changed();
582                             }
583                             if (scope.filecount < scope.maxfiles && scope.maxfiles!=-1) {
584                                 var button_addfile  = Y.one("#btnadd-"+scope.client_id);
585                                 button_addfile.setStyle('display', 'inline');
586                                 button_addfile.on('click', function(e) {
587                                     var options = scope.filepicker_options;
588                                     options.formcallback = scope.filepicker_callback;
589                                     // XXX: magic here, to let filepicker use filemanager scope
590                                     options.magicscope = scope;
591                                     options.savepath = scope.currentpath;
592                                     M.core_filepicker.show(Y, options);
593                                 }, this);
594                             }
595                         }
596                     });
597                 };
598                 M.util.show_confirm_dialog(ev, dialog_options);
599             }
600             function rename (type, ev, obj) {
601                 var scope = this;
602                 var perform = function(e) {
603                     var newfilename = Y.one('#fm-rename-input').get('value');
604                     if (!newfilename) {
605                         return;
606                     }
608                     var action = '';
609                     var params = {};
610                     if (fileinfo.type == 'folder') {
611                         params['filepath']   = fileinfo.filepath;
612                         params['filename']   = '.';
613                         params['newdirname'] = newfilename;
614                         action = 'renamedir';
615                     } else {
616                         params['filepath']   = fileinfo.filepath;
617                         params['filename']   = fileinfo.fullname;
618                         params['newfilename'] = newfilename;
619                         action = 'rename';
620                     }
621                     scope.request({
622                         action: action,
623                         scope: scope,
624                         params: params,
625                         callback: function(id, obj, args) {
626                             if (obj == false) {
627                                 alert(M.str.repository.fileexists);
628                             } else {
629                                 scope.refresh(obj.filepath);
630                                 if (typeof M.core_formchangechecker != 'undefined') {
631                                     M.core_formchangechecker.set_form_changed();
632                                 }
633                             }
634                             Y.one('#fm-rename-input').set('value', '');
635                             scope.rename_dialog.hide();
636                         }
637                     });
638                 };
640                 var dialog = Y.one('#fm-rename-dlg');
641                 if (!dialog) {
642                     dialog = Y.Node.create('<div id="fm-rename-dlg"><div class="hd">'+M.str.repository.enternewname+'</div><div class="bd"><input type="text" id="fm-rename-input" /></div></div>');
643                     Y.one(document.body).appendChild(dialog);
644                     this.rename_dialog = new YAHOO.widget.Dialog("fm-rename-dlg", {
645                          width: "300px",
646                          fixedcenter: true,
647                          visible: true,
648                          constraintoviewport : true
649                          });
651                 }
652                 var buttons = [ { text:M.str.moodle.rename, handler:perform, isDefault:true},
653                                   { text:M.str.moodle.cancel, handler:function(){this.cancel();}}];
655                 this.rename_dialog.cfg.queueProperty('buttons', buttons);
656                 this.rename_dialog.render();
657                 this.rename_dialog.show();
658                 //var k1 = new YAHOO.util.KeyListener(scope, {keys:13}, {fn:function(){perform();}, correctScope: true});
659                 //k1.enable();
660                 Y.one('#fm-rename-input').set('value', fileinfo.fullname);
661             }
662             function move(type, ev, obj) {
663                 var scope = this;
664                 var itemid = this.options.itemid;
665                 // setup move file dialog
666                 var dialog = null;
667                 if (!Y.one('#fm-move-dlg')) {
668                     dialog = Y.Node.create('<div id="fm-move-dlg"></div>');
669                     Y.one(document.body).appendChild(dialog);
670                 } else {
671                     dialog = Y.one('#fm-move-dlg');
672                 }
674                 dialog.set('innerHTML', '<div class="hd">'+M.str.repository.moving+'</div><div class="bd"><div id="fm-move-div">'+M.str.repository.nopathselected+'</div><div id="fm-tree"></div></div>');
676                 this.movefile_dialog = new YAHOO.widget.Dialog("fm-move-dlg", {
677                      width : "600px",
678                      fixedcenter : true,
679                      visible : false,
680                      constraintoviewport : true
681                      });
683                 var treeview = new YAHOO.widget.TreeView("fm-tree");
685                 var dialog = this.movefile_dialog;
686                 function _move(e) {
687                     if (!treeview.targetpath) {
688                         return;
689                     }
690                     var params = {};
691                     if (fileinfo.type == 'folder') {
692                         action = 'movedir';
693                     } else {
694                         action = 'movefile';
695                     }
696                     params['filepath'] = fileinfo.filepath;
697                     params['filename'] = fileinfo.fullname;
698                     params['newfilepath'] = treeview.targetpath;
699                     scope.request({
700                         action: action,
701                         scope: scope,
702                         params: params,
703                         callback: function(id, obj, args) {
704                             var p = '/';
705                             if (obj) {
706                                 p = obj.filepath;
707                             }
708                             dialog.cancel();
709                             scope.refresh(p);
710                             if (typeof M.core_formchangechecker != 'undefined') {
711                                 M.core_formchangechecker.set_form_changed();
712                             }
713                         }
714                     });
715                 }
717                 var buttons = [ { text:M.str.moodle.move, handler:_move, isDefault:true },
718                                   { text:M.str.moodle.cancel, handler:function(){this.cancel();}}];
720                 this.movefile_dialog.cfg.queueProperty("buttons", buttons);
721                 this.movefile_dialog.render();
723                 treeview.subscribe("dblClickEvent", function(e) {
724                     // update destidatoin folder
725                     this.targetpath = e.node.data.path;
726                     var title = Y.one('#fm-move-div');
727                     title.set('innerHTML', '<strong>"' + this.targetpath + '"</strong> has been selected.');
728                 });
730                 function loadDataForNode(node, onCompleteCallback) {
731                     var params = {};
732                     params['filepath'] = node.data.path;
733                     var obj = {
734                         action: 'dir',
735                         scope: scope,
736                         params: params,
737                         callback: function(id, obj, args) {
738                             data = obj.children;
739                             if (data.length == 0) {
740                                 // so it is empty
741                             } else {
742                                 for (var i in data) {
743                                     var textnode = {label: data[i].fullname, path: data[i].filepath, itemid: this.itemid};
744                                     var tmpNode = new YAHOO.widget.TextNode(textnode, node, false);
745                                 }
746                             }
747                             this.oncomplete();
748                         }
749                     };
750                     obj.oncomplete = onCompleteCallback;
751                     scope.request(obj);
752                 }
754                 this.movefile_dialog.subscribe('show', function(){
755                     var rootNode = treeview.getRoot();
756                     treeview.setDynamicLoad(loadDataForNode);
757                     treeview.removeChildren(rootNode);
758                     var textnode = {label: M.str.moodle.files, path: '/'};
759                     var tmpNode = new YAHOO.widget.TextNode(textnode, rootNode, true);
760                     treeview.draw();
761                 }, this, true);
763                 this.movefile_dialog.show();
764             }
765             var shared_items = [
766                 {text: M.str.moodle.rename+'...', onclick: {fn: rename, obj: options, scope: this}},
767                 {text: M.str.moodle.move+'...', onclick: {fn: move, obj: options, scope: this}}
768             ];
769             // delete is reserve word in Javascript
770             shared_items.push({text: M.str.moodle['delete']+'...', onclick: {fn: remove, obj: options, scope: this}});
771             var menu = new YAHOO.widget.Menu(menuid, {xy:position, clicktohide:true});
772             menu.clearContent();
773             menu.addItems(menuitems);
774             menu.addItems(shared_items);
775             menu.render(document.body);
776             menu.subscribe('hide', function(){
777                 this.fireEvent('destroy');
778             });
779             menu.show();
780         }
781     });
783     // finally init everything needed
784     // kill nonjs filemanager
785     var item = document.getElementById('nonjs-filemanager-'+options.client_id);
786     if (item && !options.usenonjs) {
787         item.parentNode.removeChild(item);
788     }
789     // hide loading picture
790     item = document.getElementById('filemanager-loading-'+options.client_id);
791     if (item) {
792         item.parentNode.removeChild(item);
793     }
794     // display filemanager interface
795     item = document.getElementById('filemanager-wrapper-'+options.client_id);
796     if (item) {
797         item.style.display = '';
798     }
800     var manager = new FileManagerHelper(options);
801     var dndoptions = {
802         filemanager: manager,
803         acceptedtypes: options.accepted_types,
804         clientid: options.client_id,
805         maxfiles: options.maxfiles,
806         maxbytes: options.maxbytes,
807         itemid: options.itemid,
808         repositories: manager.filepicker_options.repositories,
809         containerprefix: '#filemanager-',
810     };
811     M.form_dndupload.init(Y, dndoptions);
812 };