Login   Register  
PHP Classes
elePHPant
Icontem

File: media/file-picker.js

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Peter He  >  File Picker  >  media/file-picker.js  >  Download  
File: media/file-picker.js
Role: Application script
Content type: text/plain
Description: main js file, source
Class: File Picker
Let the user browse and pick server side files
Author: By
Last change:
Date: 2008-10-02 19:13
Size: 10,217 bytes
 

Contents

Class file image Download
/*
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 />' + 
                                ' &nbsp; ' + 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();
    }

}