'Get a data list
@param r: the S3Request
@param attr: parameters for the method handler'

def _datalist(self, r, **attr):

    authorised = self._permitted()
    if (not authorised):
        r.unauthorised()
    resource = self.resource
    get_config = resource.get_config
    get_vars = self.request.get_vars
    layout = get_config('list_layout', None)
    list_id = get_vars.get('list_id', attr.get('list_id', 'datalist'))
    if hasattr(layout, 'list_fields'):
        list_fields = layout.list_fields
    else:
        list_fields = resource.list_fields()
    orderby = get_config('list_orderby', get_config('orderby', None))
    if (orderby is None):
        if ('created_on' in resource.fields):
            default_orderby = (~ resource.table['created_on'])
        else:
            for f in list_fields:
                rfield = resource.resolve_selector(f)
                if (rfield.field and (rfield.colname != str(resource._id))):
                    default_orderby = rfield.field
                    break
    else:
        default_orderby = None
    response = current.response
    s3 = response.s3
    if ('dl_pagelength' in attr):
        pagelength = attr['dl_pagelength']
    elif s3.dl_pagelength:
        pagelength = s3.dl_pagelength
    else:
        pagelength = 10
    if ('dl_rowsize' in attr):
        rowsize = attr['dl_rowsize']
    elif s3.dl_rowsize:
        rowsize = s3.dl_rowsize
    else:
        rowsize = 1
    if (pagelength % rowsize):
        pagelength = ((int((pagelength / rowsize)) + 1) * rowsize)
    record_id = get_vars.get('record', None)
    if (record_id is not None):
        from s3query import FS
        resource.add_filter((FS('id') == record_id))
        start = 0
        limit = 1
    else:
        (start, limit) = self._limits(get_vars)
    output = {}
    representation = r.representation
    if ((representation == 'dl') and (r.http in ('DELETE', 'POST'))):
        if ('delete' in get_vars):
            return {'item': self._dl_ajax_delete(r, resource)}
        else:
            r.error(405, current.ERROR.BAD_METHOD)
    if (representation in ('html', 'dl', 'popup')):
        if limit:
            initial_limit = min(limit, pagelength)
        else:
            initial_limit = pagelength
        if (not orderby):
            orderby = default_orderby
        (datalist, numrows, ids) = resource.datalist(fields=list_fields, start=start, limit=initial_limit, orderby=orderby, list_id=list_id, layout=layout)
        if (numrows == 0):
            s3.no_formats = True
            if (r.component and ('showadd_btn' in output)):
                del output['showadd_btn']
        ajax_url = attr.get('list_ajaxurl', None)
        if (not ajax_url):
            vars = dict(((k, v) for (k, v) in r.get_vars.iteritems() if (k not in ('start', 'limit'))))
            ajax_url = r.url(representation='dl', vars=vars)
        if ((representation == 'dl') or (not limit)):
            limit = numrows
        dl = datalist.html(start=(start if start else 0), limit=limit, pagesize=pagelength, rowsize=rowsize, ajaxurl=ajax_url)
        data = dl
    else:
        r.error(415, current.ERROR.BAD_FORMAT)
    if (representation == 'html'):
        response.view = self._view(r, 'list_filter.html')
        output['items'] = data
    elif (representation == 'dl'):
        response.view = 'plain.html'
        output['item'] = data
    elif (representation == 'popup'):
        response.view = 'popup.html'
        output['items'] = data
        if s3.debug:
            appname = current.request.application
            sappend = s3.scripts.append
            sappend(('/%s/static/scripts/jquery.infinitescroll.js' % appname))
            sappend(('/%s/static/scripts/jquery.viewport.js' % appname))
            sappend(('/%s/static/scripts/S3/s3.dataLists.js' % appname))
        else:
            s3.scripts.append(('/%s/static/scripts/S3/s3.dataLists.min.js' % current.request.application))
    return output
