Advice regarding form and validation

Hi there,

I’m building a web app whereby one sports player can challenge another player to a match and a confirmation email is sent to both players (containing a Challenge ID). On completing the match, one of the players can record the result using the challenge ID. I have modelled this using two models; a Challenge model and a Result model.

On the result/index page, I display all of the results in a table (using CGridView). I’ve added a simple form (comprising 1 label, 1 text field, 1 submit button) above this results table, which allows a player to enter a Challenge ID and click Submit. The Challenge ID entered is checked against the Challenge model to see if it corresponds to an open challenge (i.e. a challenge for which a result has not yet been recorded), before the player is taken to the result/create page. If the player enters an invalid Challenge ID, I would like to show an appropriate message next to the simple form.

I’ve created the simple form in result/index as follows…


<?php $form=$this->beginWidget('CActiveForm', array(

    'id'=>'record-result-form',

    'action'=>array('result/create'),

    'enableAjaxValidation'=>false,

)); ?>


    <div class="row">

        <?php echo CHtml::label('To record a match result, enter the Challenge ID:', 'challengeId'); ?>

        <?php echo CHtml::textField('challengeId', '', array('maxlength'=>6)); ?>

    </div>


    <div class="row buttons">

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

    </div>


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

In my ignorance (I’m pretty new to Yii), I’ve modified the actionCreate function of the ResultController to include validation checks on the Challenge ID as follows…


	public function actionCreate()

	{

	   

	    if (!isset($_REQUEST['challengeId']) || 

	        empty($_REQUEST['challengeId']) || 

	        !is_numeric($_REQUEST['challengeId']) ||

	        Challenge::model()->findByPk($_REQUEST['challengeId']) === NULL) {

	       $this->redirect(array('result/index'));

	    }


	    $model=new Result;

            $model->challengeId=$_REQUEST['challengeId'];

...



At the moment it does what I want except that I’m not sure how to output a message if the Challenge ID is invalid?

I suspect that there’s a much tidier/better/more-MVC way to do the above, whereby the validation isn’t just poked into a random place, so I would value any comments to that end (i.e. what’s the “proper” way to do this?).

Any advice would be much appreciated.

I think you have to do this in your model class, specifically in the rules() method. Please try to see the documentation for more info about it :)

On another note, consider getting both players to submit the result, unless you trust them fully ;)

Good idea levz. I’ve added a custom validation method to my Result model class as follows…


    /**

     * Validates challengeId entered against Result model to ensure a match result has not already been recorded.

     */

	public function resultPermitted($attribute,$params) 

	{

	    // check if a match result has already been recorded for this challenge

	    $matchResult = Result::model()->findByAttributes(array('challengeId'=>$attribute));

	    // report validation error if match result already exists

	    if ($matchResult !== null) {

	       $this->addError($attribute, 'A match result has already been recorded for this challenge.');	    

	    }  

	}

However, the simple single-field form I was referring to above, in which only a Challenge ID can be entered, is on the result/index page and is not the form used to create a new result, it simply provides access to the result/create page. So, how do I tie my custom validation rule into my ad-hoc form? Adding it the rules function won’t have an effect. Do I need to create my form in a different manner?

Good idea - thanks.