Manual:HTMLForm (Tutorial 2)
El resto de esta pƔgina trata sobre el uso de HTMLForm a travƩs de entradas genƩricas $formDescriptor (configuraciones que son comunes a todos los tipos de campos).
Estamos por tanto trabajando solo en entradas HTMLTextField.
Saltar la parte genérica e ir directamente a la parte de especificación de los campos
Aquà estamos en /mediawiki/extensions/MyForm/MyForm_body.php y trabajando en la función execute()...
Punto de partida
public function execute( $par ) {
$this->setHeaders();
$this->getOutput()->addHTML( 'Hello World' );
}
AƱadir un campo simple de texto
Reemplacemos «Hello World» por un campo de texto denominado simpletextfield
public function execute( $par ) {
$this->setHeaders();
// Vector formDescriptor para indicar a HTMLForm quƩ construir
$formDescriptor = [
'simpletextfield' => [
'label' => 'Simple Text Field', // Label of the field
'class' => 'HTMLTextField', // Input type
]
];
// Construye el objeto HTMLForm
$htmlForm = HTMLForm::factory( 'table', $formDescriptor, $this->getContext() );
// Texto que mostrar en el botón de enviar
$htmlForm->setSubmitText( 'Allons-y gaiement' );
$htmlForm->show(); // Muestra el formulario
}
Ahora el formulario tiene este aspecto:
AƱadir una retrollamada
Desgraciadamente, el código anterior muestra el formulario, pero el formulario no funciona. ”Tenemos que escribir algo de lógica para procesar la entrada del formulario!
public function execute( $par ) {
$this->setHeaders();
// Vector formDescriptor para indicar a HTMLForm quƩ construir
$formDescriptor = [
'simpletextfield' => [
'label' => 'Simple Text Field', // Label of the field
'class' => 'HTMLTextField', // Input type
]
];
// Construye el objeto HTMLForm con el nombre de formulario 'myform'
$htmlForm = new HTMLForm( $formDescriptor, $this->getContext(), 'myform' );
// Texto que mostrar en el botón de enviar
$htmlForm->setSubmitText( 'Allons-y gaiement' );
// Establecemos una función de retrollamada
$htmlForm->setSubmitCallback( [ $this, 'processInput' ] );
// Llama a processInput() en tu clase que extiende SpecialPage al enviar
// Muestra el formulario
$htmlForm->show();
}
// Función de retrollamada
// Retrollamada al pulsar en enviar, aquĆ hacemos toda la lógica que queremos implementarā¦
public static function processInput( $formData ) {
// Si se devuelve 'true', no se volverĆ” a mostrar el formulario
if ( $formData['simpletextfield'] === 'next' ) {
return true;
} elseif ( $formData[ 'simpletextfield' ] === 'again' ) {
// Si se devuelve 'false', se volverĆ” a mostrar el formulario
return false;
}
// Si se devuelve una cadena, se mostrarĆ” en forma de mensaje de error con el formulario
return 'Try again';
}
Ahora, el formulario procesa los datos enviados:
MĆ©todo de envĆo
El formulario se puede configurar para utilizar ya sea el mĆ©todo de envĆo POST o GET.
- POST (predeterminado): El contenido de los campos del formulario no se muestra en la URL de la pĆ”gina. Este mĆ©todo deberĆa utilizarse para formularios que cambien el contenido del wiki (por ejemplo, editar pĆ”ginas o bloquear usuarios).
- GET: El contenido de los campos del formulario se muestra en la URL de la pĆ”gina. La URL resultante se puede guardar como marcador o enlazar para permitir que otros accedan a ella. Sin embargo, el envĆo de formularios muy largos (con varios kilobytes de texto) puede fallar. Este mĆ©todo deberĆa utilizarse para formularios que no cambien el contenido del wiki (por ejemplo, mostrar una lista de pĆ”ginas).
Si tratas de enviar los datos mediante una solicitud GET, tendrƔs que aƱadir lo siguiente:
$htmlForm->setMethod( 'get' );
Nótese que los formularios GET que utilicen un campo check o multiselect deben tener un Ā«identificador de formularioĀ» para funcionar correctamente, al igual que si estabas utilizando varios formularios en una pĆ”gina ā vĆ©ase Utilizar varios formularios en una sola pĆ”gina mĆ”s adelante.
Añadir validación
Los campos se pueden validar individualmente antes de ejecutar la función de retrollamada.
Primero se lo indicamos a HTMLForm aƱadiendo esta lĆnea:
// Llama a validateSimpteTextField() en tu clase que extiende SpecialPage
'validation-callback' => [ $this, 'validateSimpleTextField' ],
en formDescriptor:
// Vector formDescriptor para indicar a HTMLForm quƩ construir
$formDescriptor = [
'simpletextfield' => [
// Etiqueta del campo
'label' => 'Simple Text Field',
'class' => 'HTMLTextField',
// Llama a validateSimpteTextField() en tu clase que extiende SpecialPage
'validation-callback' => [ $this, 'validateSimpleTextField' ],
]
];
Entonces escribimos la lógica de validación:
public static function validateSimpleTextField( $simpleTextField, $allData ) {
if ( $simpleTextField === 'merde' ) {
return 'Excuse my French';
}
return true;
}
Ahora, la lógica de validación verifica los datos enviados antes de procesarlos:
Campo obligatorio
Puedes especificar que un campo es obligatorio sin mƔs que aƱadir
'required' => true,
al formDescriptor. Cualquier validation-callback sobreescribirÔ 'required'. Si necesitas validar un campo obligatorio, añade la siguiente lógica a tu función de validación por retrollamada:
if ( $simpleTextField === '' ) {
return wfMessage( 'htmlform-required', 'parseinline' );
}
AƱadir filtros
El filtrado se produce ANTES de la validación para cambiar la entrada.
Declaración correspondiente en formDescriptor:
'filter-callback' => [ $this, 'filterSimpleTextField' ],
Lógica de filtrado:
public static function filterSimpleTextField( $simpleTextField, $allData ) {
// AƱadir '?!?' a la entrada
return $simpleTextField . '?!?';
}
Añadir soporte de internacionalización (i18n)
Esta funcionalidad permite traducir la etiqueta al idioma definido en las preferencias de la interfaz del usuario. Basta con reemplazar 'label' por 'label-message' en formDescriptor para obtener automƔticamente la cadena a travƩs de la rutina i18n:
$formDescriptor = [
'simpletextfield' => [
// Identificador del mensaje i18n para la etiqueta del campo
'label-message' => 'myform-simpletextfield',
// Tipo de entrada
'class' => 'HTMLTextField',
'validation-callback' => [ $this, 'validateSimpleTextField' ],
'filter-callback' => [ $this, 'filterSimpleTextField' ],
]
];
No olvides aƱadir la entrada correcta en los archivos de localización. Por ejemplo, aquĆ, en inglĆ©s y francĆ©s:
"myform-simpletextfield": "International Simple Text Field"
"myform-simpletextfield": "Champ de texte simple international"
Para el botón de enviar, tenemos que hacerlo «manualmente»:
$htmlForm->setSubmitText( wfMessage( 'myform-submit' ) );
Por supuesto, como siempre, tendrÔs que añadir la entrada myform-submit en los archivos de localización.
AƱadir secciones
Ahora tendremos que añadir algunos campos y organizarlos, asà que cambiemoos a un formDescriptor de mayor tamaño.
$formDescriptor = [
'field1' => [
'section' => 'section1',
'class' => 'HTMLTextField',
'label' => 'field1',
],
'field2' => [
'section' => 'section1',
'class' => 'HTMLTextField',
'label' => 'field1',
],
'field3' => [
'section' => 'section2',
'class' => 'HTMLTextField',
'label' => 'field1',
],
'field4' => [
'section' => 'section3',
'class' => 'HTMLTextField',
'label' => 'field1',
]
];
La cadena de sección mostrada se extrae automĆ”ticamente de los archivos de localización. AquĆ, por tanto, tenemos que aƱadir esto a en.json:
{
"section1": "The First Section",
"section2": "Section II",
"section3": "Third Section"
}
Ahora el formulario tiene este aspecto:
Subsecciones
Las secciones se pueden anidar fĆ”cilmente con el increĆble poder de /.
$formDescriptor = [
'field1' => [
'section' => 'section1',
'class' => 'HTMLTextField',
'label' => 'field1',
],
'field2' => [
'section' => 'section1/subsectionA',
'class' => 'HTMLTextField',
'label' => 'field1',
],
'field3' => [
'section' => 'section2/subsectionB',
'class' => 'HTMLTextField',
'label' => 'field1',
],
'field4' => [
'section' => 'section2/subsectionC',
'class' => 'HTMLTextField',
'label' => 'field1',
]
];
Los identificadores de i18n tendrƔn esta forma:
'subsectionA'
Ahora, el formulario tiene este aspecto:
AƱadir texto de ayuda
¿Qué piensas sobre brindarles a los usuarios unas instrucciones para utilizar tu formulario con facilidad?
help o help-message (un nombre de mensaje i18n) estÔn aquà para ti.
$formDescriptor = [
'field1' => [
'section' => 'section1',
'class' => 'HTMLTextField',
'label' => 'field1',
'help' => 'Just say something!',
],
];
Ahora el formulario tiene este aspecto:
AƱadir CLASS e ID HTML
cssclass y id estÔn aquà para ti.
$formDescriptor = [
'field1' => [
'section' => 'section1',
'class' => 'HTMLTextField',
'label' => 'field1',
// AƱade a la clase del objeto contenedor
'cssclass' => 'AClassForField1',
// AƱade al objeto de entrada
'id' => 'AnIdForField1',
],
];
Cambiar el nombre de la entrada
Por defecto, el nombre de la entrada es wp{$fieldname}; para el ejemplo anterior, el nombre de la entrada es por tanto wpfield1. Esto se puede cambiar con name:
$formDescriptor = [
'field1' => [
'section' => 'section1',
'class' => 'HTMLTextField',
'label' => 'field1',
'cssclass' => 'AClassForField1',
'id' => 'AnIdForField1',
'name' => 'ANameForField1',
],
];
Simplemente para darte una idea, he aquĆ la salida HTML generada:
<tr class="mw-htmlform-field-HTMLTextField AClassForField1">
<td class="mw-label">
<label for="AnIdForField1">field1</label>
</td>
<td class="mw-input">
<input id="AnIdForField1" size="45" name="ANameForField1">
</td>
</tr>
Deshabilitar la entrada
disabled estĆ” presente y el usuario no puede modificar la entrada. (En algunos navegadores puede que no sea posible copiar el valor.) El elemento no se enviarĆ” al servidor.
'disabled' => true,
”Tan simple como eso!
Hacer que una entrada sea de solo lectura
readonly estĆ” presente, y el usuario no puede modificar la entrada. El elemento se enviarĆ” al servidor.
'readonly' => true,
De nuevo, ”tan simple como eso!
Utilizar varios formularios en una sola pƔgina
| Versión de MediaWiki: | ≥ 1.28 |
Si utilizas varios formularios en una sola pÔgina especial (por ejemplo, uno para mostrar resultados de búsqueda y otro para modificar un resultado), tienes que establecer un «identificador de formulario» para permitir que HTMLForm detecte cuÔl de los formularios se estÔ enviando. El identificador puede ser cualquier cadena, y debe ser diferente para cada formulario.
$htmlForm->setFormIdentifier( 'myform1' );
Por motivos tƩcnicos, esto tambiƩn es necesario a la hora de utilizar un campo check o multiselect en un formulario GET; de otra manera, HTML no podrƔ detectar quƩ formulario se ha enviado y por tanto si debe cargar los valores predeterminados o no.[1]
PĆGINA SIGUIENTE DEL TUTORIAL





