"MDL-21240, fixed the conflict marks I introduced, sorry for that"
[moodle.git] / repository / filepicker.js
1 // YUI3 File Picker module for moodle
2 // Author: Dongsheng Cai <dongsheng@moodle.com>
4 /**
5  *
6  * File Picker UI
7  * =====
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
14  *
15  * Filepicker options:
16  * =====
17  * this.options.client_id, the instance id
18  * this.options.contextid
19  * this.options.itemid
20  * this.options.repositories, stores all repositories displaied in file picker
21  * this.options.formcallback
22  *
23  * Active repository options
24  * =====
25  * this.active_repo.id
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
31  * 
32  * Server responses
33  * =====
34  * this.filelist, cached filelist
35  * this.pages
36  * this.page
37  * this.filepath, current path
38  * this.logindata, cached login form
39  */
41 M.core_filepicker = M.core_filepicker || {};
43 /**
44  * instances of file pickers used on page
45  */
46 M.core_filepicker.instances = M.core_filepicker.instances || {};
48 /**
49  * Init and show file picker
50  */
51 M.core_filepicker.show = function(Y, options) {
52     if (!M.core_filepicker.instances[options.client_id]) {
53         M.core_filepicker.init(Y, options); 
54     }
55     M.core_filepicker.instances[options.client_id].show();
56 };
58 /**
59  * Add new file picker to current instances
60  */
61 M.core_filepicker.init = function(Y, options) {
62     var FilePickerHelper = function(options) {
63         FilePickerHelper.superclass.constructor.apply(this, arguments);
64     }
66     FilePickerHelper.NAME = "FilePickerHelper";
67     FilePickerHelper.ATTRS = {
68         options: {},
69         lang: {}
70     };
72     Y.extend(FilePickerHelper, Y.Base, {
73         api: M.cfg.wwwroot+'/repository/repository_ajax.php',
75         initializer: function(options) {
76             this.options = options;
77         },
79         destructor: function() {
80         },
82         request: function(args, redraw) {
83             var api = this.api + '?action='+args.action;
84             var params = {};
85             var scope = this;
86             if (args['scope']) {
87                 scope = args['scope'];
88             }
89             params['repo_id']=args.repository_id;
90             params['p'] = args.path?args.path:'';
91             params['page'] = args.page?args.page:'';
92             params['env']=this.options.env;
93             // the form element only accept certain file types
94             params['accepted_types']=this.options.accepted_types;
95             params['sesskey']=M.cfg.sesskey;
96             params['client_id'] = args.client_id;
97             params['itemid'] = this.options.itemid?this.options.itemid:0;
98             if (args['params']) {
99                 for (i in args['params']) {
100                     params[i] = args['params'][i];
101                 }
102             }
103             var cfg = {
104                 method: 'POST',
105                 on: {
106                     complete: function(id,o,p) {
107                         if (!o) {
108                             alert('IO FATAL');
109                             return;
110                         }
111                         var data = null;
112                         try {
113                             data = Y.JSON.parse(o.responseText);
114                         } catch(e) {
115                             alert(M.str.repository.invalidjson+' - |'+source+'| -'+stripHTML(o.responseText));
116                         }
117                         args.callback(id,data,p);
118                     }
119                 },
120                 arguments: {
121                     scope: scope
122                 },
123                 headers: {
124                     'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
125                     'User-Agent': 'MoodleFilePicker/3.0'
126                 },
127                 data: build_querystring(params),
128                 context: this
129             };
130             if (args.form) {
131                 cfg.form = args.form;
132             }
133             Y.io(api, cfg);
134             if (redraw) {
135                 this.wait('load');
136             }
137         },
139         build_tree: function(node, level) {
140             var client_id = this.options.client_id;
141             if(node.children) {
142                 node.title = '<i><u>'+node.title+'</u></i>';
143             }
144             var info = {
145                 label:node.title,
146                 //title:fp_lang.date+' '+node.date+fp_lang.size+' '+node.size,
147                 filename:node.title,
148                 source:node.source?node.source:'',
149                 thumbnail:node.thumbnail,
150                 path:node.path?node.path:[]
151             };
152             var tmpNode = new YAHOO.widget.TextNode(info, level, false);
153             //var tooltip = new YAHOO.widget.Tooltip(tmpNode.labelElId, {
154                 //context:tmpNode.labelElId, text:info.title});
155             if(node.repo_id) {
156                 tmpNode.repo_id=node.repo_id;
157             }else{
158                 tmpNode.repo_id=this.active_repo.id;
159             }
160             if(node.children) {
161                 if(node.expanded) {
162                     tmpNode.expand();
163                 }
164                 tmpNode.isLeaf = false;
165                 tmpNode.client_id = client_id;
166                 if (node.path) {
167                     tmpNode.path = node.path;
168                 } else {
169                     tmpNode.path = '';
170                 }
171                 for(var c in node.children) {
172                     this.build_tree(node.children[c], tmpNode);
173                 }
174             } else {
175                 tmpNode.isLeaf = true;
176             }
177         },
178         view_files: function() {
179             this.viewbar.set('disabled', false);
180             if (this.viewmode == 1) {
181                 this.view_as_icons();
182             } else if (this.viewmode ==2) {
183                 this.view_as_list();
184             } else {
185                 this.view_as_icons();
186             }
187         },
188         view_as_list: function() {
189             var client_id = this.options.client_id;
190             var list = this.filelist;
191             var panel_id = '#panel-'+client_id;
192             this.viewmode = 2;
193             Y.one(panel_id).set('innerHTML', '');
195             this.print_header();
196             var tree = Y.Node.create('<div id="treeview-'+client_id+'"></div>');
197             Y.one(panel_id).appendChild(tree);
198             this.treeview = new YAHOO.widget.TreeView('treeview-'+client_id);
200             for(k in list) {
201                 this.build_tree(list[k], this.treeview.getRoot());
202             }
203             var scope = this;
204             this.treeview.subscribe('clickEvent', function(e){
205                 if(e.node.isLeaf){
206                     var fileinfo = {};
207                     fileinfo['title'] = e.node.data.filename;
208                     fileinfo['source'] = e.node.data.source;
209                     fileinfo['thumbnail'] = e.node.data.thumbnail;
210                     scope.select_file(fileinfo);
211                 }
212             });
213             this.treeview.draw();
214         },
215         view_as_icons: function() {
216             var client_id = this.options.client_id;
217             var list = this.filelist;
218             var panel_id = '#panel-'+client_id;
219             this.viewmode = 1;
220             Y.one(panel_id).set('innerHTML', '');
222             this.print_header();
224             var gridpanel = Y.Node.create('<div id="fp-grid-panel-'+client_id+'"></div>');
225             Y.one('#panel-'+client_id).appendChild(gridpanel);
226             var count = 0;
227             for(var k in list) {
228                 var node = list[k];
229                 var grid = document.createElement('DIV');
230                 grid.className='fp-grid';
231                 // the file name
232                 var title = document.createElement('DIV');
233                 title.id = 'grid-title-'+client_id+'-'+String(count);
234                 title.className = 'label';
235                 if (node.shorttitle) {
236                     node.title = node.shorttitle;
237                 }
238                 title.innerHTML += '<a href="###"><span>'+node.title+"</span></a>";
240                 if(node.thumbnail_width){
241                     grid.style.width = node.thumbnail_width+'px';
242                     title.style.width = (node.thumbnail_width-10)+'px';
243                 } else {
244                     grid.style.width = title.style.width = '90px';
245                 }
246                 var frame = document.createElement('DIV');
247                 frame.style.textAlign='center';
248                 if(node.thumbnail_height){
249                     frame.style.height = node.thumbnail_height+'px';
250                 }
251                 var img = document.createElement('img');
252                 img.src = node.thumbnail;
253                 if(node.thumbnail_alt) {
254                     img.alt = node.thumbnail_alt;
255                 }
256                 if(node.thumbnail_title) {
257                     img.title = node.thumbnail_title;
258                 }
260                 var link = document.createElement('A');
261                 link.href='###';
262                 link.id = 'img-id-'+client_id+'-'+String(count);
263                 if(node.url) {
264                     // hide 
265                     //grid.innerHTML += '<p><a target="_blank" href="'+node.url+'">'+M.str.repository.preview+'</a></p>';
266                 }
267                 link.appendChild(img);
268                 frame.appendChild(link);
269                 grid.appendChild(frame);
270                 grid.appendChild(title);
271                 gridpanel.appendChild(grid);
273                 var y_title = Y.one('#'+title.id);
274                 var y_file = Y.one('#'+link.id);
275                 if(node.children) {
276                     y_file.on('click', function(e, p) {
277                         if(p.dynload) {
278                             var params = {};
279                         }else{
280                             this.filelist = p.children;
281                             this.view_files();
282                         }
283                     }, this, node);
284                     y_title.on('click', function(e, p){
285                         //Y.Event.simulate(y_file, 'click');
286                     }, this, node);
287                 } else {
288                     var fileinfo = {};
289                     fileinfo['title'] = list[k].title;
290                     fileinfo['source'] = list[k].source;
291                     fileinfo['thumbnail'] = list[k].thumbnail;
292                     y_title.on('click', function(e, args) {
293                         this.select_file(args);
294                     }, this, fileinfo);
295                     y_file.on('click', function(e, args) {
296                         this.select_file(args);
297                     }, this, fileinfo);
298                 }
299                 count++;
300             }
301         },
302         select_file: function(args) {
303             var client_id = this.options.client_id;
304             var thumbnail = Y.one('#fp-grid-panel-'+client_id);
305             if(thumbnail){
306                 thumbnail.setStyle('display', 'none');
307             }
308             var header = Y.one('#fp-header-'+client_id);
309             if (header) {
310                 header.setStyle('display', 'none');
311             }
312             var footer = Y.one('#fp-footer-'+client_id);
313             if (footer) {
314                 footer.setStyle('display', 'none');
315             }
316             var path = Y.one('#path-'+client_id);
317             if(path){
318                 path.setStyle('display', 'none');
319             }
320             var panel = Y.one('#panel-'+client_id);
321             var html = '<div class="fp-rename-form">';
322             html += '<p><img src="'+args.thumbnail+'" /></p>';
323             html += '<p><label for="newname-'+client_id+'">'+M.str.repository.saveas+':</label>';
324             html += '<input type="text" id="newname-'+client_id+'" value="'+args.title+'" /></p>';
326             var le_checked = '';
327             var le_style = '';
328             if (this.options.repositories[this.active_repo.id].return_types == 1) {
329                 // support external links only
330                 le_checked = 'checked';
331                 le_style = ' style="display:none;"';
332             } else if(this.options.repositories[this.active_repo.id].return_types == 2) {
333                 // support internal files only
334                 le_style = ' style="display:none;"';
335             }
336             if (this.options.externallink && this.options.env == 'editor') {
337                 html += '<p'+le_style+'><input type="checkbox" id="linkexternal-'+client_id+'" value="" '+le_checked+' />'+M.str.repository.linkexternal+'</p>';
338             }
339             html += '<p><input type="hidden" id="filesource-'+client_id+'" value="'+args.source+'" />';
340             html += '<input type="button" id="fp-confirm-'+client_id+'" value="'+M.str.repository.getfile+'" />';
341             html += '<input type="button" id="fp-cancel-'+client_id+'" value="'+M.str.moodle.cancel+'" /></p>';
342             html += '</div>';
344             var getfile_form = Y.Node.create(html);
345             panel.appendChild(getfile_form);
347             var getfile = Y.one('#fp-confirm-'+client_id);
348             getfile.on('click', function(e) {
349                 var client_id = this.options.client_id;
350                 var scope = this;
351                 var repository_id = this.active_repo.id;
352                 var title = Y.one('#newname-'+client_id).get('value');
353                 var filesource = Y.one('#filesource-'+client_id).get('value');
354                 var params = {'title':title, 'file':filesource, 'savepath': this.options.savepath};
356                 if (this.options.env == 'editor') {
357                     var linkexternal = Y.one('#linkexternal-'+client_id).get('checked');
358                     if (linkexternal) {
359                         params['linkexternal'] = 'yes';
360                     }
361                 } if (this.options.env == 'url') {
362                     params['linkexternal'] = 'yes';
363                 }
365                 this.wait('download', title);
366                 this.request({
367                     action:'download',
368                     client_id: client_id,
369                     repository_id: repository_id,
370                     'params': params,
371                     callback: function(id, obj, args) {
372                         if (scope.options.editor_target&&scope.options.env=='editor') {
373                             scope.options.editor_target.value=obj.url;
374                             scope.options.editor_target.onchange();
375                         }
376                         scope.hide();
377                         obj.client_id = client_id;
378                         var formcallback_scope = null;
379                         if (args.scope.options.magicscope) {
380                             formcallback_scope = args.scope.options.magicscope;
381                         } else {
382                             formcallback_scope = args.scope;
383                         }
384                         scope.options.formcallback.apply(formcallback_scope, [obj]);
385                     }
386                 }, true);
387             }, this);
388             var cancel = Y.one('#fp-cancel-'+client_id);
389             cancel.on('click', function(e) {
390                 this.view_files();
391             }, this);
392             var treeview = Y.one('#treeview-'+client_id);
393             if (treeview){
394                 treeview.setStyle('display', 'none');
395             }
396         },
397         wait: function(type) {
398             var panel = Y.one('#panel-'+this.options.client_id);
399             panel.set('innerHTML', '');
400             var name = '';
401             var str = '<div style="text-align:center">';
402             if(type=='load') {
403                 str += '<img src="'+M.util.image_url('i/loading')+'" />';
404                 str += '<p>'+M.str.repository.loading+'</p>';
405             }else{
406                 str += '<img src="'+M.util.image_url('i/progressbar')+'" />';
407                 str += '<p>'+M.str.repository.copying+' <strong>'+name+'</strong></p>';
408             }
409             str += '</div>';
410             try {
411                 panel.set('innerHTML', str);
412             } catch(e) {
413                 alert(e.toString());
414             }
415         },
416         render: function() {
417             var client_id = this.options.client_id;
418             var filepicker_id = 'filepicker-'+client_id;
419             var fpnode = Y.Node.create('<div class="file-picker" id="'+filepicker_id+'"></div>');
420             Y.one(document.body).appendChild(fpnode);
421             // render file picker panel
422             this.mainui = new YAHOO.widget.Panel(filepicker_id, {
423                 draggable: true,
424                 close: true,
425                 underlay: 'none',
426                 zindex: 9999999,
427                 monitorresize: false,
428                 xy: [50, YAHOO.util.Dom.getDocumentScrollTop()+20]
429             });
430             var layout = null;
431             this.mainui.beforeRenderEvent.subscribe(function() {
432                 YAHOO.util.Event.onAvailable('layout-'+client_id, function() {
433                     layout = new YAHOO.widget.Layout('layout-'+client_id, {
434                         height: 480, width: 700,
435                         units: [
436                         {position: 'top', height: 32, resize: false,
437                         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'},
438                         {position: 'left', width: 200, resize: true, scroll:true,
439                         body:'<ul class="fp-list" id="fp-list-'+client_id+'"></ul>', gutter: '0 5 0 2', minWidth: 150, maxWidth: 300 },
440                         {position: 'center', body: '<div class="fp-panel" id="panel-'+client_id+'"></div>',
441                         scroll: true, gutter: '0 2 0 0' }
442                         ]
443                     });
444                     layout.render();
445                 });
446             });
447             this.mainui.setHeader('File Picker');
448             this.mainui.setBody('<div id="layout-'+client_id+'"></div>');
449             this.mainui.render();
450             this.rendered = true;
452             var scope = this;
453             // adding buttons
454             var view_icons = {label: M.str.repository.iconview, value: 't',
455                 onclick: {
456                     fn: function(){
457                         scope.view_as_icons();
458                     }
459                 }
460             };
461             var view_listing = {label: M.str.repository.listview, value: 'l',
462                 onclick: {
463                     fn: function(){
464                         scope.view_as_list();
465                     }
466                 }
467             };
468             this.viewbar = new YAHOO.widget.ButtonGroup({
469                 id: 'btngroup-'+client_id,
470                 name: 'buttons',
471                 disabled: true,
472                 container: 'fp-viewbar-'+client_id
473             });
474             this.viewbar.addButtons([view_icons, view_listing]);
475             // processing repository listing
476             var r = this.options.repositories;
477             Y.on('contentready', function(el) {
478                 var list = Y.one(el);
479                 var count = 0;
480                 for (var i in r) {
481                     var id = 'repository-'+client_id+'-'+count;
482                     var link_id = id + '-link';
483                     list.append('<li id="'+id+'"><a class="fp-repo-name" id="'+link_id+'" href="###">'+r[i].name+'</a></li>');
484                     Y.one('#'+link_id).prepend('<img src="'+r[i].icon+'" width="16" height="16" />&nbsp;');
485                     Y.one('#'+link_id).on('click', function(e, scope, repository_id) {
486                         scope.repository_id = repository_id;
487                         Y.all(el+' li a').setStyle('backgroundColor', 'transparent');
488                         e.currentTarget.setStyle('backgroundColor', '#CCC');
489                         this.list({'repo_id':repository_id});
490                     }, this /*handler running scope*/, this/*second argument*/, r[i].id/*third argument of handler*/);
491                     count++;
492                 }
493             }, '#fp-list-'+client_id, this /* handler running scope */, '#fp-list-'+client_id /*first argument of handler*/);
494         },
495         parse_repository_options: function(data) {
496             this.filelist = data.list?data.list:null;
497             this.filepath = data.path?data.path:null;
498             this.active_repo = {};
499             this.active_repo.issearchresult = Boolean(data.issearchresult);
500             this.active_repo.pages = Number(data.pages?data.pages:null);
501             this.active_repo.page = Number(data.page?data.page:null);
502             this.active_repo.id = data.repo_id?data.repo_id:null;
503             this.active_repo.nosearch = data.nosearch?true:false;
504             this.active_repo.norefresh = data.norefresh?true:false;
505             this.active_repo.nologin = data.nologin?true:false;
506             this.active_repo.help = data.help?data.help:null;
507             this.active_repo.manage = data.manage?data.manage:null;
508         },
509         print_login: function(data) {
510             var client_id = this.options.client_id;
511             var repository_id = data.repo_id;
512             var l = this.logindata = data.login;
513             var loginurl = '';
514             var panel = Y.one('#panel-'+client_id);
515             var action = 'login';
516             if (data['login_btn_action']) {
517                 action=data['login_btn_action'];
518             }
519             var form_id = 'fp-form-'+client_id;
520             var download_button_id = 'fp-form-download-button-'+client_id;
521             var search_button_id   = 'fp-form-search-button-'+client_id;
522             var login_button_id    = 'fp-form-login-button-'+client_id;
523             var popup_button_id    = 'fp-form-popup-button-'+client_id;
525             var str = '<div class="fp-login-form">';
526             str += '<form id="'+form_id+'">';
527             var has_pop = false;
528             str +='<table width="100%">';
529             for(var k in l) {
530                 str +='<tr>';
531                 if(l[k].type=='popup') {
532                     // pop element
533                     loginurl = l[k].url;
534                     str += '<td colspan="2"><p class="fp-popup">'+M.str.repository.popup+'</p>';
535                     str += '<p class="fp-popup"><button id="'+popup_button_id+'">'+M.str.repository.login+'</button>';
536                     str += '</p></td>';
537                     action = 'popup';
538                 }else if(l[k].type=='textarea') {
539                     // textarea element
540                     str += '<td colspan="2"><p><textarea id="'+l[k].id+'" name="'+l[k].name+'"></textarea></p></td>';
541                 }else if(l[k].type=='select') {
542                     // select element
543                     str += '<td align="right"><label>'+l[k].label+':</label></td>';
544                     str += '<td align="left"><select id="'+l[k].id+'" name="'+l[k].name+'">';
545                     for (i in l[k].options) {
546                         str += '<option value="'+l[k].options[i].value+'">'+l[k].options[i].label+'</option>';
547                     }
548                     str += '</select></td>';
549                 }else{
550                     // input element
551                     var label_id = '';
552                     var field_id = '';
553                     var field_value = '';
554                     if(l[k].id) {
555                         label_id = ' for="'+l[k].id+'"';
556                         field_id = ' id="'+l[k].id+'"';
557                     }
558                     if (l[k].label) {
559                         str += '<td align="right" width="30%" valign="center">';
560                         str += '<label'+label_id+'>'+l[k].label+'</label> </td>';
561                     } else {
562                         str += '<td width="30%"></td>';
563                     }
564                     if(l[k].value) {
565                         field_value = ' value="'+l[k].value+'"';
566                     }
567                     if(l[k].type=='radio'){
568                         var list = l[k].value.split('|');
569                         var labels = l[k].value_label.split('|');
570                         str += '<td align="left">';
571                         for(var item in list) {
572                             str +='<input type="'+l[k].type+'"'+' name="'+l[k].name+'"'+
573                                 field_id+' value="'+list[item]+'" />'+labels[item]+'<br />';
574                         }
575                         str += '</td>';
576                     }else{
577                         str += '<td align="left">';
578                         str += '<input type="'+l[k].type+'"'+' name="'+l[k].name+'"'+field_value+' '+field_id+' />';
579                         str += '</td>';
580                     }
581                 }
582                 str +='</tr>';
583             }
584             str +='</table>';
585             str += '</form>';
587             // custom lable text
588             var btn_label = data['login_btn_label']?data['login_btn_label']:M.str.repository.submit;
589             if (action != 'popup') {
590                 str += '<p><input type="button" id="';
591                 switch (action) {
592                     case 'search':
593                         str += search_button_id;
594                         break;
595                     case 'download':
596                         str += download_button_id;
597                         break;
598                     default:
599                         str += login_button_id;
600                         break;
601                 }
602                 str += '" value="'+btn_label+'" /></p>';
603             }
605             str += '</div>';
607             // insert login form
608             try {
609                 panel.set('innerHTML', str);
610             } catch(e) {
611                 alert(e.toString()+M.str.quiz.xhtml);
612             }
613             // register buttons
614             // process login action
615             var login_button = Y.one('#'+login_button_id);
616             var scope = this;
617             if (login_button) {
618                 login_button.on('click', function(){
619                     // collect form data
620                     var data = this.logindata;
621                     var scope = this;
622                     var params = {};
623                     for (var k in data) {
624                         if(data[k].type!='popup') {
625                             var el = Y.one('[name='+data[k].name+']');
626                             var type = el.get('type');
627                             params[data[k].name] = '';
628                             if(type == 'checkbox') {
629                                 params[data[k].name] = el.get('checked');
630                             } else {
631                                 params[data[k].name] = el.get('value');
632                             }
633                         }
634                     }
635                     // start ajax request
636                     this.request({
637                         'params': params,
638                         'scope': scope,
639                         'action':'signin',
640                         'path': '',
641                         'client_id': client_id,
642                         'repository_id': repository_id,
643                         'callback': function(id, o, args) {
644                             scope.parse_repository_options(o);
645                             scope.view_files();
646                             if (o.msg) {
647                                 // do something
648                             }
649                         }
650                     }, true);
651                 }, this);
652             }
653             var search_button = Y.one('#'+search_button_id);
654             if (search_button) {
655                 search_button.on('click', function(){
656                     var data = this.logindata;
657                     var params = {};
659                     for (var k in data) {
660                         if(data[k].type!='popup') {
661                             var el = document.getElementsByName(data[k].name)[0];
662                             params[data[k].name] = '';
663                             if(el.type == 'checkbox') {
664                                 params[data[k].name] = el.checked;
665                             } else if(el.type == 'radio') {
666                                 var tmp = document.getElementsByName(data[k].name);
667                                 for(var i in tmp) {
668                                     if (tmp[i].checked) {
669                                         params[data[k].name] = tmp[i].value;
670                                     }
671                                 }
672                             } else {
673                                 params[data[k].name] = el.value;
674                             }
675                         }
676                     }
677                     this.request({
678                             scope: scope,
679                             action:'search',
680                             client_id: client_id,
681                             repository_id: repository_id,
682                             form: {id: 'fp-form-'+scope.options.client_id,upload:false,useDisabled:true},
683                             callback: function(id, o, args) {
684                                 o.issearchresult = true;
685                                 scope.parse_repository_options(o);
686                                 scope.view_files();
687                             }
688                     }, true);
689                 }, this);
690             }
691             var download_button = Y.one('#'+download_button_id);
692             if (download_button) {
693                 download_button.on('click', function(){
694                     alert('download');
695                 });
696             }
697             var popup_button = Y.one('#'+popup_button_id);
698             if (popup_button) {
699                 popup_button.on('click', function(){
700                     window.open(loginurl, 'repo_auth', 'location=0,status=0,scrollbars=0,width=500,height=300');
701                     active_filepicker = this;
702                 }, this);
703             }
705         },
706         search: function(args) {
707             var data = this.logindata;
708             var params = {};
710             for (var k in data) {
711                 if(data[k].type!='popup') {
712                     var el = document.getElementsByName(data[k].name)[0];
713                     params[data[k].name] = '';
714                     if(el.type == 'checkbox') {
715                         params[data[k].name] = el.checked;
716                     } else if(el.type == 'radio') {
717                         var tmp = document.getElementsByName(data[k].name);
718                         for(var i in tmp) {
719                             if (tmp[i].checked) {
720                                 params[data[k].name] = tmp[i].value;
721                             }
722                         }
723                     } else {
724                         params[data[k].name] = el.value;
725                     }
726                 }
727             }
728             this.request({
729                     scope: scope,
730                     action:'search',
731                     client_id: client_id,
732                     repository_id: repository_id,
733                     form: {id: 'fp-form-'+scope.options.client_id,upload:false,useDisabled:true},
734                     callback: function(id, o, args) {
735                         o.issearchresult = true;
736                         scope.parse_repository_options(o);
737                         scope.view_files();
738                     }
739             }, true);
740         },
741         list: function(args) {
742             var scope = this;
743             if (!args) {
744                 args = {};
745             }
746             if (!args.repo_id) {
747                 args.repo_id = scope.active_repo.id;
748             }
749             scope.request({
750                 action:'list',
751                 client_id: scope.options.client_id,
752                 repository_id: args.repo_id,
753                 path:args.path?args.path:'',
754                 page:args.page?args.page:'',
755                 callback: function(id, obj, args) {
756                     if (obj.login) {
757                         scope.viewbar.set('disabled', true);
758                         scope.print_login(obj);
759                     } else if (obj.upload) {
760                         scope.viewbar.set('disabled', true);
761                         scope.parse_repository_options(obj);
762                         scope.create_upload_form(obj);
763                     
764                     } else if (obj.iframe) {
766                     } else if (obj.list) {
767                         obj.issearchresult = false;
768                         scope.viewbar.set('disabled', false);
769                         scope.parse_repository_options(obj);
770                         scope.view_files();
771                     }
772                     if (obj.msg) {
773                         // TODO: Print message
774                     }
775                 }
776             }, true);
777         },
778         create_upload_form: function(data) {
779             var client_id = this.options.client_id;
780             Y.one('#panel-'+client_id).set('innerHTML', '');
782             this.print_header();
783             var id = data.upload.id+'_'+client_id;
784             var str = '<div id="'+id+'_div" class="fp-upload-form">';
785             str += '<form id="'+id+'" method="POST">';
786             str += '<label for="'+id+'_file">'+data.upload.label+': </label>';
787             str += '<input type="file" id="'+id+'_file" name="repo_upload_file" />';
788             str += '<input type="hidden" name="itemid" value="'+this.options.itemid+'" />';
789             str += '<div class="fp-upload-btn"><a id="'+id+'_action" href="###" >'+M.str.repository.upload+'...</a></div>';
790             str += '</form>';
791             str += '</div>';
792             var upload_form = Y.Node.create(str);
793             Y.one('#panel-'+client_id).appendChild(upload_form);
794             var scope = this;
795             Y.one('#'+id+'_action').on('click', function() {
796                 Y.use('io-upload-iframe', function() {
797                     scope.request({
798                             scope: scope,
799                             action:'upload',
800                             client_id: client_id,
801                             params: {'savepath':scope.options.savepath},
802                             repository_id: scope.active_repo.id,
803                             form: {id: id, upload:true},
804                             callback: function(id, o, args) {
805                                 if (scope.options.editor_target&&scope.options.env=='editor') {
806                                     scope.options.editor_target.value=o.url;
807                                     scope.options.editor_target.onchange();
808                                 }
809                                 scope.hide();
810                                 o.client_id = client_id;
811                                 var formcallback_scope = null;
812                                 if (args.scope.options.magicscope) {
813                                     formcallback_scope = args.scope.options.magicscope;
814                                 } else {
815                                     formcallback_scope = args.scope;
816                                 }
817                                 scope.options.formcallback.apply(formcallback_scope, [o]);
818                             }
819                     }, true);
820                 });
821             }, this);
822         },
823         print_header: function() {
824             var r = this.active_repo;
825             var scope = this;
826             var client_id = this.options.client_id;
827             var repository_id = this.active_repo.id;
828             var panel = Y.one('#panel-'+client_id);
829             var str = '<div id="fp-header-'+client_id+'">';
830             str += '<div class="fp-toolbar" id="repo-tb-'+client_id+'"></div>';
831             str += '</div>';
832             var head = Y.Node.create(str);
833             panel.appendChild(head);
834             //if(this.active_repo.pages < 8){
835                 this.print_paging('header');
836             //}
839             var toolbar = Y.one('#repo-tb-'+client_id);
841             if(!r.nosearch) {
842                 var html = '<a href="###"><img src="'+M.util.image_url('a/search')+'" /> '+M.str.repository.search+'</a>';
843                 var search = Y.Node.create(html);
844                 search.on('click', function() {
845                     scope.request({
846                         scope: scope,
847                         action:'searchform',
848                         repository_id: repository_id,
849                         callback: function(id, obj, args) {
850                             var scope = args.scope;
851                             var client_id = scope.options.client_id;
852                             var repository_id = scope.active_repo.id;
853                             var container = document.getElementById('fp-search-dlg');
854                             if(container) {
855                                 container.innerHTML = '';
856                                 container.parentNode.removeChild(container);
857                             }
858                             var container = document.createElement('DIV');
859                             container.id = 'fp-search-dlg';
861                             var dlg_title = document.createElement('DIV');
862                             dlg_title.className = 'hd';
863                             dlg_title.innerHTML = 'filepicker';
865                             var dlg_body = document.createElement('DIV');
866                             dlg_body.className = 'bd';
868                             var sform = document.createElement('FORM');
869                             sform.method = 'POST';
870                             sform.id = "fp-search-form";
871                             sform.innerHTML = obj.form;
873                             dlg_body.appendChild(sform);
874                             container.appendChild(dlg_title);
875                             container.appendChild(dlg_body);
876                             Y.one(document.body).appendChild(container);
877                             var search_dialog= null;
878                             function dialog_handler() {
879                                 scope.viewbar.set('disabled', false);
880                                 scope.request({
881                                         scope: scope,
882                                         action:'search',
883                                         client_id: client_id,
884                                         repository_id: repository_id,
885                                         form: {id: 'fp-search-form',upload:false,useDisabled:true},
886                                         callback: function(id, o, args) {
887                                             scope.parse_repository_options(o);
888                                             scope.view_files();
889                                         }
890                                 }, true);
891                                 search_dialog.cancel();
892                             }
894                             var search_dialog = new YAHOO.widget.Dialog("fp-search-dlg", {
895                                postmethod: 'async',
896                                draggable: true,
897                                width : "30em",
898                                fixedcenter : true,
899                                zindex: 766667,
900                                visible : false,
901                                constraintoviewport : true,
902                                buttons: [
903                                {
904                                    text:M.str.repository.submit,
905                                    handler:dialog_handler,
906                                    isDefault:true
907                                }, {
908                                    text:M.str.moodle.cancel,
909                                    handler:function(){
910                                        this.destroy()
911                                    }
912                                }]
913                             });
914                             search_dialog.render();
915                             search_dialog.show();
916                         }
917                     });
918                 },this);
919                 toolbar.appendChild(search);
920             }
921             // weather we use cache for this instance, this button will reload listing anyway
922             if(!r.norefresh) {
923                 var html = '<a href="###"><img src="'+M.util.image_url('a/refresh')+'" /> '+M.str.repository.refresh+'</a>';
924                 var refresh = Y.Node.create(html);
925                 refresh.on('click', function() {
926                     this.list();
927                 }, this);
928                 toolbar.appendChild(refresh);
929             }
930             if(!r.nologin) {
931                 var html = '<a href="###"><img src="'+M.util.image_url('a/logout')+'" /> '+M.str.repository.logout+'</a>';
932                 var logout = Y.Node.create(html);
933                 logout.on('click', function() {
934                     this.request({
935                         action:'logout',
936                         client_id: client_id,
937                         repository_id: repository_id,
938                         path:'',
939                         callback: function(id, obj, args) {
940                             scope.viewbar.set('disabled', true);
941                             scope.print_login(obj);
942                         }
943                     }, true);
944                 }, this);
945                 toolbar.appendChild(logout);
946             }
948             if(r.manage) {
949                 var mgr = document.createElement('A');
950                 mgr.href = r.manage;
951                 mgr.target = "_blank";
952                 mgr.innerHTML = '<img src="'+M.util.image_url('a/setting')+'" /> '+M.str.repository.manageurl;
953                 toolbar.appendChild(mgr);
954             }
955             if(r.help) {
956                 var help = document.createElement('A');
957                 help.href = r.help;
958                 help.target = "_blank";
959                 help.innerHTML = '<img src="'+M.util.image_url('a/help')+'" /> '+M.str.repository.help;
960                 toolbar.appendChild(help);
961             }
963             // only show in icons view
964             if (this.viewmode == 1) {
965                 this.print_path();
966             }
967         },
968         get_page_button: function(page) {
969             var r = this.active_repo;
970             var css = '';
971             if (page == r.page) {
972                 css = 'class="cur_page" ';
973             }
974             var str = '<a '+css+'href="###" id="repo-page-'+page+'">';
975             return str;
976         },
977         print_paging: function(html_id) {
978             var client_id = this.options.client_id;
979             var scope = this;
980             var r = this.active_repo;
981             var str = '';
982             var action = '';
983             if(r.pages) {
984                 str += '<div class="fp-paging" id="paging-'+html_id+'-'+client_id+'">';
985                 str += this.get_page_button(1)+'1</a> ';
987                 var span = 5;
988                 var ex = (span-1)/2;
990                 if (r.page+ex>=r.pages) {
991                     var max = r.pages;
992                 } else {
993                     if (r.page<span) {
994                         var max = span;
995                     } else {
996                         var max = r.page+ex;
997                     }
998                 }
1000                 // won't display upper boundary
1001                 if (r.page >= span) {
1002                     str += ' ... ';
1003                     for(var i=r.page-ex; i<max; i++) {
1004                         str += this.get_page_button(i);
1005                         str += String(i);
1006                         str += '</a> ';
1007                     }
1008                 } else {
1009                     // this very first elements
1010                     for(var i = 2; i < max; i++) {
1011                         str += this.get_page_button(i);
1012                         str += String(i);
1013                         str += '</a> ';
1014                     }
1015                 }
1017                 // won't display upper boundary
1018                 if (max==r.pages) {
1019                     str += this.get_page_button(r.pages)+r.pages+'</a>';
1020                 } else {
1021                     str += this.get_page_button(max)+max+'</a>';
1022                     str += ' ... '+this.get_page_button(r.pages)+r.pages+'</a>';
1023                 }
1024                 str += '</div>';
1025             }
1026             if (str) {
1027                 var a = Y.Node.create(str);
1028                 Y.one('#fp-header-'+client_id).appendChild(a);
1030                 Y.all('#fp-header-'+client_id+' .fp-paging a').each(
1031                     function(node, id) {
1032                         node.on('click', function(e) {
1033                             var id = node.get('id');
1034                             var re = new RegExp("repo-page-(\\d+)", "i");
1035                             var result = id.match(re);
1036                             var args = {};
1037                             args.page = result[1];
1038                             if (scope.active_repo.issearchresult) {
1039                                 scope.request({
1040                                         scope: scope,
1041                                         action:'search',
1042                                         client_id: client_id,
1043                                         repository_id: r.id,
1044                                         params: {'page':result[1]},
1045                                         callback: function(id, o, args) {
1046                                             o.issearchresult = true;
1047                                             scope.parse_repository_options(o);
1048                                             scope.view_files();
1049                                         }
1050                                 }, true);
1052                             } else {
1053                                 scope.list(args);
1054                             }
1055                         });
1056                     });
1057             }
1058         },
1059         print_path: function() {
1060             var client_id = this.options.client_id;
1061             if (this.viewmode == 2) {
1062                 return;
1063             }
1064             var panel = Y.one('#panel-'+client_id);
1065             var p = this.filepath;
1066             if (p && p.length!=0) {
1067                 var path = Y.Node.create('<div id="path-'+client_id+'" class="fp-pathbar"></div>');
1068                 panel.appendChild(path);
1069                 for(var i = 0; i < p.length; i++) {
1070                     var link = document.createElement('A');
1071                     link.href = "###";
1072                     link.innerHTML = p[i].name;
1073                     //link.id = 'path-'+client_id+'-'+repo_id;
1074                     var sep = Y.Node.create('<span>/</span>');
1075                     
1076                     path.appendChild(link);
1077                     path.appendChild(sep);
1078                 }
1079             }
1080         },
1081         hide: function() {
1082             this.mainui.hide();
1083         },
1084         show: function() {
1085             if (this.rendered) {
1086                 var panel = Y.one('#panel-'+this.options.client_id);
1087                 panel.set('innerHTML', '');
1088                 this.mainui.show();
1089             } else {
1090                 this.launch();
1091             }
1092         },
1093         launch: function() {
1094             this.render();
1095         }
1096     });
1098     M.core_filepicker.instances[options.client_id] = new FilePickerHelper(options);
1099 };