simple form

Ass a noob i am having difficulties creating a registration form:

in sitecontroller:




public function actionRegister()

        {

           $model =new RegisterForm;

           $visitor = new Visitor;

           

		if(isset($_POST['RegisterForm']))

		{

			$model->attributes=$_POST['RegisterForm'];

                 

			if($model->validate())

			{

				

  

                                    $visitor->attributes = $model->attributes;

                                

                                    $visitor->save();

                                

                                    if($visitor->save())

                                    {

                                        //success

                                        Yii::app()->user->setFlash('register','Takk för din påmelding, en e-post er nå sent som en kvittering');

                                        $this->refresh();

                                    }

                                    else

                                    {

                                        //fail

                                        Yii::app()->user->setFlash('register','Beklager, det uppsto en feil vennligst forsok på nytt.');

                                        $this->refresh();

                                    }

                                        

                                


                                

				

                                //$this->redirect(Yii::app()->user->returnUrl);

			}

		}

		$this->render('register',array('model'=>$model));


                //print_r($modelForm->attributes);

        }




the form model:

RegisterForm.php


<?php


/**

 * ContactForm class.

 * ContactForm is the data structure for keeping

 * contact form data. It is used by the 'contact' action of 'SiteController'.

 */

class RegisterForm extends CFormModel

{

	public $transport;

	public $hotel;

        public $allergy;

        public $needs;


        public $firstname;

	public $lastname;

	//public $companyname;

        public $email;

        public $mobilephone;

        public $confirm;

       

	/**

	 * Declares the validation rules.

	 */

	public function rules()

	{

		return array(

			// name, email, subject and body are required

			array('transport', 'required', 'message'=> '{attribute} må velges.'),

                        array('hotel', 'required', 'message'=> 'Hotel må velges.'),

                        array('firstname', 'required', 'message'=> 'Fornavn må fylles in.'),

                        array('lastname', 'required', 'message'=> 'Etternavn må fylles in.'),

                        array('mobilephone', 'required', 'message'=> 'Mobiltelefon må fylles in.'),

                        array('confirm', 'required','requiredValue'=>'1', 'message'=> 'Betingelser må akepteres.'),

			// email has to be a valid email address

			array('email', 'email', 'message'=> 'E-post er ikke en gyldig e-post.'),

                        array('mobilephone', 'numerical', 'message'=> 'Mobiltelefon er ikke ett gyldigt nummer.'),

			// verifyCode needs to be entered correctly

			//array('verifyCode', 'captcha', 'allowEmpty'=>!extension_loaded('gd')),

		);

	}


	/**

	 * Declares customized attribute labels.

	 * If not declared here, an attribute would have a label that is

	 * the same as its name with the first letter in upper case.

	 */

	public function attributeLabels()

        {

            return array(

			'id' => 'ID',

			'firstname' => 'Fornavn',

			'lastname' => 'Etternavn',

			'email' => 'E-post',

			'mobilephone' => 'Mobiletelefon',

			'timeregistered' => 'Tid Registrert',

			'transport' => 'Transport',

			'allergy' => 'Alleriger',

			'needs' => 'Andre behov',

                        'hotel' => 'Hotel',

		);

        }

}

the view for the form:

register.php


<?php

$this->pageTitle=Yii::app()->name . ' - Register';

$this->breadcrumbs=array(

	'Register',

);

?>


<h1>Påmelding</h1>


<?php if(Yii::app()->user->hasFlash('register')): ?>


<div class="flash-success">

	<?php echo Yii::app()->user->getFlash('register'); ?>

</div>


<?php else: ?>


<p>

Fyll in din information her.

</p>


<div class="form">


<?php $form=$this->beginWidget('CActiveForm'); ?>


	<p class="note">Felt med <span class="required">*</span> må fylles in.</p>


	<?php echo $form->errorSummary($model, 'Vennligst endre føljende feil:'); ?>

       

	<div class="row">

		<?php echo $form->labelEx($model,'transport'); ?>

                <?php echo $form->dropDownList($model,'transport', array(''=>'-- Velg by --', 'Oslo'=>'Oslo','Bergen'=>'Bergen','Hamar'=>'Hamar')); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model,'hotel'); ?>

		<?php echo $form->dropDownList($model,'hotel', array('Nej, takk'=>'Nej, takk','Enkeltrom'=>'Enkeltrom','Dobbeltrom'=>'Dobbeltrom')); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model,'allergy'); ?>

		<?php echo $form->textField($model,'allergy',array('size'=>60,'maxlength'=>128)); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model,'needs'); ?>

		<?php echo $form->textArea($model,'needs',array('rows'=>6, 'cols'=>50)); ?>

	</div>


        <div class="row">

		<?php echo $form->labelEx($model,'firstname'); ?>

		<?php echo $form->textField($model,'firstname'); ?>

	</div>


        <div class="row">

		<?php echo $form->labelEx($model,'lastname'); ?>

		<?php echo $form->textField($model,'lastname'); ?>

	</div>


        <div class="row">

		<?php echo $form->labelEx($model,'email'); ?>

		<?php echo $form->textField($model,'email'); ?>

	</div>


        <div class="row">

		<?php echo $form->labelEx($model,'mobilephone'); ?>

		<?php echo $form->textField($model,'mobilephone'); ?>

	</div>


        <div class="row">

            <?php echo CHtml::activeCheckBox($model,'confirm'); ?>

            <?php echo 'Jeg har lest og akseptert betingelsene.' ?>

        </div>


	<div class="row buttons">

		<?php echo CHtml::submitButton('Submit'); ?>

	</div>


<?php $this->endWidget(); ?>


</div><!-- form -->


<?php endif; ?>

the model for the entries:

Visitor.php


<?php


/**

 * This is the model class for table "tbl_visitor".

 *

 * The followings are the available columns in table 'tbl_visitor':

 * @property integer $id

 * @property string $firstname

 * @property string $lastname

 * @property string $email

 * @property string $mobilephone

 * @property string $timeregistered

 * @property string $transport

 * @property string $allergy

 * @property string $needs

 */

class Visitor extends CActiveRecord

{

	/**

	 * Returns the static model of the specified AR class.

	 * @return Visitor the static model class

	 */

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}


	/**

	 * @return string the associated database table name

	 */

	public function tableName()

	{

		return 'tbl_visitor';

	}


	/**

	 * @return array validation rules for model attributes.

	 */

	public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array(

			array('firstname, lastname, email, mobilephone, timeregistered, transport, allergy, needs', 'required'),

			array('firstname, lastname, email, mobilephone, transport', 'length', 'max'=>255),

			// The following rule is used by search().

			// Please remove those attributes that should not be searched.

			array('id, firstname, lastname, email, mobilephone, timeregistered, transport, allergy, needs', 'safe', 'on'=>'search'),

		);

	}


	/**

	 * @return array relational rules.

	 */

	public function relations()

	{

		// NOTE: you may need to adjust the relation name and the related

		// class name for the relations automatically generated below.

		return array(

		);

	}


	/**

	 * @return array customized attribute labels (name=>label)

	 */

	public function attributeLabels()

	{

		return array(

			'id' => 'ID',

			'firstname' => 'Fornavn',

			'lastname' => 'Etternavn',

			'email' => 'E-post',

			'mobilephone' => 'Mobiletelefon',

			'timeregistered' => 'Tid Registrert',

			'transport' => 'Transport',

			'allergy' => 'allergi',

			'needs' => 'Behov',

		);

	}


	/**

	 * Retrieves a list of models based on the current search/filter conditions.

	 * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.

	 */

	public function search()

	{

		// Warning: Please modify the following code to remove attributes that

		// should not be searched.


		$criteria=new CDbCriteria;


		$criteria->compare('id',$this->id);


		$criteria->compare('firstname',$this->firstname,true);


		$criteria->compare('lastname',$this->lastname,true);


		$criteria->compare('email',$this->email,true);


		$criteria->compare('mobilephone',$this->mobilephone,true);


		$criteria->compare('timeregistered',$this->timeregistered,true);


		$criteria->compare('transport',$this->transport,true);


		$criteria->compare('allergy',$this->allergy,true);


		$criteria->compare('needs',$this->needs,true);


		return new CActiveDataProvider(get_class($this), array(

			'criteria'=>$criteria,

		));

	}

}

what am i doing wrong? the form isnt saving to the database… is it the "public $confirm;"? how to i remove this from the post array for the database?

thanks

Do you see the failure flash message when saving?

A note: You use 2 models with lot of duplicate attributes. You don’t need that. You could use Visitor as form model and create e.g. a “register” scenario. That would make your code simpler and maybe easier to read. You should also add $confirm as public variable if you want to verify that, too.

As Mike wrote, you are using two models that complicates things…

For example in visitor model you have a required rule for timeregistered but in the registerform there are no timeregistered… so when you give visitor->save() it fails if this attribute is not set…

NOTE: in actionRegister you call two times save()




$visitor->save();        // <-- this is not needed

if($visitor->save())



I suggest you read the Working with forms - http://www.yiiframework.com/doc/guide/form.overview

there is explained how to create the register form - model - action, when you complete this you will easily add all other attributes…

ok i feel very stupid here. not sure what you mean by making a scenario…you are talking about the validation right?

changed the code to:


public function actionRegister()

        {

           $model =new RegisterForm;

           $visitor = new Visitor;

           

		if(isset($_POST['RegisterForm']))

		{

			$model->attributes=$_POST['RegisterForm'];

                 

			if($model->validate())

			{

				

                                    $visitor->transport=$_POST['RegisterForm']['transport'];

                                    $visitor->firstname=$_POST['RegisterForm']['firstname'];

                                    $visitor->lastname=$_POST['RegisterForm']['lastname'];

                                    $visitor->email=$_POST['RegisterForm']['email'];

                                    $visitor->mobilephone=$_POST['RegisterForm']['mobilephone'];

                                    $visitor->allergy=$_POST['RegisterForm']['allergy'];

                                    $visitor->needs=$_POST['RegisterForm']['needs'];

                                    $visitor->hotel=$_POST['RegisterForm']['hotel'];

                                    $visitor->timeregistered= '2008-10-10 15:15:15';

                                

                                  

                                

                                    if($visitor->save())

                                    {

                                        //success

                                        Yii::app()->user->setFlash('register','Takk för din påmelding, en e-post er nå sent som en kvittering');

                                        $this->refresh();

                                    }

                                    else

                                    {

                                        //fail

                                        Yii::app()->user->setFlash('register','Beklager, det uppsto en feil vennligst forsok på nytt.');

                                        $this->refresh();

                                    }

   

			}

		}

		$this->render('register',array('model'=>$model));

        }

i am getting to the error screen yes. what bothers me i cant see what is wrong? log doesnt show anything either… I need to have a separate Register formbecause i will make the form more advanced when i get this to work?..haha hope this goes well.

if i make the visitor the model the validation is not working at all and i am not coming to the fail screen either…

As Mike has mentioned, it is better to use one data model with different scenarios. I use a similar scheme for my user model where the I have register and create scenarios (actions) in the UserController. Here is partial code from UserController.




	/**

	 * Creates a new model.

	 * If creation is successful, the browser will be redirected to the 'view' page.

	 */

	public function actionCreate()

	{

		$model=new User;

		// Uncomment the following line if AJAX validation is needed

		// $this->performAjaxValidation($model);


		if(isset($_POST['User']))

		{

			$model->attributes=$_POST['User'];

			if($model->save())

				$this->redirect(array('view','id'=>$model->id));

		}

		$this->render('create',array(

			'model'=>$model,

		));

	}

	

	

	

	/**

	 * Added for User Registeration 

	 * Displays a particular model.

	 

	 */

	public function actionRegister()

	{

		$model=new User('register');

		

		if(isset($_POST['User']))

		{

			$model->attributes=$_POST['User'];

			if($model->save()) {

				// Registration Successful. Send Email

			     $message = "Sending Message... Please Wait Dear";


                             ... Code to send email 


		}

		

		// Calls protected\views\user\register.php 

		$this->render('register',array(

			'model'=>$model,

		));	

          }

	



And in my user model, I set different rules for different scenarios.




	public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array( 

			array('username, password, email', 'required'),

			array('userlevel', 'numerical', 'integerOnly'=>true),

			array('username, password, passwordVerify, email', 'length', 'max'=>128),

			array('firstname, lastname, title', 'length', 'max'=>50),

			array('profile', 'safe'),

			

			// added for password comparision during 'actionRegister' 

			array('passwordVerify', 'required','on'=>'register'),			

			array('firstname', 'required','on'=>'register'),			

			array('password', 'compare', 'compareAttribute'=>'passwordVerify', 'on'=>'register'),

			

			// The following rule is used by search().

			array('username, email, profile, firstname, lastname, title, userlevel', 'safe', 'on'=>'search'),

			

			// added to ensure that username is unique 

			array('username', 'unique'),

			

			// Added for Verify Code (Captcha) 

			array('verifyCode', 'captcha', 'allowEmpty'=>!extension_loaded('gd') ,'on'=>'register'),

			

			

		);

	}

Hope, this may help.

I recommend to read this (and maybe read it a second and third time ;) ):

http://www.yiiframework.com/doc/guide/form.model

It explains the concept of safe attributes and how to work with scenario. A scenario is like a specific use case for a model. You can define different rules for each scenario in your model. Your Visitor model could e.g. have the scenarios “login” and “register”. That way you don’t need RegisterForm but can use Visitor right in place.

thanks! i rendered a CRUD model to see how it was made i got it how it works now.

However…

The "confirm" checkbox should not be saved to the database, but still i want it validated in the form.

What is best practice to handle this kind of thing? do i put it in the model but "ignore" in the validation rules?? or do i manually choose what fields to send back to the model in the controller?

thanks again

Add a public property $confirm to your ActiveRecord. It will be ignored when saving to DB but you can define rules for it and validate it like any other attribute.