I am trying to implement a series of multi-select list pickers that function like the “Genres” and “Artists” lists in itunes.
While I have enabled multi-select in all the forms, the multi-select does not seem to perpetuate down the hierarchy.
Using itunes as an example, picking multiple Genre’s is not showing all the artists with that genre, but instead only shows those in the genre that was clicked on last.
In my case the hierarchy is deeper than and goes across 5 levels: Schools-> Buildings-> Spaces->Elements → Sub_Elements
The relations are all “inner joins” with each building having a “school_id” etc.
and I want to be able to multi-select any combination of [Schools-> Buildings-> Spaces->Elements] and get a list of all the Sub_elements in that selection.
I’ve uploaded a sample solution to show what I mean.
thank you very much upfront for you help.
Micah
itunes_filter.servoy (11 KB)
I came up with a work-around that constructs a query based on the selected indexes and uses it to find the correct list of records in the related form.
However it seems rather un-elegant as the find code needs to be implemented for each form and there might also be a quicker way to get the selected PKs from the the foundset.
If anyone has any suggestions, please post!
The first code snippet is a Global function that takes a foundset and returns a Query string formatted for a find() function:
function makeFindQuery(myFoundset){
//Get the currently selected index from the foundset
var selection = myFoundset.getSelectedIndexes();
//Create Data Array from selection to obtain records
var data = [];
for( i in selection ){
data.push(myFoundset.getRecord(selection[i]));
}
//Construct the Query based on the record PK
var findQuery = "";
for(d in data){
var record = data[d];
findQuery += record.getPKs()[0];
if(d != data.length-1){
findQuery += "||";
}
}
return findQuery;
}
The second code snippet needs to be placed into the onRecordSelection Event listener of each picklist form, where the form and foreign key to find need to be specified:
function onRecordSelection(event) {
var findQuery = globals.makeFindQuery(foundset);
application.output(findQuery);
forms.lst_spaces.controller.find();
forms.lst_spaces.building_id = findQuery;
forms.lst_spaces.controller.search();
}
For anyone who doesn’t want to download the sample, don’t forget to enable multiselect for each picklist as well via the onShow Event listener:
function onShow(firstShow, event) {
// TODO Auto-generated method stub
if(firstShow){
foundset.multiSelect = true;
}
}
Micah,
There is a foundset.getSelectedRecords() method to get the selected records directly.
In stead of using find, using add/removeFoundSetFilterParam might be more convenient:
subelements_foundset.addFoundSetFilterParam('spaces_id', 'in', ids, 'spacesFilter')
subelements_foundset.loadAllRecords()
Rob
Hi Rob,
thanks for your tip! I implemented it and it turned out slightly shorter and perhaps more elegant.
Since it is not possible to apply filters directly to a related Foundset, one has to still go through the specific Form (and it’s Foundset) for the code to work.
So I created a Global function ‘quickFilter’ that takes three parameters:
- The source JSFoundset object that is used to get the selected Records.
- The name String of the property that the filter should be applied to.
- The Form object that contains the Foundset that the filter should be applied to.
/**
* // TODO generated, please specify type and doc for the params
* @param {JSFoundset} source
* @param {String} property
* @param {Form} targetForm
*
* @properties={typeid:24,uuid:"2B45F74A-264D-4540-BD05-ED2701430708"}
*/
function quickFilter(source,property,targetForm){
targetForm.foundset.removeFoundSetFilterParam('cusFilter');
var selection = source.getSelectedRecords();
var ids = new Array();
for(rec in selection){
ids.push(selection[rec][property]);
}
var success = targetForm.foundset.addFoundSetFilterParam(property, 'in', ids,'cusFilter');
targetForm.foundset.loadAllRecords();
}
In the ‘onRecordSelection’ event listener for each multiselect picklist the global function is then called:
globals.quickFilter(foundset,'school_id',forms.lst_buildings);
If there is an even better way of doing this I appreciate suggestions.
Thanks,
Micah