|
#1
|
|||
|
|||
|
I am trying to determine how to programmatically add a clause to a FilterBuilder, i.e. click a button and a new clause gets added to a FilterBuilder. I am assuming that FilterBuilder.addClause(FilterClause) would do the trick, but I cannot make sense out of how to construct a FilterClause such that this does what I want. I have been searching through the forums, showcase code, etc. and can't find an example that constructs a FilterClause or uses FilterBuilder.addClause. Is there an example anywhere that shows the construction of a FilterClause and invocation of FilterBuilder.addClause such that the result is the same as if the user had clicked on the + sign and added a new clause?
As some background, I am trying to use FilterBuilder as a means to construct a nested boolean expression that is specific to my application and not equivalent to a database table query/filter condition. What I would like to be able to do is provide a list of values to pick from (equivalent to the "Country", "Government", "G8", etc. fields in the FilterBuilder showcase example), then simple choices of "Equals" or "Not Equal", and either "True" or "False". I would like the default of each to be "Equals" and "True". The list of items to filter on may be several hundred items long. As such, I would like to construct a separate tree, and allow for a doubleClick on a tree node (or perhaps a drag from the tree to the FilterBuilder) to add the selected item to the FilterBuilder programmatically. Is this possible, and is addClause the way to do it? Additional questions: 1) It appears you cannot just pass a list of values to pick from in FilterBuilder. My data (the values I want to pick from to construct a filter clause) are in rows in a database table, _not_ the columns of the table. It seems that the designers of FilterBuilder did not consider this case. To work around this, I am constructing a DataSource dynamically that translates each row to a DataSourceField. Is there a better way? 2) You can limit the available operators via setValidOperators(OperatorId.EQUALS, OperatorId.NOT_EQUAL) and limit the allowable values using setValueMap("True", "False");. But is there a way to force the default value of a new filter clause to be "True" instead of blank? 3) Is there a way to configure FilterBuilder so that instead of presenting my list of several hundred values as a simple drop down list, it could be a Picktree or other structure that would be simpler to navigate? Thank you very much. |
|
#2
|
|||
|
|||
|
Take a look at the "Big Filter" example in the latest nightlies. It allows you to supply a DataSource from which field definitions are fetched. The interface is a ComboBox, so the user gets type-ahead completion on the fieldName.
As far as adding a clause or defaulting a clause to a particular value, just call setCriteria() and the FilterBuilder constructs clauses for you. Note that FilterBuilder.addClause() is for a very specialized use case, and the docs will soon be updated to clarify this. |
|
#3
|
||||
|
||||
|
Quote:
Quote:
Quote:
Quote:
Also, is there any way to get the filter comparison value to default to "True" instead of a blank? |
|
#4
|
|||
|
|||
|
Use setFieldPickerProperties to influence how the FormItem appears, including the ability to create your own pop-up grid or tree if desired.
Right now, there's no incremental addCriteria() method - are you looking for this because you'd like the new clause to animate out? If you're just worried about there being kind of a "flash", create a new FilterBuilder with new criteria and put it on top, and destroy the old FilterBuilder after the new one is showing. |
|
#5
|
|||
|
|||
|
I hope you don't mind me elbowing my way into this thread. But I'd also like a way to manage the FilterBuilder criteria programmatically. A typical UI construct for me involves a ListGrid or other UI component, which the user can click on to change the filter criteria, in addition to using the FilterBuilder UI to further refine the selection. So I'd like some way for handlers on the other UI components to change or add selected criteria in the FilterBuilder.
|
|
#6
|
|||
|
|||
|
I will try the 2 filterbuilder approach and see what it looks like, thanks for the suggestion, Isomorphic.
As a general comment, it was quite painful and took a lot of trial and error to extend the existing FilterBuilder criteria by retrieving and manipulating the AdvancedCriteria object. I could not figure out a way to manipulate the AdvancedCriteria object directly, and Criteria methods like addCriteria() did not seem to work as expected. I am including my sample code because (1) wow this is a lot to do for what seems like it should be a simple operation, maybe there is a better way that someone could suggest, but I could not figure out and (2) if this really is the only/best way, maybe it would be helpful to someone else in the future to see a full example of how make this work. The following assumes you have a variable called newFieldName that holds the name of the filter to be added. I had the below code on the onDoubleClick() handler of a TreeGrid such that double-clicking on a tree node added the associated condition to the filterbuilder. For my purposes, each new filter clause would be added with an "Equals True" condition by default, as shown below. Code:
// Add new filter clause to existing filter builder
// Steps: AdvancedCriteria -> JSO AC -> JSO criteria array -> JSO extended array -> JSO flattened array -> new JSO AC -> new AC
// Get current builder criteria as javascript object
JavaScriptObject currentCriteriaJso = filterBuilder.getCriteria().getJsObj();
// Get current individual criterias as array
JavaScriptObject[] criterias = JSOHelper.getAttributeAsJavaScriptObjectArray(currentCriteriaJso, "criteria");
// Define new criteria for selected filter
String newCriteriaString = "{\"fieldName\":\"" + newFieldName + "\",\"operator\":\"equals\",\"value\":\"True\"}";
// Convert to JavaScript object
JavaScriptObject newCriteriaItemJso = JSOHelper.eval(newCriteriaString);
// Create extended array and populate with current criteria
JavaScriptObject[] newCriterias = new JavaScriptObject[criterias.length + 1];
for (int i = 0; i <criterias.length; i++ )
{
newCriterias[i] = criterias[i];
}
// Add new criteria to end
newCriterias[criterias.length] = newCriteriaItemJso;
// Flatten array back to single JSO
JavaScriptObject newCriteriaFlatJso = JSOHelper.arrayConvert(newCriterias);
// Set new criteria attribute value
JSOHelper.setAttribute(currentCriteriaJso, "criteria", newCriteriaFlatJso);
// Create new advanced criteria from new criteria JSO
AdvancedCriteria newAc = new AdvancedCriteria(currentCriteriaJso);
// Set new criteria on filterbuilder
filterBuilder.setCriteria(newAc);
|
|
#7
|
|||
|
|||
|
There's a known glitch where AdvancedCriteria.addCriteria(), which is inherited from Criteria, does the wrong thing. A fix is already scheduled. Use strictly the AdvancedCriteria APIs to correctly form and manipulate AdvancedCriteria.
|
|
#8
|
|||
|
|||
|
Quote:
|
|
#9
|
|||
|
|||
|
"appending a new condition" means combining it with the existing conditions with the AND operator, so use the second constructor, passing Operation.AND, the existing AdvancedCriteria, and a new AdvancedCriteria with the new condition(s).
|