Cómo hacer un campo de solo lectura usando hook_form_alter

12

Estoy tratando de hacer que algunos de los campos del formulario de perfil de Drupal sean de solo lectura en el modo de edición. Estoy usando el siguiente código en hook_alter

$form[field_organisation_company_name][und][0]['#after_build'][]='_build_element_readonly';

function _build_element_readonly($element, &$form_state) {  
    $element['value']['#attributes']['readonly'] = 'readonly';
    return $element;
}

En la interfaz de usuario presentada se muestra como de solo lectura, pero aún así, puedo cambiar el valor usando firebug y guardar. ¿Hay alguna forma de prevenir este comportamiento?

Jayesh Jose
fuente

Respuestas:

6

Parece que podría lograr lo que necesita con los permisos de campo . Campo por campo, puede establecer permisos para:

  • Crear valor propio para el campo
  • Editar valor propio para el campo
  • Editar el valor de cualquier persona para el campo
  • Ver valor propio para el campo
  • Ver el valor de cualquier persona para el campo

Por lo tanto, podría permitir fácilmente a sus usuarios crear el valor para el campo inicialmente, pero tan pronto como lo tengan, solo será editable por un administrador.

Clive
fuente
+1. Como OP quiere permitir a los administradores editar el valor, field_permissionssería más fácil que hacer el trabajo de manera sucia.
AyeshK
Sí, esta es una respuesta mucho mejor que la mía :)
Alfred Armstrong
6

Cuando configura un campo como readonly, el navegador bloquea el campo y envía los datos de vuelta al servidor al enviarlo. Otro atributo es disabledque bloquea el campo y no envía datos al servidor.

Para ambos casos, puede establecer forzosamente el valor para que sea el mismo después del envío. Por lo tanto, incluso cuando el campo se establece en readonlyo disabled, y el usuario modificó el HTML y envió datos diferentes, $form_state['values']permanecerá sin cambios.

function _build_element_readonly($element, &$form_state) {  
    $element['value']['#attributes']['readonly'] = 'readonly';
    $element['value']['#value'] = isset($element['value']['#default_value']) 
       ?  $element['value']['#default_value']
       :  ''; 
    return $element;
}

Tenga en cuenta que establecemos #value desde #default_value. #default_value es la forma habitual de establecer el valor predeterminado que se carga cuando se crea el formulario, y $form_state['values']contendrá el valor predeterminado o la entrada del usuario. Cuando configura #valueexplícitamente, la entrada del usuario se ignora y #valuese utilizará.

De todos modos, recomiendo usar '#access' => FALSE,al ocultar elementos de formulario. Eliminará el elemento por completo, mientras le permite utilizar sus valores.

AyeshK
fuente
1

No puede evitar que Firebug cambie los campos de solo lectura. Pero si el campo de texto es de solo lectura, su único propósito es mostrar datos. Entonces, ¿por qué no cambiar el elemento de entrada contra un elemento de texto?

En su lugar, podría usar el atributo "deshabilitado", porque los campos de entrada deshabilitados no se envían al servidor.

¡También puede eliminar el atributo "deshabilitado" con firebug, pero el núcleo de drupal no reacciona ante los cambios de los campos de entrada deshabilitados!

larrydahooster
fuente
Gracias larrydahooster por la ayuda. Mi requisito es algo así como bloquear algunos de los campos rellenados por el usuario en el momento del registro. Mientras está en el modo de edición de perfil, desea mostrar esta información al usuario, pero quiere evitar que el usuario actualice estos campos. Solo el súper usuario puede editar estos campos
Jayesh Jose
1

La forma más segura de hacer esto es cambiar el tipo de campo para que sea un 'elemento'. http://api.drupal.org/api/drupal/developer!topics!forms_api_reference.html/7#item

Alfred Armstrong
fuente
Usando el atributo #disabled resuelvo el problema. En mi caso, solo algunos usuarios pueden editar el campo, mientras que otros solo pueden ver el campo. Escribí una lógica basada en el rol del usuario y resolví el problema. Gracias a todos
Jayesh Jose
1

Puede usar Permisos de campo + Solo lectura de campo .

Los permisos de campo le permitirán hacer que algunos de sus campos no sean accesibles para ciertos usuarios.

Field Readonly le permitirá mostrar los campos no accesibles como elementos de solo lectura en los formularios de edición (en lugar de ocultarlos).

anrikun
fuente
1

Creo que usar #disabled = true;es la forma más fácil de lograr esto en lugar de agregar algún módulo pesado a su núcleo, como ejemplo, deshabilito la edición del campo de imagen personalizado en user_profile_form cuando el usuario lo llena antes.

function MY_CUSTOM_MODULE_form_alter(&$form, $form_state, $form_id){

        if($form_id == 'user_profile_form'){
            if($form['field_national_front']['und'][0]['#default_value']['fid']){
                $form['field_national_front']['und']['#disabled'] = true;
             }
          //ym($form);
        }
}

Además, puede verificar el rol de usuario y simplemente deshabilitar (campo de solo lectura) para usuarios no administradores.

    function MY_CUSTOM_MODULE_form_alter(&$form, $form_state, $form_id){
       global $user;
       if($form_id == 'user_profile_form'){
           if($form['field_national_front']['und'][0]['#default_value']['fid'] && !in_array('webadmin', $user->roles)){
              $form['field_national_front']['und']['#disabled'] = true;
         }
//ym($form);
    }
}
Yusef
fuente