kvesteri/wtforms-components

read_only doesn't work as expected for BooleanField, DateTimeField, or SelectField

alexlewinprosper opened this issue · 8 comments

In my form base class, I call read_only in the init function as in the example in the docs:

https://wtforms-components.readthedocs.io/en/latest/#read-only-fields

It achieves the desired effect for StringField and TextAreaField, but not for the others.

Please let me know whether or not you can address this...if not, I might try to address it and submit a pull request.

Thanks.

I am assuming that I ran into this issue with BooleanField. My issue is that the field state can still be modified in the form, so the user doesn't understand that the field is read only.

The rendered html for current checkbox is

<input checked id="test_field" name="test_field" readonly type="checkbox" value="y">

For some odd reason setting readonlyattribute doesn't prevent changing the checkbox field state. So we could fix this by adding disabled attribute to the html like:

<input checked disabled id="test_field" name="test_field" readonly type="checkbox" value="y">

The same modification should also be done to the radio buttons, and possibly to some others as well.

Assuming that we want to show the user that the field can't be modified we now have two options:

  1. Make all readonly fields also disabled
  2. Create list of fields that should also be disabled when readonly is set
  3. Create separate function to add disabled attribute to fields, use it with these odd fields

I think that the readonly modification in the python code can also add the disabled attribute, so I would go with the option 1. I think it would be the easiest option, and it would hide the html oddness from the application code.

Adding disabled attribute does have some effects. I have found two small changes that come from adding the disabled attribute to all fields, but I think we can live with these:

  1. User can't see the potential choices in disabled select box
  2. User cant select text from disabled text input.

@tvuotila, @kvesteri: I would like to hear your input about this.

Thanks @quantus, yes, that's what I was seeing, and you described the symptoms more precisely than I had...

(tagging my other account so that I can follow from there: @alexlewin )

One of my applications was relying heavily on read_only() for making text input fields read-only on a per-request conditional basis. Therefore, validation is still configured for these fields, which was not an issue becuase reaonly fields are still sent as part of the form.

This is not the case anymore with disabled fields, which I think is a huge change in behavior. I am currently trying to circumvent the issue but it would be good to have a disabled parameter for read_only() that would be passed to the proxy widget to specify which behavior is expected.

If there is a validation error, how can user change the read only field value?
If there never is an error, why are you validating the field?

Simple solution is:

read_only(field)
field.validators = []

In-line validators require a bit more code.

That's exactly the workaround that I used. Still, wouldn't it make more sense to add disabled only for problematic input types (ie. boolean, datetime and select)?

There is a security issue: "Data from the client should never be trusted". Currently, read_only does not correctly enforce this. How i see it, read only field should have the same value regardless of whether the field is sent or not. User should not be able to edit the read only field.

@kaiyou is right. And the workaround doesn't help is you're validating other fields based on the value of a read only field. The read_only function no longer implements the readonly attribute correctly, now it's adding unrelated attributes - I'd consider this broken behaviour.