ActiveCheckBoxList for Table Rows

This first example code works to make an activeCheckBoxList of each row for one table field. It list all itemNames and icludes a checkbox for each.


<div id="name">

<?php echo CHtml::activeCheckBoxList($model, 'itemId',

            CHtml::listData(

                ServiceItem::model()->findAll(), 'itemId',

                        'itemName'), array('template'=>'{input} {label}'));

?>

</div>

I need each row to include data from all of the fields.

CException:

ServiceItem and its behaviors do not have a method or closure named "queryAll".


<div id="all">

<?php echo CHtml::activeCheckBoxList($model, 'itemId',

		CHtml::listData(

		ServiceItem::model()->queryAll('true','Itemid=>1'),

	'itemId','itemDescription'));

?></div>

So, in the model I added…




/* Get data from servieItem table for activeCheckBoxList */

	public function populatelist()

	{

		$allitems = Yii::app()->db->createCommand()

			->select('itemId, itemName, itemDescription, timeEstimate')

			->from('serviceItem')

			->where(':itemId=itemId', array(':itemId'=>1))

			->queryAll();

		return $allitems;

	}

In the view…




<?php echo CHtml::activeCheckBoxList($model, 'itemId',

		CHtml::listData(

		ServiceItem::model()->populatelist(),

	'itemId','itemName'));

?>

There isn’t an error,(yea) but only the itemName is listed with a checkbox.

??

Several questions first, as everything else depends on these:1. What are you trying to achieve finally?

  1. If your first example worked okay, what was wrong with the result that you started to change it?

Will try to guess what are the actual problems:

I assume itemId is PK, so it’s natural you get only one result with this condition:


->where(':itemId=itemId', array(':itemId'=>1))

Also notice you dropped using


array('template'=>'{input} {label}')

which was used before.

And it’s natural you’ve got the error

At that moment you called method queryAll() which doesn’t exist in AR. You had to call findAll(), the same as in the first example to avoid the error.

I need each row to include data from all of the fields. The first example would only produce rows for one of the fields, no matter how I tried, so I tried a different approach.


array('template'=>'{input} {label}')

This was dropped because it was only necessary for manipulating display arrangement, they appear by default. I can add them if desired, once I get the data to display properly.

Q. Is it possible for the first example to display all table data with the checkbox at the beginning of each row? If so, how?

In this example from the doc for CDbcommand… ->where … What is the colon before id indicating?


$user = Yii::app()->db->createCommand()

    ->select('username, password')

    ->from('tbl_user')

    ->where('id=:id', array(':id'=>1))

    ->queryRow();

There’re several approaches.

  1. Using virtual attribute in listData() (I’d prefer this one most probably)




echo CHtml::activeCheckBoxList($model, 'itemId', CHtml::listData(ServiceItem::model()->findAll(), 'itemId', 'itemData'));



In your model:





    public function getItemData() {

        return $itemId .' '. $itemName .' '. $itemDescription .' '. $itemEstimate;

    }



  1. Using custom function to populate array (the way you started to implement)




    public function populateList() {

        $data = Yii::app()->db->createCommand()

                ->select('itemId, CONCAT(itemId, " ", itemName, " ", itemDescription, " ", itemEstimate) as itemData')

                ->from('serviceItem')

                ->queryAll();

        $res = array();

        foreach ($data as $row) {

            $res[$row['id']] = $row['itemData'];

        }

        return $res;

   }



You’ll need to declare


public $itemData

in your model or use one of attributes, such as itemDescriptiom or itemName if the attribute’s name isn’t important

  1. overwrite CHtml::listData() to except array of attributes, it is described in one of the old topics.

  2. In the same thread you’ll find one more modification of ‘CONCAT’ solution - is to write the sql with concatenation directly in your listData() method. This one example.

http://th.php.net/ma...t.bindparam.php :

[font="verdana, arial, helvetica, sans-serif"][size="2"]Parameter identifier. For a prepared statement using named placeholders, this will be a parameter name of the form [/size][/font]:name[font="verdana, arial, helvetica, sans-serif"][size="2"]. For a prepared statement using question mark placeholders, this will be the 1-indexed position of the parameter.[/size][/font]

Thanks Yugene, I appreciate your help!

PHP Error:

I haven’t tried the other yet,… one step at a time.

Q. Will one method be better than the other for doing calculations on the selected items? I will need the timeEstimate total selected x the hrRate to display a jobEstimate for the visitor. I am assuming it doesn’t matter, but thought I would ask anyway.


public $itemData;

I just added this to the model…


/*example from Yugene -  using virtual attribute with activeCheckboxlist */

public $itemData;




public function getItemData() {

        return itemId .' '. itemName .' '. itemDescription .' '. itemEstimate;

    }

The checkboxes are all there however that’s all there is!

UPDATE: Upon trying the second example of a custom function as Yugene has generously supplied, the result remains the same; Checkboxes with nothing else.

Which brings me to … [quote="Yugene"]3. overwrite CHtml::listData() to except array of attributes, it is described in one of the old topics.

  1. In the same thread you’ll find one more modification of ‘CONCAT’ solution - is to write the sql with concatenation directly in your listData() method…
    [/quote]
    hmmm, so list data is not capable of identifying concatenated values. As it is, listData is designed for returning row values for one field. The solution is to extend the CHtml class so that it will identify the concatenation. wow. okay.

I thought to do the checkboxlist seperatly for each field and then with CSS line them up to ‘appear’ as one however if a visitor has style turned off, or if they use a reader then the page would not make any sense.

I will update with my results, but first I need to do something about my s-l-o-w - c-o-m-p-u-t-e-r, it is very annoying!

Sorry, there was a copy-paste caused typo. Of course I meant variables


$itemId .' '. $itemName .' '. $itemDescription .' '. $itemEstimate

And if your checkboxes are still not working - provide your code to find the issue.

I made the $ correction to the getItemData function but of course, it still only displays the boxes.

The following code is based on the example from the linked thread. I chose the example of CONCAT in the listData view, because it seemed to be not only easier but there was debate about messing with the CHtml class which I would like to reaserch more before implementing.


<div>CONCAT listData in view <br />


<?php echo CHtml::activeCheckBoxList($model, 'itemId', 

        CHtml::listData(serviceItem::model()->findAllbySql(

                'SELECT itemId, CONCAT(itemId," ",itemName, " ", itemDescription," ",timeEstimate) as itemData FROM serviceItem'

                ), 'itemId', 'itemName'),

        array('template'=>'{input} {label}')

);

?>

</div>

Again only the boxes are showing which is probably because there is only the SELECT command and nothing expressing the display of data. So, in this context how does that work? And, is the ‘as itemData’ after the concatination right?

Please notice, you’re selecting itemId and itemData, nothing more.

Then you’re trying to populate your list with itemId and itemName.

Using itemData instead of itemName should fix your problem.

Yes!

It looks great and I can add a ‘WHERE’ to select a single row…


<?php echo CHtml::activeCheckBoxList($model, 'itemId', 

        CHtml::listData(serviceItem::model()->findAllbySql(

                'SELECT itemId, CONCAT(itemName, " ", itemDescription," ",timeEstimate) as itemData FROM serviceItem WHERE itemId=1'

                ), 'itemId', 'itemData'),

        array('template'=>'{input} {label}')

);

?>

Styling will be limited due to all fields being in the label however now that I understand how it works I should be able to create a sensible page for all types of visitors.

Thank-you!

Nice to hear it works for you now :)

Though I’d still suggested to make the first mentioned approach to work - with virtual attribute - cause it’s a very useful and convenient feature you can use extensively in your project and simplify a lot your application code. At least you could try to play with it a bit more to understand this approach for a future use.

You could read a bit more about virtual attributes at wiki if you’re interested.

Have a nice coding,

Yuga

Thanks, examples helped me a lot.

Would anyone tell me where I can find a way to make a filter that is updated with ajax as I’m selecting activeCheckBoxList?

Fabio