Pylons / deform

A Python HTML form library.
Other
416 stars 160 forks source link

Select widgets with colander.Set() for multiple values do not render when readonly is True #404

Open stevepiercy opened 4 years ago

stevepiercy commented 4 years ago

Let's say there are Admin and non-Admin users. An Admin user would always be able to edit the values in the select, whereas a non-Admin would be able to readonly.

When using selects with multiple values, we must use colander.Set() for the typ of the colander.SchemaNode() as demonstrated in:

However when we want to show them as readonly by adding readonly=True to the node, then the values do not render.

If we change the typ to colander.String(), then the values will render, but then we lose the editing of colander.Set().

To workaround this dilemma, we need to use a deferred typ.

@colander.deferred
def deferred_pepper_typ(node, kw):
    is_admin = kw["is_admin"]
    if is_admin:
        return colander.Set()
    return colander.String()

@colander.deferred
def deferred_pepper_widget(node, kw):
    is_admin = kw["is_admin"]
    readonly = False
    if not is_admin:
        readonly = True
    deform.widget.Select2Widget(
        values=choices,
        readonly=readonly,
        multiple=True)

pepper = colander.SchemaNode(
    typ=deferred_pepper_typ,
    widget=deferred_pepper_widget,
)

Ideally when readonly=True for a select widget that has a set of values, then those values would be rendered.