una poner modelos imagen formularios example dinamicos como botones activeform php yii

php - poner - yii2 formularios dinamicos



Mejor práctica de asistente de formulario de página de Yii (2)

Hay un par de formas de abordar esto. Te veo publicado en el foro de Yii, así que supongo que también has buscado por allí, pero en caso de que no lo hayas hecho:

Lo que he hecho es (solo para un simple formulario ActiveRecord de 2 pasos) tomar una sola acción y dividirla en bloques condicionales basados ​​en el nombre del botón, que YTI POSTs en un formulario enviado (nota: no funciona con ajax submits ) Luego, dependiendo del botón al que se presionó, presento la forma correcta y establezco el escenario correcto en mi modelo para fines de validación.

Un campo de "paso" oculto como el que usted tiene podría servir para el mismo propósito que la comprobación del nombre de submitButton. Tal vez guarde el "paso" en el estado de formulario en lugar de agregar un campo oculto, pero cualquiera estaría bien.

Algunas personas usan el atributo stateful activeForm para guardar los datos de un solo paso en el asistente, o puede usar la sesión, o incluso guardar en una tabla de base de datos temporal. En mi ejemplo completamente no probado, estoy usando la funcionalidad de formulario con estado.

Aquí hay un ejemplo de lo que hice básicamente para un formulario ActiveRecord. Esto va en el "actionCreate":

<?php if (isset($_POST[''cancel''])) { $this->redirect(array(''home'')); } elseif (isset($_POST[''step2''])) { $this->setPageState(''step1'',$_POST[''Model'']); // save step1 into form state $model=new Model(''step1''); $model->attributes = $_POST[''Model'']; if($model->validate()) $this->render(''form2'',array(''model''=>$model)); else { $this->render(''form1'',array(''model''=>$model)); } } elseif (isset($_POST[''finish''])) { $model=new Model(''finish''); $model->attributes = $this->getPageState(''step1'',array()); //get the info from step 1 $model->attributes = $_POST[''Model'']; // then the info from step2 if ($model->save()) $this->redirect(array(''home'')); else { $this->render(''form2'',array(''model''=>$model)); } else { // this is the default, first time (step1) $model=new Model(''new''); $this->render(''form1'',array(''model''=>$model)); } ?>

Los formularios se verían así:

Formulario 1:

<?php $form=$this->beginWidget(''CActiveForm'', array( ''enableAjaxValidation''=>false, ''id''=>''model-form'', ''stateful''=>true, )); <!-- form1 fields go here --> echo CHtml::submitButton("Cancel",array(''name''=>''cancel''); echo CHtml::submitButton("On to Step 2 >",array(''name''=>''step2''); $this->endWidget(); ?>

Forma 2:

<?php $form=$this->beginWidget(''CActiveForm'', array( ''enableAjaxValidation''=>false, ''id''=>''model-form'', ''stateful''=>true, )); <!-- form2 fields go here --> echo CHtml::submitButton("Back to Step 1",array(''name''=>''step1''); echo CHtml::submitButton("Finish",array(''name''=>''finish''); $this->endWidget(); ?>

¡Espero que sea de ayuda!

Intento crear un formulario de varias páginas con Yii, pero soy bastante nuevo en PHP y Yii y me pregunto cuál es la mejor práctica para escribir un formulario de varias páginas. Hasta ahora, lo que planeo hacer es agregar un campo oculto llamado ''paso'' que contiene el paso actual en el que está el usuario en el formulario (el formulario está dividido en 3 pasos / páginas). Entonces, con eso en mente, así es como planeo manejar al usuario haciendo clic en los botones anterior / siguiente en el Controlador:

public function actionCreate() { $userModel = new User; $data[''activityModel''] = $activityModel; $data[''userModel''] = $userModel; if (!empty($_POST[''step''])) { switch $_POST[''step'']: case ''1'': $this->render(''create_step1'', $data); break; case ''2'': $this->render(''create_step2'', $data); break; }else { $this->render(''create_step1'', $data); } }

¿Este enfoque tiene sentido? ¿O estoy fuera de la base y hay una forma mucho mejor y más optimizada de hacerlo en Yii / PHP?

¡Gracias!


Yii proporciona una función llamada estados de página para implementar cosas como un asistente de formulario de múltiples pasos / múltiples páginas.

Echemos un vistazo a los documentos Yii primero:

Un estado de página es una variable persistente en las solicitudes POST de la misma página. Para utilizar estados de página persistentes, los formularios deben ser con estado, que se generan mediante {@link CHtml :: statefulForm}.

Entonces las formas de cada paso / página deben ser formas con estado. Para generar una forma con estado, solo necesita establecer la propiedad CActiveForm::stateful en true cuando inicia el widget ActiveForm. Dentro de su controlador puede obtener y establecer sus estados de página con CController::getPageState() o CController::setPageState() .

Así que estos son los conceptos básicos que funcionan bastante bien si la implementación de su asistente de formularios de varias páginas se realiza en el estilo tradicional sin solicitudes AJAX.

Sin embargo, si desea utilizar las llamadas AJAX para enviar datos de paso y mostrar el siguiente paso, los estados de la página de Yii no se pueden utilizar.

¿Por qué? Todos los estados de la página se transportan a través de HTTP-POST dentro de un campo de entrada oculto. El campo de entrada se llena con Yii mientras se procesa la salida. El procesamiento de salida comienza después del renderizado y reemplazará partes de la salida. Así que la función de estados de página de Yii requiere el procesamiento de salida . Por otro lado, las respuestas AJAX pueden corromperse porque el procesamiento de salida también puede agregar etiquetas <link> o <script> al comienzo de la salida para cargar los archivos JS y CSS necesarios.

Al final implementé mi propia versión de formularios con estado. Puedo obtener mis datos con estado con la función estática llamada ActiveFormWidget::getRequestMultiStepData() cada vez que lo necesito.

Aviso: Hay una desventaja en mi implementación: todos los datos con estado deben recopilarse antes de que se inicialice el widget de formulario. Pero nunca tuve un problema con eso hasta ahora. Sin embargo, aquí está el código:

class ActiveFormWidget extends CActiveForm { public static $inputNameMultiStepData = ''_multiStepData''; public $multiStep = false; public $multiStepData = array(); public function init() { parent::init(); # Hidden-Fields if ($this->multiStep) { echo Html::hiddenField(static::$inputNameMultiStepData, static::encodeInputData($this->multiStepData)); } } /** * Gets all multi step data sent. * @return array|mixed */ public static function getRequestMultiStepData() { return isset($_REQUEST[static::$inputNameMultiStepData]) ? static::decodeInputData($_REQUEST[static::$inputNameMultiStepData]) : array(); } /** * Encodes form data like Yii does for stateful forms. * @param $data * @return string */ public static function encodeInputData($data) { $data = Yii::app()->getSecurityManager()->hashData(serialize($data)); return base64_encode($data); } /** * Decodes form data like Yii does for stateful forms. * @param $data * @return bool|mixed */ public static function decodeInputData($data) { $data = base64_decode($data); $data = Yii::app()->getSecurityManager()->validateData($data); if ($data !== false) { return unserialize($data); } else { return false; } } }