'Render list data as HTML (nested DIVs)
@param start: index of the first item (in this page)
@param limit: total number of available items
@param pagesize: maximum number of items per page
@param rowsize: number of items per row
@param ajaxurl: the URL to Ajax-update the datalist
@param empty: message to display if the list is empty
@param popup_url: the URL for the modal used for the \'more\'
button (=> we deactivate InfiniteScroll)
@param popup_title: the title for the modal'

def html(self, start=None, limit=None, pagesize=None, rowsize=None, ajaxurl=None, empty=None, popup_url=None, popup_title=None):

    T = current.T
    resource = self.resource
    list_fields = self.list_fields
    rfields = resource.resolve_selectors(list_fields)[0]
    list_id = self.list_id
    render = self.layout
    render_row = self.row_layout
    if (not rowsize):
        rowsize = 1
    pkey = str(resource._id)
    records = self.records
    if (records is not None):
        if hasattr(render, 'prep'):
            render.prep(resource, records)
        if current.response.s3.dl_no_header:
            items = []
        else:
            items = [DIV((T('Total    Records:    %(numrows)s') % {'numrows': self.total}), _class='dl-header', _id=('%s-header' % list_id))]
        if (empty is None):
            empty = resource.crud.crud_string(resource.tablename, 'msg_no_match')
        empty = DIV(empty, _class='dl-empty')
        if (self.total > 0):
            empty.update(_style='display:none')
        items.append(empty)
        row_idx = (int((self.start / rowsize)) + 1)
        for group in self.groups(records, rowsize):
            row = []
            col_idx = 0
            for record in group:
                if (pkey in record):
                    item_id = ('%s-%s' % (list_id, record[pkey]))
                else:
                    item_id = ('%s-[id]' % list_id)
                item = render(list_id, item_id, resource, rfields, record)
                if hasattr(item, 'add_class'):
                    _class = ('dl-item    dl-%s-cols    dl-col-%s' % (rowsize, col_idx))
                    item.add_class(_class)
                row.append(item)
                col_idx += 1
            _class = ('dl-row    %s' % (((row_idx % 2) and 'even') or 'odd'))
            if render_row:
                row = render_row(list_id, resource, rowsize, row)
                if hasattr(row, 'add_class'):
                    row.add_class(_class)
            else:
                row = DIV(row, _class=_class)
            items.append(row)
            row_idx += 1
    else:
        raise NotImplementedError
    dl = DIV(items, _class='dl', _id=list_id)
    dl_data = {'startindex': start, 'maxitems': limit, 'totalitems': self.total, 'pagesize': pagesize, 'rowsize': rowsize, 'ajaxurl': ajaxurl}
    if popup_url:
        input_class = 'dl-pagination'
        a_class = 's3_modal    dl-more'
    else:
        input_class = 'dl-pagination    dl-scroll'
        a_class = 'dl-more'
    from gluon.serializers import json as jsons
    dl_data = jsons(dl_data)
    dl.append(DIV(INPUT(_type='hidden', _class=input_class, _value=dl_data), A(T('more...'), _href=(popup_url or ajaxurl), _class=a_class, _title=popup_title), _class='dl-navigation'))
    return dl
