create CHtml::textField with custom data attributes


I was searching for a way to use the custom data- variables in textfields and was unable to find anything. I thought it should be pretty easy so looked at how to create my own extended class. In the end it was really very easy and only took a few minutes.

I have a "components" folder at the same level as controllers, models etc, where I put all my custom classes. HEre is what I did.

Created a new file called MyCHtml.php in my components folder.

Added the following code to it:

class MyCHtml extends CHtml


    static function textFieldWithDataVars($name, $value='', $htmlOptions = array(), $datavars = array()) {

        $dvtext = ' ';

        foreach($datavars as $datakey => $dataval) {

            $dvtext .= trim($datakey).'="'.$dataval.'" ';


        return str_replace("/>", "{$dvtext}/>", parent::textField($name, $value, $htmlOptions));



So instead of using "echo CHtml::textField" I now use "echo MyCHtml::textFieldWithDataVars" with a 4th parameter which is the array of all the data attributes I need, for instance.

echo MyCHtml::textFieldWithDataVars("testfld", "testval", null, array("data-test1=>"testdata1", "data-test2"=>"testdata2"));

and the following html is generated in the page:

<input value="testval" name="testfld" id="testfld" data-test1="testdata1" data-test2="testdata2" type="text"></input>

I would appreciate any advice about if this is the best way to achieve this.

You can now just add all the other elements you want custom data variables for to this class.

NOTE: If you use NetBeans and have the php set up for intellisense, you can generate the parent:: code by typing "static function text" then select the entry from the popup.


Greg J

It’s not necessary in this case (unless of course you need this to be set in separate method argument for some reason). You can add “data-*” attribute in $htmlOptions array like any other attribute.

You can do the same thing using the following code:

 echo CHtml::textField('testfld','testval',array('data-test1'=>'testdata1','data-test2'=>'testdata1'));

It will produce:

<input data-test1="testdata1" data-test2="testdata1" type="text" value="testval" name="testfld" id="testfld">

great stuff! I could have sworn I had tried this first, I mustnt have been looking at the right element in the page as when I couldnt see the data variables I went down this path.

Although I feel like a bit of a drip right now for posting something so useless there is one good outcome, I taught myself how to extend a class!


We are glad to help :)