Related
I've been reading Yii's docs about CNumberFormatter and I didn't found any documentation about formatting a number in an ordinal way. So my question is:
Is it entirely possible to format a number using Yii's built-in CNumberFormatter class in an ordinal manner.
Example: $number = 1 -> format to ordinal -> returns `1st`.
If yes, how?
Extend your own formatter class, add code from Display numbers with ordinal suffix in PHP:
<?php
class CustomFormatter extends CFormatter {
public function formatOrdinal($value) {
$ends = array('th','st','nd','rd','th','th','th','th','th','th');
if (($value%100) >= 11 && ($value%100) <= 13)
return $value. 'th';
else
return $value. $ends[$value % 10];
}
}
Implement it in Yii's main.php config file:
// application components
'components' => array(
'format' => array(
'class' => 'application.extensions.CustomFormatter',
),
...
I want to display the name of Shift instead of shift_id
I have a dropboxlist from other table that is like this
<div>
<?php echo $form->labelEx($model,'mon'); ?>
<?php echo $form->dropDownList($model, 'mon', CHtml::listData(
Shift::model()->findAll(), 'shft_id', 'name'),
array('prompt' => 'Select a Department')
); ?>
<?php echo $form->error($model,'mon'); ?>
I have two tables that is
Day: id_day,mon,tues,wed,etc
Shift: shft_id,start,end,name,status
Here is the relation in the day
'shift'=>array(self::HAS_MANY,'Shift','shft_id'),
For Shift:
'day'=>array(self::BELONGS_TO,'Day','id_day'),
It is already working. The choices in the dropbox was the name of the Shift, and puts the shft_id in the mon,tues,wed,etc. In the view of the form it looks like
id_user: 3
mon:5
tues:5
wed:6
what I wanted to be is that in the view.
id_user: 3
mon: 6am-5pm
tues: 7am-6pm
etc.etc.
I dont know what command it is. I have no idea. Help me please
Instead of User::getusername() method.
I think you can simply use this in one line.
// format models resulting using listData
<?php echo $form->dropdownlist($model,'user_id', CHtml::listData(User::model()->findAll(),'id', 'name')); ?>
below is an example which I think may solved your problem
in _form.php
<?php echo $form->dropdownlist($model,'user_id', User::getusername()); ?>
<?php echo $form->error($model,'user_id'); ?></th>
in User model
public function getusername()
{
$criteria2=new CDbCriteria;
$criteria2->select='*';
$quser=User::model()->findAll($criteria2);
foreach($quser as $r)
{
$user_id= $r->user_id;
$user_name=$r->user_name;
$user_array[$user_id]=$user_name;
}
return $user_array;
}
I'm trying to understand what you are really asking. I believe you were saying that you are already able to populate your records correctly from the dropdowns. But when you are displaying, the view is only showing the shift_id value? The relation for the day should be able to get your shift name. How are you displaying the list:
mon: 5
tue: 5
wed: 6
I'm trying to understand if you need help displaying the dropdown items properly, or how to display the shift name later after the values have been set in the database. Also, your 'Day' table has me confused. What are the field names? Are they 'day_id' and 'day'? Or do you actually name the fields after each day of the week?
If you are displaying the data through a foreach and are getting each day (let's assume it is $day) object, then the relationship to 'shift' can give you the name like this: echo $day->shift->name; if the name displays as '#am-#pm'. Otherwise you can display it like this:
echo sprintf('%d a.m. - %d p.m.',$day->shift->start,$day->shift->end);
Thanks for the people who helped me. It did lead me to the answer anyone who has the same problem here is what i did.
In my model/Day
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'monday'=>array(self::BELONGS_TO,'Shift','mon'),
'tuesday'=>array(self::BELONGS_TO,'Shift','tue'),
'wednesday'=>array(self::BELONGS_TO,'Shift','wed'),
'thursday'=>array(self::BELONGS_TO,'Shift','thurs'),
'friday'=>array(self::BELONGS_TO,'Shift','fri'),
'saturday'=>array(self::BELONGS_TO,'Shift','sat'),
'sunday'=>array(self::BELONGS_TO,'Shift','sun'),
);
}
and In my models/Shift
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'day_mon' =>array(self::HAS_MANY,'Day','mon'),
'day_tue' =>array(self::HAS_MANY,'Day','tue'),
'day_wed' =>array(self::HAS_MANY,'Day','wed'),
'day_thurs'=> array(self::HAS_MANY,'Day','thurs'),
'day_fri'=>array(self::HAS_MANY,'Day','fri'),
'day_sat'=>array(self::HAS_MANY,'Day','sat'),
'day_sun'=>array(self::HAS_MANY,'Day','sun'),
);
}
The problem is with my relations. its not set properly, so you need to set it properly then go to Day/view
<?php $this->widget('bootstrap.widgets.TbDetailView',array(
'data'=>$model,
'attributes'=>array(
'id_day',
array(
'name'=>'mon',
'value'=>CHtml::encode($model->monday->name)
),
Here is the output
If you have a detail veiw then use the following code:
widget('zii.widgets.CDetailView', array(
'data'=>$model,
'attributes'=>array(
'id',
'name',
array(
'label' => $model->shift->getAttributeLabel('shift_name'),
'value' => $model->shift->shift_name
),)); ?>
In case anybody else will be in my boat, what you will need to do is edit view.php in view/modelname/view.php
widget('zii.widgets.CDetailView', array(
'data'=>$model,
'attributes'=>array(
'id',
'name',
'country_id')); ?>
into
widget('zii.widgets.CDetailView', array(
'data'=>$model,
'attributes'=>array(
'id',
'name',
array(
'label' => $model->country->getAttributeLabel('country'),
'value' => $model->country->name
),)); ?>
I'm trying to build a form that will enable the user to change values for multiple rows and then click submit. I am able to retrieve the rows from the database and display them in a table. However, instead of a textfield. I want to them to be droplists.
The $list contains options I want to display for each row's drop list.
What am I missing?
<div class="row bottom">
<?php
$list = CHtml::listData(Attendancetype::model()->findAll(), 'AttendanceTypeID', 'AttendanceTypeName');
print_r($list);
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=> $model->search(),
'columns'=>array(
'CalendarDate',
'GradeName',
array(
'value'=>'$data->TeacherFirstName . " " . $data->TeacherLastname',
'header'=>'Teacher'
),
array(
'value'=>'$data->FirstName . " " . $data->LastName',
'header'=>'Student'
),
array(
'value'=>$list,
'type'=>'raw',
'header'=>'Status'
),
),
));
?>
</div>
Current error message.
PHP warning
call_user_func_array() expects parameter 1 to be a valid callback, array must have exactly two members
C:\wamp\www\yii\framework\base\CComponent.php(611)
599 * #since 1.1.0
600 */
601 public function evaluateExpression($_expression_,$_data_=array())
602 {
603 if(is_string($_expression_))
604 {
605 extract($_data_);
606 return eval('return '.$_expression_.';');
607 }
608 else
609 {
610 $_data_[]=$this;
611 return call_user_func_array($_expression_, $_data_);
612 }
613 }
614 }
615
616
Just to add to previous answer. If you want to use external variable you need to define it in your CColumn.
So your code will look like:
$list = CHtml::listData(Attendancetype::model()->findAll(), 'AttendanceTypeID', 'AttendanceTypeName');
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=> $model->search(),
'columns'=>array(
....
array('header'=>'Action',
'type'=>'raw',
'value'=> function ($data,$row) use $list {return CHtml::dropDownlist('actionList','', $list,array());}
),
This will work like you need. Same with Ninad answer.
Cgridview is most flexible yii widget and have alot of wiki examples.
Try doing this in your cgridview
array('header'=>'Action',
'type'=>'raw',
'value'=>"CHtml::dropDownlist('actionList','', CHtml::listData(
Attendancetype::model()->findAll(), 'AttendanceTypeID', 'AttendanceTypeName'),array())"
),
I'm using ClistView to display the content of a dataprovider.
ClistView is supposed to call a partial view, that will loop for each model.
I would like to display something (i.e. a tag) before the first model and something (i.e. a ) after the last model of the pagination.
Assume that I have a view (index.php):
$this->widget('zii.widgets.CListView', array(
'dataProvider'=>$localDataProvider,
'itemView'=>'_view', // refers to the partial view named '_post'
'summaryText'=>'Sono visualizzati i record da {start} a {end} su un totale di {count} libri',
'pager' => Array(
'header' => 'Vai alla pagina',
'prevPageLabel' => 'Indietro',
'nextPageLabel' => 'Avanti',
),
));
In _view.php I have just the cells of a table.
If I put before the widget the html to render the table header and just after the html to render the table footer I obtain that inside the div there is the html of the pager.
How I can shift the header and the footer directly in _view.php?
Thanks
With this class extension:
Yii::import('zii.widgets.CListView');
class PlainCListView extends CListView
{
public $preItemsTag = '';
public $postItemsTag = '';
public function renderItems()
{
echo $this->preItemsTag."\n";
$data=$this->dataProvider->getData();
if(($n=count($data))>0)
{
$owner=$this->getOwner();
$render=$owner instanceof CController ? 'renderPartial' : 'render';
$j=0;
foreach($data as $i=>$item)
{
$data=$this->viewData;
$data['index']=$i;
$data['data']=$item;
$data['widget']=$this;
$owner->$render($this->itemView,$data);
if($j++ < $n-1)
echo $this->separator;
}
}
else
$this->renderEmptyText();
echo $this->postItemsTag."\n";
}
}
I's possible to override the lines of the base version of the class
echo CHtml::openTag($this->itemsTagName,array('class'=>$this->itemsCssClass))."\n";
echo CHtml::closeTag($this->itemsTagName);
With this solution with code:
$pre_html = '<table><thead><th>Codice Account</th><th>Nome</th></thead><tbody>';
$post_html = '</tbody></table>';
$this->widget('zii.widgets.PlainCListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_view',
'preItemsTag'=>$pre_html,
'postItemsTag'=>$post_html,
'summaryText'=>'Sono visualizzati i record da {start} a {end} su un totale di {count} libri',
'pager' => Array(
'header' => 'Vai alla pagina',
'prevPageLabel' => 'Indietro',
'nextPageLabel' => 'Avanti',
),
'sortableAttributes'=>array('titolo'),
'enableSorting'=>0,
));
It's possible to get in the output what I need.
Since you are trying to generate a table, you should be trying to do it using CGridView instead of CListView.
Try setting the template for the CClistView as
'template' => "<your header tag>{items}<your footer tag>{pager}",
you might arrange the template stuff as you need.
I am using CGridView in Yii, how can I display a single record in 2 lines?
Basically I want to show a record details in 1st row of table and on other row I want to display its summary, I tried it with div and css but can't get proper results, is anyone there who can help me in this case?
I am using like this:
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'bidding-grid',
'itemsCssClass' => 'data-default',
'dataProvider'=>$model,
'summaryText' => '',
'columns'=>array(
'people_detail_for_bid.Person' => array(
'type'=>'raw',
'name'=>'people_detail_for_bid.Person',
'value'=>'Yii::app()->Controller->createUserNameLink($data->people_detail_for_bid->PeopleFirstName." ".$data->people_detail_for_bid->PeopleLastName, $data->people_detail_for_bid->PeopleId).
"<br><span class=decriptionText>".$data->people_detail_for_bid->PeopleDesignation."</span>".
"<br><span class=decriptionText>".$data->people_detail_for_bid->PeopleEmail."</span>"',
'htmlOptions'=>array('width'=>200),
),
'timeAgo' => array(
'type'=>'raw',
'name'=>'timeAgo',
'value'=>'"<span class=decriptionText>".Yii::app()->Controller->_ago($data->PBPostedOn)."</sapn>"',
'htmlOptions'=>array('width'=>150),
),
),
));
?>
I think the best and cleanest way to accomplish this is to create a new extension and extend it to CGridView, override the renderTableRow function like this:
/**
* Renders a table body row.
* #param integer $row the row number (zero-based).
*/
public function renderTableRow($row)
{
if($this->rowCssClassExpression!==null)
{
$data=$this->dataProvider->data[$row];
echo '<tr class="'.$this->evaluateExpression($this->rowCssClassExpression,array('row'=>$row,'data'=>$data)).'">';
}
else if(is_array($this->rowCssClass) && ($n=count($this->rowCssClass))>0)
echo '<tr class="'.$this->rowCssClass[$row%$n].'">';
else
echo '<tr>';
$colCtr = 0;
foreach($this->columns as $column){
$column->renderDataCell($row);
$colCtr++;
}
echo "</tr>\n";
echo "<tr><td colspan=\"$colCtr\">This is the summary row. </td></tr>";
}
You can customize what you are rendering in the columns, so if you want to show two different fields of your table in the same row, you have to create a function in your model:
public function customColumn()
{
return $this->PeopleDesignation.'<br/>'.$this->PeopleEmail;
}
And then assign the method to the value of your column:
array(
'type'=>'html',
'value'=>'$data->customColumn()'
),
Cheers, Pablo.
After too much search .. and I tried with different ways now finally got a solution for this .. that solution is basically a kind of 2nd way to do anything not actual way .. but it works to me ..
.....
.....
'timeAgo' => array(
'type'=>'raw',
'name'=>'timeAgo',
'value'=>'"<span class=decriptionText>".Yii::app()->Controller->_ago($data->PBPostedOn)."</sapn></td></tr><tr><td colspan=\"6\"><span class=decriptionText>".$data->PBSummary."</span>"',
'htmlOptions'=>array('width'=>150),
),
.....
.....
added some table tags on last column to close row and added another one.
hope it works for all ..
thanks ..
Sounds like 2 interleaved CGridViews. So you might try that, but I can't imagine it will work out well:
Overlay one CGridView over the other, with enough transparent space in each row for the other to display it's row, and ...
a. one `CGridView` table offset vertically by half a row height, *OR*
b. one table's row's text vertically top-aligned & the other bottom-aligned
But somehow I doubt that's a CGridView capability ;) And keeping the two in sync so they pagenate and scroll together would be darn near impossible. Sounds like you need to enhance CGridView or derive a new widget from CGridView. I wonder if JQuery has something to do this?