'Render this widget as HTML helper object(s)
@param resource: the resource
@param values: the search values from the URL query'

def widget(self, resource, values):

    attr = self._attr(resource)
    opts = self.opts
    name = attr['_name']
    (ftype, levels, noopt) = self._options(resource, values=values)
    if noopt:
        return SPAN(noopt, _class='no-options-available')
    _class = self._class
    if (('_class' in attr) and attr['_class']):
        _class = ('%s    %s' % (_class, attr['_class']))
    attr['_class'] = _class
    base_id = attr['_id']
    base_name = attr['_name']
    widgets = []
    w_append = widgets.append
    operator = self.operator
    field_name = self.field
    fname = (self._prefix(field_name) if resource else field_name)
    cols = opts.get('cols', None)
    if cols:
        if ('groupedopts-filter-widget' not in _class):
            attr['_class'] = ('%s    groupedopts-filter-widget' % _class)
        attr['cols'] = cols
        for level in levels:
            options = levels[level]['options']
            groupedopts = S3GroupedOptionsWidget(cols=cols, size=(opts['size'] or 12))
            name = ('%s-%s' % (base_name, level))
            dummy_field = Storage(name=name, type=ftype, requires=IS_IN_SET(options, multiple=True))
            attr['_id'] = ('%s-%s' % (base_id, level))
            attr['_name'] = name
            _values = values.get(('%s$%s__%s' % (fname, level, operator)))
            w_append(groupedopts(dummy_field, _values, **attr))
    else:
        T = current.T
        if ('multiselect-filter-widget' not in _class):
            _class = ('%s    multiselect-filter-widget' % _class)
        header_opt = opts.get('header', False)
        if ((header_opt is False) or (header_opt is True)):
            setting = current.deployment_settings.get_ui_location_filter_bulk_select_option()
            if (setting is not None):
                header_opt = setting
        first = True
        hide = True
        s3 = current.response.s3
        for level in levels:
            name = ('%s-%s' % (base_name, level))
            attr['_id'] = ('%s-%s' % (base_id, level))
            attr['_name'] = name
            _values = values.get(('%s$%s__%s' % (fname, level, operator)))
            w = S3MultiSelectWidget(filter=opts.get('filter', 'auto'), header=header_opt, selectedList=opts.get('selectedList', 3), noneSelectedText=(T('Select    %(location)s') % dict(location=levels[level]['label'])))
            if first:
                attr['_class'] = _class
                options = levels[level]['options']
                dummy_field = Storage(name=name, type=ftype, requires=IS_IN_SET(options, multiple=True))
                widget = w(dummy_field, _values, **attr)
                first = False
            else:
                if hide:
                    _class = ('%s    hide' % _class)
                    attr['_class'] = _class
                    hide = False
                jquery_ready = s3.jquery_ready
                s3.jquery_ready = []
                dummy_field = Storage(name=name, type=ftype, requires=IS_IN_SET([], multiple=True))
                widget = w(dummy_field, _values, **attr)
                script = s3.jquery_ready[0]
                s3.jquery_ready = jquery_ready
                script = ('S3.%s=function(){%s}' % (name.replace('-', '_'), script))
                s3.js_global.append(script)
            w_append(widget)
    attr['_id'] = base_id
    attr['_name'] = base_name
    return TAG[''](*widgets)
