El API de CakePHP: FormHelper::input
No hay mejor manera aprender a usar un framework como CakePHP que ver el código fuente.En esta oportunidad revisaré la función input del FormHelper.
De una discusión del grupo CakePHP-esp me ha surgido la idea para este post (y dependiendo de la audiencia, podría convertirlo en una serie).
CakePHP 1.2 presenta, en su helper Form, una función muy poderosa para crear los campos de un formulario.
El primer parámetro de esta función debe ser el nombre del campo de la tabla que deseamos solicitar al usuario. Por ejemplo:
Teniendo una tabla person con un campo name VARCHAR(140) NOT NULL
Generará un campo input de tipo texto cuya longitud máxima es 140 y será requerido.
Ahora bién, toda ese conocimiento lo saca Cake de la base de datos. Sin embargo, la función ofrece al desarrollador un el segundo parámetro con el cual modificar el resultado. El parámetro $options, el cual debe ser un arreglo asociativo (los índices son strings):
- type – permite modificar el tipo de campo a crear, los valores para este índice pueden ser: checkbox, radio, text, password, file, select, time, date, datetime y textarea
- Si no se indica, CakePHP trata de adivinarlo a partir de la definición del campo en la base de datos.
- Si no se indica y el nombre del campo es psword, passwd, o password, type será password.
- Si en el controlador se hace una llamada a Controller::set con una variable cuyo nombre sea el plural del campo, cake utilizará type=’select’ (se puede forzar a que sea ‘radio’).
Por ejemplo:
- options – arreglo de pares para popular campos de seleccion (select, checkbox y radio). Si este campo se indica pero type no, entonces será ‘select’. El ejemplo anterior, se puede hacer sin modificar el controlador, de la siguiente manera:
- maxlength – este campo permite limitar el número de caracteres que puede insertar el usuario en el campo (por supuesto, sólo es válido si type es ‘input’).
- timeFormat – permite definir el formato en el que se introducirá el tiempo (campos de tipo ‘time’ o ‘datetime’ sólamente).
- Los valores posibles son 24, 12 o NONE
- dateFormat – permite definir el formato en el que se introducirán las fechas (campos de tipo ‘datetime’ y ‘date’ sólamente)
- Los valores posbiles DMY, MDY, YMD o NONE
- selected – opción (el valor, no el texto visible) pre-seleccionada (sólo en campos de tipo ‘select’).
- Los campos de tipo ‘date’, ‘datetime’ y ‘time’ también aceptan este índice. El valor debe expresarse en formato estandar de fechas: ‘Y-m-d’, ‘Y-m-d H:M:S’ o ‘H:M:S’
- Para fechas y tiempos, selected puede ser un arreglo asociativo. Los índices válidos son: day, month, year, hours, minutes, seconds y meridian (am o pm)
- multiple – sólo para campos select. Indica si es un select mútiple o no (true, false).
- Si el select es múltiple, selected puede ser un arreglo con varias entradas para cada valor seleccionado)
- empty – sólo para campos select. Indica si el select tendrá un primer valor vacío.
- label – permite al desarrollador seleccionar el texto que identifica al campo.
- El valor de este índice también puede ser un arreglo asociativo cuyos índices pueden ser: text y otros atributos html propios del tag label (for, class, id, style, etc).
- div - permite definir las características del div que rodea al input y al label.
- Si se indica false, cake no crea el div.
- Si se indica un string, se selecciona como valor del atributo class (en lugar de type que se usa normalmente).
- Si es un un arreglo asociativo, se admiten los siguientes índices:
- class - sustituye en el atributo class el valor por defecto (type).
- tag – nombre del tag a usar en lugar de div (p, span, etc…)
- otros atributos html para el div.
- id – atributo id del input. Cake cambia automáticamente el atributo for del label.
- Utilizar algo distinto a un string es malo para la accesibilidad ya que hace que el atributo for del label falle.
- before – texto que aparecerá antes del label
- between – texto que aparecerá después del label.
- after – texto que aparecerá después del input.
Esas son todas los parámetros que pude detectar luego de ver por un ráto el tan temido API de CakePHP. Si encuentras que algún dato es incorrecto notificamelo en los comentarios.
Si te pareció interesante esta entrada y te gustaría que haga una serie, deja un comentario también indicando qué funciones te parecen interesantes.
Recibe otros artículos como este automáticamente
Suscríbete vía RSS a aikon.com.ve ||
¿Qué es RSS?
Puedes poner un ejemplo con select?
Por ejemplo, una opción de select con datos estaticos.. (“activo”, “inactivo”)
gracias de antemano
diciembre 3, 2008 // 12:43
Hola Carlos,
Pensé que con el ejemplo en la sección *type* estaba claro. De todos modos he agregado el ejemplo que pides.
Saludos
diciembre 3, 2008 // 17:06
Muy bueno tu aporte. Te pregunto: se puede modificar el nombre del archivo ahi mismo. como?
Necesito hacer un sitio donde se pueda subir fotos, estoy usando el upload behaviour, y cuanto hay dos fotos que se llaman igual no me las sube. Entonces si le puedo modificar el nombre antes de que actue el behaviour…
Muchas gracias.. espero haber sido claro.
diciembre 10, 2008 // 14:12
Cristo,
Lo que preguntas no se puede lograr con el FormHelper, probablemente debas hacerlo a nivel del modelo: tal vez modificando los datos (y los archivos) en beforeSave.
Saludos
diciembre 10, 2008 // 14:31
Hola Joaquín,
En relación con la interesante descripción que has dado quisiera plantear la siguiente cuestión:
Tenemos 2 tablas:
‘notas’ (id, titulo, texto, tema_id) que contiene descripciones que me interesan: y
‘temas’ (id, tema) que contiene la clasificación de los textos que inserto en ‘notas’: recetas de cocina, electrónica, mecánica, etc.
Por lo tanto, tema_id en ‘notas’ es foreign key procedente de id en ‘temas’.
En los formularios de creación y edición de ‘notas’, por cada nota se pide: título de la nota (titulo), texto de la nota (texto) y tema (tema_id).
Para facilitarle la vida al usuario, al insertar el tema de la nota, queremos mostrarle un desplegable que visualice los temas: recetas de cocina, electrónica, mecánica, etc., le permita seleccionar uno y guarde en la tabla una fila pero con la foreign key numérica que tenemos en ‘temas’.
Es decir visualizamos la lista de temas pero lo que guardamos es la id del tema.
La descripción que has dado me sugiere que en CakePHP habría que utilizar un ‘select’, pero ¿cómo se le indica a CakePHP que visualice la lista de temas y lo que guarde sea el id del tema?.
Este asunto parece esencial para evitar tener que recordar id asociados a temas.
Gracias por adelantado.
diciembre 18, 2008 // 5:20
En el controlador debes hacer
$this->set('temas', $this->Nota->Tema->find('list'));Esto va a hacer disponible en la vista la variable $temas que tiene la lista de temas en el formato adecuado para que al guardar se guarde el id en el campo ‘tema_id’.
Saludos
diciembre 18, 2008 // 21:18
Cómo llenar las listas de selección en CakePHP:
[...] poco les hablé sobre FormHelper::input de CakePHP y en los comentarios recibí la pregunta de cómo lograr rellenar con valores de la base de datos [...]
diciembre 18, 2008 // 22:59
Gracias por tu respuesta. Efectivamente, el ejemplo sobre ‘notas’ y ‘temas’ ha funcionado.
He acabado usando Bake, que produce el form directamente. Es asombroso el ahorro de tiempo de codificación ‘a mano’.
diciembre 19, 2008 // 13:22
Hola Paco,
Me alegra que haya te funcionado. Y genial que utilices bake, te ahorra mucho tiempo en código que no es necesario escribir y escribir! Terminas con un codigo PHP más uniforme y manejable.
Te agradezco también por inspirar una entrada al respecto de cómo llenar las listas de selección en CakePHP.
Saludos
diciembre 19, 2008 // 22:36
Hablando de bake, ¿alguien conoce alguna herramienta como el bake pero gráfica?
febrero 23, 2009 // 7:28
Felipe, si usas mac: http://www.widgetpress.com/modelbaker
febrero 23, 2009 // 10:19
Hola.Esta muy buena la información pero
tengo una consulta tengo el siguiente form,
input(‘RedeemItem.description’,array(‘type’=>’textarea’,'size’ => ’100′,’maxlength’=>225));?>
pero no cumple la condición del maximo de texto, que puedo hacer? Gracias
abril 15, 2009 // 13:30
Hola yoxs,
Los textarea no tienen un atributo que pueda determinar la maxima longitud del texto (es una limitacion de HTML, no de CakePHP). La opcion basica es usar una regla de validacion para que cake notifique al usuario del la limitacion. La otra opcion – adicional – es usar javascript, por ejemplo: http://www.shiningstar.net/articles/articles/javascript/dynamictextareacounter.asp
abril 15, 2009 // 14:30
ok si ya le implemente javascript que habia encontrado antes, es que pense que si existia la opcion, pero muchas gracias.Estare consultando por aca si no hay problema.
abril 15, 2009 // 16:01
No hay problema, bienvenido!
abril 15, 2009 // 16:12
Es más estoy buscando manipular el objeto select, como se le asignan el array de atributos, es que necesito uno que muestre numeros de 1 a 20 es para seleccionar cantidad de productos, y luego el numero elegido pase a otra vista.Imagino que podars ayudarme y de ante mano te lo agradesco.
abril 15, 2009 // 16:13
jejej seria bievenida
abril 15, 2009 // 16:14
Entonces me corrijo: bienvenida! jajaja
En el segundo parametro de la funcion puedes pasar el parametro ‘options’ => array(1,2,…,20) y eso deberia generar el select con 20 opciones.
tambien sirve: ‘options’ => range(1,20)
abril 15, 2009 // 16:23
muchas gracias, ya lo estaba haciendo de manera muy tediosa jeje.
Una consulta más, tengo un bonton que me lleva a otra vista y necesito que lleve el id de un articulo, cuando hacia una lista de links solo bastaba con mandarlo asi :
link($re['RedeemItem']['title'],’/admin/redeem_items/view_redeem/’.$re['RedeemItem']['id']); ?>
Pero ahora es un boton el que me lleva a esa vista y necesito que lleve el id de ese producto en especifico. No se si me entiendes.
abril 15, 2009 // 17:56
Tienes 2 opciones:
1) Cambiar el url al que apunta el form:
http://api.cakephp.org/class/form-helper#method-FormHelpercreate
En este caso la accion recibiria el valor como un parametro de la funcion.
2) Agregar un campo hidden
input(‘id’, array(‘type’ => ‘hidden’, ‘value’ => $id))
En este caso el valor viene en $this->data
abril 15, 2009 // 18:13
sip, ya tenia eso. lo que hice fue ponerlo aqui.y funciono sin embargo gracias.
$form->create(‘RedeemItem’, array(‘action’=>’redeem_confirm/’.$item['RedeemItem']['id']))?>
Muy buena pagina me habia costado encontrar una. je
abril 15, 2009 // 18:23
hola nose si viene al caso, es que necesito un consejo sobre el metodo round()
pues tengo valores que aveces vienen 3.00 por ejemplo, y quiero que muestre los ceros pero, apesar de que lo pongo asi:
cuando trae ceros no los coloca. Si los decimales son difrentes de cero no hay problema.
abril 16, 2009 // 10:36
asi lo pongo.
round($total,2)
abril 16, 2009 // 10:38
Revisa esto: http://www.phpreferencebook.com/tag/sprintf/
abril 16, 2009 // 10:48
gracias use numeric_format().
abril 16, 2009 // 12:07
Hola tengo una duda… yo tengo maquetado el diseño de un formulario pero cada input tiene una clase definida… por ejemplo
Intento que al usar cakePHP salga lo mismo en los formularios pero no lo he conseguido… puedes ayudarme con eso? te lo agradeceré mucho..
Saludos
abril 18, 2009 // 12:53
Hola Zully, no puedes postear html en los comentarios… disculpa esa.
En el segundo parámetro ($opsitons) puedes usar:
‘div’ => array(‘class’ => ‘miclase’)
Saludos
abril 18, 2009 // 19:44
Hola de nuevo. Disculpa la molestia me gustaria un consejo de como hacer un objeto(calendario) que simplemente me de la fecha en un campo de texto para poder generar una busqueda de un historial. Lo estaba intentando con un codigo en javascript pero se me complico, si me pudieran dar algun consejillo. Gracias
abril 20, 2009 // 10:11
Ya lo solucione,,,,de todos modos gracias.
abril 20, 2009 // 12:36
tengo el siguiente error.
Fatal error: Call to a member function numbers() on a non-object in C:\wamp\www\gold-pay\app\views\elements\transaction_history.thtml on line 8
y sucede al mover la linea que crea un form.es extraño
abril 20, 2009 // 14:41
Que tienes en la linea 8 de transaction_history.thtml?
Por cierto, deberias empezar a usar CakePHP 1.2
abril 20, 2009 // 14:52
echo $paginator->numbers();
abril 20, 2009 // 14:55
$paginator es null o lo sobreescribiste con algo…
Puede ser que no has llamado $this->paginate en el controlador
abril 20, 2009 // 15:02
algo como esto?
$data = $this->paginate(‘Transaction’);
$this->set(compact(‘data’));
ya lo habia puesto es que lo extraño es que en esa vista nose usa, lamenos eso creo
abril 20, 2009 // 16:20
Pega tu codigo del la accion aca (y cualquier cosa que creas importante): http://bin.cakephp.org/
abril 20, 2009 // 16:26
listo
abril 20, 2009 // 17:07
cual es el url que genero?
abril 20, 2009 // 17:10
oooooo….creo que ya
abril 20, 2009 // 17:16
$totals = $this->find( ‘all’, array(
‘conditions’ => array(
‘OR’ => array(‘Transaction.user_id ‘ => 1, ‘transaction_type_id ‘ => 12),
‘Transaction.status ‘ => ‘cancel’
),
‘fields’ => array(‘Transaction.transaction_type_id’,'TransactionType.name’, ‘SUM(Transaction.amount) as total’),
‘group’ => ‘Transaction.transaction_type_id’
));
TENGO ESTA CONDICION ANTERIOR EN EL MODELO, COMO AGREGARIAS ESTA OTRA PARTE DE LA CONDICION,
ES QUE NO PUEDO CON EL array_push().
array(‘Transaction.date BETWEEN ? AND ?’ => array($dateMin,$dateMax)
gracias
abril 20, 2009 // 18:04
Hola Yoxs,
Creo que en cake (1.2) lo indicas
array(‘Transaction.date BETWEEN’ => array($dateMin, $dateMax)
Nunca he usado el operador BETWEEN en cake, pero debe seguir el mismo estilo que el resto de los operadores en cake
abril 20, 2009 // 18:56
sip es que no da error , epro parece no estar haciendo la consulta….mmmm voy a buscar entonces }
gracias
abril 21, 2009 // 9:30
sabes como poner en read-only, un form es que ‘disable’ no funciona pero al refrescar pierde la información.
gracias y perdona las molestias
abril 21, 2009 // 12:14
usa ‘readonly’ => true
abril 21, 2009 // 12:27
muy amable, gracias
abril 21, 2009 // 12:33
se puede tener varios forms que se dijiran ala mismo metodo en el controlador pero que tengan diferentes botones y dos de esos forms contengan campos hidden. Sin importar que estos tengan el mismo nombre.
abril 21, 2009 // 13:53
No puedes tener campos con el mismo nombre. Y si, puedes tener varios forms con la misma accion: solo que debes tener una manera de detectar las diferencias para hacer cosas distintas con cada uno (un campo hidden, o un parametro adicional en la accion – en cuyo caso ya no seria la misma accion)
abril 21, 2009 // 13:57
mmmm sip, mejor lo hice con javascript…., enviandole los parametros por medio de un metodo.
Por cierto sabes de algun metodo en javascript para generar la fecha, es que con la clase date hay que hacer varias condiciones para obtener la deseada.
abril 21, 2009 // 15:18
ya las puse,,,,,gracias
abril 21, 2009 // 18:25
hola, espero no molestar de causalidad sabes como puedo preguntar en una consulta en cakephp con el metodo find , si un campo es igual a nulo.:)
abril 24, 2009 // 14:54
yap,,,
abril 24, 2009 // 15:09
Hola Yoxs,
Disculpa que no pude atenderte hoy, estuve todo el día offline. Te agradezco tu atención
Debería hacer un chat sólo para ti
Sería bueno que dejes las soluciones a tus dudas cuando las encuentres, así todos aprendemos.
abril 24, 2009 // 21:28
jjeje es que me da verguenza:) porque son muy simples mis preguntas, y pues las respuestas pues imagino son fáciles por eso no pongo las soluciones,,,
Por eso volvi jejej espero no moleste hoy,,, es uqe necesito poner el metodo onchange en el select pero es que no se en que array debo hacerlo.
mmmm
abril 28, 2009 // 13:34
ah estaria genial lodel chat jejej
abril 28, 2009 // 13:35
creo que es es el tercer array verdad?
abril 28, 2009 // 13:38
yap,,,,si ese era, para llamar un metodo de javascript y cambie el estado de otro combo.
array(“onchange”=>”getIndex()”)
abril 28, 2009 // 13:44
Hola, quisiera preguntar en el caso de que yo tenga en mi form tenga una lista o un select de seleccion multiple y quiera guardar los seleccionados en una tabla como lo haria?…
por ejemplo tengo una relacion N:N entre rubros y subrubros… donde obviamente un rubro puede tener muchos subrubros y un subrubro puede pertenecer a mas de un rubro… yo quiero tener para un rubro (en un formulario) una lista de seleccion multiple que me muestre todos los subrubros disponibles y asi podes serleccionar los subrubros que componen a ese rubro… es decir… para un rubro de la tabla rubro mostrar una lista con todos los subrubros y guardar los seleccionados en RxS (donde RxS es la tabla para la relacion muchos a muchos) como lo deberia hacer? alguna idea?
espero que se haya entendido
Atte
Nicolas
mayo 9, 2009 // 14:21
estupendo el artículo, gracias por ayudar a la comunidad.
febrero 28, 2010 // 9:03
saludos muy bueno tu post, tengo un problema al hacer el select tengo:
echo $form->input(‘idiomas’, array( “type” => “select”, “options” => $listaIdiomas));
donde listaIdiomas es mi arreglo que guarda todos los valores de la base d datos pero quiero que se guarde en la tabla tal cual se muestra en pantalla, pero guarda es el indice, intenté con:
echo $form->input(‘idiomas’, array( “type” => “select”, “options” => $listaIdiomas, “value” =>$listaIdiomas));
pero no funca igual.
otra pregunta es como puedo hacer consultas propias usando el find(), que incluyan 2 tablas o mas por ejemplo.
febrero 3, 2011 // 18:54
@david
Si quieres que se guarde en la tabla “Español” en lugar de “1″ tienes que hacer que $listaIdiomas sea
array(“Español” => “Español”, …)
Sin embargo no te lo recomiendo, si tienes una tabla idiomas la idea es que sea una referencia (relación) a esta tabla. Ahora si es una lista fija de idiomas entonces puedes crear esa lista como una arreglo y guardar en la base de datos el indice correcto.
En cuanto a las búsquedas, si defines correctamente las relaciones entre los modelos Cake debería traer la información completa.
febrero 7, 2011 // 11:29
hola… como puedo comparar el mes de una fecha que obtengo de la base de datos, con un mes que cargo de un array $meses=array(’01′,’02′,’03′,’04′,’05′,’06′,’07′,’08′,’09′,’10′,’11′,’12′). Estoy haciendo una consulta donde obtenga el numero de casos positivos o falsos $resultado_ggex=array(‘V’,'F’) registrados por meses, algo asi:
for ($i=0; $i<count($resultado_ggex);$i++){
for ($j=0; $j Diagnostico -> find(‘count’, array( ‘conditions’ => array( ‘Diagnostico.resultado_ggex’ => $resultado_ggex[$i], date_format(date_create(strtotime(‘Diagnostico.fecha_lectura_microscopica’)),’m')=>$meses[$j])));
}
}
no se si esto sea correcto…
febrero 23, 2011 // 18:38
Perdon el codigo no salio completo
for ($i=0; $i<count($resultado_ggex);$i++){
for ($j=0; $j Diagnostico -> find(‘count’, array( ‘conditions’ => array( ‘Diagnostico.resultado_ggex’ => $resultado_ggex[$i], date_format(date_create(strtotime(‘Diagnostico.fecha_lectura_microscopica’)),’m')=>$meses[$j])));
}
}
Les agradeceria mucho, cualquier sugerencia.
febrero 23, 2011 // 18:40
Hola Comunidad, estoy leyendo de un archivo excel el contenido que debe ser insertado en una base de datos, Sin embargo tengo un pequeño problema con
la clave foránea de los modelos. y no se insertan en las tablas….
por ejemplo el Dominio está asociado a Norma ¿pero cómo le asigno el idNormas al modelo Dominio automáticamente si no es leído desde el archivo de excel ?
hice un for que recorre el archivo de excel de esta manera:
for ($i = 0; $i < 2; $i++) {
for( $j = 0; $j sheets[0]['cells'][$i + 1][$j + 1];
for ($k = 0; $k < 4; $k++) {
for( $l = 0; $l sheets[0]['cells'][$k + 1][$l + 1];
for ($m = 0; $m < 6; $m++) {
for( $n = 0; $n sheets[0]['cells'][$m + 1][$n + 1];
for ($o = 0; $o < 8; $o++) {
for( $p = 0; $p sheets[0]['cells'][$o + 1][$p + 1];
}
}
}
}
}
}
}
}
pr($product); exit();
return $product;
y al imprimir la variable $product me imprime lo siguiente:
Array
( [Norma] => Array
(
[nombrenormas] => Los Mandamientos
[detallesnormas] => Leyes Religiosas
)
[Dominio] => Array
(
[nombredominios] => 1.-Amar a Dios sobre todas las Cosas.
)
[Objetivogeneral] => Array
(
[nombreObjetivo] => 1.1-Ama a tu prójimo como a ti mismo
)
[Objetivoespecifico] => Array
(
[nombreObjetivoE] => 1.1.1 Con toda la mente y con todo el corazón
)
)
pero no deberia estar asi, sino que en cada modelo le debo asignar su respectiva asociación. Por ejemplo digo yo que sería así:
Array
( [Norma] => Array
(
[nombrenormas] => Los Mandamientos
[detallesnormas] => Leyes Religiosas
)
[Dominio] => Array
(
[nombredominio] => 1. – Amar a Dios Sobre todas las cosas
[Norma_id] => 02
)
[Objetivogeneral] => Array
(
[nombreObjetivo] => 1.1-Ama a tu prójimo como a ti mismo
[Dominio_id] => 04
)
[Objetivoespecifico] => Array
(
[nombreObjetivoE] => 1.1.1 Con toda la mente y con todo el corazón
[ObjetivoGeneral_id] => 06
)
pero no se cómo ni donde hacerlo…. en el ciclo for de la clase MY_READER_excel? o en el Controlador al Cargar el Archivo?….
Bueno, no se si me puedan ORIENTAR…. gracias…
marzo 15, 2011 // 16:26
saludos gente de este foro les tengo una pregunta hay alguna manera de poner los elementos de un formulario que estén de manera horizontal, ejemplo pongo un campo nombre y justo al lado derecho este un campo de apellido porque veo que en cakephp nada mas coloca los campos uno tras de otro de manera vertical
cakephp los coloca asi:
Nombre:[ ]
Apellido:[ ]
Me gustaria tenerlos asi:
Nombre:[ ] Apellido:[ ]
Disculpen si la pregunta es tonta jejejejeje
mayo 4, 2011 // 10:26