How can I make an entire HTML form "readonly"?

Viewed 202354

I have two pages with HTML forms. The first page has a submission form, and the second page has an acknowledgement form. The first form offers a choice of many controls, while the second page displays the data from the submission form again with a confirmation message. On this second form all fields must be static.

From what I can see, some form controls can be readonly and all can be disabled, the difference being that you can still tab to a readonly field.

Rather than doing this field by field is there any way to mark the whole form as readonly/disabled/static such that the user can't alter any of the controls?

16 Answers

This is an ideal solution for disabling all inputs, textareas, selects and buttons in a specified element.

For jQuery 1.6 and above:

// To fully disable elements
$('#myForm :input').prop('disabled', true); 

Or

// To make elements readonly
$('#myForm :input').prop('readonly', true); 

jQuery 1.5 and below:

$('#myForm :input').prop('disabled', 'disabled');

And

$('#myForm :input').prop('readonly', 'readonly');
<form inert>

This won't change the styling of the form but will stop all the inputs from being focusable and stop any buttons from being clickable.

Easiest way

$('#yourform .YOUR_CLASS_FOR_INPUTS').prop('readonly', true);

A simple need : display non-editable form (that can become editable later on) with minimum code and headache.

If you can't use the 'disabled' attribut (as it erases the value's input at POST), and noticed that html attribut 'readonly' works only on textarea and some input(text, password, search, as far I've seen), and finally, if you don't want to bother with duplicating all your select, checkbox and radio with hidden input logics, you might find the following function or any of his inner logics to your liking :

addReadOnlyToFormElements = function (idElement) {
    
        // textarea an input of type (text password search) work with the html readonly
        $('#' + idElement + ' textarea, #' + idElement + ' input').prop('readonly',true);
    
        // but you still have to destroy their associated objects, as I.E, datepicker (in our old project, datepicker is appended to input where 'Date' is in name attribut, don't ask why)
        $('#' + idElement + ' input[name*="Date"]').datepicker('destroy');
    
        // html readonly don't work on input of type checkbox and radio, neither on select. So, a safe trick is to disable the non-selected items
        $('#' + idElement + ' input[type="checkbox"]:not(:checked), #' + idElement + ' input[type="radio"]:not(:checked)').prop('disabled',true); 
        $('#' + idElement + ' select>option:not([selected])').prop('disabled',true);
    
        // and, on the selected ones, to disable mouse/keyoard events and mimic readOnly appearance
        $('#' + idElement + ' input[type="checkbox"]:checked').prop('tabindex','-1').css('pointer-events','none').css('opacity','0.5');
        $('#' + idElement + ' input[type="radio"]:checked').css('opacity','0.5');
        $('#' + idElement + ' select').css('background-color','#eee');
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

And there's nothing easier than to remove these readonly

removeReadOnlyFromFormElements = function (idElement) {

    // just remove the html readonly on textarea and input
    $('#' + idElement + ' textarea, #' + idElement + ' input').prop('readonly',false);

    // and restore their Objects, as I.E, datepicker
    $('#' + idElement + ' input[name*="Date"]').datepicker();

    // Remove the disabled attribut on non-selected
    $('#' + idElement + ' input[type="checkbox"]:not(:checked), #' + idElement + ' input[type="radio"]:not(:checked)').prop('disabled',false); 
    $('#' + idElement + ' select>option:not([selected])').prop('disabled',false);

    // Restore mouse/keyboard events and remove readOnly appearance on selected ones
    $('#' + idElement + ' input[type="checkbox"]:checked').prop('tabindex','').css('pointer-events','').css('opacity','');
    $('#' + idElement + ' input[type="radio"]:checked').css('opacity','');
    $('#' + idElement + ' select').css('background-color','');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

You can use an opaque layer over the form:

  1. Put position: relative on the form
  2. Add the transparent blocking div as a child of this form with position: absolute and top, bottom, left, right equal to 0

Another simple way that's supported by all browsers would be:

HTML:

<form class="disabled">
  <input type="text" name="name" />
  <input type="radio" name="gender" value="male">
  <input type="radio" name="gender" value="female">
  <input type="checkbox" name="vegetarian">
</form>

CSS:

.disabled {
  pointer-events: none;
  opacity: .4;
}

But be aware, that the tabbing still works with this approach and the elements with focus can still be manipulated by the user.

You add html invisible layer over the form. For instance

<div class="coverContainer">
<form></form>
</div>

and style:

.coverContainer{
    width: 100%;
    height: 100%;
    z-index: 100;
    background: rgba(0,0,0,0);
    position: absolute;
}

Ofcourse user can hide this layer in web browser.

To make a whole fieldset disabled conditionally in angular you can do like this:

 <fieldset [attr.disabled]="isEditable ? null : 'disabled'">
Related