In my view I have a link which is calling a function in Controller. The function in controller is making a pdf. It is supposed to make pdf of only $model->id. But I am unable to send the value of $model->id into controller via my link.
View
<?php
echo CHtml::link('Save/Print',array('print'),array('class'=>'btnPrint btn btn-info','target'=>'new'));
?>
<?php
$this->widget('zii.widgets.CDetailView', array(
'data'=>$model,
'attributes'=>array(
'id',
'name',
'father_name',
'cnic',
'customername',
),
));
?>
Controller
public function actionPrint($id) {
ini_set('max_execution_time',360);
ini_set('memory_limit', '128M');
$mPDF1 = Yii::app()->ePdf->mpdf('','A4');
$mPDF1->SetHTMLHeader('<h3 style="text-align: center;">'.mb_strtoupper(str_replace('Hello','',Yii::app()->name),'UTF-8').'</h3>');
// $id=35;
$records = Candidate::model()->findByPk($id);
$html = '';
$html .= $this->renderPartial('view', array('model'=>$records),true);
$mPDF1->WriteHTML($html, false);
$mPDF1->Output();
}
How will I send the value of id?
go like this for singel link
// $model->id is the id you want to send
echo CHtml::link(
'Save/Print',
Yii::app()->createUrl('Save/Print' , array('id' => $model->id)),
array('class'=>'btnPrint btn btn-info','target'=>'_blank'));
if you want it in a grid
$this->widget('zii.widgets.CDetailView', array(
'data'=>$model,
'attributes'=>array(
array(
'name' => 'id',
'value' => 'echo CHtml::link(
"Save/Print",
Yii::app()->createUrl("Save/Print" , array("id" => $data->id)),
array("class"=>"btnPrint btn btn-info","target"=>"_blank"));',
'type' => 'raw',
),
'name',
'father_name',
'cnic',
'customername',
),
));
Related
I'm just trying to wrap my head around the yii framework at the moment and I've created a function to delete multiple database records at once. In the view I've got a grid with a reference to each item and a checkbox next to it
<?php $this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
'htmlOptions'=>array(
'class'=>''
),
'columns'=>array(
...
array(
'class'=>'CLinkColumn',
'header'=>'Handle',
'labelExpression'=>'$data->handle',
'urlExpression'=>'Yii::app()->createUrl(".../item/view", array("id"=>$data->id))',
),
array(
'class'=>'CCheckBoxColumn',
'header'=>'Select',
'selectableRows'=>'2',
),
),
Then further down the page I want a button (delete selected) which sends an array of all of the items to a delete function. My thoughts were it would be something akin to this:
<a href="
<?php echo Yii::app()->createUrl('.../item/bulkDelete','array("id" => $data->id)')?>"
class="btn">Delete Selected</a>
But I don't understand how to get a reference for each checked item instead of :
"id" => $data->id
as I used to call pass an item to the view function earlier. If anyone can help it will be greatly appreciated.
Edit:
View:
$form = $this->beginWidget('CActiveForm', array(
'id' => 'itemForm',
'action' => array('.../item/bulkDelete'),
));
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
'htmlOptions'=>array(
'class'=>''
),
array(
'class'=>'CLinkColumn',
'header'=>'Handle',
'labelExpression'=>'$data->handle',
'urlExpression'=>'Yii::app()->createUrl(".../item/view", array("id"=>$data->id))',
),
array(
'class'=>'CCheckBoxColumn',
'header'=>'Select',
'selectableRows'=>'2',
),
... //More Columns
), //End of Grid
...
echo CHtml::SubmitButton('Delete Multiple');
$this->endWidget();
Controller:
public function actionBulkDelete()
{
if(isset($_POST['id'])&& !empty($_POST['id']))
{
Yii::app()->user->setFlash('success', 'Delete Items');
$this->redirect(array('.../item/index'));
}
else
{
Yii::app()->user->setFlash('success', 'No Items Selected');
$this->redirect(array('.../item/index'));
}
}
Wrap the grid view inside a form, and do the following changes in your columns array:
$form = $this->beginWidget('CActiveForm', array(
'id' => 'some-grid-form',
'action' => array('myController/myAction'),
));
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
'selectableRows' => 2,
'columns'=>array(
array(
'id' => 'id',
'class' => 'CCheckBoxColumn',
),
//... rest of your columns
),
array(
'class'=>'CButtonColumn',
),
),
));
echo CHtml::SubmitButton('Multiple Delete');
$this->endWidget(); // end form
And in your Controller's myAction:
public function actionmyAction()
{
if(isset($_POST['id']) && !empty($_POST['id'])) { //you'll get all the ids in an array
//print_r($_POST['id']);
//your delete function here, also add a few validation here to authenticate deletion
$ids = $_POST['id'];
$criteria = new CDbCriteria;
$criteria->addInCondition('id',$ids);
MyModel::model()->deleteAll($criteria);
//.... render with success flash message etc.
}
}
I'am trying to implement a dropdownlist inside the gridview, but it is not working.
Here's my code
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'user-grid',
'dataProvider'=>$model->roadies_search(),
'filter' =>$model,
'columns'=>array(
array(
'name'=>'hname_search',
'header'=>'Hospital Name',
'value'=>'($data->AssociatedHospitals) ? $data->AssociatedHospitals : ""',
),
array(
'type'=>'raw',
'header'=>'Users',
'id' => 'test',
'value'=>function(){
$res=Yii::app()->db->createCommand("SELECT name,id FROM med_user WHERE rank>3")->queryAll();
$html = '<select name="user" style="width:100%;">
<option selected>Select User</option>
';
foreach ($res as $key) {
$html.='<option value="'.$key['id'].'">'.$key['name'].'</option>
';
}
$html.='</select>';
return $html;
},
),
)
));
I have tried it using the following function too:
public function getUsername(){
$res=Yii::app()->db->createCommand("SELECT name,id FROM med_user WHERE rank>3")->queryAll();
return CHtml::dropDownList('usersselectlist'.$this->id,'user_id',CHtml::listData($res, 'id', 'name'));
}
I want to show all the users as a dropdown, for every row in the gridview.
EDIT
I figured out that the dropdown works fine for firefox, but the problem is with chrome. It is not showing the selected values.
Here's an example
Chrome: http://i.imgur.com/eAvBRwO.png
Firefox: http://i.imgur.com/7wBc1GX.png
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'user-grid',
'dataProvider'=>$model->roadies_search(),
'filter' =>$model,
'columns'=>array(
array(
'name'=>'hname_search',
'header'=>'Hospital Name',
'value'=>'($data->AssociatedHospitals) ? $data->AssociatedHospitals : ""',
),
array(
'type'=>'raw',
'header'=>'Users',
'id' => 'test',
'value'=>function(){
// but better prepare data in model and set here from controller
$dataReader = Yii::app()
->db
->createCommand("SELECT name,id FROM med_user WHERE rank>3")
->query();
$dropList = array();
foreach ($dataReader as $row) {
$id = $row['id'];
$dropList[$id] = $row['name'];
}
return CHtml::dropDownList('my', null/* or selected id */, $dropList);
},
),
)
));
It's really bad way. You will do SQL query for each row, why not use it outside of grid?
$res=Yii::app()->db->createCommand("SELECT name,id FROM med_user WHERE rank>3")->queryAll();
$select_data = CHtml::listData($res, 'id', 'name');
......
array(
'type'=>'raw',
'header'=>'Users',
'id' => 'test',
'value'=>function($data) use ($select_data){
return CHtml::dropDownList('usersselectlist'.$data->id','',$select_data);
},
),
.......
Something like this should work.
Hello i created a separate search form having input box and button.
in my model i want to search products by category wise...
but problem is that when input box is empty and clicking on search buttons it displays all entries from the database table..
controller code is-
class AddController extends Controller
{
public function actionAddsearch()
{
$model_form = new Add("search");
$attributes = Yii::app()->getRequest()->getPost("Add");
if(!is_null($attributes))
{
$model_form->setAttributes(Yii::app()->getRequest()->getPost("Add"));
}
$this->render("searchResults", array(
"model" => $model_form,
"models" => $model_form->searchAdd(),
));
}
model code--
class Add extends CActiveRecord
{
public function searchAdd()
{
$criteria = new CDbCriteria();
$criteria->compare("addname", $this->category, TRUE, "OR");
$criteria->compare("category", $this->category, TRUE, "OR");
return Add::model()->findAll($criteria);
}
view code- addsearch.php
<div class="search-bar">
<?php
$form=$this->beginWidget('bootstrap.widgets.TbActiveForm',array(
"action"=>$this->createUrl("add/addsearch"),
'type'=>'search',
)
);
echo $form->textFieldRow($model,'category');
echo "        ";
$this->widget('bootstrap.widgets.TbButton',array(
'buttonType'=>'submit',
'type'=>'success',
'size'=>'large',
'label'=>'Search For Products ',
));
$this->endWidget();
?>
</div>
searchResults.php
<?php
echo "<h4>Results for Your Search</h4>";
foreach($models as $model):
$this->beginWidget('bootstrap.widgets.TbDetailView',array(
'type'=>'bordered condensed',
'data' => array(
'Shop Name' =>CHtml::link(CHtml::encode($model->addname),array('add/view','id'=> $model->addid)),
'Category' => $model->category
),
'attributes' => array(array('name' => 'Shop Name', 'label' => 'Name of Shop','value'=>CHtml::link(CHtml::encode($model->addname),
array('add/view','id'=>$model->addid)),'type'=>'raw'),
array('name' => 'Category', 'label' => 'Category of Shop'),
),
)
);
echo "<br><hr><br>";
$this->endWidget();
endforeach;
?>
what is wrong in the code??
I want to display no any product when text box is empty..
thanks in advance
change this
if(!is_null($attributes))
{
$model_form->setAttributes(Yii::app()->getRequest()->getPost("Add"));
}
$this->render("searchResults", array(
"model" => $model_form,
"models" => $model_form->searchAdd(),
));
To
if($attributes)
{
$model_form->setAttributes(Yii::app()->getRequest()->getPost("Add"));
$this->render("searchResults", array(
"model" => $model_form,
"models" => $model_form->searchAdd(),
));
}
1) Is the 'caterory' attribute safe on search scenario ? (in rules)
2) category is an attribute of the table schema ?
how can I save value as ivar from dropDownlist in yii? here my code, which doesn't work :/
declaration of ivar:
public $blaaa;
and my dropdownlist code:
echo CHtml::dropDownList(
'categoryDropDownList',
'',
CHtml::listData(Category::model()->findAll(), 'id', 'name'),
array(
'empty' => 'Select Category',
'onchange'=>function () {
$this->blaaa = 'js:this.value';
}
));
I tried also with ajax, but it also doesnt work:
'ajax' => array(
'type' => 'POST',
'url' => CController::createUrl('category/actionBla'),
'data' => array('id' => 'js:this.value')
where
public function bla()
{
if (isset($_POST['id'])) {
$this->blaaa = $_POST['id'];
}
thanks in advance for help!
In ajax section, change url as below
'url' => CController::createUrl('category/bla'),
In controller, your function name should be
public function actionBla()
I solved my problem with echo'ing CHtml::dropDownList in form:
echo CHtml::form();
echo CHtml::dropDownList(
'categoryDropDownList',
'',
CHtml::listData(Category::model()->findAll(), 'id', 'name'),
array(
'empty' => 'Select Category'
));
echo CHtml::endForm();
and now activeForm bother about sending parameters via POST
I'm using cakephp, I have a model "comment" with two fields : "model_type" and "model_id" in order to comment every item of my application (eg Picture, News, Article, ...) with a single Comment model.
I wonder how to make this. (A component "Comment" for controller that could be commented ?)
Finally I want to list comment in view just with a helper:
$comment->show('model_name', 'item_id');
that would display correctly paginated comments and a form for adding a new comment to the item.
Thanks.
Edit: See this too : http://bakery.cakephp.org/articles/AD7six/2008/03/13/polymorphic-behavior
The Solution
A multi model commenting system and pagination just with :
<?php echo $this->element('comments',
array(
'model_type' => "model_name",
'model_id' => $data['model']['id'],
'order_field' => 'created',
'order' => 'asc')); ?>
The model
Scheme :
- id
- model_type
- model_id
- content
(optional:)
- user_id
- created
- updated
- rating
- ...
The Comment Model :
// {app}/models/comment.php
class Comment extends AppModel{
public $name = 'Comment';
// List of model that could be commented
protected $model_list = array(
'news' => array(
'name' => 'News', // here it's the model's name
'field' => 'validated'), // A field for validation ( allow comments only on validaded items)
'articles' => array(
'name' => 'Article',
'field' => 'validated')
);
// This is an example
public $belongsTo = array(
'User' => array(
'conditions' => 'User.validated = true'
)
);
public $validate = array(
'model_type' => array(
'rule' => 'checkModelType',
'message' => "Something goes wrong !"
),
'model_id' => array(
'rule' => 'checkModelId',
'message' => "Something goes wrong !"
),
'content' => array(
'rule' => 'notEmpty',
'message' => "Empty content !"
)
);
// Check if the model is commentable
public function checkModelType($data){
$model_type = $data['model_type'];
return in_array($model_type, array_keys($this->model_list));
}
// Check if the item exists and is validated
public function checkModelId($data){
$model_id = intval($data['model_id']);
$model = $this->model_list[$this->data['Comment']['model_type']];
$params = array(
'fields' => array('id', $model['field']),
'conditions' => array(
$model['name'].'.'.$model['field'] => 1, // Validated item
$model['name'].'.id' => $model_id
)
);
// Binding model to Comment Model since there is no $belongsTo
return (bool) ClassRegistry::init($model['name'])->find('first', $params);
}
}
The Controller
// {app}/controllers/comments_controller.php
class CommentsController extends AppController
{
public $name = 'Comments';
// Pagination works fine !
public $paginate = array(
'limit' => 15,
'order' => array(
'Comment.created' => 'asc')
);
// The action that lists comments for a specific item (plus pagination and order !)
public function view($model_type, $model_id, $order_field = 'created', $order = 'DESC'){
$conditions = array(
'Comment.model_type' => $model_type,
'Comment.model_id' => $model_id
);
// (optional)
if($order_field != 'created') {
$this->paginate['order'] = array(
'Comment.'.$order_field => $order,
'Comment.created' => 'asc');
}
// Paginate comments
$comments = $this->paginate($conditions);
// This allow to use paginator with requestAction
$paginator = ClassRegistry::getObject('view')->loaded['paginator'];
$paginator->params = $this->params;
return compact('comments', 'paginator');
}
public function add(){
// What you want !
}
}
The views
Comments element
/* {app}/views/elements/comments.ctp
#params : $model_type
* : $model_id
*
* */
$result = $this->requestAction("/comments/view/$model_type/$model_id/$order_field/$order/", $this->passedArgs);
$paginator = $result['paginator'];
$comments = $result['comments'];
$paginator->options(array('url' => $this->passedArgs));
?>
<h2>Comments</h2>
<fieldset class="commentform">
<legend>Add un commentaire</legend>
<?php
// Form
echo $form->create('Comment', array('action' => 'add'));
echo $form->hidden('model_type', array('value' => $model_type));
echo $form->hidden('model_id', array('value' => $model_id));
echo $form->input('content');
<?php
echo $form->end('Send');
?>
</fieldset>
<div class="paginationBar">
<?php
echo $paginator->prev('<< ', null, null, array('class' => 'disabled'));
echo '<span class="pagination">',$paginator->numbers(),'</span>';
echo $paginator->next(' >>', null, null, array('class' => 'disabled'));
?>
</div>
<?php
foreach($comments as $comment){
echo $this->element('comment', array('comment' => $comment));
}
?>
<div class="paginationBar">
<?php
echo $paginator->prev('<< ', null, null, array('class' => 'disabled'));
echo '<span class="pagination">',$paginator->numbers(),'</span>';
echo $paginator->next(' >>', null, null, array('class' => 'disabled'));
?>
<p><br />
<?php
echo $paginator->counter(array('format' => 'Page %page% on %pages%, displayi %current% items of %count%'));
?>
</p>
</div>
Comment element
//{app}/views/elements/comment.ctp
// A single comment view
$id = $comment['Comment']['id'];
?>
<div class="comment">
<p class="com-author">
<span class="com-authorname"><?=$comment['User']['name']?> </span>
<span class="com-date">(<?=$comment['Comment']['created']?>)</span>
</p>
<p class="com-content"><?=$comment['Comment']['content']?></p>
</div>
hm... it would be pretty complicated if you want to display paginated comments like that. You should use lazy loading: don't actually load the comments until the user click on it or something.
You should probably make an element. you can pass model_name and model_id to it. And in the element, you can create a comment 'widget' that can directly send the comment to your comments controller, using ajax; and load the paginated comments using ajax also.
Check out this plugin (it's actually a component) developed by CakeDC.
You could either implement that or, use that to create your own solution.