filter grid with integer values

Hi guys,
At the moment I’m trying to built a grid with the new 7.4.0 API. The grid is ready, but I can’t filter the column. I get my data’s from an sqlcontainer. On one hand I tried to build this with code form Demo. It doesn’t work. On the other I tried it with the following code:[code]
HeaderRow row = grid.addHeaderRowAt(1);
HeaderCell cell = row.getCell(CALLERIDCOLUMN);
final TextField filter = new TextField();
filter.setInputPrompt(“Test”);
filter.setWidth(“100%”);
filter.addValueChangeListener(new ValueChangeListener()
{
public void valueChange(ValueChangeEvent event)
{
try
{
if (!filter.getValue().isEmpty())
{

                    Integer value = Integer.parseInt(filter.getValue().toString());
                    Compare.Equal suburbFilter = new Compare.Equal(CALLERIDCOLUMN, value);
                    contain.removeAllContainerFilters();                
                    contain.addContainerFilter(new And(suburbFilter));
                    contain.addContainerFilter(suburbFilter);
                    System.out.println("debug");
                    grid.setContainerDataSource(contain);
                    
                }
            } catch (NumberFormatException e)
            {
                // TODO: Show errormessage when value not an Integer
            }
        }
    });

[/code]

I had also tried a SimpleStringFilter, but allways there is no change.

I’m sorry about the bad english.

Tanks for help
Daniel Brenzel

Hi Daniel,

Are you trying to filter on an Integer property?

Testing with the code from grid demo + your Integer filter works for me with few changes.

  1. Don’t add 2 filters where one of them is the AND of your main filter. Just add one.
  2. There’s no need to set again the dataSource once you’ve filter it.

This is what I’ve changed in the demo code, I just removed the String filter and replace it with what you provided.

[code]
// … demo code

Integer value = Integer.parseInt(event.getText());

Compare.Equal suburbFilter = new Compare.Equal(“id”, value);
f.removeAllContainerFilters();
f.addContainerFilter(suburbFilter);

// … demo code
[/code]From the demo code you can see that variable f is the datasource already set on the grid.

In case still doesn’t work for you, please let me know and would be really helpful if you can provide a full simple UI example where it doen’t work for you. Then we can make changes directly on your code and see where the problem is.

All the best,
Bogdan.

Now it works partially. I’m filter values, which are modified by an ImageRenderer and a Resource, Integerconverter.
At the moment the right number of Fields is shown when the filter is active. The problem is it remove only the last entries. So there could be still the filtered items and wrong items are removed.
We use a sql container, with a FreeformStatementDelegate. Could this be the problem. The querry string is right.
More over when all elements are removed the grid lost the formatting.

Edit:
The format is lost when the elements are added again.

Thankyou for your help Bogdan

Hi,

The filters are applied in SQLContainer. All data will be retrieved from database according to your sql query, no matter what it is. You can check this and even debug it in SQLContainer with your code. Look for filters field.

If I understand correctly you’re showing an image instead of the number stored. In this case, to test the filter, you can try 2 things:

  1. Remove the renderer and show the number as it is. See if the filter works.
  2. Add both the image renderer and the number as 2 columns in your grid and see how filter works. Compare the number with the image on the same row. Compare this result with the first one, only when showing number. Compare all this with a simple query result executed directly on the database, bypassing the app.

This way you can see exactly if ther’s a filter issue, a rendering issue or a db select issue.

Looking forward to hear from you,
Bogdan.

The renderer is valid. My status values are 1 and 2. In my example database there are two digit of 1 and six of 2. When I want to remove the digits 1 I get 4 times the 2 and 2 times the 1 so it remove the last two entrys. My Sql querry is right when buttons are klicked.

The attachment is the table… When I press a button it is disabled ant the elements with this elements should disapear. Also when the selection remove all items, the table lost it’s formation. what could cause this.
The filter are set in the datacontainer.

18456.png

Hi,

Thanks for the screenshoot. I know this kind of data and app are sensitive, but we can help you much better and faster if you can provide us a simple test with an in memory dummy data which reproduces the problem. This way we could just make fixes on your code and then you can make the changes in your main app. Or we can identify easier bugs on our side where it’s the case.

But anyway, if I got this right, and I’m sure I did :), we’re talking about the last column. This column contains for each row one of the 3 values, probabbly 1 or 2 or 3, where 1 is the green icon, 2 the blue one and 3 the red one, or any way you set them. On the filter there are toggle buttons so when green button is selected you want to display all items with value 1, if blue is selected as well you want both 1 and 2. If only red is selected you want to display only rows with value 3 on that column, or any possible combinations of the three of them. Please let me know if I’m wrong and correct me.

Now, I’ve simulated this with some dummy data and this is how it works. It can be done with less code if you’d use real toggle buttons to provide you the state of the button.

public class FilterUI extends UI {

    @WebServlet(value = "/*", asyncSupported = true)
    @VaadinServletConfiguration(productionMode = false, ui = FilterUI.class)
    public static class Servlet extends VaadinServlet {
    }

    private Grid grid;

    private static final String COLUMN = "type";

    @Override
    protected void init(VaadinRequest request) {
        IndexedContainer container = new IndexedContainer();
        container.addContainerProperty(COLUMN, Integer.class, 0);

        for (char c = 'a'; c <= 'z'; c++) {
            for (int i = 1; i <= 3; i++) {
                Item item = container.addItem("" + c + i);
                item.getItemProperty(COLUMN).setValue(i);
            }
        }

        grid = new Grid(container);
        grid.setSizeFull();
        setContent(grid);

        HeaderRow filteringHeader = grid.appendHeaderRow();

        Component filter = getColumnFilter(COLUMN);
        filteringHeader.getCell(COLUMN).setComponent(filter);
        filteringHeader.getCell(COLUMN).setStyleName("filter-header");
    }

    private Component getColumnFilter(final Object columnId) {

        Button.ClickListener clickListener = new ClickListener() {

            Map<Button, Filter> filters = new HashMap<Button, Filter>();

            @Override
            public void buttonClick(ClickEvent event) {
                Button button = event.getButton();
                Filterable filterable = (Filterable) grid
                        .getContainerDataSource();

                if (filters.get(button) == null) {
                    String caption = button.getCaption();
                    int value = Integer.parseInt(caption);

                    filters.put(button, new Compare.Equal(columnId, value));

                } else {
                    filters.remove(button);
                }

                Iterator<Filter> iterator = filters.values().iterator();
                Filter filtersArray = new Filter[filters.size()]
;
                for (int i = 0; i < filtersArray.length; i++) {
                    filtersArray[i]
 = iterator.next();
                }

                filterable.removeAllContainerFilters();
                filterable.addContainerFilter(new Or(filtersArray));
            }
        };

        HorizontalLayout layout = new HorizontalLayout();
        layout.setSizeFull();

        Button button1 = new Button("1", clickListener);
        Button button2 = new Button("2", clickListener);
        Button button3 = new Button("3", clickListener);

        layout.addComponent(button1);
        layout.addComponent(button2);
        layout.addComponent(button3);

        return layout;
    }

}
[/i]

I think the problem is because you might use more then one filter per column. In this case things get tricky because the filter algorithm will always put and AND between them. And you can’t have a field in a record with both values 1 and 2 in the same time.

Looking forward to hear from you! Let’s make this work great!
Bogdan.

Thankyou alot I have modified your code:

[code]
private void filterUpdate()
{
Map<String, Filter> filters = new HashMap<String, Container.Filter>();
Filterable f = (Filterable) grid.getContainerDataSource();
f.removeAllContainerFilters();
if (!boxButtons.getSelectedButtons().isEmpty())
{
Map<Button, Filter> filtersBoxButtons = new HashMap<Button, Filter>();

        for (Object btn : boxButtons.getSelectedButtons())
        {
            boolean incomming = ((ToggleButton) btn).getDescription().equals(INCOMING_FILTER_DESC);
            boolean outgoing = ((ToggleButton) btn).getDescription().equals(OUTGOING_FILTER_DESC);
            if (outgoing)
            {
                filtersBoxButtons.put((Button) btn,
                        new Compare.Equal(BOXCOLUMN, de.will.obelisk.fax.Fax.BOX_OUTBOX));
            } else if (incomming)
            {
                filtersBoxButtons
                        .put((Button) btn, new Compare.Equal(BOXCOLUMN, de.will.obelisk.fax.Fax.BOX_INBOX));
            }

        }

        Iterator<Filter> iterator = filtersBoxButtons.values().iterator();
        Filter[] filtersArray = new Filter[filtersBoxButtons.size()]

;
for (int i = 0; i < filtersArray.length; i++)
{
filtersArray[i]
= iterator.next();
}
filters.put(BOXCOLUMN, new Or(filtersArray));
}

    if (!readButtons.getSelectedButtons().isEmpty())
    {
        Map<Button, Filter> filtersStatusButton = new HashMap<Button, Container.Filter>();
        for (Object btn : readButtons.getSelectedButtons())
        {
            boolean read = ((ToggleButton) btn).getDescription().equals(READ_FILTER_DESC);
            boolean unread = ((ToggleButton) btn).getDescription().equals(UNREAD_FILTER);
            if (read)
            {
                filtersStatusButton
                        .put((Button) btn, new Compare.Equal(STATUSCOLUMN, de.will.obelisk.fax.Fax.READ));
            } else if (unread)
            {
                filtersStatusButton.put((Button) btn,
                        new Compare.Equal(STATUSCOLUMN, de.will.obelisk.fax.Fax.NEWLY));
            }
        }
        Iterator<Filter> iterator = filters.values().iterator();
        Filter[] filtersArray = new Filter[filtersStatusButton.size()]

;
for (int i = 0; i < filtersArray.length; i++)
{
filtersArray[i]
= iterator.next();
}
filters.put(STATUSCOLUMN, new Or(filtersArray));
}

    if (!filterField.isEmpty())
    {
        SimpleStringFilter filter = null;
        filter = new SimpleStringFilter(CALLERIDCOLUMN, filterField.getValue(), true, true);
        filters.put(CALLERIDCOLUMN, filter);
        grid.cancelEditor();
    }

    if (!statusButtons.getSelectedButtons().isEmpty())
    {
        Map<Button, Filter> filtersFaxStatus = new HashMap<Button, Filter>();

        for (Object btn : statusButtons.getSelectedButtons())
        {
            boolean ok = ((ToggleButton) btn).getDescription().equals(SUCCESSFUL_FILTER_DESC);
            boolean error = ((ToggleButton) btn).getDescription().equals(ERRONOUS_FILTER_DESC);
            boolean sending = ((ToggleButton) btn).getDescription().equals(SENDING_FILTER_DESC);
            if (ok)
            {
                filtersFaxStatus.put((Button) btn, new Compare.Equal(FAXSTATUSCOLUMN,
                        de.will.obelisk.fax.Fax.FAXSTATUS_OK));
                System.out.println("OKfilter");
            } else if (error)
            {
                filtersFaxStatus.put((Button) btn, new Compare.Equal(FAXSTATUSCOLUMN,
                        de.will.obelisk.fax.Fax.FAXSTATUS_ERROR));
                System.out.println("ERRor");
            } else if (sending)
            {
                filtersFaxStatus.put((Button) btn, new Compare.Equal(FAXSTATUSCOLUMN,
                        de.will.obelisk.fax.Fax.FAXSTATUS_SENDING));
                System.out.println("sending");
            }

        }

        Iterator<Filter> iterator = filtersFaxStatus.values().iterator();
        Filter[] filtersArray = new Filter[filtersFaxStatus.size()]

;
for (int i = 0; i < filtersArray.length; i++)
{
filtersArray[i]
= iterator.next();
}
filters.put(BOXCOLUMN, new Or(filtersArray));

    }
    Iterator<Filter> iterator = filters.values().iterator();
    Filter filterArray[] = new Filter[filters.size()]

;
for (int i = 0; i < filterArray.length; i++) {
filterArray[i]
= iterator.next();
}
f.addContainerFilter(new And(filterArray));

}

[/code]But there are still two little problem. If I remove all entries, every formatting is lost. Style options are useless. How I can keep the formatting?

Another Problem is updating. If I I change the Container I get a nullpointer. Is there an option to refresh the grid?

So the filters are working now right?

What do you mean by “remove all entries”? Deleting them all? Or just filter them all out?

Normally, only changing the data from the Container should update automatically the Grid. Like filtering does. There’s actually no point in setting another data source on the grid. Does this always happen when set a new Container? Might be a bug so we need to make sure.

when I filter all items the grid is a clear and formatting. when I remove a filter and the items come back I have a table with the following:
18503.png

You lost me now :slight_smile: sorry. This picture looks pretty much the same as the one you sent yesterday. So isn’t it OK? How is the formatting lost?

You mean the date format?

I’m so sorry about my post, but my English is not as well as it should be. Normally is the whole area, wich is shown in the picture, coverd and the collumns have their own width. when all Items are disapeared and they arpeard again the collum with is set to a value around 100 pixel. the rest of the page (left the white area) isn’t coverd any more by the grid.

Have I explain it understandable?

So the width of the columns will change when applying filters that will clear the table and then apply again filters to see some data… ? hmm… Ok I’ll test this and see what solution we find. I think I noticed the same yesterday in that small demo I wrote you.

Can you please confirm you have the same behaviour in you app as well as in the demo I posted?

I have used your code in my app. I only expand it with the other filters. If I modify the grid with again it doesn’t react. Could this be a bug

Daniel, testing on my demo I get the width difference when app opens vs after using the filters. The width indeed resets to 100px. I would wait until 7.4.1 is released, hopefully tomorrow, I understand it comes with a lot of fixes so maybe this is also covered. Otherwise I’ll look more into this.

// Row when grid opens with data.
<tr class="v-grid-row v-grid-row-stripe v-grid-row-has-data" style="width: 1253px; transform: translate3d(0px, 38px, 0px);">
<td class="v-grid-cell" colspan="1" style="height: 38px; width: 1253px;">2</td>
</tr>

// Same row after applying filter multiple times so that you get the grid cleared then filled again.
<tr class="v-grid-row v-grid-row-stripe v-grid-row-has-data" style="width: 100px; transform: translate3d(0px, 38px, 0px);">
<td class="v-grid-cell" colspan="1" style="height: 38px; width: 100px;">2</td>
</tr>

Hi,

How is it going with your progress? As far as I see, due to some technical issues, 7.4.1 was still not released.

I looked for similar tickets and I found some. Please have a look at them and see if they describe your problem as well, otherwise, please file a new ticket.

http://dev.vaadin.com/ticket/16684
http://dev.vaadin.com/ticket/16975
http://dev.vaadin.com/ticket/17043

I see that these bugs are not yet fixed in 7.4.1 :frowning:

Thanks,
Bogdan.

I seemed there is a mistake in the tickets. It is fixed in my WebApp. I have still an other question, which is not responsed. Would you be so kind, to have a look on it?

Thank you for all your assistance

Daniel

Hi,

You mean the problems described in those 3 tickets are fixed in the Vaadin version you’re using?

What question are you referring to? So I can have a look at it.


https://vaadin.com/forum#!/thread/9343847

Sorry I forgot the link