ENUM DB type in Yii

Ok, I can’t wait! :lol:

I’ve dropped your code (commented out the line resolveName()) in my model file.

Then, in the view I’ve called it in this way:


<?php echo CHtml::activeDropDownList( $model,'status',$model->enumItem($model, 'status') ); ?>

Where ‘status’ is an [font=“Courier New”]ENUM(‘Active’,‘Inactive’,‘Deleted’)[/font].

Hope to help someone :D

I usally put this code in a class that I call ZHtml and put in compoment.

In this class there are my helpers. As they are static, they can be called on the class itself:




class ZHtml extends CHtml

{

        public static function enumItem($model,$attribute)

        {

                $attr=$attribute;

                self::resolveName($model,$attr);

                preg_match('/\((.*)\)/',$model->tableSchema->columns[$attr]->dbType,$matches);

                foreach(explode(',', $matches[1]) as $value)

                {

                        $value=str_replace("'",null,$value);

                        $values[$value]=Yii::t('enumItem',$value);

                }

                

                return $values;

        }  


       public static function enumDropDownList($model, $attribute, $htmlOptions)

       {

          return CHtml::activeDropDownList( $model, $attribute,ZHtml::enumItem($model,  $attribute), $htmlOptions);

       

       

       }


}



This allow you to write in the view (without any change in the model):


<?php echo CHtml::activeDropDownList( $model,'status',ZHtml::enumItem($model, 'status') ); ?>

or , more tasty:


<?php echo ZHtml::enumDropDownList( $model,'status'); ?>

Thanks zaccaria for that stuff, it helped me too.

suppose I have ENUM(‘Active’,‘Inactive’,‘Deleted’)

How to get the value I saved in my text field when I want to modify the form?

If I select ‘Inactive’ and save then I noticed that ‘Active’ allways come first during any modification in the form.

Thanks!

Simply use ve helper, you don’t need any textfield.

Just write


<?php echo ZHtml::enumDropDownList( $model,'status'); ?>

and all will be fine.

If it is not saved the value, maybe is a problem of safe attributes.

Maybe I didn’t notice something but I can see it’s working now very well without any other modifications

That’s a great stuff!

Thanks

Yeahh!!

I was wondering what else could be wrong… this piece of code has 2 years and alway did his work.

Happy that it helped.

Heres a little snippet to get it to work with Postgresql9 as well.


<?php

class ZHtml extends CHtml

{

        public static function enumItem($model,$attribute)

        {

		$values = array();

                $attr=$attribute;

                self::resolveName($model,$attr);

		if( $model->tableSchema instanceof CPgsqlTableSchema ) {

			$sql=<<<EOD

SELECT enumlabel FROM pg_enum

JOIN pg_type ON pg_type.oid = pg_enum.enumtypid

WHERE pg_type.typname = :table

EOD;

			$command=Yii::app()->db->createCommand($sql);

			$command->bindValue(':table',$model->tableSchema->columns[$attr]->dbType);


			$values=$command->queryColumn();

			

			Yii::trace( "Enum values were: ".print_r( $values, true ) );

		

		} else {

			if( preg_match('/\((.*)\)/',$model->tableSchema->columns[$attr]->dbType,$matches) > 0 ) {

				foreach(explode(',', $matches[1]) as $value)

				{

					$value=str_replace("'",null,$value);

					$values[$value]=Yii::t('enumItem',$value);

				}

			}

		} 

                return $values;

        }  


       public static function enumDropDownList($model, $attribute, $htmlOptions = array())

       {

          return CHtml::activeDropDownList( $model, $attribute,ZHtml::enumItem($model,  $attribute), $htmlOptions);

       

       

       }


}

?>

Hey,

Thanks for the concise instructions, I had to make one modification though, as enumDropDownList takes 3 arguments, the last one being $htmlOptions, i had to add [color="#006400"]array()[/color] as an argument, eg


<?php echo ZHtml::enumDropDownList($model,'status', array()); ?>

I’m pretty new to this so if that is dangerous, let me know.

Cheers!

Generally, $htmlOptions is given a default argument $htmlOptions=array()

I changed it to the following when I used it:




public static function enumDropDownList($model, $attribute, $htmlOptions=array())

{

	return CHtml::activeDropDownList($model, $attribute, ZHtml::enumItem($model, $attribute), $htmlOptions);

}



I’ve just implemented your code… Really great stuff, even after 2 years! Thanks!

great helper class Zaccaria. Thanks! :D

To set the selected item when using in update forms add this snippet, (replace ‘attr’ in 2 places with your model attribute):


<?php echo ZHtml::enumDropDownList($model, 'attr',

                 array(

                         'options'=>array('$model->attr'=>array('selected'=>true)),

                 ))

?>

thanks zachri , it helped me

A wiki Article on dropdownlist version of this code [enumDropdownlist](http://www.yiiframework.com/wiki/303/drop-down-list-with-enum-values-for-column-of-type-enum-incorporate-into-giix/ "enumDropdownlist")

A wiki article on the RadioButtonlist version of this code [enumRadioButtonlist](http://www.yiiframework.com/wiki/334/radio-button-list-with-enum-values-for-column-of-type-enum-incorporate-into-giix/ "enumRadioButtonlist")

If you use MySQL SETs, you might find setItem useful. It does require enumItem by Zaccaria, in the posts above.

Suggestions are welcome.




		public static function setItem($model, $attribute)

	{

    	$options = array_keys(self::enumItem($model, $attribute));


    	$values = array();

    	// $options has all possible values, but not yet the combinations.

    	$values[] = '';

    	for ($i = 0; $i < count($options); $i++)

    	{

        	$element = $options[$i];

        	$values[$element] = $element;

        	self::traverseItems($i + 1, $options, $element, $values);

    	}

    	$element = implode(",", $options);

    	$values[$element] = $element;

    	return $values;

	}


	private static function traverseItems($start, $options, &$element, array &$values)

	{

    	$copy = $element;

    	for ($j = $start; $j < count($options); $j++)

    	{

        	$element = $element . "," . $options[$j];

        	$values[$element] = $element;

        	self::traverseItems($j + 1, $options, $element, $values);

        	$element= $copy;

    	}

	}



enumItem in case you don’t want to scrollup (made by Zaccaria, not made by me)




	public static function enumItem($model, $attribute)

	{

    	$matches = $values = array();


    	$attr = $attribute;

    	CHtml::resolveName($model, $attr);

    	preg_match('/\((.*)\)/', $model->tableSchema->columns[$attr]->dbType, $matches);

    	foreach (explode(',', $matches[1]) as $value)

    	{

        	$value = str_replace("'", null, $value);

        	$values[$value] = Yii::t('enumItem', $value);

    	}


    	return $values;

	}

Has anyone worked out a way to return the results ordered alphabetically?

Cheers!

Sort the results:




  public static function enumItem($model, $attribute)

	{

    	$matches = $values = array();


    	$attr = $attribute;

    	CHtml::resolveName($model, $attr);

    	preg_match('/\((.*)\)/', $model->tableSchema->columns[$attr]->dbType, $matches);

    	foreach (explode(',', $matches[1]) as $value)

    	{

        	$value = str_replace("'", null, $value);

        	$values[$value] = Yii::t('enumItem', $value);

    	}


    	asort($values);


    	return $values;

	}



Haha, such a n00b i am… dont know why I didnt think of that.

thanks!

This discuss solved all enum data type issues I have.

Very helpful, thanks a lot. :)

Nice solution, Zaccaria! Thanks!