Gridview Chtml::listdata

So here is my question, below is CGridView, what I am trying to do is pass the phase_id from the grid to the EditableColumn source: which is using CHtml::listData(COSTCODES::model()->findAllByAttributes(array("phase_id"=>1)),"id", "description")

Note when I use array("phase_id"=>1) a number for the id it works I just need to be able to pass the value from phase_id from the grid column…

!Stumped!


$table_data = RatesPhase::model()->findByRatenamesPk($model->id);

 

 

//$model2 = COSTCODES::model()->findAllByAttributes(array('phase_id'=>$table_data[0]['phases_id']));

 

$this->widget('zii.widgets.grid.CGridView', array(

        'id'=>'rates-phase-grid',

        'htmlOptions' => array('class' => 'table table-striped table-bordered table-hover'),

        'dataProvider'=>$table_data,

        /*'filter'=>$model,*/

        'columns'=>array(

                array(

                'class'=>'CButtonColumn',

                'viewButtonUrl'=>'Yii::app()->createUrl("/RatesPhase/view/", array("id"=>$data["rates_id"]))'

                                ,

                'updateButtonUrl'=>'Yii::app()->createUrl("/RatesPhase/update/", array("id"=>$data["rates_id"]))'

                                ,

                'deleteButtonUrl'=>'Yii::app()->createUrl("/RatesPhase/delete/", array("id"=>$data["rates_id"]))'

                               

                ),

 

       

                'phases_id',

               

                array(

                                          'class' => 'editable.EditableColumn',

                                          'name'  => 'cost_code_id',

                                         

                                          'headerHtmlOptions' => array('style' => 'width: 100px'),

                                          'editable' => array(

                                                  'type'          => 'checklist',                                

                                               

                                                  'model' =>$table_data,

                                                  'url'           => $this->createUrl('costCodesRequiredJoin/create'),

                                                  'placement'     => 'right',

                                                  'source'                => CHtml::listData(COSTCODES::model()->findAllByAttributes(array("phase_id"=>1)),"id", "description"),

                                                'onSave' => 'js: function(e, params) {

                        alert("Saved value: " + params.newValue); console.log(params);

                }')

         ),

                 

               

               

        ),

));

use $data->phase_id variable for the parameter

Unfortunately that is not working, below is the function I am using for the dataprovider

Model function


public function findByRatenamesPk($id)

	{

		// Warning: Please modify the following code to remove attributes that

		// should not be searched.


		$criteria=new CDbCriteria;


		$criteria->compare('rates_id',$this->rates_id);

		$criteria->compare('customer_id',$this->customer_id);

		$criteria->compare('customers_id',$this->customers_id);

		$criteria->compare('phase_id',$this->phase_id,true);

		$criteria->compare('cost_code_id',$this->cost_code_id);

		$criteria->compare('full_description',$this->full_description,true);

		$criteria->compare('description',$this->description,true);

		$criteria->compare('contract_description',$this->contract_description,true);

		$criteria->compare('rate',$this->rate);

		$criteria->compare('unit_type',$this->unit_type,true);

		$criteria->compare('effective_date',$this->effective_date,true);

		$criteria->compare('adminfee',$this->adminfee);

		$criteria->compare('po_no',$this->po_no,true);

		$criteria->compare('prepared_by',$this->prepared_by,true);

		$criteria->compare('rate_name',$this->rate_name,true);

		$criteria->compare('form_index',$this->form_index);

		$criteria->compare('schedule_group_id',$this->schedule_group_id);

		$criteria->compare('nonbillable',$this->nonbillable);

		$criteria->compare('ordering',$this->ordering);

		$criteria->compare('rate_names_id',$id);

		$criteria->compare('phases_id',$this->phases_id);


		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

		));

	}

	}

in the view dataprovider


 $dataProvider = RatesPhase::model()->findByRatenamesPk($model->id);

Try this:

view:




// .....

'editable' => array(

    // ..... 

    'source' => 'js:function() { 

        return "'.$this->createUrl('CostCodeSource', array('id' => '__ID__')).'".replace("__ID__", this.getAttribute("data-pk"));

    }',

    // .....

)

// .....



controller:




// .....

public function actionCostCodeSource($id) {

    $model = SomeModel::model()->findByPk($id);

    $data = CHtml::listData(COSTCODES::model()->findAllByAttributes(array("phase_id"=>$model->phase_id)), "id", "description");

    echo CJSON::encode($data);

} 

// .....



BINGO!

You are the champion. Thanks much!

Maybe someone can help me figure this out:

How to maintain what is checked / not checked.

I know that I could update the database by using the URL and passing the ids that I want to update with a for loop. No problem, but how do you maintain what has been checked and not checked.

just a little about the structure: This field is part of a gridview which is from model RatePhase which is included on a list view of model CostCodes and the checklist would then update a related model called CostCodesGroupRequired.

So right now I am able to send the data

I use a function in the RatesPhase controller to update the desired table from the checklist url




public function actionUpdateCostCodeGroups()

foreach($_POST['value'] as $val) {

	$connection = Yii::app()->db;	

	$sql = "INSERT INTO cost_code_groups_required 

                (phase_id,cost_code_id) 

                values ('".$_POST['pk']."','" . $val . "')";

	$command = $connection->createCommand($sql);

	$rows=$command->execute();

	//echo $val;

}






the source is:




public function actionCostCodeSource($id) {

    $model = RatesPhase::model()->findByPk($id);

	$connection=Yii::app()->db;

	$sql = "SELECT COST_CODES.id, cost_codes_required_join.cost_code_id, cost_codes_required_join.id as 

        ccr_id, COST_CODES.description

	FROM COST_CODES

	LEFT JOIN cost_codes_required_join

	ON COST_CODES.id=cost_codes_required_join.cost_code_id AND  

        cost_codes_required_join.cost_codes_required_group_id = ".$model->cost_code_id." WHERE

	COST_CODES.phase_id = ".$model->phase_id;


	$count=Yii::app()->db->createCommand('SELECT COUNT(*) FROM COST_CODES

	LEFT JOIN cost_codes_required_join

	ON COST_CODES.id=cost_codes_required_join.cost_code_id AND          

        cost_codes_required_join.cost_codes_required_group_id = '.$model->cost_code_id.' WHERE

	COST_CODES.phase_id = '.$model->phase_id)->queryScalar();


	$command=$connection->createCommand($sql);

	$rows=$command->queryAll(); 

	$aAry = array();

	foreach($rows as $row){

	$aAry [$row['id']] = $row['id'].' | '.$row['description'];

	}

    $data = CHtml::listData(COSTCODES::model()->findAllByAttributes(array("phase_id"=>$model->phase_id)), "id", "description");

    echo CJSON::encode($aAry);

	//echo $sql;

} 



The editable column





array( 

	'class' => 'editable.EditableColumn',

	'name'  => 'cost_code_id',

        'headerHtmlOptions' => array('style' => 'width: 100px'),

	'editable' => array(

	'type' => 'checklist',	

	'model'=> $dataProvider,

	'url' => $this->createURL('UpdateCostCodeGroups',array('id'=>'phase_id')),

	'placement' => 'right',

	'source' => 'js:function() { return "'.$this->createUrl('rateNames/CostCodeSource',                                

                     array('id' => (('__ID__')).'".replace("__ID__", this.getAttribute("data-pk")); }',

						 

	'onSave' => 'js: function(e, params) { alert("Saved value: " + params.newValue ); console.log(params);}'

)),




Hi again,

I found a better solution without ID + js replace hack: you can use the $data variable in the htmlOptions because it is evaluated in the EditableColumn:




array( 

  'class' => 'editable.EditableColumn',

  'name'  => 'cost_code_id',

    'headerHtmlOptions' => array('style' => 'width: 100px'),

  'editable' => array(

    'type' => 'checklist',  

    ...

    'htmlOptions' => array(

      'data-url' => 'Yii::app()->controller->createUrl("rateNames/CostCodeSource", array("id" => $data->id))'

    )

    'source' => 'js:function() { return $(this).data("url"); }',

    ...

  )

),



Notice:

Use the binds in the SQLs - here it is dangerous (SQL Injection):




$sql = "INSERT INTO cost_code_groups_required 

  (phase_id,cost_code_id) 

  values ('".$_POST['pk']."','" . $val . "')";

$command = $connection->createCommand($sql);

$command->execute();



better:




$sql = "INSERT INTO cost_code_groups_required 

  (phase_id,cost_code_id) 

  values (:pk,:value)";

$command = $connection->createCommand($sql);

$command->execute(array(

  ':pk' => Yii::app()->request->getPost('id'),

  ':value' => $value

));



or build by Yii:




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

$insertedRows = $command->insert('cost_code_groups_required', array(

  'phase_id' => Yii::app()->request->getPost('id'),

  'cost_code_id' => $value

));



This works in that it submits to the database, but it does not maintain what has been previously selected.

Any Help Would be greatly appreciated.

I am hoping someone can help me with this.

I had the same problem as Preacher and I managed to fix it with the solution given my Argent.

However, it’s not the PK I am looking to replace in the JS function.

As an example: -


replace("__ID__", this.getAttribute("data-pk"))

I want to replace() with a field in an attribute from the model called ‘artist_id_fk_nn’.

Can anyone help me with this? I need this solution for multiple TbEditableColumn columns so any help would be very much appreciated!

Thanks in advance,

U4EA

Try this extension