2017년 8월 1일 화요일

How to do Autofill


Abe Getzler
Sep 2016

This sample app shows how to use a stored list of words to suggest autocompletion for a text field.  The sample word list is built from a copy of the US Declaration of Independence, which happened to be handy.  


Warning:  The text block containing my word list is too long for some web browsers.  It will blow up the browser if you try to show its contents.  I really should have loaded it from a Media text file.
Sample run


Screenshot 2014-08-22 17.06.31.png
Screenshot 2014-08-22 17.06.44.png


Designer
Desiigner.jpg


There’s not much here.  

A text box for you to start typing into
A ListView to show possible word matches
A Clock to check and refresh the word list every 100 ms.
Initialization
Initialization.jpg
Initialization takes a while, because of the long lists it has to set up to speed dictionary search.  This example was written before the Progress Notifier block existed, so I took the lazy way out and used the Screen1 Title to show progress.  Clock1 had to be disabled, because it checks the very lists this event builds.   My word list is in the monster text block global variable Source, so I have to extract all the words, ignoring white space (spaces, commas, periods, etc.).  


After I extract all the words, I run the word list through a filter to eliminate duplicates.  This is necessary because my word source was a big random pile of text.


After I have a distinct list of words, I build another data structure called dictionary, which is meant to give me rapid lookup based on leading text parts of words.


Remove_duplicates
remove_duplicates.jpg


This general purpose filter will take a list as input and output a new list containing single instances of the values in the original list.


Build_dictionary


This routine builds a two column table (fragment, complete word) with several rows per word, depending on how long each word is.  For example, the word fragment would have the rows

(fra, fragment)
(frag, fragment)
(fragm, fragment)
(fragme, fragment)

build_dictionary.jpg
Extract_fragments
extract_fragments.jpg
This filter takes a single word and returns a list of all the leading fragments of that word, in lower case, minimum length 3, up to 1 letter short of the complete word.


Globals


Beware the global text value Source.  It is too large for many browsers if uncollapsed in the Blocks Editor.globals.jpg
Clock1.Timer

Clock1_Timer.jpg


The Clock Timer periodically checks to see if the word being typed warrants refreshing the list view of possible word matches.  Word fragments shorter than 3 letters are not checked, for efficiency.  


The list view is hidden if there are no word candidates.


The prior entry is kept in a global, to see if new letters have been typed.  This is meant to save effort checking the same fragment over and over again if the user types slowly.


If we have new letters, check the fragment if its downshifted value is in column 1 of the dictionary (which I hope is all lower case.  (I’m not sure, you check it.))  The WHERE_EQ filter takes a table and returns a new table containing just the rows that have a matching value in the requested column number.  The next filter, DISTINCT, takes an input table and returns a 1 dimensional list of just one copy of each distinct value in the requested column.  That list is loaded into the list view.


WHERE_EQ
WHERE_EQ.jpg
Return just the rows where a given column number match a given value.

DISTINCT
DISTINCT.jpg


Take a table and return a simple list of the distinct values in a given column number.
This is good for loading a list view or list picker Elements list.


ListView1.AfterPicking
ListView1_AfterPicking.jpg
After the user selects an item from the list view of word suggestions,

Replace the word fragment in the text box with the complete word
Hide the keyboard
Hide the list view

Links:


More Projects: Index of AI2 Projects


댓글 없음:

댓글 쓰기