'helper_js': ("bika_widgets/worksheettemplatelayoutwidget.js",),
        'helper_css': ("bika_widgets/worksheettemplatelayoutwidget.css",),
    })

    security.declarePublic('get_template_rows')
    def get_template_rows(self, num_positions, current_field_value):
        try: num_pos = int(num_positions)
        except ValueError: num_pos = 10

        rows = []
        i = 1
        if current_field_value:
            for row in current_field_value:
                if num_pos > 0:
                    if i > num_pos:
                        break
                rows.append(row)
                i = i + 1
        for i in range(i, (num_pos + 1)):
            row = {
                'pos': i,
                'type': 'a',
                'sub': 1}
            rows.append(row)
        return rows

registerWidget(WorksheetTemplateLayoutWidget,
               title = 'WS Template Analyses Layout',
               description = ('Worksheet analyses layout.'),
               )
Beispiel #2
0
        [a.sort() for a in groupedIndexes.values()]

        config['groupedIndexes'] = groupedIndexes
        return config

    def SearchResults(self, request, context, accessor):
        """search results"""

        options = dict(original_context=context)
        res = getMultiAdapter((accessor(), request),
                              name='display_query_results')
        return res(**options)


registerWidget(QueryWidget,
               title='Query',
               description=('Field for storing a query'))


class WidgetTraverse(_WidgetTraverse):
    def getConfig(self):
        """get the config"""
        registry = getUtility(IRegistry)
        # First grab the base config, so we can use the operations
        registryreader = IQuerystringRegistryReader(registry)
        registryreader.prefix = "plone.app.querystring.operation"
        op_config = registryreader.parseRegistry()
        # Then combine our fields
        registryreader = IQuerystringRegistryReader(registry)
        registryreader.prefix = "bika.lims.bika_catalog_query"
        config = registryreader.parseRegistry()
Beispiel #3
0
from dependencies.dependency import ClassSecurityInfo
from dependencies.dependency import RecordWidget
from dependencies.dependency import registerWidget
import datetime

class DurationWidget(RecordWidget):
    security = ClassSecurityInfo()
    _properties = RecordWidget._properties.copy()
    _properties.update({
        'macro': "bika_widgets/durationwidget",
    })

registerWidget(DurationWidget,
               title = 'DurationWidget',
               description = (''),
               )
        'macro': "bika_widgets/srtemplateartemplateswidget",
    })

    security = ClassSecurityInfo()

    security.declarePublic('process_form')
    def process_form(self, instance, field, form, empty_marker = None,
        emptyReturnsMarker = False):
        bsc = getToolByName(instance, 'bika_setup_catalog')
        value = []
        service_uids = form.get('uids', None)
        return service_uids, {}

    security.declarePublic('ARTemplates')
    def ARTemplates(self, field, allow_edit = False):
        fieldvalue = getattr(field, field.accessor)()
        view = SRTemplateARTemplatesView(
            self,
            self.REQUEST,
            fieldvalue = fieldvalue,
            allow_edit = allow_edit
        )
        return view.contents_table(table_only = True)


registerWidget(
    SRTemplateARTemplatesWidget,
    title = 'SR Template AR Templates Selector',
    description = ('SR Template AR Templates Selector'),
)
        service_uids = form.get('uids', None)

        if instance.portal_type == 'AnalysisProfile':
            # Hidden analyses?
            outs = []
            hiddenans = form.get('Hidden', {})
            if service_uids:
                for uid in service_uids:
                    hidden = hiddenans.get(uid, '')
                    hidden = True if hidden == 'on' else False
                    outs.append({'uid':uid, 'hidden':hidden})
            instance.setAnalysisServicesSettings(outs)

        return service_uids, {}

    security.declarePublic('Analyses')
    def Analyses(self, field, allow_edit = False):
        """ Print analyses table
        """
        fieldvalue = getattr(field, field.accessor)()
        view = AnalysisProfileAnalysesView(self,
                                      self.REQUEST,
                                      fieldvalue = fieldvalue,
                                      allow_edit = allow_edit)
        return view.contents_table(table_only = True)

registerWidget(AnalysisProfileAnalysesWidget,
               title = 'Analysis Profile Analyses selector',
               description = ('Analysis Profile Analyses selector'),
               )
Beispiel #6
0
from dependencies.dependency import DecimalWidget as _d
from dependencies.dependency import registerPropertyType
from dependencies.dependency import registerWidget

from dependencies.dependency import ClassSecurityInfo

_marker = []


class DecimalWidget(_d):
    _properties = _d._properties.copy()
    _properties.update({
        'macro': "bika_widgets/decimal",
        'unit': '',
    })

    security = ClassSecurityInfo()


registerWidget(DecimalWidget,
               title='Decimal',
               description=('Renders a HTML text input box which '
                            'accepts a fixed point value'),
               )

registerPropertyType('unit', 'string', DecimalWidget)
Beispiel #7
0
    def process_form(self, instance, field, form, empty_marker = None,
                     emptyReturnsMarker = False):
        """ Some special field handling for disabled fields, which don't
        get submitted by the browser but still need to be written away.
        """
        bsc = getToolByName(instance, 'bika_setup_catalog')
        default = super(PartitionSetupWidget,self).process_form(
            instance, field, form, empty_marker, emptyReturnsMarker)
        if not default:
            return [], {}
        value = default[0]
        kwargs = len(default) > 1 and default[1] or {}
        newvalue = []
        for v in value:
            v = dict(v)
            if v.get('separate', '') == 'on' and not 'preservation' in v:
                container_uid = v.get('container', [''])[0];
                if container_uid:
                    container = bsc(UID=container_uid)[0].getObject();
                    if container.getPrePreserved():
                        pres = container.getPreservation()
                        if pres:
                            v['preservation'] = [pres.UID()]
            newvalue.append(v)
        return newvalue, kwargs

registerWidget(PartitionSetupWidget,
               title = 'PartitionSetupWidget',
               description = (''),
               )
Beispiel #8
0
from dependencies.dependency import DecimalWidget as _d
from dependencies.dependency import registerPropertyType
from dependencies.dependency import registerWidget

from dependencies.dependency import ClassSecurityInfo

_marker = []


class DecimalWidget(_d):
    _properties = _d._properties.copy()
    _properties.update({
        'macro': "bika_widgets/decimal",
        'unit': '',
    })

    security = ClassSecurityInfo()


registerWidget(
    DecimalWidget,
    title='Decimal',
    description=('Renders a HTML text input box which '
                 'accepts a fixed point value'),
)

registerPropertyType('unit', 'string', DecimalWidget)
    })

    security.declarePublic('get_template_rows')

    def get_template_rows(self, num_positions, current_field_value):
        try:
            num_pos = int(num_positions)
        except ValueError:
            num_pos = 10

        rows = []
        i = 1
        if current_field_value:
            for row in current_field_value:
                if num_pos > 0:
                    if i > num_pos:
                        break
                rows.append(row)
                i = i + 1
        for i in range(i, (num_pos + 1)):
            row = {'pos': i, 'type': 'a', 'sub': 1}
            rows.append(row)
        return rows


registerWidget(
    WorksheetTemplateLayoutWidget,
    title='WS Template Analyses Layout',
    description=('Worksheet analyses layout.'),
)
Beispiel #10
0
            repeatUnit = fn + "_repeatunit" in form and form[
                fn + "_repeatunit"] or None
            repeatPeriod = fn + "_repeatperiodselected" in form and form[
                fn + "_repeatperiodselected"] or None
            repeatEnabled = (repeatUnit and fn + "_repeatenabled" in form
                             and form[fn + "_repeatenabled"]
                             == 'on') and True or False
            repeatUntil = fn + "_repeatuntil" in form and form[
                fn + "_repeatuntil"] or None
            repeatUntilEnabled = (
                repeatUntil and fn + "_repeatuntilenabled" in form
                and form[fn + "_repeatuntilenabled"] == 'on') and True or False

            value.append({
                'fromenabled': fromEnabled,
                'fromdate': fromDate,
                'repeatenabled': repeatEnabled,
                'repeatunit': repeatUnit,
                'repeatperiod': repeatPeriod,
                'repeatuntilenabled': repeatUntilEnabled,
                'repeatuntil': repeatUntil
            })

        return value, {}


registerWidget(
    ScheduleInputWidget,
    title='ScheduleInputWidget',
    description=('Control for scheduling'),
)
Beispiel #11
0
from dependencies.dependency import SelectionWidget as _s
from dependencies.dependency import registerWidget

from dependencies.dependency import ClassSecurityInfo


class SelectionWidget(_s):
    _properties = _s._properties.copy()
    _properties.update({
        'macro': "bika_widgets/selection",
    })

    security = ClassSecurityInfo()


registerWidget(SelectionWidget)
Beispiel #12
0
        # Sort each index list
        [a.sort() for a in groupedIndexes.values()]

        config['groupedIndexes'] = groupedIndexes
        return config

    def SearchResults(self, request, context, accessor):
        """search results"""

        options = dict(original_context=context)
        res = getMultiAdapter((accessor(), request),
                              name='display_query_results')
        return res(**options)

registerWidget(QueryWidget, title='Query',
               description=('Field for storing a query'))


class WidgetTraverse(_WidgetTraverse):

    def getConfig(self):
        """get the config"""
        registry = getUtility(IRegistry)
        # First grab the base config, so we can use the operations
        registryreader = IQuerystringRegistryReader(registry)
        registryreader.prefix = "plone.app.querystring.operation"
        op_config = registryreader.parseRegistry()
        # Then combine our fields
        registryreader = IQuerystringRegistryReader(registry)
        registryreader.prefix = "bika.lims.bika_catalog_query"
        config = registryreader.parseRegistry()
                                  'partition':Partitions[service_uid]})

        if instance.portal_type == 'ARTemplate':
            # Hidden analyses?
            outs = []
            hiddenans = form.get('Hidden', {})
            if service_uids:
                for uid in service_uids:
                    hidden = hiddenans.get(uid, '')
                    hidden = True if hidden == 'on' else False
                    outs.append({'uid':uid, 'hidden':hidden})
            instance.setAnalysisServicesSettings(outs)

        return value, {}

    security.declarePublic('Analyses')
    def Analyses(self, field, allow_edit = False):
        """ Print analyses table
        """
        fieldvalue = getattr(field, field.accessor)()
        view = ARTemplateAnalysesView(self,
                                      self.REQUEST,
                                      fieldvalue = fieldvalue,
                                      allow_edit = allow_edit)
        return view.contents_table(table_only = True)

registerWidget(ARTemplateAnalysesWidget,
               title = 'AR Template Analyses Layout',
               description = ('AR Template Analyses Layout'),
               )
Beispiel #14
0
from dependencies.dependency import registerPropertyType
from lims.browser import ulocalized_time as ut


class DateTimeWidget(TypesWidget):
    _properties = TypesWidget._properties.copy()
    _properties.update({
        'show_time': False,
        'macro': "bika_widgets/datetimewidget",
        'helper_js': ("bika_widgets/datetimewidget.js", ),
        'helper_css': ("bika_widgets/datetimewidget.css", ),
    })

    security = ClassSecurityInfo()

    def ulocalized_time(self, time, context, request):
        val = ut(time,
                 long_format=self._properties['show_time'],
                 time_only=False,
                 context=context,
                 request=request)
        return val


registerWidget(
    DateTimeWidget,
    title='DateTimeWidget',
    description=('Simple text field, with a jquery date widget attached.'))

registerPropertyType('show_time', 'boolean')
Beispiel #15
0
from dependencies.dependency import ClassSecurityInfo
from dependencies.dependency import RecordWidget
from dependencies.dependency import registerWidget
import datetime

class CoordinateWidget(RecordWidget):
    security = ClassSecurityInfo()
    _properties = RecordWidget._properties.copy()
    _properties.update({
        'macro': "bika_widgets/coordinatewidget",
    })

registerWidget(CoordinateWidget,
               title = 'CoordinateWidget',
               description = '',
               )
Beispiel #16
0
        # a poor workaround for Plone repeating itself.
        # XXX this is important XXX
        key = field.getName() + '_value'
        if key in instance.REQUEST:
            return instance.REQUEST[key], {}
        value = form.get(field.getName(), empty_marker)

        if not value:
            return value, {}
        if value is empty_marker:
            return empty_marker
        if emptyReturnsMarker and value == '':
            return empty_marker

        # we make sure that empty "value" inputs are saved as "" empty string.
        for i in range(len(value)):
            value[i] = dict(value[i])
            if 'value' not in value[i]:
                value[i]['value'] = ''

        instance.REQUEST[key] = value
        return value, {}

    def jsondumps(self, val):
        return json.dumps(val)

registerWidget(RecordsWidget,
               title = 'RecordsWidget',
               description = '',
               )
Beispiel #17
0
from dependencies.dependency import IntegerWidget as _i
from dependencies.dependency import registerPropertyType
from dependencies.dependency import registerWidget

from dependencies.dependency import ClassSecurityInfo

_marker = []


class IntegerWidget(_i):
    _properties = _i._properties.copy()
    _properties.update({
        'macro': "bika_widgets/integer",
        'unit': '',
    })

    security = ClassSecurityInfo()

registerWidget(IntegerWidget,
               title='Integer',
               description=('Renders a HTML text input box which '
                            'accepts a integer value'),
               )

registerPropertyType('unit', 'string', IntegerWidget)
Beispiel #18
0
from dependencies.dependency import IntegerWidget as _i
from dependencies.dependency import registerPropertyType
from dependencies.dependency import registerWidget

from dependencies.dependency import ClassSecurityInfo

_marker = []


class IntegerWidget(_i):
    _properties = _i._properties.copy()
    _properties.update({
        'macro': "bika_widgets/integer",
        'unit': '',
    })

    security = ClassSecurityInfo()


registerWidget(
    IntegerWidget,
    title='Integer',
    description=('Renders a HTML text input box which '
                 'accepts a integer value'),
)

registerPropertyType('unit', 'string', IntegerWidget)
Beispiel #19
0
                Min = Min if Min else False
                Max = form['max'][0][uid]
                Max = Max if Max else False
                # big old false check because these could be zeroes
                if Min is not False \
                  and Max is not False \
                  and result is not False:
                    value.append({'uid': uid,
                                  'result': result,
                                  'min': Min,
                                  'max': Max})
        return value, {}

    security.declarePublic('ReferenceResults')

    def ReferenceResults(self, field, allow_edit=False):
        """ Prints a bika listing with categorized services.
            field contains the archetypes field with a list of services in it
        """
        fieldvalue = getattr(field, field.accessor)()
        view = TableRenderShim(self,
                               self.REQUEST,
                               fieldvalue=fieldvalue,
                               allow_edit=allow_edit)
        return view()

registerWidget(ReferenceResultsWidget,
               title='Reference definition results',
               description=('Reference definition results.'),
               )
Beispiel #20
0
        # Return a dict with the options defined in the schema whose widget needs an edit button.
        return {
            'visible': self.edit_button.get('visible', False),
            'url': self.edit_button.get('url'),
            'return_fields': json.dumps(self.edit_button.get('return_fields')),
            'js_controllers': json.dumps(self.edit_button.get('js_controllers',[])),
            'overlay_handler': self.edit_button.get('overlay_handler', ''),
            'overlay_options': json.dumps(self.edit_button.get('overlay_options',{
                'filter': 'head>*,#content>*:not(div.configlet),dl.portalMessage.error,dl.portalMessage.info',
                'formselector': 'form[id$="base-edit"]',
                'closeselector': '[name="form.button.cancel"]',
                'width': '70%',
                'noform': 'close',}))
            }

registerWidget(ReferenceWidget, title='Reference Widget')

class ajaxReferenceWidgetSearch(BrowserView):

    """ Source for jquery combo dropdown box
    """

    def __call__(self):
        CheckAuthenticator(self.request)
        page = self.request['page']
        nr_rows = self.request['rows']
        sord = self.request['sord']
        sidx = self.request['sidx']
        colModel = json.loads(_u(self.request.get('colModel', '[]')))
        discard_empty = json.loads(_c(self.request.get('discard_empty', "[]")))
        rows = []
Beispiel #21
0
        return items


class ServicesWidget(TypesWidget):
    _properties = TypesWidget._properties.copy()
    _properties.update({
        'macro': "bika_widgets/serviceswidget",
    })

    security = ClassSecurityInfo()

    security.declarePublic('getServices')

    def Services(self, field, show_select_column=True):
        """ Prints a bika listing with categorized services.
            field contains the archetypes field with a list of services in it
        """
        services = ServicesView(self, self.REQUEST, field)
        services.show_select_column = show_select_column
        services.select_checkbox_name = field.getName()
        return services.contents_table(table_only=True)


registerWidget(
    ServicesWidget,
    title='Analysis Services',
    description=('Categorised AnalysisService selector.'),
)

#registerPropertyType('default_search_index', 'string', ServicesWidget)
# ../../skins/bika/bika_widgets/artemplatepartitionswidget.pt
from dependencies.dependency import ClassSecurityInfo
from dependencies.dependency import registerWidget
from lims.browser.widgets import RecordsWidget


class ARTemplatePartitionsWidget(RecordsWidget):
    _properties = RecordsWidget._properties.copy()
    _properties.update({
        'helper_js': (
            "bika_widgets/recordswidget.js",
            "bika_widgets/artemplatepartitionswidget.js",
        )
    })

    security = ClassSecurityInfo()


registerWidget(
    ARTemplatePartitionsWidget,
    title='AR Template Partition Layout',
    description=('AR Template Partition Layout'),
)
Beispiel #23
0
from dependencies.dependency import ClassSecurityInfo
from dependencies.dependency import RecordWidget
from dependencies.dependency import registerWidget
import datetime


class CoordinateWidget(RecordWidget):
    security = ClassSecurityInfo()
    _properties = RecordWidget._properties.copy()
    _properties.update({
        'macro': "bika_widgets/coordinatewidget",
    })


registerWidget(
    CoordinateWidget,
    title='CoordinateWidget',
    description='',
)
Beispiel #24
0
from dependencies.dependency import ClassSecurityInfo
from dependencies.dependency import TypesWidget
from dependencies.dependency import registerWidget
from dependencies.dependency import registerPropertyType
from lims.browser import ulocalized_time as ut


class DateTimeWidget(TypesWidget):
    _properties = TypesWidget._properties.copy()
    _properties.update(
        {
            "show_time": False,
            "macro": "bika_widgets/datetimewidget",
            "helper_js": ("bika_widgets/datetimewidget.js",),
            "helper_css": ("bika_widgets/datetimewidget.css",),
        }
    )

    security = ClassSecurityInfo()

    def ulocalized_time(self, time, context, request):
        val = ut(time, long_format=self._properties["show_time"], time_only=False, context=context, request=request)
        return val


registerWidget(
    DateTimeWidget, title="DateTimeWidget", description=("Simple text field, with a jquery date widget attached.")
)

registerPropertyType("show_time", "boolean")
Beispiel #25
0
    
    def process_form(self, instance, field, form, empty_marker=None, emptyReturnsMarker=False):
        
        values = len(instance.getScheduleCriteria())>0 and instance.getScheduleCriteria() or []
        
        if "form.button.save" in form:
            value = []            
            fn = form['fieldName']
            fromDate = fn + "_fromdate" in form and form[fn+"_fromdate"] or None
            fromEnabled = (fromDate and fn + "_fromenabled" in form and form[fn+"_fromenabled"] == 'on') and True or False            
            repeatUnit = fn + "_repeatunit" in form and form[fn+"_repeatunit"] or None
            repeatPeriod = fn + "_repeatperiodselected" in form and form[fn+"_repeatperiodselected"] or None
            repeatEnabled = (repeatUnit and fn + "_repeatenabled" in form and form[fn+"_repeatenabled"] == 'on') and True or False           
            repeatUntil = fn + "_repeatuntil" in form and form[fn+"_repeatuntil"] or None
            repeatUntilEnabled = (repeatUntil and fn + "_repeatuntilenabled" in form and form[fn+"_repeatuntilenabled"] == 'on') and True or False
            
            value.append({'fromenabled': fromEnabled,
                          'fromdate': fromDate,
                          'repeatenabled': repeatEnabled,
                          'repeatunit':repeatUnit,
                          'repeatperiod':repeatPeriod,
                          'repeatuntilenabled':repeatUntilEnabled,
                          'repeatuntil':repeatUntil})
            
        return value, {}      
       

registerWidget(ScheduleInputWidget,
               title = 'ScheduleInputWidget',
               description = ('Control for scheduling'),
               )
Beispiel #26
0
            self.edit_button.get('overlay_handler', ''),
            'overlay_options':
            json.dumps(
                self.edit_button.get(
                    'overlay_options', {
                        'filter':
                        'head>*,#content>*:not(div.configlet),dl.portalMessage.error,dl.portalMessage.info',
                        'formselector': 'form[id$="base-edit"]',
                        'closeselector': '[name="form.button.cancel"]',
                        'width': '70%',
                        'noform': 'close',
                    }))
        }


registerWidget(ReferenceWidget, title='Reference Widget')


class ajaxReferenceWidgetSearch(BrowserView):
    """ Source for jquery combo dropdown box
    """
    def __call__(self):
        CheckAuthenticator(self.request)
        page = self.request['page']
        nr_rows = self.request['rows']
        sord = self.request['sord']
        sidx = self.request['sidx']
        colModel = json.loads(_u(self.request.get('colModel', '[]')))
        discard_empty = json.loads(_c(self.request.get('discard_empty', "[]")))
        rows = []
Beispiel #27
0

        self.categories.sort()

        return items

class ServicesWidget(TypesWidget):
    _properties = TypesWidget._properties.copy()
    _properties.update({
        'macro': "bika_widgets/serviceswidget",
    })

    security = ClassSecurityInfo()

    security.declarePublic('getServices')
    def Services(self, field, show_select_column=True):
        """ Prints a bika listing with categorized services.
            field contains the archetypes field with a list of services in it
        """
        services = ServicesView(self, self.REQUEST, field)
        services.show_select_column = show_select_column
        services.select_checkbox_name = field.getName()
        return services.contents_table(table_only=True)

registerWidget(ServicesWidget,
               title = 'Analysis Services',
               description = ('Categorised AnalysisService selector.'),
               )

#registerPropertyType('default_search_index', 'string', ServicesWidget)
                   (not isnumber(mins) or not isnumber(maxs)):
                    # If neither hidemin nor hidemax have been specified,
                    # min and max values are mandatory.
                    continue

                value.append({'keyword': keyword,
                              'uid': uid,
                              'min': mins if isnumber(mins) else '',
                              'max': maxs if isnumber(maxs) else '',
                              'hidemin': hidemin if isnumber(hidemin) else '',
                              'hidemax': hidemax if isnumber(hidemax) else '',
                              'error': err if isnumber(err) else '0',
                              'rangecomment': rangecomment})
        return value, {}

    security.declarePublic('AnalysisSpecificationResults')
    def AnalysisSpecificationResults(self, field, allow_edit = False):
        """ Prints a bika listing with categorized services.
            field contains the archetypes field with a list of services in it
        """
        fieldvalue = getattr(field, field.accessor)()
        view = AnalysisSpecificationView(self,
                                            self.REQUEST,
                                            fieldvalue = fieldvalue,
                                            allow_edit = allow_edit)
        return view.contents_table(table_only = True)

registerWidget(AnalysisSpecificationWidget,
               title = 'Analysis Specification Results',
               description = ('Analysis Specification Results'))
Beispiel #29
0
from dependencies.dependency import SelectionWidget as _s
from dependencies.dependency import registerWidget

from dependencies.dependency import ClassSecurityInfo

class SelectionWidget(_s):
    _properties = _s._properties.copy()
    _properties.update({
        'macro': "bika_widgets/selection",
    })

    security = ClassSecurityInfo()

registerWidget(SelectionWidget)
# ../../skins/bika/bika_widgets/artemplatepartitionswidget.pt
from dependencies.dependency import ClassSecurityInfo
from dependencies.dependency import registerWidget
from lims.browser.widgets import RecordsWidget


class ARTemplatePartitionsWidget(RecordsWidget):
    _properties = RecordsWidget._properties.copy()
    _properties.update({
        'helper_js': ("bika_widgets/recordswidget.js",
                      "bika_widgets/artemplatepartitionswidget.js",)
    })

    security = ClassSecurityInfo()

registerWidget(ARTemplatePartitionsWidget,
               title='AR Template Partition Layout',
               description=('AR Template Partition Layout'),
               )
Beispiel #31
0
        iso = [c for c in COUNTRIES if c['Country'] == country or c['ISO'] == country]
        if not iso:
            return items
        iso = iso[0]['ISO']
        items = [x for x in STATES if x[0] == iso]
        items.sort(lambda x,y: cmp(x[2], y[2]))
        return items

    def getDistricts(self, country, state):
        items = []
        if not country or not state:
            return items
        # get ISO code for country
        iso = [c for c in COUNTRIES if c['Country'] == country or c['ISO'] == country]
        if not iso:
            return items
        iso = iso[0]['ISO']
        # get NUMBER of the state for lookup
        snr = [s for s in STATES if s[0] == iso and s[2] == state]
        if not snr:
            return items
        snr = snr[0][1]
        items = [x for x in DISTRICTS if x[0] == iso and x[1] == snr]
        items.sort(lambda x,y: cmp(x[1], y[1]))
        return items

registerWidget(AddressWidget,
               title = 'Address Widget',
               description = ('Simple address widget with country/state lookups'),
               )