Changeset 2139


Ignore:
Timestamp:
03/02/10 16:44:01 (14 years ago)
Author:
asaikawa
Message:

Ticket #946 - Criada nova forma de funcionamento do componente que atualiza o cache a cada nova entrada no input

Location:
trunk/workflow
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/workflow/inc/smarty/wf_plugins/function.wf_autocomplete_input.php

    r1935 r2139  
    2828        $defaultValues = array( 
    2929                'minLength'     => 1, 
    30                 'style'         => "width: 200px" 
     30                'style'         => "width: 200px", 
     31                'mode'          => "POPULATE_ON_LOAD" 
    3132        ); 
    3233        $extractParams = array( 
     
    3839                'idValue', 
    3940                'textValue', 
    40                 'style' 
     41                'style', 
     42                'mode' 
    4143        ); 
    4244 
     
    7981        $extraParams = json_encode($extraParams); 
    8082 
     83        /* se o componente for do tipo padrão (POPULATE_ON_LOAD), não necessita de função para onkeyup */ 
     84        if ($mode == 'POPULATE_ON_LOAD'){ 
     85                $inputElement = <<<EOF 
     86                <input id="$name_input" name="$name_input" type="text" value="$textValue" style="$style" onfocus="checkDataLoaded('$name');" onblur="setTimeout('selectAutocompleteElement(\'$name\')', 500);"/> 
     87EOF; 
     88        } 
     89        elseif ($mode == 'REPOPULATE_ON_CHANGE'){ 
     90                $inputElement = <<<EOF 
     91                <input id="$name_input" name="$name_input" type="text" value="$textValue" style="$style" onblur="setTimeout('selectAutocompleteElement(\'$name\')', 500);" onkeyup="updateCacheRequestsTimeout('$name', '$ajaxClass', '$ajaxMethod', this.value, '$mode')"/> 
     92EOF; 
     93        } 
     94 
     95        /* Cria todos os elementos HTML necessários para o componente */ 
    8196        $output = <<<EOF 
    8297        <input id="$name" name="$name" type="hidden"/> 
    83         <input id="$name_input" name="$name_input" type="text" value="$textValue" style="$style" onfocus="checkDataLoaded('$name');" onblur="setTimeout('selectAutocompleteElement(\'$name\')', 500);"/> 
     98        $inputElement 
    8499        <span id="$name_response"></span> 
    85100        <div id="$name_list" class="autocomplete" style="display: none;"></div> 
    86         <script>autocompleteSelect('$name', '$ajaxClass', '$ajaxMethod', $sep$methodParam$sep, $extraParams);</script> 
     101        <script>autocompleteSelect('$name', '$ajaxClass', '$ajaxMethod', $sep$methodParam$sep, '$mode', $extraParams);</script> 
    87102EOF; 
    88103        return $output; 
  • trunk/workflow/js/jscode/wf_autocomplete_input.js

    r1935 r2139  
    11var _cache = new Array(); 
    2  
     2var autocompleterObjs = new Array(); 
     3var myTimer; 
     4 
     5/* Verifica se o componente já foi populado (usado quando o tipo do componente é POPULATE_ON_LOAD) */ 
    36function checkDataLoaded(elementId) 
    47{ 
     
    1821} 
    1922 
     23/* Faz a verificação se o conteúdo digitado tem um correspondente na lista */ 
    2024function selectAutocompleteElement(elementId) 
    2125{ 
    2226        if ($('input' + elementId) == null) return -1; 
    2327        var value = $('input' + elementId).value; 
    24         var items = _cache['requests'][_cache['elements'][elementId]['hash']]['data']; 
     28        var items = new Object(); 
     29        if(_cache['requests'][_cache['elements'][elementId]['hash']] != undefined) 
     30                items = _cache['requests'][_cache['elements'][elementId]['hash']]['data']; 
    2531        var index = autocompleteIndexOf(items, value); 
    2632        $(elementId).value = index; 
     
    3036} 
    3137 
    32 function autocompleteIndexOf(array, value) 
    33 { 
    34         for (key in array){ 
    35                 if (array[key].toLowerCase() == value.toLowerCase()){ 
    36                         return key; 
     38/* Percorre o objeto comparando cada item com o valor digitado no componente, e retorna o índice, se encontrar */ 
     39function autocompleteIndexOf(items, value) 
     40{ 
     41        for (key in items){ 
     42                if(items.hasOwnProperty(key)){ 
     43                        if (items[key].toLowerCase() == value.toLowerCase()){ 
     44                                return key; 
     45                        } 
    3746                } 
    3847        } 
     
    4049} 
    4150 
    42 function arrayValues(array) 
     51function arrayValues(items) 
    4352{ 
    4453        var i = 0; 
    4554        var arr = Array(); 
    46         for (key in array){ 
    47                 arr[i++] = array[key]; 
     55        for (key in items){ 
     56                arr[i++] = items[key]; 
    4857        } 
    4958        return arr; 
    5059} 
    5160 
     61function removeAccents(text) { 
     62        var accents = 'áàãâäéèêëíìîïóòõôöúùûüçÁÀÃÂÄÉÈÊËÍÌÎÏÓÒÕÖÔÚÙÛÜÇ'; 
     63        var normalLetters = 'aaaaaeeeeiiiiooooouuuucAAAAAEEEEIIIIOOOOOUUUUC'; 
     64        var newText = ''; 
     65 
     66        for (i = 0; i < text.length; i++) { 
     67                if (accents.search(text.substr(i, 1)) >= 0) { 
     68                        newText += normalLetters.substr(accents.search(text.substr(i, 1)), 1); 
     69                } 
     70                else { 
     71                        newText += text.substr(i, 1); 
     72                } 
     73        } 
     74 
     75        return newText; 
     76} 
     77 
     78/* Cria, ou recria, o objeto autocompleter do componente, carregando a lista com os valores que já devem estar no cache */ 
    5279function autocompletePopulate(elementId) 
    5380{ 
     
    5582                var items = _cache['requests'][_cache['elements'][elementId]['hash']]['data']; 
    5683                var values = arrayValues(items); 
    57                 new Autocompleter.Local('input' + elementId, 'list' + elementId, values, { 
     84                autocompleterObjs[elementId] = new Autocompleter.Local('input' + elementId, 'list' + elementId, values, { 
    5885                        'choices':9, 
    5986                        'partialChars': _cache['elements'][elementId]['minLength'] 
    6087                }); 
    61         } 
    62         _cache['elements'][elementId]['populated'] = true; 
    63 } 
    64  
    65 function catchJsonError(dados){ return false; } 
    66  
    67 function autocompleteSelect(elementId, ajaxClass, ajaxMethod, methodParam, extraParams) 
    68 { 
    69         // se o parâmetro for um objeto, transforma em uma string para gerar o hash 
     88                _cache['elements'][elementId]['populated'] = true; 
     89        } 
     90} 
     91 
     92/* Cria array para armazenar os elementos */ 
     93function createCacheElementsArray(){ 
     94        if(_cache['elements'] == null) 
     95                _cache['elements'] = new Array(); 
     96} 
     97 
     98/* Cria array para armazenar os valores das requisições ajax */ 
     99function createCacheRequestsArray(){ 
     100        if(_cache['requests'] == null) 
     101                _cache['requests'] = new Array(); 
     102} 
     103 
     104/* Seta os valores do componente no _cache */ 
     105function createCacheElement(elementId, ajaxClass, ajaxMethod, methodParam, componentMode, extraParams){ 
     106        // se o parâmetro for um objeto, transforma em uma string para gerar o hash 
    70107        var _param = (typeof(methodParam) == 'object')? JSON.stringify(methodParam) : methodParam; 
    71         var str = ajaxClass + ajaxMethod + _param; 
    72         // Cria hash que identifica classe, método e parâmetro. 
    73         // Componente verifica se hash já existe para não fazer requisições ajax desnecessárias 
    74         var hash = new SHA1(str).hexdigest(); 
     108 
     109        // se o componente tiver que ser populado em sua criação, calcula o hash 
     110        if (componentMode == 'POPULATE_ON_LOAD'){ 
     111                var str = ajaxClass + ajaxMethod + _param; 
     112                // Cria hash que identifica classe, método e parâmetro. 
     113                // Componente verifica se hash já existe para não fazer requisições ajax desnecessárias 
     114                var hash = new SHA1(str).hexdigest(); 
     115        } 
     116        // senão, não há a necessidade de calcular o hash, pois a lista será carregada posteriormente 
     117        else 
     118                var hash = ""; 
    75119 
    76120        if(extraParams['minLength'] == null){ 
     
    89133        } 
    90134 
    91         func = function (dados) 
    92         { 
    93                 var result = dados[ajaxMethod]['data']; 
    94                 if (result !== false){ 
    95                         // guarda valores localmente 
    96                         _cache['requests'][hash]['data'] = result; 
    97                         _cache['requests'][hash]['populated'] = true; 
    98                         // Envia dados para o componente 
    99                         autocompletePopulate(elementId); 
    100                 } 
    101         }; 
    102  
    103         // Relaciona chamada ajax ao objeto 
    104         if(_cache['elements'] == null){ 
    105                 _cache['elements'] = new Array(); 
    106         } 
     135        createCacheElementsArray(); 
    107136 
    108137        if(_cache['elements'][elementId] == null){ 
     
    111140                _cache['elements'][elementId]['minLength'] = extraParams['minLength']; 
    112141        } else { 
    113                 // por algum motivo componente já existe. 
    114                 // Se o _cache na posição hash não for null, requisição ajax já foi feita. 
    115                 // Se o objeto já foi populado e está sendo escrito novamente, manda popular denovo  
    116                 //   (isso pode acontecer quando o componente é escrito através de javascript) 
     142                // por algum motivo componente já existe. 
     143                // Se o _cache na posição hash não for null, requisição ajax já foi feita. 
     144                // Se o objeto já foi populado e está sendo escrito novamente, manda popular denovo 
     145                //   (isso pode acontecer quando o componente é escrito através de javascript) 
    117146                if(_cache['requests'][hash] != null) 
    118147                        if (_cache['requests'][hash]['populated'] == true){ 
     
    121150                        } 
    122151        } 
    123  
    124         // Cria array para armazenar localmente os valores da requisição ajax 
    125         if(_cache['requests'] == null) 
    126                 _cache['requests'] = new Array(); 
     152} 
     153 
     154function catchJsonError(dados){ return false; } 
     155 
     156/* Controle de timeout para chamar a função updateCacheRequests quando o usuário ficar 0.3 segundos sem digitar. (chamada no onkeyup do componente do tipo REPOPULATE_ON_CHANGE) */ 
     157function updateCacheRequestsTimeout(elementId, ajaxClass, ajaxMethod, methodParam, componentMode){ 
     158        clearTimeout(myTimer); 
     159        myTimer = setTimeout("updateCacheRequests('" + elementId + "', '" + ajaxClass + "', '" + ajaxMethod + "', '" + methodParam + "', '" + componentMode + "')", 300); 
     160} 
     161 
     162/* Função que faz o gerenciamento das chamadas ajax e atualiza a lista de opções para seleção. */ 
     163var updateCacheRequests = function(elementId, ajaxClass, ajaxMethod, methodParam, componentMode){ 
     164        // se o parâmetro for um objeto, transforma em uma string para gerar o hash 
     165        var _param = (typeof(methodParam) == 'object')? JSON.stringify(methodParam) : methodParam; 
     166        var str = ajaxClass + ajaxMethod + _param; 
     167        // Cria hash que identifica classe, método e parâmetro. 
     168        // Componente verifica se hash já existe para não fazer requisições ajax desnecessárias 
     169        var hash = new SHA1(str).hexdigest(); 
    127170 
    128171        if(_cache['requests'][hash] == null){ 
     
    131174                _cache['requests'][hash]['data'] = new Array(); 
    132175 
    133                 // Faz a requisição ajax/Json 
    134                 var nc = new NanoController(); 
    135                 nc.setWfUrl(); 
    136                 nc.setSuccessHandler(func); 
    137                 nc.setExceptionHandler(catchJsonError); 
    138                 nc.setErrorHandler(catchJsonError); 
    139                 nc.addVirtualRequest(ajaxMethod, 
    140                 { 
    141                         action: ajaxClass, 
    142                         mode:   ajaxMethod 
    143                 }, methodParam); 
    144                 nc.sendRequest(); 
    145         } 
    146 } 
     176                if (componentMode == 'POPULATE_ON_LOAD'){ 
     177                        func = function (dados) 
     178                        { 
     179                                var result = dados[ajaxMethod]['data']; 
     180                                if (result !== false){ 
     181                                        // guarda valores localmente 
     182                                        _cache['requests'][hash]['data'] = result; 
     183                                        _cache['requests'][hash]['populated'] = true; 
     184                                        // Envia dados para o componente 
     185                                        autocompletePopulate(elementId); 
     186                                } 
     187                        }; 
     188 
     189                        // Faz a requisição ajax/Json 
     190                        var nc = new NanoController(); 
     191                        nc.setWfUrl(); 
     192                        nc.setSuccessHandler(func); 
     193                        nc.setExceptionHandler(catchJsonError); 
     194                        nc.setErrorHandler(catchJsonError); 
     195                        nc.addVirtualRequest(ajaxMethod, 
     196                                { 
     197                                        action: ajaxClass, 
     198                                        mode:   ajaxMethod 
     199                                }, methodParam); 
     200                        nc.sendRequest(); 
     201                } 
     202                else{ 
     203                        if(_param.length >= 3){ 
     204                                func = function (dados) 
     205                                { 
     206                                        var result = dados[ajaxMethod]['data']; 
     207                                        if(typeof(result) == "object" && result.length != 0){ 
     208                                                // guarda valores localmente 
     209                                                _cache['requests'][hash]['data'] = result; 
     210                                                _cache['requests'][hash]['populated'] = true; 
     211                                                _cache['elements'][elementId]['hash'] = hash; 
     212                                                var values = arrayValues(result); 
     213                                                autocompleterObjs[elementId].options.array = values; 
     214                                                autocompleterObjs[elementId].getUpdatedChoices(); 
     215                                        } 
     216                                }; 
     217 
     218                                // Faz a requisição ajax/Json 
     219                                var nc = new NanoController(); 
     220                                nc.setWfUrl(); 
     221                                nc.setSuccessHandler(func); 
     222                                nc.setExceptionHandler(catchJsonError); 
     223                                nc.setErrorHandler(catchJsonError); 
     224                                nc.addVirtualRequest(ajaxMethod, 
     225                                        { 
     226                                                action: ajaxClass, 
     227                                                mode:   ajaxMethod 
     228                                        }, removeAccents(methodParam)); 
     229                                nc.sendRequest(); 
     230                        } 
     231                } 
     232        } 
     233        else{ 
     234                // Se for do modo que deve repopular a lista a cada tecla pressionada e o _cache referente à entrada digitada já estiver populada 
     235                if (componentMode == 'REPOPULATE_ON_CHANGE' && _cache['requests'][hash]['populated']){ 
     236                        _cache['elements'][elementId]['hash'] = hash; 
     237                        var values = arrayValues(_cache['requests'][hash]['data']); 
     238                        autocompleterObjs[elementId].options.array = values; 
     239                } 
     240        } 
     241} 
     242 
     243/* Função que prepara o _cache, criando e setando os valores para cada componente */ 
     244function autocompleteSelect(elementId, ajaxClass, ajaxMethod, methodParam, componentMode, extraParams) 
     245{ 
     246        createCacheElement(elementId, ajaxClass, ajaxMethod, methodParam, componentMode, extraParams); 
     247        createCacheRequestsArray(); 
     248 
     249        // Se o componente é do tipo que deve repopular a lista a cada tecla, cria um objeto autocompleter com a lista vazia 
     250        if(componentMode == 'REPOPULATE_ON_CHANGE') 
     251                autocompleterObjs[elementId] = new Autocompleter.Local('input' + elementId, 'list' + elementId, new Array(), { 
     252                        'choices':9, 
     253                        'partialChars': _cache['elements'][elementId]['minLength'] 
     254                }); 
     255 
     256        updateCacheRequests(elementId, ajaxClass, ajaxMethod, methodParam, componentMode); 
     257} 
Note: See TracChangeset for help on using the changeset viewer.