¿Cómo puedo hacer que un formulario HTML completo sea de "solo lectura"?

155

Tengo dos páginas con formularios HTML. La primera página tiene un formulario de envío y la segunda página tiene un formulario de reconocimiento. El primer formulario ofrece una variedad de controles, mientras que la segunda página muestra nuevamente los datos del formulario de envío con un mensaje de confirmación. En este segundo formulario, todos los campos deben ser estáticos.

Por lo que puedo ver, algunos controles de formulario pueden ser readonlyy todos pueden serdisabled , la diferencia es que aún puede tabular a un campo de solo lectura.

En lugar de hacer este campo por campo, ¿hay alguna forma de marcar todo el formulario como de solo lectura / deshabilitado / estático de modo que el usuario no pueda alterar ninguno de los controles?

Mawg dice que reinstalar a Mónica
fuente

Respuestas:

310

Envuelva los campos de entrada y otras cosas en a <fieldset>y dele el disabled="disabled"atributo.

Ejemplo ( http://jsfiddle.net/7qGHN/ ):

<form>
    <fieldset disabled="disabled">
        <input type="text" name="something" placeholder="enter some text" />
        <select>
            <option value="0" disabled="disabled" selected="selected">select somethihng</option>
            <option value="1">woot</option>
            <option value="2">is</option>
            <option value="3">this</option>
        </select>
    </fieldset>
</form>

Klemen Tušar
fuente
2
Solución simple y grandiosa para mí. Gracias
demo
2
La mejor solución para el lado del cliente :) +1
Sisir
1
Bastante simple, esta es la mejor solución del lado del cliente hasta ahora.
brunocoelho
Nota: Esto tiene el efecto secundario de hacer que "los controles de formulario que son descendientes [de los conjuntos de campos], excepto los descendientes de su primer elemento opcional <leyenda> ... [no] reciban eventos de exploración, como clics del mouse o relacionados con el foco "( developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset ). Por lo tanto, cualquier escucha de eventos js que haya definido en descendientes puede no funcionar.
Eric Freese
2
@EricFreese Solo en estado desactivado, que es lo que desea en el 99% de los casos.
Honza Kalfus
11

No todos los elementos de formulario se pueden configurar readonly, por ejemplo:

  • casillas de verificación
  • cajas de radio
  • Subir archivo
  • ...más..

Entonces, la solución razonable sería establecer todos los disabledatributos de los elementos del formulario true, ya que el OP no indicó que el formulario "bloqueado" específico se debe enviar al servidor (que eldisabled atributo no permite).

Otra solución, que se presenta en la demostración a continuación, es colocar una capa en la parte superior del formelemento que evitará cualquier interacción con todos los elementos dentro del formelemento, ya que esa capa se establece con un z-indexvalor mayor :

MANIFESTACIÓN:

var form = document.forms[0], // form element to be "readonly"
    btn1 = document.querySelectorAll('button')[0],
    btn2 = document.querySelectorAll('button')[1]

btn1.addEventListener('click', lockForm)
btn2.addEventListener('click', lockFormByCSS)

function lockForm(){
  btn1.classList.toggle('on');
  [].slice.call( form.elements ).forEach(function(item){
      item.disabled = !item.disabled;
  });
}

function lockFormByCSS(){
  btn2.classList.toggle('on');
  form.classList.toggle('lock');
}
form{ position:relative; } 
form.lock::before{
  content:'';
  position:absolute;
  z-index:999;
  top:0;
  right:0;
  bottom:0;
  left:0;
}

button.on{ color:red; }
<button type='button'>Lock / Unlock Form</button>
<button type='button'>Lock / Unlock Form (with CSS)</button>
<br><br>
<form>
  <fieldset>
    <legend>Some Form</legend>
    <input placeholder='text input'>
    <br><br>
    <input type='file'>
    <br><br>
    <textarea placeholder='textarea'></textarea>
    <br><br>
    <label><input type='checkbox'>Checkbox</label>
    <br><br>
    <label><input type='radio' name='r'>option 1</label>
    <label><input type='radio' name='r' checked>option 2</label>
    <label><input type='radio' name='r'>option 3</label>
    <br><br>
    <select>
      <option>options 1</option>
      <option>options 2</option>
      <option selected>options 3</option>
    </select>
  </fieldset>
</form>

vsync
fuente
1
Tenga en cuenta que la solución CSS está incompleta ya que no impide la navegación del teclado.
Tanriol
7

Puede usar esta función para deshabilitar el formulario:

function disableForm(formID){
  $('#' + formID).children(':input').attr('disabled', 'disabled');
}

Vea la demostración de trabajo aquí

Tenga en cuenta que usa jQuery.

Sarfraz
fuente
+1 Gracias, pero no puedo usar soluciones del lado del cliente, vea la pregunta actualizada (lo siento, mi mal)
Mawg dice que reinstale a Mónica el
6

En la página de confirmación, no coloque el contenido en controles editables, solo escríbalos en la página.

Doobi
fuente
1
Este es realmente el enfoque más sensato. No presente un formulario no editable a un usuario, o terminará siendo una entrada en la pregunta "Menos asombro".
kibibu
1
¿cómo? ¿Cómo puedo mostrar una casilla de verificación y su condición de verificación / no marcada, o un grupo de radio con su elemento seleccionado, etc.?
Mawg dice reinstalar a Mónica el
1
@Mawg tal vez sería una opción simplemente enumerar los elementos 'seleccionados', sin casillas de verificación. Como en una confirmación de pedido de pizza: simplemente enumere todos los ingredientes que seleccionó.
marc82ch
En este caso no, pero gracias por un buen pensamiento lateral que podría ayudar a otros.
Mawg dice que reinstalar a Monica
4

No hay una forma integrada que yo sepa para hacer esto, por lo que deberá encontrar una solución personalizada dependiendo de lo complicado que sea su formulario. Deberías leer esta publicación:

Convierta formularios HTML a solo lectura ( Actualización : enlace de publicación roto, enlace archivado )

EDITAR: Según su actualización, ¿por qué está tan preocupado por tenerlo como de solo lectura? Puede hacerlo desde el lado del cliente, pero si no, tendrá que agregar la etiqueta requerida a cada control o convertir los datos y mostrarlos como texto sin formato sin controles. Si está tratando de que sea de solo lectura para que la próxima publicación no se modifique, entonces tiene un problema porque cualquiera puede meterse con la publicación para producir lo que quiera, de modo que cuando finalmente reciba los datos, será mejor que lo esté revisando. nuevamente para asegurarse de que sea válido.

Kelsey
fuente
+1 Gracias, pero no puedo usar las soluciones del lado del cliente, vea la pregunta actualizada (lo siento, mi mal)
Mawg dice que reinstale a Monica el
"Según su actualización, ¿por qué está tan preocupado por que solo se lea? Puede hacerlo desde el lado del cliente" Lo siento, pero 1) No puedo hacerlo desde el lado del cliente (no es mi elección) y 2) si parece para el usuario como si estuviera cambiando cosas que podrían confundirlo.
Mawg dice que reinstalar a Mónica el
@mawg bien si es solo para imágenes, entonces, lo único que puedo recomendar es reemplazar todos los controles en línea con su equivalente de texto o agregar la propiedad de solo lectura a los controles. No hay bala de plata y tengo la sensación de que es lo que estás buscando. ¿Puedes publicar un fragmento del código que puedes modificar? Sería útil obtener una base para lo que está trabajando.
Kelsey
+1 gracias por la sugerencia. Nunca lo había notado antes, pero debo haber completado 100 o 1,000 si los formularios y recordar vagamente una versión de solo lectura, no solo texto. Tal vez debería completar un poco más y observar :-)
Mawg dice que reinstale a Monica el
3
Sorpresa ... 6 años después, el enlace ya no funciona.
mwallisch
3

No hay una forma HTML oficial totalmente compatible para hacerlo, pero un poco de JavaScript puede ser muy útil. Otro problema con el que se encontrará es que los campos deshabilitados no se muestran en los datos POST

Michael Clerx
fuente
44
Si ya ha validado los datos, debe guardarlos del lado del servidor de todos modos. Enviarlo de un lado a otro al cliente es un gran agujero de seguridad. Incluso si usa css, js o html para congelar los campos, puede editarlos con firebug o cambiando manualmente la siguiente solicitud HTTP
Michael Clerx,
+1 Gracias, pero no puedo usar las soluciones del lado del cliente, vea la pregunta actualizada (lo siento, mi mal)
Mawg dice que reinstale a Monica el
3

Esta es una solución ideal para deshabilitar todas las entradas , áreas de texto , selecciones y botones en un elemento específico.

Para jQuery 1.6 y superior :

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

O

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

jQuery 1.5 y abajo :

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

Y

$('#myForm :input').prop('readonly', 'readonly');
Místico
fuente
2

Otra forma simple que es compatible con todos los navegadores sería:

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;
}

Pero tenga en cuenta que las pestañas aún funcionan con este enfoque y que los elementos con foco aún pueden ser manipulados por el usuario.

M. Neuweiler
fuente
1

Tener todos los identificadores de formulario numerados y ejecutar un bucle for en JS.

 for(id = 0; id<NUM_ELEMENTS; id++)
   document.getElementById(id).disabled = false; 
TTT
fuente
+1 Gracias, pero no puedo usar las soluciones del lado del cliente, vea la pregunta actualizada (lo siento, mi mal)
Mawg dice que reinstale a Monica el
1

Prefiero usar jQuery:

$('#'+formID).find(':input').attr('disabled', 'disabled');

find () iría mucho más profundo hasta el enésimo hijo anidado que children (), que busca solo hijos inmediatos.

usuario163861
fuente
1
Gracias, te votaré por intentarlo, ya que eres nuevo. PERO, tenga en cuenta que claramente pedí una solución del lado del servidor. En ese momento solo codifiqué PHP y aún no JS. Una sugerencia amigable para leer la pregunta, ya que algunos podrían despreciarlo por esto :-( Bienvenido a bordo :-)
Mawg dice que reinstale a Monica el
1

La manera más fácil

$('#yourform *').prop('readonly', true);
Samir Rahimy
fuente
es cierto, pero este es solo un ejemplo de hacha, puede cambiar su segundo selector a cualquier otro, por ejemplo $ ('# yourform .yourclass_for_inputs'). prop ('readonly', true);
Samir Rahimy
1

Agrega una capa invisible HTML sobre el formulario. Por ejemplo

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

y estilo:

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

Por supuesto, el usuario puede ocultar esta capa en el navegador web.

Marcin Żurek
fuente