Passed
Push — 2.x ( 7c9886...165ef1 )
by Jordi
07:30
created

QuerySelectWidget.get_api_url()   A

Complexity

Conditions 2

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 9
rs 10
c 0
b 0
f 0
cc 2
nop 2
1
# -*- coding: utf-8 -*-
2
3
import json
4
5
import six
6
7
from bika.lims import api
8
from AccessControl import ClassSecurityInfo
9
from Products.Archetypes.Registry import registerWidget
10
from Products.Archetypes.Widget import TypesWidget
11
from Products.CMFPlone.utils import base_hasattr
12
13
_marker = object
14
15
16
class QuerySelectWidget(TypesWidget):
17
    """AT Backport of Dexterity Queryselect Widget
18
19
    https://github.com/senaite/senaite.core/pull/2177
20
    """
21
    security = ClassSecurityInfo()
22
    _properties = TypesWidget._properties.copy()
23
    _properties.update({
24
        "macro": "senaite_widgets/queryselectwidget",
25
        "query": {},
26
        "limit": 25,
27
        "catalog": "portal_catalog",
28
        "api_url": None,
29
        "disabled": False,
30
        "readonly": False,
31
        "multi_valued": False,
32
        "allow_user_value": False,
33
        "search_wildcard": True,
34
        "value_key": "uid",
35
        "padding": 3,
36
        "display_template": None,
37
        "hide_input_after_select": False,
38
    })
39
40 View Code Duplication
    def attr(self, context, name, default=None):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
41
        """Get the named attribute of the widget or from the context
42
        """
43
        value = getattr(self, name, _marker)
44
        if value is _marker:
45
            return default
46
        if isinstance(value, six.string_types):
47
            if base_hasattr(context, value):
48
                attr = getattr(context, value)
49
                if callable(attr):
50
                    attr = attr()
51
                if attr:
52
                    value = attr
53
        return value
54
55
    def to_value(self, value):
56
        """Extract the value from the request or get it from the field
57
        """
58
        # the value might come from the request, e.g. on object creation
59
        if isinstance(value, six.string_types):
60
            value = filter(None, value.split("\r\n"))
61
        # we handle always lists in the templates
62
        if value is None:
63
            return []
64
        if not isinstance(value, (list, tuple)):
65
            value = [value]
66
        return value
67
68
    def get_api_url(self, context):
69
        """JSON API URL to use for this widget
70
        """
71
        portal = api.get_portal()
72
        portal_url = api.get_url(portal)
73
        api_url = self.attr(context, "api_url")
74
        if not api_url:
75
            api_url = "{}/@@API/senaite/v1".format(portal_url)
76
        return api_url
77
78
    def get_input_widget_attributes(self, context, field, value):
79
        """Return input widget attributes for the ReactJS component
80
        """
81
        attributes = {
82
            "data-id": field.getName(),
83
            "data-name": field.getName(),
84
            "data-values": self.to_value(value),
85
            "data-value_key": self.attr(context, "value_key"),
86
            "data-columns": self.attr(context, "columns"),
87
            "data-query": self.attr(context, "query"),
88
            "data-multi_valued": self.attr(context, "multi_valued"),
89
            "data-api_url": self.get_api_url(context),
90
            "data-search_index": self.attr(context, "search_index"),
91
            "data-search_wildcard": self.attr(context, "search_wildcard"),
92
            "data-limit": self.attr(context, "limit"),
93
            "data-catalog": self.attr(context, "catalog"),
94
            "data-allow_user_value": self.attr(context, "allow_user_value"),
95
            "data-hide_input_after_select": self.attr(
96
                context, "hide_input_after_select"),
97
        }
98
99
        # convert all attributes to JSON
100
        for key, value in attributes.items():
101
            attributes[key] = json.dumps(value)
102
103
        return attributes
104
105
106
registerWidget(QuerySelectWidget, title="QuerySelectWidget")
107