'Initialize this form element for a particular record. Retrieves
the component data for this record from the database and
converts them into a JSON string to populate the input field with.
@param resource: the resource the record belongs to
@param record_id: the record ID
@return: the JSON for the input field.'

def extract(self, resource, record_id):

    self.resource = resource
    component_name = self.selector
    if (component_name in resource.components):
        component = resource.components[component_name]
        options = self.options
        if component.link:
            link = options.get('link', True)
            if link:
                component = component.link
        table = component.table
        tablename = component.tablename
        pkey = table._id.name
        fields_opt = options.get('fields', None)
        labels = {}
        widgets = {}
        if fields_opt:
            fields = []
            for f in fields_opt:
                if isinstance(f, tuple):
                    if (len(f) > 2):
                        (label, f, w) = f
                        widgets[f] = w
                    else:
                        (label, f) = f
                    labels[f] = label
                if (f in table.fields):
                    fields.append(f)
        else:
            fields = [f.name for f in table if (f.readable or f.writable)]
        if (pkey not in fields):
            fields.insert(0, pkey)
        if ('virtual_fields' in options):
            virtual_fields = options['virtual_fields']
        else:
            virtual_fields = []
        if ('orderby' in options):
            orderby = options['orderby']
        else:
            orderby = component.get_config('orderby')
        if record_id:
            if ('filterby' in options):
                f = self._filterby_query()
                if (f is not None):
                    component.build_query(filter=f)
            if ('extra_fields' in options):
                extra_fields = options['extra_fields']
            else:
                extra_fields = []
            all_fields = ((fields + virtual_fields) + extra_fields)
            start = 0
            limit = (1 if (options.multiple is False) else None)
            data = component.select(all_fields, start=start, limit=limit, represent=True, raw_data=True, show_links=False, orderby=orderby)
            records = data['rows']
            rfields = data['rfields']
            for f in rfields:
                if (f.fname in extra_fields):
                    rfields.remove(f)
                else:
                    s = f.selector
                    if s.startswith('~.'):
                        s = s[2:]
                    label = labels.get(s, None)
                    if (label is not None):
                        f.label = label
        else:
            records = []
            rfields = []
            for s in fields:
                rfield = component.resolve_selector(s)
                label = labels.get(s, None)
                if (label is not None):
                    rfield.label = label
                rfields.append(rfield)
            for f in virtual_fields:
                rfield = component.resolve_selector(f[1])
                rfield.label = f[0]
                rfields.append(rfield)
        headers = [{'name': rfield.fname, 'label': s3_unicode(rfield.label)} for rfield in rfields if (rfield.fname != pkey)]
        self.widgets = widgets
        items = []
        has_permission = current.auth.s3_has_permission
        for record in records:
            row = record['_row']
            row_id = row[str(table._id)]
            item = {'_id': row_id}
            permitted = has_permission('update', tablename, row_id)
            if (not permitted):
                item['_readonly'] = True
            for rfield in rfields:
                fname = rfield.fname
                if (fname == pkey):
                    continue
                colname = rfield.colname
                field = rfield.field
                widget = field.widget
                if isinstance(widget, S3Selector):
                    value = widget.serialize(widget.extract(row[colname]))
                elif hasattr(field, 'formatter'):
                    value = field.formatter(row[colname])
                else:
                    value = row[colname]
                text = s3_unicode(record[colname])
                item[fname] = {'value': value, 'text': text}
            items.append(item)
        validate = options.get('validate', None)
        if ((not validate) or (not isinstance(validate, tuple)) or (not (len(validate) == 2))):
            request = current.request
            validate = (request.controller, request.function)
        (c, f) = validate
        data = {'controller': c, 'function': f, 'resource': resource.tablename, 'component': component_name, 'fields': headers, 'defaults': self._filterby_defaults(), 'data': items}
    else:
        raise AttributeError('Undefined    component')
    return json.dumps(data, separators=SEPARATORS)
