Table Column order save in cache ...

Hi !

Is it possible to store table column order location in cache ?, so that after the next login or form reload columns was in the same spot?

Thanks!

Hello,

You can store this kind of information in Cookies.

    public void put(String key, String value) {
        if (VaadinService.getCurrentRequest() != null) {
            Cookie myCookie = new Cookie(key, value);
            myCookie.setMaxAge(2500000); // in seconds (+/- 1 month)
            myCookie.setPath(VaadinService.getCurrentRequest().getContextPath());
            if (VaadinService.getCurrentResponse() != null) {
                VaadinService.getCurrentResponse().addCookie(myCookie);
            }
        }
    }

So here in Vaadin is no default methods for saving column orders ? :frowning: i am sad …

OK i writed a test example and i think all is working nice … need to test a little bit more
//EDIT for column width too :wink:

package com.MyApp.ui.components;

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.Vector;

import com.MyApp.SU;
import com.MyApp.ui.panels.myLog;
import com.vaadin.ui.Table;

@SuppressWarnings("serial")
public class MyAppWrapedTable extends Table {
    public static myLog mylog = myLog.getInstance();

    public MyAppWrapedTable() {
        addStyleName("wordwrap-headers");
        this.setColumnCollapsingAllowed(true);
        this.setColumnReorderingAllowed(true);
        this.setCacheRate(4);

        this.addAttachListener(new AttachListener() {
            public void attach(AttachEvent event) {
                Vector<String> visibleVec = getVec();
                if (visibleVec != null) {
                    MyAppWrapedTable.this.setVisibleColumns(visibleVec.toArray());
                }
                for (Object ob : MyAppWrapedTable.this.getVisibleColumns()) {
                    String value = SU.getCookie(ob.toString()+"WIDTH");
                    if (value != null) {
                        MyAppWrapedTable.this.setColumnWidth(ob.toString(), Integer.valueOf(value));
                    }
                } 
            }
        });

     this.addDetachListener(new DetachListener() {
            public void detach(DetachEvent event) {
                int i = 0;
                for (Object o : DisnetWrapedTable.this.getVisibleColumns()) {
                    i++;
                    SU.putCookie(o.toString(), String.valueOf(i), new Long(25000000));
                    SU.putCookie(o.toString() + "WIDTH", String.valueOf(DisnetWrapedTable.this.getColumnWidth(o)), new Long(25000000));
                }
            }
        });
    }

    @Override
    public String getColumnHeader(final Object propertyId) {
        final String originalHeader = super.getColumnHeader(propertyId);
        if (originalHeader != null) {
            final String layoutedHeader = originalHeader.replaceAll("\n", "<br />");
            return layoutedHeader;
        }
        return originalHeader;
    }

    private Vector<String> getVec() {
        Boolean byDefault = false;
        Vector<String> vec = new Vector<String>();
        Map<Long, String> reorderMap = new HashMap<Long, String>();
        for (Object ob : MyAppWrapedTable.this.getVisibleColumns()) {
            String value = SU.getCookie(ob.toString());
            if (value == null) {
                byDefault = true;
            } else {
                reorderMap.put(Long.valueOf(SU.getCookie(ob.toString())), ob.toString());
            }
        }
        if (!byDefault) {
            Map<Long, String> treeMap = new TreeMap<Long, String>(reorderMap);
            for (Long idx : treeMap.keySet()) {
                vec.add(treeMap.get(idx));
            }
        } else {
            vec = null;
        }
        return vec;

    }
}

and for cookies

 public static void putCookie(String key, String value) {
        putCookie(key, value, new Long(3600));
    }

    public static void putCookie(String key, String value, Long exp) {
        if (exp == null)
            exp = new Long(0);
        if (VaadinService.getCurrentRequest() != null) {
            Cookie myCookie = new Cookie(key, value);
            myCookie.setMaxAge(Integer.valueOf(exp.intValue()));
            myCookie.setPath(VaadinService.getCurrentRequest().getContextPath());
            if (VaadinService.getCurrentResponse() != null) {
                VaadinService.getCurrentResponse().addCookie(myCookie);
            }
        }
    }

    public static String getCookie(String key) {
        if (VaadinService.getCurrentRequest() != null) {
            Cookie cookies = VaadinService.getCurrentRequest().getCookies();
            for (int i = 0; i < cookies.length; i++) {
                if (key.equals(cookies[i]
.getName())){
                    return cookies[i]
.getValue();   
                }
            }
        }
        return null;
    }

    public static void delCookie(String key) {
        delCookie(key, "");
    }

    public static void delCookie(String key, String value) {
        putCookie(key, value, new Long(0));
    }
[/i]
[/i]

Ok I reached a problem here !

Are some other ways how to store this kind of info (Column order , Column width)?
Because modern browsers still got a limit of cookies MAX: 180 cookies in Chrome when this size is reached then Vaadin throws Cookies are disabled error …

If i were you i wouldn’t store the actual information in the cookies. I would rather store an id in the Browser which can be used by the system to retrieve the necessery information from a backend database. This way you can link information to a Browser by only using one cookie per Website/Web application.
If you want to have it specific to the logged in user you can link it up user the user name, userid, … depending on what you have as an identifier.

You sugest to store column order and width info at data base? it’s not a problem but there is no other ways how to do this ?

There might be another way of doing it but it seems to me that this one would be the cleanest.
Cookies shouldn’t store complete information (for security issues and just because it’s just not that clean). Also this way you can only link the data to a browser so when another user logs in on the same browser he will be associated with the information of another user while linking the information to the actual logged in user is safer.
Then you just need some kind of way to safe the information persistent server side. A data base was just the first idea there probably are dozens of other ways to store information on a server…

Ok thanks for tip i already stored the info in DB.

only on detach listener i wanted to catch event when table was affected or modified not in every time

this.addDetachListener(new DetachListener() { public void detach(DetachEvent event) { try { int i = 0; String tableId = WrapedTable.this.getId(); for (Object o : WrapedTable.this.getVisibleColumns()) { i++; utility.save(tableId, o.toString(), WrapedTable.this.getColumnWidth(o), i); } } catch (Exception e) { mylog.pl("Ex @ detach from Table " + e.getMessage()); e.printStackTrace(); } } }); Founded out that:

this.getColumnWidth(o) returns -1 if column width wasn’t changed maybe are some method who returns something similar for table column reorder change?

this.isModified() is something else and are not returning corectly result …

getColumnWidth doesn’t return -1 if the width wasn’t changed. It returns -1 if the width wasn’t set. This is an ok solution if you don’t modify any column width when initializing and populating the table by calling setColumnWidth(…).

There is no method of table returning if the order was changed. Nonetheless there is the ColumnReorderListener. This way you should be able to catch the event when a user is reordering a column
https://vaadin.com/api/com/vaadin/ui/Table.html#addColumnReorderListener(com.vaadin.ui.Table.ColumnReorderListener)

Perfect !
With that listener it will be aviable to store event in class who extends table and then on detach watch event action for storing table column’s.

Thanks Marius Reinwald !