Selection Object questions

I have a couple of requirements that I can’t seem to satisfy with a single selection object - maybe someone can point me at one that will work, or show me why one that I think won’t work, in fact will work…

I am going to be loading a list of up to 500,000 elements that people are going to want to filter and then make multiple selections. So I would like to be able to use Lazy Loading, Multiple Selection and filtering. And I can’t find a component that does all three things. A Select object allows for filtering, but doesn’t seem to do lazy loading. A ComboBox doesn’t allow for multiple selections. I was looking at the LazyContainer - is that something I could attach to a ListSelect object??

Am I missing something simple here? Any pointers and/or sample code would be appreciated. I’m planning to start with some simple string filters, but going forward, I want to allow users to filter using more complex regular expressions (something like “abc.*def” or “[ab]
cde” so I expect I will have to implement a custom filter at some point - but I still need to manage the selection object.

Thanks in advance,

nbc

Hi!

Have you tried
TokenField addon
? It supports lazy loading, multiselection and filtering. Lazy loading and filtering comes with a ComboBox that it uses and the way how selected values are rendered can be customized.

I had not seen this add-on - I will go take a look right now - thanks!

nbc

I’m trying to work with the TokenField object, and I’m having a problem with the multi-selection part. My code looks like this:

jc_RRD_Record = crrd.jcGetAllRrdRecord(); //JPAContainer which holds my 500K records

tf_RRD = new TokenField(“Select File(s)”);
tf_RRD.setWidth(“500px”);
tf_RRD.setImmediate(true);
tf_RRD.setNewTokensAllowed(false);
tf_RRD.setTokenCaptionPropertyId(“rrdPath”);
tf_RRD.setFilteringMode(ComboBox.FILTERINGMODE_CONTAINS);
tf_RRD.setContainerDataSource(jc_RRD_Record);

This brings up a text box, and when I start typing, the entries in the jc_RRD_Record container gets filtered properly. It displays the current list of files to be selected. However, I can’t seem to select more than one entry at at time. I would like to be able to click on an entry and then SHIFT/Click or /click to select a contiguous or non-contiguous group of files. Instead of that, as soon as I click on an entry, or hit or the tokenfield creates a new token entry for me. So what do I need to do to get multiple selections?

I tried putting the container into a ListSelect object (as per code in the tokenfield demo program) but that did not seem to help - however, I may have done that incorrectly… Is it necessary to put the container into a multi-selectable list object before assigning it to the tokenfield?

thanks,

nbc

Hi,

Unfortunately TokenField does not support this. The combobox part of TokenField is actually the core Vaadin ComboBox component, and thus it supports exactly the same features.

Selecting multiple entries at once from a combobox is not very commonly seen (except perhaps on iOS), but I can see how it would be useful in some cases with TokenField…

Best Regards,
Marc

I see - in that case, I think I’m back to my original question - is there something I can use that allows for Lazy Loading (since I have a very large data set), multiple selection, and filtering? I’m going to want to eventually add a custom filter that uses more formal regular expressions, rather than a simple ‘contains string’ or ‘starts with string’, but that can come a bit later - I would like to get the display/selection object working first…

Anyone??

thanks,

nbc

There are a number of ways you could go about this, mostly it depends on how you want it to look and work.

TokenField does multiple selection by selecting one item (‘token’) at a time and adding to the selected set. We already determined this is not how you’d like it to work, though.

Another option would be to use a Table and a TextField to filter that. Here is a quick example showing what I mean. It does regex matching in the otherwise simplistic filter:

public void init() {
        Window w = new Window();
        setMainWindow(w);

        // fill a container with dummy data - we'll use it as datasource and for filtering
        final IndexedContainer data = new IndexedContainer();
        final String[] words = "Quidquid latine dictum sit altum sonatur"
                .split(" ");
        for (int i = 0; i < 5000; i++) {
            data.addItem(words[i % 6]
 + " " + i);
        }

        // text field for filtering
        TextField tf = new TextField();
        tf.setInputPrompt("filter...");
        // filter while typing (this is quite configurable, BTW)
        tf.addListener(new TextChangeListener() {
            public void textChange(final TextChangeEvent event) {
                // just a simplistic example w/ regex
                data.removeAllContainerFilters();
                if (event.getText().length() > 0) {
                    data.addContainerFilter(new Filter() {
                        public boolean passesFilter(Object itemId, Item item)
                                throws UnsupportedOperationException {
                            String s = itemId.toString();
                            return s.matches(event.getText());
                        }
                        public boolean appliesToProperty(Object propertyId) {
                            // you might want to read about this
                            return true;
                        }
                    });
                }
            }
        });
        w.addComponent(tf);

        final Table t = new Table();
        t.setContainerDataSource(data);

        t.setSelectable(true); // remember this
        t.setMultiSelect(true); // and this
        t.setColumnHeaderMode(Table.COLUMN_HEADER_MODE_HIDDEN);
        t.setRowHeaderMode(Table.ROW_HEADER_MODE_ID);
        t.setWidth("200px");
        w.addComponent(t);
    }

(One note: there is a performance regression in IndexedContainer in 6.6.?, so this application will be slow to start it you add a lot of items to the container. I’m reviewing a patch for the issue right now… Ticket:
http://dev.vaadin.com/ticket/7517
)

Maybe this is something you could work from?

Best Regards,
Marc

I tried using a table with my JPAContainer and a textfield filter. That actually does seem to do the job. At the moment, the filter is the included ‘like’ filter which allows me a wild card, but at some point, I will probably try to create a full regular expression filter along the lines that you suggested. I had tried an indexed container before and yes, there are definitely performance issues with it, but the JPAContainer seems to be doing the job pretty well at the moment. However, in my testing, I’m only using a very small dataset (6000) records - the production system will be 100x larger… so I’ll need to be very careful about performance.

I think this approach will solve my problem - thanks very much for the help

nbc

Hi,

Just popping in to note that IndexedContainer is fixed now - the performance issue was indeed a regression, which was quickly fixed after I filed the ticket.

Best Regards,
Marc

Good to know - thanks!

nbc