/*
Program Name: File Picker
Program URI: http://code.google.com/p/file-picker/
Description: Display and choose files from your website.
Copyright (c) 2008 Hpyer (hpyer[at]yahoo.cn)
Dual licensed under the MIT (MIT-LICENSE.txt)
and GPL (GPL-LICENSE.txt) licenses.
*/
var FilePicker = {
params: {
uri: '.',
key: 'FP_RESULT',
multi: true,
access: 'file-picker.php',
unicode: true,
delay: 300
},
last_click: null,
timer: null,
/*
@desc Initialization
@since 1.0.2
@return void
*/
init: function(params) {
$.extend(this.params, params);
$.base64.is_unicode = this.params.use_unicode;
$.ajaxSetup({
url: this.params.access,
dataType: 'json'
});
this.do_translate_options();
this.events_binder();
this.get_list();
},
/*
@desc Operation completed, return the JSON string like: {uri:"/path/to/folder", files:["file_1.txt", "file_2.jpg"]}
@return void
*/
do_complete: function() {
var self = FilePicker;
var obj = '{' +
'uri:"' + self.get_uri() + '", ' +
'files:[' + self.get_selected(true) + ']' +
'}';
self.do_close(obj);
},
/*
@desc Close window, and return the JSON string
@param string obj
@return void
*/
do_close: function(obj) {
var self = FilePicker;
if (typeof(obj) != 'string') obj = '';
eval('window.opener.' + self.params.key + '=\'' + obj + '\';');
window.close();
},
/*
@desc Get the URI of current folder
@return string
*/
get_uri: function() {
var uri;
uri = $.base64.decode($('#folders_tree').val());
uri = uri == '/' ? '' : uri;
return this.params.uri + uri;
},
/*
@desc Get JSON string that be translated with all the selected file(s)
@return string
*/
get_selected: function(with_quote) {
var t = $('li.selected');
if (t.length == 1){
return with_quote ? '"' + t.text() + '"' : t.text();
}
return $.map(t, function(li){return '"' + li.innerHTML + '"';}).join(', ');
},
/*
@desc select the file/folder
@param object obj
@param boolean set_filename [default:false]
@return void
*/
do_select: function(obj, set_filename) {
set_filename = set_filename || false;
obj.addClass('selected');
$('#filename_box').val(set_filename ? this.get_selected() : '');
},
/*
@desc Unselect all file(s)/folder(s), and clear the information
@return void
*/
do_unselect: function() {
$('li.selected').removeClass('selected');
$('#filename_box').val('');
FilePicker.do_hide_info();
$('#filename_box').focus();
},
/*
@desc Show the information box
@param object evt
@return void
*/
do_show_info: function(evt) {
var box = $('#info_box').addClass('info_box')
.css("top", (evt.pageY + 10) + "px")
.css("left",(evt.pageX + 10) + "px").fadeIn('fast');
},
/*
@desc Hide the information box
@param boolean without_box
@return void
*/
do_hide_info: function(without_box) {
var box = $('#info_box').empty();
if (!without_box){
box.hide();
}
},
/*
@desc Get JSON string that be translated with all the selected file(s)
@return string
*/
do_translate_options: function() {
$('#folders_tree option').each(function(){
$(this).text($.base64.decode($(this).text()));
});
},
/*
@desc Change the current folder to it parent
@return void
*/
do_up: function() {
var dir = $.base64.decode($('#folders_tree').val());
var p = dir.lastIndexOf('/');
if (p < 0 || dir == '/') return false;
var s = dir.substr(0,p);
s = (s == '') ? '/' : $.base64.encode(s);
$('#folders_tree').val(s);
FilePicker.get_list();
},
/*
@desc Deal with the incident of double-clicking on the file/folder
@return void
*/
do_dblclick: function(){
var self = FilePicker;
clearTimeout(self.timer);
var elmt = $(this);
if (elmt.attr('ftype') == 'folder'){
var dir = $.base64.decode($('#folders_tree').val());
if (dir != '/') dir += '/';
$('#folders_tree').val($.base64.encode(dir + elmt.text()));
self.get_list();
} else {
self.do_select(elmt);
self.do_complete();
}
},
/*
@desc Deal with the incident of clicking on the file/folder
@param object event
@return void
*/
do_click: function(evt) {
var self = FilePicker;
var elmt = $(this);
self.do_hide_info();
$('#filename_box').focus();
if (!self.params.multi){
self.do_unselect();
}
if (self.params.multi && elmt.attr('ftype') == 'folder'){
if (!evt.shiftKey){
// Don't remember this item, if SHIFT key was pushed down
self.last_click = elmt.attr('id');
}
if (evt.ctrlKey){
// Only one folder can be selected
return false;
}
var t = $('li.selected').removeClass('selected');
if (t.length == 1 && t.attr('id') == elmt.attr('id')){
// Unselect current folder if it was selected
self.do_unselect();
return false;
}
self.do_select(elmt);
} else { // files
if (evt.ctrlKey){
self.last_click = elmt.attr('id');
// Unselect folder(s)
$('li.selected[ftype=folder]').removeClass('selected');
// Select/Unselect current file
$(this).toggleClass('selected');
$('#filename_box').val(self.get_selected());
} else if (self.params.multi && evt.shiftKey){
// To delay the operation
} else {
self.last_click = elmt.attr('id');
var t = $('li.selected').removeClass('selected');
if (t.length == 1 && t.attr('id') == elmt.attr('id')){
// Unselect current file if it was selected
self.do_unselect();
return false;
}
self.do_select(elmt, true);
}
}
if (self.params.multi && evt.shiftKey){
if (!self.last_click){
// Select current item, if no one selected
self.last_click = elmt.attr('id');
self.do_select(elmt);
} else {
self.do_unselect();
var first_id = parseInt(self.last_click.split('_')[1]);
var this_id = parseInt(elmt.attr('id').split('_')[1]);
if (first_id > this_id){
$('#list > li').slice(this_id, first_id + 1).each(function(){
FilePicker.do_select($(this));
});
} else {
$('#list > li').slice(first_id, this_id + 1).each(function(){
FilePicker.do_select($(this));
});
}
}
// Unselect Folder(s)
$('li.selected[ftype=folder]').removeClass('selected');
$('#filename_box').val(self.get_selected());
}
/*
@desc Make sure the click/dblclick works alone.
Click will be disabled if the event was dblclick
@since 1.0.2
*/
clearTimeout(self.timer);
self.timer = setTimeout(function () {
self.get_info(evt);
}, self.params.delay);
return false;
},
/*
@desc Get infomation of the selected file/folder
@return void
*/
get_info: function(evt) {
this.do_hide_info(true);
var t = $('li.selected');
if (t.length == 1){
// Initialize the information box
this.do_show_info(evt);
$('<img />').attr('id', 'info_loading_img').attr('src', $('#loading_img')
.attr('src')).appendTo('#info_box');
$.ajax({
data:{
action: 'info',
dir: $('#folders_tree').val(),
file: $.base64.encode(t.text())
},
success: function(json){
var self = FilePicker;
$('#info_box').html($('<label></label>').attr('id', 'btn_close')
.text('X').click(function(){self.do_hide_info(false);}));
var i = 0;
$.each(json, function(i, item){
if ($('#info_box').css('display') == 'none') return false;
if (item.key == 'preview'){
var src = self.get_uri() + '/' + $.base64.decode(item.value);
$('<img />').attr('id', 'preview_img')
.attr('alt', item.trans).attr('src', src)
.click(function(){window.open(this.src,'_blank','');})
.prependTo('#info_box');
} else {
if (i == 0){
item.value = $.base64.decode(item.value);
}
$('#info_box').append(
'<strong>' + item.trans + '</strong>:<br />' +
' ' + item.value + '<br />'
);
}
i++;
});
}
});
}
},
/*
@desc Get file(s)/folder(s) list of current directory
@param boolean read_cache [default:true]
@return void
*/
get_list: function(read_cache) {
if ( typeof(read_cache) == 'undefined' ) read_cache = true;
// Clean memory when the list was change
this.last_click = null;
this.do_hide_info();
$('#loading_img').show();
$('#list').empty();
$('#filename_box').val('');
$.ajax({
cache: read_cache,
data: {
action: 'list',
dir: $('#folders_tree').val(),
filter: $('#filter_box').val()
},
success: function(json){
var self = FilePicker;
$('#loading_img').hide();
// To store filename(s) that be used for Auto-Complete
var files = [];
$.each(json, function(i,item){
item.name = $.base64.decode(item.name);
$('<li></li>').attr('id','item_'+i).attr('ftype',item.type)
.attr('title', item.name).html(item.name)
.addClass(item.type).click(self.do_click)
.dblclick(self.do_dblclick).appendTo('#list');
if (item.type != 'folder') {
files.push(item.name);
}
});
$('#filename_box').autocompleteArray(files, {onItemSelect: function(){
// `Click` the file that selected from the list of Auto-Complete
$('li:not(li[ftyp:folder])').each(function(){
if ($(this).html() == $('#filename_box').val()){
$(this).click();
return false;
}
});
}});
self.do_unselect();
}
});
},
/*
@desc Bind all events that we need
@return void
*/
events_binder: function() {
var self = FilePicker;
$('body').bind('selectstart', function(){return false;});
$('#file_picker_form').bind('submit', function(){return false;});
$('#list_box').bind('click', self.do_unselect);
$('#folders_tree').bind('change', function(){self.get_list(true);});
$('#btn_refresh').bind('click', function(){self.get_list(false);});
$('#btn_up').bind('click', self.do_up);
$('#btn_complete').bind('click', self.do_complete);
$('#btn_cancel').bind('click', self.do_close);
$('#info_box').ppdrag();
}
}
|