Changeset 16517

Show
Ignore:
Timestamp:
05/30/08 21:30:49 (4 months ago)
Author:
adrenalin
Message:

Starting to document Chooser widget's operations.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/midcom/midcom.helper.datamanager2/static/chooser/jquery.chooser_widget.js

    <
    r15646 r16517  
    1 /** 
     1/**  
    22 * midcom_helper_datamanager2_widget_chooser_widget - jQuery plugin 1.0 
    3  * 
     3 *  
    44 * Jerry Jalava <jerry.jalava@gmail.com> 
    55 * Arttu Manninen <arttu@kaktus.cc> 
    66 */ 
    77 
    8 /** 
     8/**  
    99 * @name midcom_helper_datamanager2_widget_chooser_widget 
    1010 * @cat Plugins/Midcom 
     
    1313 * @param Map options Optional settings 
    1414 * @option String widget_id The id of the widget instance. Default: chooser_widget 
    15  * @option Number result_limit Limit the number of items in the results box. Is also send as a "limit" parameter to backend on request. Default: 10 
     15 * @option Number result_limit Limit the number of items in the results box. Is also send as a 'limit' parameter to backend on request. Default: 10 
    1616 * @option Boolean renderer_callback If this is set to true, then when user presses tab it creates a tag from current input value if we don't have any results. Default: false 
    1717 * @option String id_field Name of the objects field to be used as identifier. Default: guid 
     
    2424 
    2525 
    26 jQuery.fn.extend({ 
     26jQuery.fn.extend( 
     27
    2728    midcom_helper_datamanager2_widget_chooser_widget: function(url, options) 
    2829    { 
     
    3132            url: url || null 
    3233        }, options); 
    33         // return this.each(function()
     34        // return this.each(function()
    3435        return new jQuery.midcom_helper_datamanager2_widget_chooser(this, options); 
    3536        // }); 
     
    3738    midcom_helper_datamanager2_widget_chooser_add_result_item: function(data, item) 
    3839    { 
    39         return this.trigger("add_result_item",[data, item]); 
     40        return this.trigger('add_result_item',[data, item]); 
    4041    }, 
    4142    midcom_helper_datamanager2_widget_chooser_remove_result_item: function(item_id) 
    4243    { 
    43         return this.trigger("remove_result_item",[item_id]); 
     44        return this.trigger('remove_result_item',[item_id]); 
    4445    } 
    4546}); 
     
    4748jQuery.midcom_helper_datamanager2_widget_chooser = function(input, options) 
    4849{ 
    49     var KEY = { 
     50    var KEY = 
     51    { 
    5052        UP: 38, 
    5153        DOWN: 40, 
     
    5759    }; 
    5860 
    59     var CLASSES = { 
    60         LOADING: "chooser_widget_search_loading", 
    61         IDLE: "chooser_widget_search_idle", 
    62         FAILED: "chooser_widget_search_failed" 
     61    var CLASSES = 
     62    { 
     63        LOADING: 'chooser_widget_search_loading', 
     64        IDLE: 'chooser_widget_search_idle', 
     65        FAILED: 'chooser_widget_search_failed' 
    6366    }; 
    64  
     67     
     68    /**  
     69     * Timeout or when the results will be automatically hidden 
     70     *  
     71     * @var int timeout 
     72     */ 
    6573    var timeout; 
     74     
     75    /**  
     76     * Time when the unused results will be hidden after the mouse out 
     77     *  
     78     * @var int blurTimeout 
     79     */ 
    6680    var blurTimeout; 
    67     var previousValue = ""; 
     81     
     82    /**  
     83     *  
     84     *  
     85     * @var String previousValue 
     86     */ 
     87    var previousValue = ''; 
     88     
     89    /**  
     90     * Switch to determine if the focus is in this chooser field 
     91     *  
     92     * @var int hasFocus 
     93     */ 
    6894    var hasFocus = 0; 
     95     
     96    /**  
     97     * Code of the last key press 
     98     *  
     99     * @var String lastKeyPressCode 
     100     */ 
    69101    var lastKeyPressCode; 
     102     
     103    /**  
     104     * Last used term 
     105     *  
     106     * @var String last_term 
     107     */ 
    70108    var last_term; 
    71          
     109     
     110    /**  
     111     * Create button for the creation mode 
     112     *  
     113     * @var mixed create_button 
     114     */ 
    72115    var create_button = null; 
    73116    var creation_dialog = null; 
    74     var input_element = jQuery(input).attr("autocomplete", "off").addClass(CLASSES.IDLE); 
     117    var input_element = jQuery(input).attr('autocomplete', 'off').addClass(CLASSES.IDLE); 
     118     
     119    /**  
     120     * Object to determine which is the last list item. New items will be inserted after this. 
     121     *  
     122     * @var DOM insert_after 
     123     */ 
    75124    var insert_after = input_element; 
    76125         
     
    83132    input_element.show(); 
    84133     
    85     var results_holder = jQuery.midcom_helper_datamanager2_widget_chooser.ResultsHolder(options, input, insert_after);     
     134    var results_holder = jQuery.midcom_helper_datamanager2_widget_chooser.ResultsHolder(options, input, insert_after); 
    86135     
    87136    hideResultsNow(); 
    88137     
    89138    jQuery('.widget_chooser_static_items_table').hide(); 
    90     jQuery('.chooser_widget_existing_item_static_input').each(function(){ 
     139    jQuery('.chooser_widget_existing_item_static_input').each(function() 
     140    { 
    91141        this.checked = false; 
    92142    }); 
    93  
     143     
     144    /**  
     145     * On the change event of the chooser search field 
     146     *  
     147     * @param mixed crap             Not used for anything at the moment 
     148     * @param mixed skipPrevCheck    Not used for anything at the moment 
     149     */ 
    94150    function onChange(crap, skipPrevCheck) 
    95151    { 
     
    99155        } 
    100156         
    101         var currentValue = input_element.val();                         
     157        var currentValue = input_element.val(); 
    102158        if (currentValue == previousValue) 
    103159        { 
     
    118174    }; 
    119175     
     176    /**  
     177     * Hide the result set after the determined timeout 
     178     */ 
    120179    function hideResults() 
    121180    { 
     
    123182        timeout = setTimeout(hideResultsNow, 200); 
    124183    }; 
    125  
     184     
     185    /**  
     186     * Hide the results immediately 
     187     */ 
    126188    function hideResultsNow() 
    127189    { 
     
    129191        clearTimeout(timeout); 
    130192    }; 
    131  
    132     function receiveData(q, data) { 
    133         if ( data && data.length && hasFocus ) 
     193     
     194    /**  
     195     * Handle the received data 
     196     *  
     197     * @param String q      Query 
     198     * @param Array data    Returned DOM objects 
     199     */ 
     200    function receiveData(q, data) 
     201    { 
     202        if (   data 
     203            && data.length 
     204            && hasFocus) 
    134205        { 
    135206            stopLoading(); 
     
    143214    }; 
    144215     
     216    /**  
     217     * Request the results 
     218     *  
     219     * @param String term       Search term 
     220     * @param Function success  Function to be triggered upon success 
     221     * @param Function failure  Function to be triggered upon failure 
     222     *  
     223     */ 
    145224    function request(term, success, failure) 
    146225    { 
     226        console.log(success); 
    147227        last_term = term; 
    148228         
    149229        input_element.removeClass(CLASSES.IDLE); 
    150         input_element.removeClass(CLASSES.FAILED);         
     230        input_element.removeClass(CLASSES.FAILED); 
    151231        input_element.addClass(CLASSES.LOADING); 
    152232         
     
    155235        term = term.toLowerCase(); 
    156236         
    157         jQuery.ajax({ 
    158             type: "POST", 
     237        jQuery.ajax( 
     238        { 
     239            type: 'POST', 
    159240            url: options.url, 
    160241            dataType: 'xml', 
    161             data: jQuery.extend({ 
     242            data: jQuery.extend( 
     243            { 
    162244                query: term, 
    163245                limit: options.result_limit 
    164246            }, {extra_params: options.extra_params}), 
    165             error: function(obj, type, expobj) { 
     247            error: function(obj, type, expobj) 
     248            { 
    166249                failure(type, expobj); 
    167250            }, 
    168             success: function(data) { 
     251            success: function(data) 
     252            { 
    169253                var parsed = parse(data); 
    170254                success(term, parsed); 
     
    173257    } 
    174258     
     259    /**  
     260     * Called upon loading stop 
     261     *  
     262     * @param Function type      Function that will be triggered upon loading stop 
     263     * @param Function expobj    Function that will be used to export objects 
     264     */ 
    175265    function stopLoading(type, expobj) 
    176     {         
     266    { 
     267        console.log(expobj); 
    177268        input_element.removeClass(CLASSES.IDLE); 
    178269        input_element.removeClass(CLASSES.FAILED); 
    179270        input_element.removeClass(CLASSES.LOADING); 
    180         if (type == "undefined"
     271        if (type == 'undefined'
    181272        { 
    182273            input_element.addClass(CLASSES.IDLE); 
     
    188279    } 
    189280     
     281    /** 
     282     * Parse the loaded results 
     283     *  
     284     * @param Array data    Result data 
     285     * @return Array        Containing parsed data 
     286     */ 
    190287    function parse(data) 
    191288    { 
    192289        var results = []; 
    193         jQuery('result',data).each(function(idx) {             
     290        jQuery('result', data).each(function(idx) { 
    194291            var rel_this = jQuery(this); 
    195292             
    196             results[idx] = {                  
    197                 id:rel_this.find("id").text(),  
    198                 guid:rel_this.find("guid").text() 
     293            results[idx] = { 
     294                id:rel_this.find('id').text(), 
     295                guid:rel_this.find('guid').text() 
    199296            }; 
    200297             
    201             jQuery.each(options.result_headers,function(i,h){ 
     298            jQuery.each(options.result_headers,function(i,h) 
     299            { 
    202300                results[idx][h.name] = rel_this.find(h.name).text(); 
    203301            }); 
     
    205303 
    206304        var parsed = []; 
    207         jQuery(results).each(function(idx){ 
     305        jQuery(results).each(function(idx) 
     306        { 
    208307            var item = results[idx]; 
    209             if (item) { 
    210                 parsed[parsed.length] = { 
     308            if (item) 
     309            { 
     310                parsed[parsed.length] = 
     311                { 
    211312                    id: item.id, 
    212313                    data: item 
    213314                }; 
    214             }             
     315            } 
    215316        }); 
    216317 
    217318        return parsed; 
    218319    } 
    219  
    220     input_element.keydown(function(event) { 
    221         // track last key pressed 
    222         lastKeyPressCode = event.keyCode; 
    223         switch(event.keyCode) { 
    224          
    225             case KEY.UP: 
    226                 event.preventDefault(); 
    227                 if ( results_holder.visible() ) 
    228                 { 
    229                     results_holder.prev(); 
    230                 } 
    231                 else 
    232                 { 
    233                     onChange(0, true); 
    234                 } 
    235                 break; 
    236                  
    237             case KEY.DOWN: 
    238                 event.preventDefault(); 
    239                 if ( results_holder.visible() ) 
    240                 { 
    241                     results_holder.next(); 
    242                 } 
    243                 else 
    244                 { 
    245                     onChange(0, true); 
    246                 } 
    247                 break; 
    248                  
    249             case KEY.RETURN: 
    250                 event.preventDefault(); 
    251                 results_holder.select_current(); 
    252                 break; 
    253                  
    254             case KEY.ESC: 
    255                 break; 
    256                  
    257             default: 
    258                 clearTimeout(timeout); 
    259                 timeout = setTimeout(onChange, options.delay); 
    260                 break; 
    261         } 
    262     }).keypress(function(event) { 
    263         // having fun with opera - remove this binding and Opera submits the form when we select an entry via return 
    264         switch(event.keyCode) { 
    265             case KEY.RETURN: 
    266                 event.preventDefault(); 
    267                 break; 
    268         } 
    269     }).focus(function(){ 
    270         // track whether the field has focus, we shouldn't process any 
    271         // results if the field no longer has focus 
    272         clearTimeout(blurTimeout); 
    273         hasFocus++; 
    274     }).blur(function() { 
    275         hasFocus = 0; 
    276         input_element.removeClass(CLASSES.LOADING); 
    277         input_element.removeClass(CLASSES.FAILED); 
    278         input_element.addClass(CLASSES.IDLE); 
    279         clearTimeout(blurTimeout); 
    280         blurTimeout = setTimeout(results_holder.clear_unselected, options.delay); 
    281     }).click(function() { 
    282         // show results when clicking in a focused field 
    283         if ( hasFocus++ > 1 && !results_holder.visible() ) { 
    284             onChange(0, true); 
    285         } 
    286     }).bind("activate", function(event, data){ 
    287         input_element.focus(); 
    288         results_holder.activate_item(data); 
    289     }).bind("add_result_item", function(event, data, item){ 
    290         results_holder.add_item(data, item); 
    291     }).bind("remove_result_item", function(event, item_id){ 
    292         results_holder.del_item(); 
    293     }); 
    294      
     320     
     321    // Input field events 
     322    input_element 
     323        .keydown(function(event) 
     324        { 
     325            // track last key pressed 
     326            lastKeyPressCode = event.keyCode; 
     327            switch(event.keyCode) 
     328            { 
     329                case KEY.UP: 
     330                    event.preventDefault(); 
     331                    if ( results_holder.visible() ) 
     332                    { 
     333                        results_holder.prev(); 
     334                    } 
     335                    else 
     336                    { 
     337                        onChange(0, true); 
     338                    } 
     339                    break; 
     340                     
     341                case KEY.DOWN: 
     342                    event.preventDefault(); 
     343                    if ( results_holder.visible() ) 
     344                    { 
     345                        results_holder.next(); 
     346                    } 
     347                    else 
     348                    { 
     349                        onChange(0, true); 
     350                    } 
     351                    break; 
     352                     
     353                case KEY.RETURN: 
     354                    event.preventDefault(); 
     355                    results_holder.select_current(); 
     356                    break; 
     357                     
     358                case KEY.ESC: 
     359                    break; 
     360                     
     361                default: 
     362                    clearTimeout(timeout); 
     363                    timeout = setTimeout(onChange, options.delay); 
     364                    break; 
     365            } 
     366        }) 
     367        .keypress(function(event) 
     368        { 
     369            // having fun with opera - remove this binding and Opera submits the form when we select an entry via return 
     370            switch(event.keyCode) 
     371            { 
     372                case KEY.RETURN: 
     373                    event.preventDefault(); 
     374                    break; 
     375            } 
     376        }) 
     377        .focus(function() 
     378        { 
     379            // track whether the field has focus, we shouldn't process any 
     380            // results if the field no longer has focus 
     381            clearTimeout(blurTimeout); 
     382            hasFocus++; 
     383        }) 
     384        .blur(function() 
     385        { 
     386            hasFocus = 0; 
     387            input_element.removeClass(CLASSES.LOADING); 
     388            input_element.removeClass(CLASSES.FAILED); 
     389            input_element.addClass(CLASSES.IDLE); 
     390            clearTimeout(blurTimeout); 
     391            blurTimeout = setTimeout(results_holder.clear_unselected, options.delay); 
     392        }) 
     393        .click(function() 
     394        { 
     395            // show results when clicking in a focused field 
     396            if ( hasFocus++ > 1 && !results_holder.visible() ) 
     397            { 
     398                onChange(0, true); 
     399            } 
     400        }) 
     401        .bind('activate', function(event, data) 
     402        { 
     403            input_element.focus(); 
     404            results_holder.activate_item(data); 
     405        }) 
     406        .bind('add_result_item', function(event, data, item) 
     407        { 
     408            results_holder.add_item(data, item); 
     409        }) 
     410        .bind('remove_result_item', function(event, item_id) 
     411        { 
     412            results_holder.del_item(); 
     413        }); 
     414     
     415    /** 
     416     * Enable the creation mode 
     417     */ 
    295418    function enable_creation_mode() 
    296419    { 
     
    300423        create_button = jQuery('#' + options.widget_id + '_create_button'); 
    301424        create_button.css('display', 'block'); 
    302         create_button.bind('click', function(){ 
     425        create_button.bind('click', function() 
     426        { 
    303427            if (jQuery('#' + options.widget_id + '_creation_dialog').css('display') == 'block') 
    304428            { 
     
    308432            var creation_url = options.creation_handler; 
    309433             
    310             if (last_term != "undefined"
     434            if (last_term != 'undefined'
    311435            { 
    312436                creation_url += '?defaults[' + options.creation_default_key + ']=' + last_term; 
     
    333457}; 
    334458 
    335 jQuery.midcom_helper_datamanager2_widget_chooser.defaults = { 
     459jQuery.midcom_helper_datamanager2_widget_chooser.defaults = 
     460
    336461    widget_id: 'chooser_widget', 
    337462    delay: 400, 
     
    348473jQuery.midcom_helper_datamanager2_widget_chooser.ResultsHolder = function(options, input, insert_after) 
    349474{ 
    350     var CLASSES = { 
    351         HOVER: "chooser_widget_result_item_hover", 
    352         ACTIVE: "chooser_widget_result_item_active", 
    353         INACTIVE: "chooser_widget_result_item_inactive", 
    354         DELETED: "chooser_widget_result_item_deleted" 
     475    var CLASSES = 
     476    { 
     477        HOVER: 'chooser_widget_result_item_hover', 
     478        ACTIVE: 'chooser_widget_result_item_active', 
     479        INACTIVE: 'chooser_widget_result_item_inactive', 
     480        DELETED: 'chooser_widget_result_item_deleted' 
    355481    }; 
    356482 
     
    359485        .hide() 
    360486        .addClass('chooser_widget_results_holder'); 
     487     
    361488    jQuery(insert_after).after( element ); 
    362489 
     
    377504        if (element) 
    378505        { 
    379             if (element.tagName == "UL"
     506            if (element.tagName == 'UL'
    380507            { 
    381508                element = jQuery(element).find('li').eq(0); 
     
    383510            } 
    384511             
    385             while(element.tagName != "LI"
     512            while(element.tagName != 'LI'
    386513            { 
    387514                element = element.parentNode; 
     
    400527        } 
    401528         
    402         jQuery.each( options.result_headers, function(i,n) { 
    403             var li_elem = jQuery("<li>") 
     529        jQuery.each( options.result_headers, function(i,n) 
     530        { 
     531            var li_elem = jQuery('<li>') 
    404532                .addClass('chooser_widget_header_item') 
    405                 .css({ 
    406                     width: block_width+'%' 
     533                .css( 
     534                { 
     535                    width: block_width + '%' 
    407536                }) 
    408             var item_content = jQuery("<div>"
     537            var item_content = jQuery('<div>'
    409538                .html( n.title ) 
    410539                .appendTo(li_elem); 
     
    415544    function dataToDom() 
    416545    { 
    417         for (var i=0; i < data.length; i++) { 
     546        for (var i=0; i < data.length; i++) 
     547        { 
    418548            if (!data[i]) 
    419549                continue; 
     
    421551            add(data[i].data); 
    422552        } 
    423         list_jq_items = list.find("li"); 
    424         if ( options.select_first ) { 
     553        list_jq_items = list.find('li'); 
     554        if ( options.select_first ) 
     555        { 
    425556            list_jq_items.eq(0).addClass(CLASSES.ACTIVE); 
    426557            active = 0; 
    427558            var active_id = list_items[0]; 
    428559 
    429             jQuery('#'+options.widget_id + '_result_item_'+active_id+'_input', list).attr({ value: active_id }); 
    430             jQuery('#'+options.widget_id + '_result_item_'+active_id).attr("keep_on_list","true"); 
     560            jQuery('#' + options.widget_id + '_result_item_' + active_id + '_input', list).attr({ value: active_id }); 
     561            jQuery('#' + options.widget_id + '_result_item_' + active_id).attr('keep_on_list','true'); 
    431562            selected_items.push(active_id); 
    432563        } 
     
    435566    function can_add(id) 
    436567    { 
    437         //console.log("can_add id: "+id); 
     568        //console.log('can_add id: ' + id); 
    438569         
    439570        var existing = false; 
    440         existing = jQuery.grep( list_items, function(n,i){ 
     571        existing = jQuery.grep( list_items, function(n,i) 
     572       { 
    441573           return n == id; 
    442574        }); 
    443575        if (existing == id) 
    444576        { 
    445             // jQuery('#'+options.widget_id+'_result_item_'+id,list).hide("fast",function(){ 
    446             //    jQuery('#'+options.widget_id+'_result_item_'+id,list).show('fast'); 
     577            // jQuery('#' + options.widget_id + '_result_item_' + id,list).hide('fast',function(){ 
     578            //    jQuery('#' + options.widget_id + '_result_item_' + id,list).show('fast'); 
    447579            //  }); 
    448580            return false; 
     
    456588        // console.log('ResultsHolder add'); 
    457589        // console.log(data); 
    458         //console.log('data.id: '+data.id); 
    459         //console.log('data.guid: '+data.guid); 
     590        //console.log('data.id: ' + data.id); 
     591        //console.log('data.guid: ' + data.guid); 
    460592         
    461593        var n=null; 
    462594         
    463595        var item_id = data[options.id_field]; 
    464         //console.log('options.id_field: '+options.id_field); 
    465         //console.log('item_id: '+item_id); 
    466          
    467         // var static_row = jQuery("#" + options.widget_id + "_existing_item_" + item_id + "_row"); 
     596        //console.log('options.id_field: ' + options.id_field); 
     597        //console.log('item_id: ' + item_id); 
     598         
     599        // var static_row = jQuery('#' + options.widget_id + '_existing_item_' + item_id + '_row'); 
    468600        // if (typeof static_row[0] != 'undefined') 
    469601        // { 
    470         //     var static_input = jQuery("#" + options.widget_id + "_existing_item_" + item_id + "_input"); 
     602        //     var static_input = jQuery('#' + options.widget_id + '_existing_item_' + item_id + '_input'); 
    471603        //     static_input.delete(); 
    472604        //     static_row.delete(); 
     
    479611        } 
    480612         
    481         //console.log("Can add!"); 
     613        //console.log('Can add!'); 
    482614         
    483615        if (! has_content) 
     
    488620         
    489621         
    490         var input_elem_name = options.widget_id + "_selections[" + item_id + "]"; 
    491          
    492         var li_elem = jQuery("<li>") 
    493         .attr({ id: options.widget_id + '_result_item_'+item_id }) 
    494         .attr("deleted","false") 
    495         .attr("keep_on_list","false") 
    496         .attr("pre_selected","false") 
    497         .addClass("chooser_widget_result_item") 
    498         .click(function(event) { 
     622        var input_elem_name = options.widget_id + '_selections[' + item_id + ']'; 
     623         
     624        var li_elem = jQuery('<li>') 
     625        .attr({ id: options.widget_id + '_result_item_' + item_id }) 
     626        .attr('deleted','false') 
     627        .attr('keep_on_list','false') 
     628        .attr('pre_selected','false') 
     629        .addClass('chooser_widget_result_item') 
     630        .click(function(event) 
     631        { 
    499632            var li_element = target(event); 
    500             jQuery("#" + options.widget_id + "_search_input").focus(); 
    501             var current_keep_status = jQuery(li_element).attr("keep_on_list"); 
    502             var current_delete_status = jQuery(li_element).attr("deleted"); 
    503             var current_presel_status = jQuery(li_element).attr("pre_selected"); 
     633            jQuery('#' + options.widget_id + '_search_input').focus(); 
     634            var current_keep_status = jQuery(li_element).attr('keep_on_list'); 
     635            var current_delete_status = jQuery(li_element).attr('deleted'); 
     636            var current_presel_status = jQuery(li_element).attr('pre_selected'); 
    504637             
    505             if (current_keep_status == "true"
    506             { 
    507                 if (current_delete_status == "false"
     638            if (current_keep_status == 'true'
     639            { 
     640                if (current_delete_status == 'false'
    508641                { 
    509642                    jQuery(li_element).removeClass(CLASSES.ACTIVE); 
    510                     if (current_presel_status == "true"
     643                    if (current_presel_status == 'true'
    511644                    { 
    512645                        remove(item_id); 
     
    536669            } 
    537670        }) 
    538         .mouseover( function(event) { 
     671        .mouseover( function(event) 
     672        { 
    539673            var jq_elem = jQuery(target(event)).addClass(CLASSES.HOVER); 
    540674        }) 
    541         .mouseout( function(event) { 
     675        .mouseout( function(event) 
     676        { 
    542677            jQuery(target(event)).removeClass(CLASSES.HOVER); 
    543678        }); 
     
    545680        if (data['pre_selected']) 
    546681        { 
    547             li_elem.attr("pre_selected","true"); 
    548         }         
     682            li_elem.attr('pre_selected','true'); 
     683        } 
    549684         
    550685        if (   options.renderer_callback 
    551686            && typeof item != 'undefined') 
    552687        { 
    553             //console.log("use renderer"); 
     688            //console.log('use renderer'); 
    554689            // PONDER:  How should we really handle the renderer_callback rendering? 
    555690            //          We could use custom javascript function, or require the data 
    556691            //          object to contain a content field which is already formatted html... 
    557             var item_content = jQuery("<div>").html(item) 
     692            var item_content = jQuery('<div>').html(item) 
    558693            .appendTo(li_elem); 
    559694            var input_elem = jQuery("<input type=\"hidden\">") 
    560             .attr({ name: input_elem_name, value: 0, id: options.widget_id + '_result_item_'+item_id+'_input' }) 
     695            .attr({ name: input_elem_name, value: 0, id: options.widget_id + '_result_item_' + item_id + '_input' }) 
    561696            .appendTo(li_elem); 
    562697        } 
     
    566701            .appendTo(li_elem); 
    567702            var input_elem = jQuery("<input type=\"hidden\">") 
    568             .attr({ name: input_elem_name, value: 0, id: options.widget_id + '_result_item_'+item_id+'_input' }) 
     703            .attr({ name: input_elem_name, value: 0, id: options.widget_id + '_result_item_' + item_id + '_input' }) 
    569704            .appendTo(li_elem); 
    570705        } 
    571706         
     707        // Add drag bar 
     708        jQuery('<div>') 
     709            .addClass('dragbar') 
     710            .prependTo(li_elem); 
     711         
    572712        li_elem.appendTo(list); 
    573713         
     
    575715    } 
    576716 
    577     function moveSelect(step) { 
     717    function moveSelect(step) 
     718    { 
    578719        active += step; 
    579720        wrapSelection(); 
     
    583724        if (jq_elem.attr('class') != CLASSES.ACTIVE) 
    584725        { 
    585             jq_elem.addClass(CLASSES.HOVER);             
     726            jq_elem.addClass(CLASSES.HOVER); 
    586727        } 
    587728    }; 
    588729     
    589     function wrapSelection() { 
    590         if (active < 0) { 
     730    function wrapSelection() 
     731    { 
     732        if (active < 0) 
     733        { 
    591734            active = list_jq_items.size() - 1; 
    592         } else if (active >= list_jq_items.size()) { 
     735        } 
     736        else if (active >= list_jq_items.size()) 
     737        { 
    593738            active = 0; 
    594739        } 
     
    596741     
    597742    function remove(id) 
    598     {         
    599         jQuery('#'+options.widget_id + '_result_item_'+id+'_input', list).attr({ value: 0 }); 
    600         jQuery('#'+options.widget_id + '_result_item_'+id).removeClass(CLASSES.ACTIVE); 
    601         jQuery('#'+options.widget_id + '_result_item_'+id).removeClass(CLASSES.INACTIVE); 
    602         jQuery('#'+options.widget_id + '_result_item_'+id).addClass(CLASSES.DELETED); 
    603         jQuery('#'+options.widget_id + '_result_item_'+id).attr("deleted","true"); 
    604         selected_items = jQuery.grep( selected_items, function(n,i){ 
     743    { 
     744        jQuery('#' + options.widget_id + '_result_item_' + id + '_input', list).attr({ value: 0 }); 
     745        jQuery('#' + options.widget_id + '_result_item_' + id).removeClass(CLASSES.ACTIVE); 
     746        jQuery('#' + options.widget_id + '_result_item_' + id).removeClass(CLASSES.INACTIVE); 
     747        jQuery('#' + options.widget_id + '_result_item_' + id).addClass(CLASSES.DELETED); 
     748        jQuery('#' + options.widget_id + '_result_item_' + id).attr('deleted','true'); 
     749        selected_items = jQuery.grep( selected_items, function(n,i) 
     750        { 
    605751            return n != id; 
    606752        }); 
     
    609755    function restore(id) 
    610756    { 
    611         jQuery('#'+options.widget_id + '_result_item_'+id+'_input', list).attr({ value: id });  
    612         jQuery('#'+options.widget_id + '_result_item_'+id).removeClass(CLASSES.DELETED); 
    613         jQuery('#'+options.widget_id + '_result_item_'+id).removeClass(CLASSES.INACTIVE); 
    614         jQuery('#'+options.widget_id + '_result_item_'+id).addClass(CLASSES.ACTIVE); 
    615         jQuery('#'+options.widget_id + '_result_item_'+id).attr("deleted","false"); 
     757        jQuery('#' + options.widget_id + '_result_item_' + id + '_input', list).attr({ value: id }); 
     758        jQuery('#' + options.widget_id + '_result_item_' + id).removeClass(CLASSES.DELETED); 
     759        jQuery('#' + options.widget_id + '_result_item_' + id).removeClass(CLASSES.INACTIVE); 
     760        jQuery('#' + options.widget_id + '_result_item_' + id).addClass(CLASSES.ACTIVE); 
     761        jQuery('#' + options.widget_id + '_result_item_' + id).attr('deleted','false'); 
    616762        selected_items.push(id); 
    617763    } 
     
    622768        { 
    623769            // Remove activation from the previously selected list element 
    624             jQuery('#'+ options.widget_id + '_results li.' + CLASSES.ACTIVE).click(); 
    625         } 
    626          
    627         jQuery('#'+options.widget_id + '_result_item_'+id+'_input', list).attr({ value: id }); 
    628         jQuery('#'+options.widget_id + '_result_item_'+id).removeClass(CLASSES.DELETED); 
    629         jQuery('#'+options.widget_id + '_result_item_'+id).removeClass(CLASSES.INACTIVE); 
    630         jQuery('#'+options.widget_id + '_result_item_'+id).addClass(CLASSES.ACTIVE); 
    631         jQuery('#'+options.widget_id + '_result_item_'+id).attr("keep_on_list","true"); 
    632         jQuery('#'+options.widget_id + '_result_item_'+id).attr("deleted","false"); 
     770            jQuery('#' + options.widget_id + '_results li.' + CLASSES.ACTIVE).click(); 
     771        } 
     772         
     773        jQuery('#' + options.widget_id + '_result_item_' + id + '_input', list).attr({ value: id }); 
     774        jQuery('#' + options.widget_id + '_result_item_' + id).removeClass(CLASSES.DELETED); 
     775        jQuery('#' + options.widget_id + '_result_item_' + id).removeClass(CLASSES.INACTIVE); 
     776        jQuery('#' + options.widget_id + '_result_item_' + id).addClass(CLASSES.ACTIVE); 
     777        jQuery('#' + options.widget_id + '_result_item_' + id).attr('keep_on_list','true'); 
     778        jQuery('#' + options.widget_id + '_result_item_' + id).attr('deleted','false'); 
    633779        selected_items.push(id); 
    634780    } 
     
    636782    function inactivate(id) 
    637783    { 
    638         jQuery('#'+options.widget_id + '_result_item_'+id+'_input', list).attr({ value: 0 }); 
    639         jQuery('#'+options.widget_id + '_result_item_'+id).removeClass(CLASSES.DELETED); 
    640         jQuery('#'+options.widget_id + '_result_item_'+id).removeClass(CLASSES.ACTIVE); 
    641         jQuery('#'+options.widget_id + '_result_item_'+id).addClass(CLASSES.INACTIVE); 
    642         jQuery('#'+options.widget_id + '_result_item_'+id).attr("keep_on_list","false"); 
    643         jQuery('#'+options.widget_id + '_result_item_'+id).attr("deleted","false"); 
     784        jQuery('#' + options.widget_id + '_result_item_' + id + '_input', list).attr({ value: 0 }); 
     785        jQuery('#' + options.widget_id + '_result_item_' + id).removeClass(CLASSES.DELETED); 
     786        jQuery('#' + options.widget_id + '_result_item_' + id).removeClass(CLASSES.ACTIVE); 
     787        jQuery('#' + options.widget_id + '_result_item_' + id).addClass(CLASSES.INACTIVE); 
     788        jQuery('#' + options.widget_id + '_result_item_' + id).attr('keep_on_list','false'); 
     789        jQuery('#' + options.widget_id + '_result_item_' + id).attr('deleted','false'); 
    644790        //selected_items.push(id); 
    645         selected_items = jQuery.grep( selected_items, function(n,i){ 
     791        selected_items = jQuery.grep( selected_items, function(n,i) 
     792        { 
    646793            return n != id; 
    647794        }); 
     
    650797    function delete_unseleted_from_list() 
    651798    { 
    652         list_jq_items = list.find("li"); 
     799        list_jq_items = list.find('li'); 
    653800        var removed_items = []; 
    654         jQuery.each( list_items, function(i,n){ 
     801        jQuery.each( list_items, function(i,n) 
     802        { 
    655803            if (n != undefined) 
    656804            { 
    657                 if (jQuery('#'+options.widget_id + '_result_item_'+n).attr("keep_on_list") == "false"
     805                if (jQuery('#' + options.widget_id + '_result_item_' + n).attr('keep_on_list') == 'false'
    658806                { 
    659                     jQuery('#'+options.widget_id + '_result_item_'+n).remove(); 
     807                    jQuery('#' + options.widget_id + '_result_item_' + n).remove(); 
    660808                    removed_items.push(n); 
    661                 }       
    662             } 
    663         }); 
    664         jQuery.each( removed_items, function(i,n){ 
     809                } 
     810            } 
     811        }); 
     812        jQuery.each( removed_items, function(i,n) 
     813        { 
    665814            list_items = unset(list_items, n, false, true); 
    666815        }); 
     
    710859     
    711860    return { 
    712         display: function(d) { 
     861        display: function(d) 
     862        { 
    713863            delete_unseleted_from_list(); 
    714864            data = d; 
     
    734884            } 
    735885        }, 
    736         visible : function() { 
    737             return element.is(":visible"); 
     886        visible : function() 
     887        { 
     888            return element.is(':visible'); 
    738889        }, 
    739         next: function() { 
     890        next: function() 
     891        { 
    740892            moveSelect(1); 
    741893        }, 
    742         prev: function() { 
     894        prev: function() 
     895        { 
    743896            moveSelect(-1); 
    744897        }, 
    745         hide: function() { 
     898        hide: function() 
     899        { 
    746900            element.hide(); 
    747901            active = -1; 
    748902        }, 
    749         current: function() { 
    750             return this.visible() && (list_jq_items.filter("." + CLASSES.ACTIVE)[0] || options.select_first && list_jq_items[0]); 
     903        current: function() 
     904        { 
     905            return this.visible() && (list_jq_items.filter('.' + CLASSES.ACTIVE)[0] || options.select_first && list_jq_items[0]); 
    751906        }, 
    752         show: function() { 
     907        show: function() 
     908        { 
    753909            element.show(); 
    754910        }, 
    755         select_current: function() { 
    756             jQuery("." + CLASSES.HOVER).click(); 
     911        select_current: function() 
     912        { 
     913            jQuery('.' + CLASSES.HOVER).click(); 
    757914        }, 
    758915        clear_unselected: function() 
    759            { 
    760                delete_unseleted_from_list(); 
    761            } 
     916        { 
     917            delete_unseleted_from_list(); 
     918        } 
    762919    }; 
    763920}; 
     
    769926        var selRange = field.createTextRange(); 
    770927        selRange.collapse(true); 
    771         selRange.moveStart("character", start); 
    772         selRange.moveEnd("character", end); 
     928        selRange.moveStart('character', start); 
     929        selRange.moveEnd('character', end); 
    773930        selRange.select(); 
    774931    } 
     
    792949