Emmanuel DEMEY wrote
> . . . .
> But you can also use the ajax mode, and when the user will change the
> displayed page, send an ajax request, and update the datatable with the
> next set of datas.
> . . . .

I am having a devil of a time getting this to work.  I'm attaching probably
too much code here.  Please don't be overly critical.  I've borrowed this
from a demonstration that I found somewhere that is using celebrities as
sample data.  I'm trying to convert it to use server side pagination and
sorting, and my database connection pool.  There have been many iterations
of this trying to get various parts of it to work.  I can suss out
everything, if I can just get the ajax requests handled on the server side.

Right now, the only way I can see is to override the DataTableModel and call
it from an event handler.  But, that just seems wrong.  Anyway, here's the
mess I've made.  Can you help me clean it up?

DataTableDemo.tml:
<t:jquery.datatable id="dataTable" t:row="model" t:rowIndex="indexBis"
t:mode="true" t:source="celebrityService" t:dataTableModel="override"
                    rowsPerPage="5" exclude="id"
reorder="lastName,firstName,occupation,DOB" options="initParams">
</t:jquery.datatable>

DataTableDemo.java
public class DataTableDemo {
    @SessionState  // I think I have to do this so the data source service
can keep track of what's been requested
    private CelebrityService celebrityService;

    @Property
    @Environmental //This annotation is required for the property bound to
'index' parameter
    private int indexBis;
    
    @Property
    @Environmental
    private Celebrity model;

    @Property
    private Celebrity celebrity;
    
    @Inject
    private TranslatorSource translatorSource;
    
    @Inject
    private ComponentResources componentResources;
    
    @Inject 
    private PageRenderLinkSource linkSource;
    
    @Inject
    private BeanModelSource beanModelSource;
    
    @Property
    private final DataTableModel override = new
OverrideDataTableModel(translatorSource, componentResources, linkSource);
    
    // This is called by tapestry because in the tml file we have
't:source="celebritySource"'
    public GridDataSource getCelebrityService() {
        if (celebrityService == null)
            celebrityService = new CelebrityService();
        return celebrityService;
    }

    @Log
    public JSONObject getInitParams(){
        JSONObject initParams = new JSONObject();
        
        // This is the search bar.
        initParams.put("bFilter", false);
        
        // This says "displaying x of y pages"
        initParams.put("bInfo", true);
        
        // Make it pass all requests to the server??
        initParams.put("sAjaxSource",
componentResources.createEventLink("Data").toAbsoluteURI());
        initParams.put("bServerSide", "true");
        initParams.put("bProcessing", "true");
        
        // Trying to resize the table, but it doesn't work.  Last name
column is still huge with true or false
        initParams.put("fnInitComplete", "function() {
this.fnAdjustColumnSizing(false); }"); 

        return initParams;
    }
    
    @OnEvent(value=JQueryEventConstants.DATA)
    void hitThisMethod() {
        override.sendResponse(request, source, model, sortModel, overrides,
mode); // This isn't complete.  I'm quite stuck here.
    }
}

OverrideDataTableModel.java  // borrowed (completely?) from
DefaultDataTableModel
public class OverrideDataTableModel implements DataTableModel {
    Logger logger = Logger.getLogger(OverrideDataTableModel.class);

    private TranslatorSource translatorSource;

    private PageRenderLinkSource linkSource;

    private Request request;

    private GridSortModel sortModel;

    private PropertyOverrides overrides;

    private ComponentResources componentResources;

    private BeanModel model;

    public OverrideDataTableModel(TranslatorSource translatorSource,
ComponentResources componentResources,
            PageRenderLinkSource linkSource) {
        super();
        logger.trace("In constructor");
        this.translatorSource = translatorSource;
        this.linkSource = linkSource;
    }

    /**
     * This method will set all the Sorting stuffs, thanks to sSortDir and
     * iSortCol DataTable parameters, coming from the request
     */
    @Log
    public void prepareResponse(GridDataSource source) {
        logger.trace("prepareResponse()");
        String sortingCols =
request.getParameter(DataTableConstants.SORTING_COLS);
        int nbSortingCols = Integer.parseInt(sortingCols);
        logger.debug("sortingCols [" + sortingCols + "]");

        String sord = request.getParameter(DataTableConstants.SORT_DIR +
"0");
        String sidx = request.getParameter(DataTableConstants.SORT_COL +
"0");
        logger.debug("sord [" + sord + "]");
        logger.debug("sidx [" + sidx + "]");
        
        if (nbSortingCols > 0) {
            List<String> names = model.getPropertyNames();

            int indexProperty = Integer.parseInt(sidx);

            String propName = names.get(indexProperty);
            logger.debug("propName [" + propName + "]");

            ColumnSort colSort = sortModel.getColumnSort(propName);

            sortModel.updateSort(propName);
        }

    }

    /**
     * method returning the desired data
     */
    @Log
    public JSONObject getResponse(GridDataSource source) {
        logger.trace("getRespons()");
        JSONObject response = new JSONObject();
        int records = source.getAvailableRows();
        logger.debug("records [" + records + "]");

        response.put("sEcho",
request.getParameter(DataTableConstants.ECHO));
        response.put("iTotalDisplayRecords", records);
        response.put("iTotalRecords", records);

        String displayStart =
request.getParameter(DataTableConstants.DISPLAY_START);
        int startIndex = Integer.parseInt(displayStart);
        logger.debug("startIndex [" + startIndex + "]");

        String displayLength =
request.getParameter(DataTableConstants.DISPLAY_LENGTH);
        logger.debug("displayLength [" + displayLength + "]");

        int rowsPerPage = Integer.parseInt(displayLength);

        int endIndex = startIndex + rowsPerPage - 1;
        if (endIndex > records - 1)
            endIndex = records - 1;
        
        // Here we go - run the query
        source.prepare(startIndex, endIndex,
sortModel.getSortConstraints());

        JSONArray rows = new JSONArray();

        for (int index = startIndex; index <= endIndex; index++) {
            JSONObject cell = new JSONObject();

            Celebrity celebrity = (Celebrity) source.getRowValue(index);

            List<String> fields = model.getPropertyNames();
            logger.debug("fields [" + fields + "]");

            for (String fieldName : fields) {
                logger.debug("fieldName [" + fieldName + "]");
                
                Object fieldValue;
                
                PropertyConduit conduit = model.get(fieldName).getConduit();

                fieldValue = conduit.get(celebrity);
                logger.debug("fieldValue [" + fieldValue + "]");

                if (!String.class.equals(model.get(fieldName).getClass())
                        &&
!Number.class.isAssignableFrom(model.get(fieldName).getClass())) {
                    Translator translator =
translatorSource.findByType(model.get(fieldName).getPropertyType());
                    if (translator != null) {
                        fieldValue = translator.toClient(fieldValue);
                    } else {
                        fieldValue = fieldValue != null ?
fieldValue.toString() : "";
                    }
                }
                cell.put(fieldName, fieldValue);
            }

            rows.put(cell);
        }

        response.put("aaData", rows);

        logger.debug("rows [" + rows + "]");
        return response;
    }

    @Override
    public JSONObject sendResponse(Request request, GridDataSource source,
BeanModel model, GridSortModel sortModel,
            PropertyOverrides overrides, boolean mode) throws IOException {
        logger.trace("sendResponse()");
        this.request = request;
        this.sortModel = sortModel;
        this.model = model;
        this.overrides = overrides;

        GridDataSource gridDataSource = source;

        prepareResponse(gridDataSource);

        JSONObject response = getResponse(gridDataSource);
        logger.debug("response [" + response.toString() + "]");
        return response;
    }
}

CelebrityService.java
public class CelebrityService implements GridDataSource {
    private SqlSessionFactory sqlSessionFactory;
    private List<Celebrity> selection; // wtf
    private int startIndex; // wtf
    private List<Celebrity> celebrities = new ArrayList<Celebrity>(); // not
going to need this for long.  This is so getRange has something to do 
    
    public CelebrityService() {
        sqlSessionFactory =
MyBatisConnectionFactory.getSqlSessionFactory();;
    }

    // not going to need this for long.  THis is so getRange() has something
to do
    public void getAllCelebrities() {
        SqlSession session = sqlSessionFactory.openSession();
        try {
            CelebrityMapper mapper =
session.getMapper(CelebrityMapper.class);
            celebrities = mapper.selectAll();
        } finally {
            session.close();       
        }
    }

    @Override
    public int getAvailableRows() {
        SqlSession session = sqlSessionFactory.openSession();
        int count;
        try {
            CelebrityMapper mapper =
session.getMapper(CelebrityMapper.class);
            count = mapper.count();
        } finally {
            session.close();       
        }
        return count;
    }

    @Override
    public void prepare(int startIndex, int endIndex, List<SortConstraint>
sortConstraints) {
        // TODO Auto-generated method stub
        selection = getRange(startIndex, endIndex);
        this.startIndex = startIndex;
    }

    @Override
    public Object getRowValue(int index) {
        // TODO Auto-generated method stub
        if (selection == null) {
            prepare(0,14, new ArrayList());
        }
        return selection.get(index - this.startIndex);
    }

    @Override
    public Class<Celebrity> getRowType() {
        return Celebrity.class;
    }
    
    private List<Celebrity> getRange(int indexFrom, int indexTo) {
        // TODO This method needs to pay attention to indexFrom and indexTo
and only get x number of records per time
        List<Celebrity> result = new ArrayList<Celebrity>();
        if (celebrities == null || celebrities.isEmpty()) {
            getAllCelebrities();
        }
        for (int i = indexFrom; i <= indexTo; i++) {
            result.add(celebrities.get(i));
        }
        return result;
    }




--
View this message in context: 
http://tapestry.1045711.n5.nabble.com/ANN-JumpStart-gets-jQuery-DataTables-example-tp5715816p5719410.html
Sent from the Tapestry - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org

Reply via email to