Slow results with dynamic AutoCompleteTextField

23 views
Skip to first unread message

rdvg...@gmail.com

unread,
Feb 13, 2018, 4:49:05 PM2/13/18
to CodenameOne Discussions
Hi,

Load about 25k of records in a table called "articles".

To do the dynamic search of the information, I made a select to the table using the "like" function. Perform a test by entering the word "salsa". For each letter the routine goes to the BD and brings "n" number of records. For example: When registering the "s" character, 23k registers come, when I type the "a" they come 15k registers .....

My intention is to type the word "salsa" but the results can take up to 3 minutes.

Is there any way to request the information to the BD when you already complete the word "salsa" and not for each character?

Thanks

Shai Almog

unread,
Feb 14, 2018, 12:26:50 AM2/14/18
to CodenameOne Discussions
Hi,
sure. I demonstrated this in the online courses but this is a pretty simple strategy.

Keep a variable called timer of type UI timer and whenever you get an event:

- If you have a timer just cancel it
- Create a new timer to send the event in 500ms or even 1 second.

That way you create a delay that lets the user keep typing.

rdvg...@gmail.com

unread,
Feb 14, 2018, 2:55:52 PM2/14/18
to CodenameOne Discussions
Hello,
I have tried several options but I only get error messages, I appreciate the support on how to insert the UITimer API.
My code:

 final DefaultListModel<String> lmArticulos = new DefaultListModel<>();
        AutoCompleteTextField atArticulo = new AutoCompleteTextField(lmArticulos) {

            @Override
            protected boolean filter(String text) {

                UITimer timer = new UITimer(new Runnable() {
                    public void run() {

                    }
                });
                timer.schedule(1000, true, fmArticulo);

                if (text.length() == 0) {
                    return false;
                }

                ArrayList l = dT.leeInformacionRegistro(text, ARTICULO_LEE_NOMBRE_REGISTRO);
                if (l.isEmpty() || l.size() == 0) {
                    return false;
                }
                lmArticulos.removeAll();
                Vector vArticulo = new Vector();
                for (int i = 0; i < l.size(); i++) {
                    Map<String, String> d = (Map<String, String>) l.get(i);
                    lmArticulos.addItem(d.get("art_nombre"));
                    Articulo aRt = new Articulo();
                    aRt.setArticulo((String) d.get("art_articulo_id"));
                    aRt.setNombre((String) d.get("art_nombre"));
                    aRt.setTamano((String) d.get("art_tamano"));
                    vArticulo.addElement(aRt);
                }
                dT.setTemporal(vArticulo);
                return true;
            }
        };

Shai Almog

unread,
Feb 15, 2018, 12:29:51 AM2/15/18
to CodenameOne Discussions
Hi,
the timer variable should be a member of the class not a variable within the body. That way you can check and cancel... Something like this will be closer to what you need:

UITimer timer;

protected boolean filter(String text) {
   
if (text.length() == 0) {
       
if(timer != null) timer.cancel();
       
return false;
   
}

   
// other logic that doesn't involve server...
   
if(timer != null) timer.cancel();
    timer
= new UITimer(() -> {
       all your server fetch code should be here
!
   
};
   

    timer
.schedule(1000, true, fmArticulo);
}


Reply all
Reply to author
Forward
0 new messages