05-14-2010 09:37 AM - edited 05-14-2010 09:59 AM
I am currently looking to get a table's rows filtered through the KeywordFilterField. The underlying data is in tabular form:
Contact { Name, Phone, etc. etc.}
The KeywordFilterField displays only what I pass to it (Contact.Name) by calling setSourceList() and filters only the Strings in that list. So if I enter digits, that is going to return a blank list, because none of the Contacts have numbers in their Names. ![]()
However, what I want to do is query the table, like an SQL query, retrieve rows that match any part of Contact.Name or Contact.Phone. (Mind you this app does not use SQLite. I am using RMS for persistent storage and I have created my database and basic queries by hand.)
Is there any way I could customize/override the Filter query so that the KeywordFilterField calls my query functions instead of it's default String Filter? This is a basic CRUD application with search. I am using KeywordFilterField because it does everything else I need.
Any help would be useful.
Solved! Go to Solution.
05-27-2010 03:03 AM
Anybody?
05-31-2010 06:32 AM - edited 05-31-2010 07:09 AM
Ok let me put it this way: does anyone know how to set a new SourceList for the KeywordFilterField whenever you type something into the text box of the KeywordFilterField? I mean something like a text change listener for the textbox of the KeywordFilterField. I tried setting a Change Listener to it, but that throws a runtime error: Multiple Change Listeners not allowed.
Any ideas?
05-31-2010 10:20 AM
This is possible with a text field and a list field, that way you can do your own custom searching since the keyword filter field does not search your data the way you want it to. Plus I know that the keyword filter field is broken and was always returning completely incorrect search results for me.
Here's an outline of what to do. Some things I can't tell you how to do such as what happens in the "searchContacts" function since that's up to you to write the code to do whatever custom searching you want.
class CustomKeywordFilterScreen extends MainScreen implements FieldChangeListener, ListFieldCallback
{
//just a slightly modified edit field for use in entering keywords
private CustomKeywordField _filterEdit;
//a standard list field
private ListField _countryList;
//temp variable to hold the last keyword searched so we don't search for it again
//you'll see this used later on
private String _previousFilterValue;
//any other private vars you need to hold search results go here
//we'll use an a Contact[] for illustration
private Contact[] _contactResults;
CustomKeywordFilterScreen()
{
super(Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR);
//initiaize to empty string
_previousFilterValue = "";
//searchContacts is whatever function you write to do the customized search you want,
//in this example passing an empty string returns all contacts
_contactResults = searchContacts(_previousFilterValue);
//create the edit field and set it as the title of the screen so it's always visible,
//even when you scroll the list
_filterEdit = new CustomKeywordField();
_filterEdit.setLabel("Search: ");
_filterEdit.setChangeListener(this);
setTitle(_filterEdit);
//create the list for showing results
_contactList = new ListField();
_countryList.setRowHeight(-2);
_contactList.setSize(_contactResults.length);
_contactList.setCallback(this);
add(_contactList);
}
protected boolean keyChar(char c, int status, int time)
{
if (c == Characters.ESCAPE)
{
//user pressed escape key, if there's something in the edit field clear it
//otherwise handle it as closing the screen or whatever else you want
if (_filterEdit.getTextLength() > 0)
{
_filterEdit.setText("");
}
else
{
//close the screen or do something else, it's your call
//maybe even do nothing, whatever you want
}
return (true);
}
else
{
//all other keystrokes set focus on the edit field
_filterEdit.setFocus();
}
return (super.keyChar(c, status, time));
}
public void fieldChanged(Field field, int context)
{
if (field == _filterEdit)
{
//test the edit field's value against the previously searched value
//if NOT the same then do a search and refresh results
if (!_filterEdit.getText().equals(_previousFilterValu e))
{
//cache the newest search keyword string
_previousFilterValue = _filterEdit.getText();
//search your data
_contactResults = searchContacts(_previousFilterValue);
//update the list size to cause it to redraw
_contactList.setSize(_contactResults.length);
}
}
}
public void drawListRow(ListField listField, Graphics graphics, int index, int y, int width)
{
if (listField == _contactList && index > -1 && index < _contactResults.length)
{
//draw your list field row as you want it to appear
}
}
public Object get(ListField listField, int index)
{
if (listField == _contactList && index > -1 && index < _contactResults.length)
{
return (_contactResults[index]);
}
return (null);
}
public int getPreferredWidth(ListField listField)
{
return (Display.getWidth());
}
public int indexOfList(ListField listField, String prefix, int start)
{
return (-1);
}
}
class CustomKeywordField extends EditField
{
CustomKeywordField()
{
super(USE_ALL_WIDTH | NO_LEARNING | NO_NEWLINE);
}
protected void paint(Graphics graphics)
{
super.paint(graphics);
//Draw caret so the edit field always shows a cursor giving the user an indication they can type at anytime,
//even when the focus is on the list field that is used in conjunction with this edit field to create a
//keyword filter field replacement
getFocusRect(new XYRect());
drawFocus(graphics, true);
}
}
05-31-2010 02:07 PM
Thank you for your reply!
That implementation was exactly what I was hoping to do with KeywordFilterField (although I did not expect code from anyone
). I plugged in my query functions into it and everything fit in perfectly.
You helped me realize that KeywordFilterField wasn't giving me as much control as I was expecting it to give me.
Thank you so much!
11-18-2011 05:22 AM
Hi.. I am creating a ListField. in each row of I am adding a image and 3 text field.
Can any one tell me how to create a keywordfilterField for this...
Thanks in advance
11-14-2012 03:46 PM