views:

57

answers:

3

I have a form that I want to present in two states:

1) Normal form

2) Person can look at the form as filled out by a user but can't change anything

It's easy to handle text inputs with the readonly property, but radio buttons, checkboxes, and dropdown menus don't use it. I can set the "disabled" property for those, but in most browsers they show up grayed out and barely visible. What I really want is for them to look like a normal form but be unclickable the way a disabled element is. Is there a way to override the normal "disabled" look? Or is the solution to disable them in some roundabout way handling clicks?

I'm using jQuery for most of this stuff, if that matters...

A: 

Just replace them with your own more controllable HTML/CSS construct, à la Niceforms, et al. (with disabled or readonly attribute, as appropriate, as fallback).

reisio
A: 

A suggestion rather an answer: you can associate an event with the state change of an element, and cancel the change.

You can do it the same way as the validate tools which allows to enter only digits or only some characters in <input type="text" /> fields. See a StackOverflow post about this.

Another solution is to put something in front of your controls. For example:

<div style="position:absolute;width:200px;height:200px;"></div>
<input type="radio" />

will make your radio button unclickable. The problem is that doing so will prevent the users to copy-paste text or using hyperlinks, if the <div/> covers the whole page. You can "cover" each control one by one, but it may be quite difficult to do.

MainMa
+1  A: 

well, you could try hacks like this....

​$(':radio:disabled').removeAttr('disabled').click(function(){
    this.checked=false;
})​;

this will select all disabled radio buttons and enabled it but when click, will not be checked...

demo

and on <select>

you could do like,

$('select:disabled').removeAttr('disabled').change(function(){
    $(this).find('option').removeAttr('selected');
    // this.value = this.defaultValue; // you may also try this..
});
Reigel
why the down vote??? please explain so that this answer could be improved...
Reigel
The problem is that this checks, than un-checks the radio button, which is visually ugly.
MainMa
`The problem is that this checks` - really??
Reigel
Hmm...I guess that could work, although the listener would need to be a little more complicated, because it would need to check the previous value and then preserve it, and for a group of radio buttons, it would need to make sure the previously checked button stays checked. I could override the default with a .change() event, too. I was hoping there was some sneaky CSS I didn't know about...
NChase
@Reigel: I will try to search if it's true. Meanwhile, I removed the downvote. ;)
MainMa
@NChase - Ahh I see, I got you.. wait... getting something to work.. ;)
Reigel
@NChase: there are no HTML/CSS solutions to "block" the state of a radio button. If you want to do it with "real" controls, you have to use JavaScript.
MainMa
@Reigel: ok, so, the problem is that it gets focus (which, like I said, is visually ugly). A control which we cannot interact with must not react visually to focus/mouse hover. In other words, if a control is responsive, it means that the user can interact with it and change its state. A disabled control is a good example: it stays gray every time, even when you hover on it or try to press it.
MainMa
@MainMa - You can "lock" the state of it with the disabled attribute, I just want to avoid the poor readability that results from the graying out. It sounds like my only option would be to use a set of listeners to override a few different possible events.
NChase
@NChase: "my only option": what about a CSS suggestion I've put in my answer?
MainMa
@MainMa Right. It would be possible to cover elements with containers, or using something like Niceforms and edit the source to make them unclickable, but then it becomes a pretty large undertaking and not something easy to apply across the board in a form with lots of elements with variable formatting.
NChase