📜 ⬆️ ⬇️

Yii expands CHtml to work with text fields.

Hello. Now I am writing another project on Yii and I would like to share some ideas. In this article I would like to describe how you can extend the functionality of the framework using the inheritance classes CHtml , CActiveForm . There is nothing complicated and innovative here, I just wanted to share it. My task was to create 2 elements:


Here is an example of the result of the following code (the code after the habrakat):

image
')
<?php $form = $this -> beginWidget ( 'MActiveForm' , array ( <br/>
'id' => 'personal-form' , <br/>
'enableAjaxValidation' => false , <br/>
) ) ; <br/>
<br/>
?> <br/>
<?php echo $form -> errorSummary ( $model ) ; ?> <br/>
<br/>
<div class="row"><br/>
<?php echo $form -> labelEx ( $model , 'gender' ) ; ?> <br/>
<?php echo $form -> labelField ( $model , 'gender' ) ; ?> <br/>
<?php echo $form -> error ( $model , 'gender' ) ; ?> <br/>
</div><br/>
<br/>
<div class="row"><br/>
<?php echo $form -> labelEx ( $model , 'firstname' ) ; ?> <br/>
<?php echo $form -> labelField ( $model , 'firstname' ) ; ?> <br/>
<?php echo $form -> error ( $model , 'firstname' ) ; ?> <br/>
</div><br/>
<br/>
<div class="row"><br/>
<?php echo $form -> labelEx ( $model , 'secondname' ) ; ?> <br/>
<?php echo $form -> labelField ( $model , 'secondname' ) ; ?> <br/>
<?php echo $form -> error ( $model , 'secondname' ) ; ?> <br/>
</div><br/>
<br/>
<div class="row"><br/>
<?php echo $form -> labelEx ( $model , 'lastname' ) ; ?> <br/>
<?php echo $form -> labelField ( $model , 'lastname' ) ; ?> <br/>
<?php echo $form -> error ( $model , 'lastname' ) ; ?> <br/>
</div> <br/>
<? $this -> endWidget ( ) ; ?> <br/>


When I wrote the first form, I realized that in yii I use the standard CActiveForm widget and it would be nice to continue using it. In the end, now I can display the form fields in this way (only the MActiveForm widget):

<?php echo $form->labelField($model,'secondname'); ?>

In fact, CActiveForm is only a mirror for methods of type activeTextField class CHtml , so I had to expand the class CHtml
and add the activeLabelField function to it (let's call our custom labelField control)

<?php <br/>
<br/>
class MHtml extends CHtml<br/>
{ <br/>
static $msPublished = false ; // css js <br/>
<br/>
protected static function registerMHtmlAsset ( ) <br/>
{ <br/>
if ( ! MHtml :: $msPublished ) <br/>
{ <br/>
$path = Yii :: app ( ) -> getAssetManager ( ) -> publish ( Yii :: getPathOfAlias ( 'application.components.assets.mhtml' ) , false , - 1 , true ) ; // false, - asset ( ) <br/>
Yii :: app ( ) -> getClientScript ( ) -> registerScriptFile ( $path . '/mhtml.js' , CClientScript :: POS_END ) ; <br/>
Yii :: app ( ) -> getClientScript ( ) -> registerCssFile ( $path . '/mhtml.css' ) ; <br/>
MHtml :: $msPublished = true ; <br/>
} <br/>
} <br/>
public static function addClass ( $class , $htmlOptions = array ( ) ) <br/>
{ <br/>
if ( isset ( $htmlOptions [ "class" ] ) ) <br/>
$htmlOptions [ "class" ] .= " " . $class ; <br/>
else $htmlOptions [ "class" ] = $class ; <br/>
<br/>
return $htmlOptions ; <br/>
} <br/>
public static function labelField ( $name , $value = '' , $htmlOptions = array ( ) ) <br/>
{ <br/>
MHtml :: registerMHtmlAsset ( ) ; <br/>
return MHtml :: textField ( $name , $value , MHtml :: addClass ( "labelInput" , $htmlOptions ) ) ; <br/>
} <br/>
<br/>
public static function activeLabelField ( $model , $attribute , $htmlOptions = array ( ) ) <br/>
{ <br/>
MHtml :: registerMHtmlAsset ( ) ; <br/>
self :: resolveNameID ( $model , $attribute , $htmlOptions ) ; <br/>
self :: clientChange ( 'change' , $htmlOptions ) ; <br/>
return self :: activeInputField ( 'text' , $model , $attribute , MHtml :: addClass ( "labelInput" , $htmlOptions ) ) ; <br/>
} <br/>
<br/>
public static function textHint ( $text , $htmlOptions = array ( ) ) <br/>
{ <br/>
MHtml :: registerMHtmlAsset ( ) ; <br/>
<br/>
return MHtml :: tag ( 'div' , MHtml :: addClass ( "textHint_mh" , $htmlOptions ) , $text ) ; <br/>
} <br/>
} <br/>
?>
<?php <br/>
<br/>
class MHtml extends CHtml<br/>
{ <br/>
static $msPublished = false ; // css js <br/>
<br/>
protected static function registerMHtmlAsset ( ) <br/>
{ <br/>
if ( ! MHtml :: $msPublished ) <br/>
{ <br/>
$path = Yii :: app ( ) -> getAssetManager ( ) -> publish ( Yii :: getPathOfAlias ( 'application.components.assets.mhtml' ) , false , - 1 , true ) ; // false, - asset ( ) <br/>
Yii :: app ( ) -> getClientScript ( ) -> registerScriptFile ( $path . '/mhtml.js' , CClientScript :: POS_END ) ; <br/>
Yii :: app ( ) -> getClientScript ( ) -> registerCssFile ( $path . '/mhtml.css' ) ; <br/>
MHtml :: $msPublished = true ; <br/>
} <br/>
} <br/>
public static function addClass ( $class , $htmlOptions = array ( ) ) <br/>
{ <br/>
if ( isset ( $htmlOptions [ "class" ] ) ) <br/>
$htmlOptions [ "class" ] .= " " . $class ; <br/>
else $htmlOptions [ "class" ] = $class ; <br/>
<br/>
return $htmlOptions ; <br/>
} <br/>
public static function labelField ( $name , $value = '' , $htmlOptions = array ( ) ) <br/>
{ <br/>
MHtml :: registerMHtmlAsset ( ) ; <br/>
return MHtml :: textField ( $name , $value , MHtml :: addClass ( "labelInput" , $htmlOptions ) ) ; <br/>
} <br/>
<br/>
public static function activeLabelField ( $model , $attribute , $htmlOptions = array ( ) ) <br/>
{ <br/>
MHtml :: registerMHtmlAsset ( ) ; <br/>
self :: resolveNameID ( $model , $attribute , $htmlOptions ) ; <br/>
self :: clientChange ( 'change' , $htmlOptions ) ; <br/>
return self :: activeInputField ( 'text' , $model , $attribute , MHtml :: addClass ( "labelInput" , $htmlOptions ) ) ; <br/>
} <br/>
<br/>
public static function textHint ( $text , $htmlOptions = array ( ) ) <br/>
{ <br/>
MHtml :: registerMHtmlAsset ( ) ; <br/>
<br/>
return MHtml :: tag ( 'div' , MHtml :: addClass ( "textHint_mh" , $htmlOptions ) , $text ) ; <br/>
} <br/>
} <br/>
?>


I will explain a little. To create a text with a tooltip, we simply create a div with the class textHint_mh.

And to create text, which when clicked turns into a text field, we create an input field with the labelInput class, which after loading the javascript code will be hidden and a div with the textHint_mh class will be shown instead.

Here is such a confusing nonsense. Now we need to extend the CActiveForm class:

<?php <br/>
<br/>
class MActiveForm extends CActiveForm<br/>
{ <br/>
public function labelField ( $model , $attribute , $htmlOptions = array ( ) ) <br/>
{ <br/>
return MHtml :: activeLabelField ( $model , $attribute , $htmlOptions ) ; <br/>
} <br/>
}
<?php <br/>
<br/>
class MActiveForm extends CActiveForm<br/>
{ <br/>
public function labelField ( $model , $attribute , $htmlOptions = array ( ) ) <br/>
{ <br/>
return MHtml :: activeLabelField ( $model , $attribute , $htmlOptions ) ; <br/>
} <br/>
}


A couple of lines. And then come into the js and css. Everything works, everything is simple. I hope someone come in handy

Source code here

Source: https://habr.com/ru/post/143800/


All Articles