Listar caixa tipoahead: Pesquisa intuitiva da lista

Tradução automática de Deepl

pelo autor convidado Chris Belanger, um desenvolvedor 4D do Canadá

List box typeahead (um método para procurar progressivamente) não é uma característica nativa das caixas de listagem. No entanto, pode facilmente implementar esta funcionalidade com alguma codificação criativa. Neste post do blogue, vou demonstrar a técnica juntamente com um exemplo de base de dados e um documento exaustivo explicando os detalhes passo a passo.

O resultado final está resumido no GIF abaixo, Ilustra duas “pesquisas”. Uma para E-L-L-I-O-T, depois outra (depois de uma ordenação de colunas) para H-A-N-N-A-H:

HDI: Listbox typeahead

O que é que queremos fazer?

Quando a caixa de listagem tiver foco (mas não no “modo de entrada”), queremos ser capazes de digitar alguns caracteres e fazer com que a caixa de listagem se desloque e seleccione a correspondência mais próxima de acordo com a “coluna de ordenação”. Por exemplo, se for ordenado pelo nome da empresa, queremos começar a digitar o nome de uma empresa e ter a caixa de listagem localizada e destacada. No entanto, quando uma caixa de listagem é o objecto focado, não pode responder a toques de tecla.

Então, como podemos resolver este problema uma vez que não parece haver uma forma de recolher os toques nas teclas?

Colocar a caixa de listagem numa subforma

O primeiro passo é colocar a caixa de listagem num subforma (na base de dados de amostras, este formulário é chamado LB). Ok … mas como é que se recolhem as teclas? Utilizando botões invisíveis com “atalhos” atribuídos a eles.

Por sua vez, todos os atalhos chamam um método para determinar o texto de pesquisa, localizá-lo na caixa de listagem, e realçá-lo para o utilizador. Pode seguir esta explicação se abrir o formulário LB na caixa de listagem da base de dados Clairvoyance.

A caixa de listagem tem o nome do objecto, LB_Browser. As suas propriedades incluem:

blank

A selecção da entidade é chamada Form.es (no contexto do Subforma LB).

Na parte inferior do formulário LB , há uma colecção de botões. Cada um tem uma tecla de atalho atribuída a ele. A linha inferior pode parecer pouco clara, mas eles lidam com o ESPAÇO, -, e _ chaves. Pode acrescentar mais, se necessário.

blank

As propriedades de cada um destes botões são ilustradas através da utilização da tecla “A” como exemplo.

O Nome do Objecto termina na CARTA, NÚMERO, ou SÍMBOLO que gera. ESPAÇO é uma excepção; utiliza o símbolo ␣ e é “traduzido” para ESPAÇO.

O título é apenas para clarificação, o Dimensionamento Horizontal é Mover, e o atalho é o toque da tecla. O único evento que deve ser verificado é On Clicked.

Quando um utilizador carrega numa tecla de atalho, o guião para esse botão é accionado com um On Clicked Form event code.

blank

O script para cada botão é:

LB_SEARCH_DO (Form; OBJECT Get name)

Interpretar o toque da tecla

O LB_SEARCH_DO O método do projecto processa as teclas. Utiliza o carácter final do Nome do Objecto para conhecer o toque da tecla a processar.

$char:=$2[[Length($2)]] // get the last character in the object’s name.

Este carácter ou será anexado à cadeia de pesquisa ou substituirá a cadeia de pesquisa, dependendo do tempo decorrido desde o último toque de tecla. Na base de dados de amostras, qualquer “esperar” mais de 1,5 segundos iniciará uma nova pesquisa.

$now:=Milliseconds
If (($now-$obj_Search.lastMillisecond)>1500) //allow up to 1.50 seconds between keystrokes.
$obj_Search. searchFor :=$char //reset .searchFor
Else
$obj_Search.searchFor :=$obj_Search.searchFor +$char //add to .searchFor
End if
$obj_Search .lastMillisecond:=$now

A pesquisa na “coluna de pesquisa” é efectuada determinando qual o registo na selecção da entidade que seria a primeira correspondência, e depois localizar este registo na selecção da entidade (“.es“).

C_OBJECT($es_GreaterEqual) // the entity selection of the >= group that match the searchFor string.
$es_GreaterEqual :=$1.es.query($attrName+" >= :1";$obj_Search.searchFor).orderBy($attrName+" ASC")

O $itemPosition dentro da selecção da entidade é determinado com:

If ($es_GreaterEqual.length>0) // if there was at least one match
$match :=$es_GreaterEqual[0] // $match = the FIRST RECORD in the collection
$itemPosition :=$es_GreaterEqual[0].indexOf($1.es)+1 // location of the matching entity within the selection
Else
$itemPosition :=$1.es.length.

End if

Agora actualize a selecção de linhas da caixa de listagem e role para que o utilizador possa ver o resultado. Mostramo-lo na linha 5 da caixa de listagem para dar algum contexto.

C_LONGINT($show) // used to cause the ITEM POSITION to show in the 5th line (or higher, if it is < 5).
LISTBOX SELECT ROW (*;$lbName;$itemPosition;lk replace selection)
$show :=Choose($itemPosition<4;1;$itemPosition-4) // it will be line 5, or closer to the top
OBJECT SET SCROLL POSITION (*;$lbName;$show;*)

Finalmente, para o bem da demonstração, carregamos a entidade seleccionada para um objecto ao qual o formulário pai pode aceder.

Form.en_edit:=Form.es[$itemPosition-1] // for the parent form’s use

E mais

Descarregue o IDH acima para ver mais de perto o conceito. Além disso, é incluído um documento exaustivo que explica a configuração do formulário pai para operar a caixa de listagem, bem como dicas para conceber a interface do utilizador e melhorar a experiência do utilizador.

Espero que isto ajude no seu próximo projecto 4D!

Chris Belanger
Chris Belanger é um revelador 4D que começou a escrever soluções 4D por volta de 1991 - começando com 4D v2.0 - enquanto residia em Yellowknife, NWT, Canadá. Ele escreveu vários sistemas para o Governo Territorial, incluindo um para gerir projectos e uma Base de Dados Terminológicos que correlacionava a terminologia em oito línguas. Chris também escreveu bases de dados 4D para gerir as operações de uma empresa grossista, uma empresa de limpeza e restauração, e várias empresas de serviços em campos petrolíferos.