Added new (clean) yii boilerplate
123
framework/zii/behaviors/CTimestampBehavior.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
/**
|
||||
* CTimestampBehavior class file.
|
||||
*
|
||||
* @author Jonah Turnquist <poppitypop@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CTimestampBehavior will automatically fill date and time related attributes.
|
||||
*
|
||||
* CTimestampBehavior will automatically fill date and time related attributes when the active record
|
||||
* is created and/or updated.
|
||||
* You may specify an active record model to use this behavior like so:
|
||||
* <pre>
|
||||
* public function behaviors(){
|
||||
* return array(
|
||||
* 'CTimestampBehavior' => array(
|
||||
* 'class' => 'zii.behaviors.CTimestampBehavior',
|
||||
* 'createAttribute' => 'create_time_attribute',
|
||||
* 'updateAttribute' => 'update_time_attribute',
|
||||
* )
|
||||
* );
|
||||
* }
|
||||
* </pre>
|
||||
* The {@link createAttribute} and {@link updateAttribute} options actually default to 'create_time' and 'update_time'
|
||||
* respectively, so it is not required that you configure them. If you do not wish CTimestampBehavior
|
||||
* to set a timestamp for record update or creation, set the corresponding attribute option to null.
|
||||
*
|
||||
* By default, the update attribute is only set on record update. If you also wish it to be set on record creation,
|
||||
* set the {@link setUpdateOnCreate} option to true.
|
||||
*
|
||||
* Although CTimestampBehavior attempts to figure out on it's own what value to inject into the timestamp attribute,
|
||||
* you may specify a custom value to use instead via {@link timestampExpression}
|
||||
*
|
||||
* @author Jonah Turnquist <poppitypop@gmail.com>
|
||||
* @package zii.behaviors
|
||||
* @since 1.1
|
||||
*/
|
||||
|
||||
class CTimestampBehavior extends CActiveRecordBehavior {
|
||||
/**
|
||||
* @var mixed The name of the attribute to store the creation time. Set to null to not
|
||||
* use a timestamp for the creation attribute. Defaults to 'create_time'
|
||||
*/
|
||||
public $createAttribute = 'create_time';
|
||||
/**
|
||||
* @var mixed The name of the attribute to store the modification time. Set to null to not
|
||||
* use a timestamp for the update attribute. Defaults to 'update_time'
|
||||
*/
|
||||
public $updateAttribute = 'update_time';
|
||||
|
||||
/**
|
||||
* @var bool Whether to set the update attribute to the creation timestamp upon creation.
|
||||
* Otherwise it will be left alone. Defaults to false.
|
||||
*/
|
||||
public $setUpdateOnCreate = false;
|
||||
|
||||
/**
|
||||
* @var mixed The expression that will be used for generating the timestamp.
|
||||
* This can be either a string representing a PHP expression (e.g. 'time()'),
|
||||
* or a {@link CDbExpression} object representing a DB expression (e.g. new CDbExpression('NOW()')).
|
||||
* Defaults to null, meaning that we will attempt to figure out the appropriate timestamp
|
||||
* automatically. If we fail at finding the appropriate timestamp, then it will
|
||||
* fall back to using the current UNIX timestamp.
|
||||
*
|
||||
* A PHP expression can be any PHP code that has a value. To learn more about what an expression is,
|
||||
* please refer to the {@link http://www.php.net/manual/en/language.expressions.php php manual}.
|
||||
*/
|
||||
public $timestampExpression;
|
||||
|
||||
/**
|
||||
* @var array Maps column types to database method
|
||||
*/
|
||||
protected static $map = array(
|
||||
'datetime'=>'NOW()',
|
||||
'timestamp'=>'NOW()',
|
||||
'date'=>'NOW()',
|
||||
);
|
||||
|
||||
/**
|
||||
* Responds to {@link CModel::onBeforeSave} event.
|
||||
* Sets the values of the creation or modified attributes as configured
|
||||
*
|
||||
* @param CModelEvent $event event parameter
|
||||
*/
|
||||
public function beforeSave($event) {
|
||||
if ($this->getOwner()->getIsNewRecord() && ($this->createAttribute !== null)) {
|
||||
$this->getOwner()->{$this->createAttribute} = $this->getTimestampByAttribute($this->createAttribute);
|
||||
}
|
||||
if ((!$this->getOwner()->getIsNewRecord() || $this->setUpdateOnCreate) && ($this->updateAttribute !== null)) {
|
||||
$this->getOwner()->{$this->updateAttribute} = $this->getTimestampByAttribute($this->updateAttribute);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the appropriate timestamp depending on the column type $attribute is
|
||||
*
|
||||
* @param string $attribute $attribute
|
||||
* @return mixed timestamp (eg unix timestamp or a mysql function)
|
||||
*/
|
||||
protected function getTimestampByAttribute($attribute) {
|
||||
if ($this->timestampExpression instanceof CDbExpression)
|
||||
return $this->timestampExpression;
|
||||
elseif ($this->timestampExpression !== null)
|
||||
return @eval('return '.$this->timestampExpression.';');
|
||||
|
||||
$columnType = $this->getOwner()->getTableSchema()->getColumn($attribute)->dbType;
|
||||
return $this->getTimestampByColumnType($columnType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the appropriate timestamp depending on $columnType
|
||||
*
|
||||
* @param string $columnType $columnType
|
||||
* @return mixed timestamp (eg unix timestamp or a mysql function)
|
||||
*/
|
||||
protected function getTimestampByColumnType($columnType) {
|
||||
return isset(self::$map[$columnType]) ? new CDbExpression(self::$map[$columnType]) : time();
|
||||
}
|
||||
}
|
||||
293
framework/zii/widgets/CBaseListView.php
Normal file
@@ -0,0 +1,293 @@
|
||||
<?php
|
||||
/**
|
||||
* CBaseListView class file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CBaseListView is the base class for {@link CListView} and {@link CGridView}.
|
||||
*
|
||||
* CBaseListView implements the common features needed by a view wiget for rendering multiple models.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package zii.widgets
|
||||
* @since 1.1
|
||||
*/
|
||||
abstract class CBaseListView extends CWidget
|
||||
{
|
||||
/**
|
||||
* @var IDataProvider the data provider for the view.
|
||||
*/
|
||||
public $dataProvider;
|
||||
/**
|
||||
* @var string the tag name for the view container. Defaults to 'div'.
|
||||
*/
|
||||
public $tagName='div';
|
||||
/**
|
||||
* @var array the HTML options for the view container tag.
|
||||
*/
|
||||
public $htmlOptions=array();
|
||||
/**
|
||||
* @var boolean whether to enable sorting. Note that if the {@link IDataProvider::sort} property
|
||||
* of {@link dataProvider} is false, this will be treated as false as well. When sorting is enabled,
|
||||
* sortable columns will have their headers clickable to trigger sorting along that column.
|
||||
* Defaults to true.
|
||||
* @see sortableAttributes
|
||||
*/
|
||||
public $enableSorting=true;
|
||||
/**
|
||||
* @var boolean whether to enable pagination. Note that if the {@link IDataProvider::pagination} property
|
||||
* of {@link dataProvider} is false, this will be treated as false as well. When pagination is enabled,
|
||||
* a pager will be displayed in the view so that it can trigger pagination of the data display.
|
||||
* Defaults to true.
|
||||
*/
|
||||
public $enablePagination=true;
|
||||
/**
|
||||
* @var array|string the configuration for the pager. Defaults to <code>array('class'=>'CLinkPager')</code>.
|
||||
* String value will be treated as the class name of the pager (<code>'ClassName'</code> value is similar
|
||||
* to the <code>array('class'=>'ClassName')</code> value). See {@link CBasePager} and {@link CLinkPager}
|
||||
* for more details about pager configuration array values.
|
||||
* @see enablePagination
|
||||
*/
|
||||
public $pager=array('class'=>'CLinkPager');
|
||||
/**
|
||||
* @var string the template to be used to control the layout of various sections in the view.
|
||||
* These tokens are recognized: {summary}, {items} and {pager}. They will be replaced with the
|
||||
* summary text, the items, and the pager.
|
||||
*/
|
||||
public $template="{summary}\n{items}\n{pager}";
|
||||
/**
|
||||
* @var string the summary text template for the view. These tokens are recognized and will be replaced
|
||||
* with the corresponding values:
|
||||
* <ul>
|
||||
* <li>{start}: the starting row number (1-based) currently being displayed</li>
|
||||
* <li>{end}: the ending row number (1-based) currently being displayed</li>
|
||||
* <li>{count}: the total number of rows</li>
|
||||
* <li>{page}: the page number (1-based) current being displayed, available since version 1.1.3</li>
|
||||
* <li>{pages}: the total number of pages, available since version 1.1.3</li>
|
||||
* </ul>
|
||||
*/
|
||||
public $summaryText;
|
||||
/**
|
||||
* @var string the message to be displayed when {@link dataProvider} does not have any data.
|
||||
*/
|
||||
public $emptyText;
|
||||
/**
|
||||
* @var string the HTML tag name for the container of the {@link emptyText} property.
|
||||
*/
|
||||
public $emptyTagName='span';
|
||||
/**
|
||||
* @var string the CSS class name for the container of all data item display. Defaults to 'items'.
|
||||
*/
|
||||
public $itemsCssClass='items';
|
||||
/**
|
||||
* @var string the CSS class name for the summary text container. Defaults to 'summary'.
|
||||
*/
|
||||
public $summaryCssClass='summary';
|
||||
/**
|
||||
* @var string the CSS class name for the pager container. Defaults to 'pager'.
|
||||
*/
|
||||
public $pagerCssClass='pager';
|
||||
/**
|
||||
* @var string the CSS class name that will be assigned to the widget container element
|
||||
* when the widget is updating its content via AJAX. Defaults to 'loading'.
|
||||
* @since 1.1.1
|
||||
*/
|
||||
public $loadingCssClass='loading';
|
||||
|
||||
/**
|
||||
* Initializes the view.
|
||||
* This method will initialize required property values and instantiate {@link columns} objects.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if($this->dataProvider===null)
|
||||
throw new CException(Yii::t('zii','The "dataProvider" property cannot be empty.'));
|
||||
|
||||
$this->dataProvider->getData();
|
||||
|
||||
if(isset($this->htmlOptions['id']))
|
||||
$this->id=$this->htmlOptions['id'];
|
||||
else
|
||||
$this->htmlOptions['id']=$this->id;
|
||||
|
||||
if($this->enableSorting && $this->dataProvider->getSort()===false)
|
||||
$this->enableSorting=false;
|
||||
if($this->enablePagination && $this->dataProvider->getPagination()===false)
|
||||
$this->enablePagination=false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the view.
|
||||
* This is the main entry of the whole view rendering.
|
||||
* Child classes should mainly override {@link renderContent} method.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->registerClientScript();
|
||||
|
||||
echo CHtml::openTag($this->tagName,$this->htmlOptions)."\n";
|
||||
|
||||
$this->renderContent();
|
||||
$this->renderKeys();
|
||||
|
||||
echo CHtml::closeTag($this->tagName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the main content of the view.
|
||||
* The content is divided into sections, such as summary, items, pager.
|
||||
* Each section is rendered by a method named as "renderXyz", where "Xyz" is the section name.
|
||||
* The rendering results will replace the corresponding placeholders in {@link template}.
|
||||
*/
|
||||
public function renderContent()
|
||||
{
|
||||
ob_start();
|
||||
echo preg_replace_callback("/{(\w+)}/",array($this,'renderSection'),$this->template);
|
||||
ob_end_flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a section.
|
||||
* This method is invoked by {@link renderContent} for every placeholder found in {@link template}.
|
||||
* It should return the rendering result that would replace the placeholder.
|
||||
* @param array $matches the matches, where $matches[0] represents the whole placeholder,
|
||||
* while $matches[1] contains the name of the matched placeholder.
|
||||
* @return string the rendering result of the section
|
||||
*/
|
||||
protected function renderSection($matches)
|
||||
{
|
||||
$method='render'.$matches[1];
|
||||
if(method_exists($this,$method))
|
||||
{
|
||||
$this->$method();
|
||||
$html=ob_get_contents();
|
||||
ob_clean();
|
||||
return $html;
|
||||
}
|
||||
else
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the empty message when there is no data.
|
||||
*/
|
||||
public function renderEmptyText()
|
||||
{
|
||||
$emptyText=$this->emptyText===null ? Yii::t('zii','No results found.') : $this->emptyText;
|
||||
echo CHtml::tag($this->emptyTagName, array('class'=>'empty'), $emptyText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the key values of the data in a hidden tag.
|
||||
*/
|
||||
public function renderKeys()
|
||||
{
|
||||
echo CHtml::openTag('div',array(
|
||||
'class'=>'keys',
|
||||
'style'=>'display:none',
|
||||
'title'=>Yii::app()->getRequest()->getUrl(),
|
||||
));
|
||||
foreach($this->dataProvider->getKeys() as $key)
|
||||
echo "<span>".CHtml::encode($key)."</span>";
|
||||
echo "</div>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the summary text.
|
||||
*/
|
||||
public function renderSummary()
|
||||
{
|
||||
if(($count=$this->dataProvider->getItemCount())<=0)
|
||||
return;
|
||||
|
||||
echo '<div class="'.$this->summaryCssClass.'">';
|
||||
if($this->enablePagination)
|
||||
{
|
||||
$pagination=$this->dataProvider->getPagination();
|
||||
$total=$this->dataProvider->getTotalItemCount();
|
||||
$start=$pagination->currentPage*$pagination->pageSize+1;
|
||||
$end=$start+$count-1;
|
||||
if($end>$total)
|
||||
{
|
||||
$end=$total;
|
||||
$start=$end-$count+1;
|
||||
}
|
||||
if(($summaryText=$this->summaryText)===null)
|
||||
$summaryText=Yii::t('zii','Displaying {start}-{end} of 1 result.|Displaying {start}-{end} of {count} results.',$total);
|
||||
echo strtr($summaryText,array(
|
||||
'{start}'=>$start,
|
||||
'{end}'=>$end,
|
||||
'{count}'=>$total,
|
||||
'{page}'=>$pagination->currentPage+1,
|
||||
'{pages}'=>$pagination->pageCount,
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(($summaryText=$this->summaryText)===null)
|
||||
$summaryText=Yii::t('zii','Total 1 result.|Total {count} results.',$count);
|
||||
echo strtr($summaryText,array(
|
||||
'{count}'=>$count,
|
||||
'{start}'=>1,
|
||||
'{end}'=>$count,
|
||||
'{page}'=>1,
|
||||
'{pages}'=>1,
|
||||
));
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the pager.
|
||||
*/
|
||||
public function renderPager()
|
||||
{
|
||||
if(!$this->enablePagination)
|
||||
return;
|
||||
|
||||
$pager=array();
|
||||
$class='CLinkPager';
|
||||
if(is_string($this->pager))
|
||||
$class=$this->pager;
|
||||
elseif(is_array($this->pager))
|
||||
{
|
||||
$pager=$this->pager;
|
||||
if(isset($pager['class']))
|
||||
{
|
||||
$class=$pager['class'];
|
||||
unset($pager['class']);
|
||||
}
|
||||
}
|
||||
$pager['pages']=$this->dataProvider->getPagination();
|
||||
|
||||
if($pager['pages']->getPageCount()>1)
|
||||
{
|
||||
echo '<div class="'.$this->pagerCssClass.'">';
|
||||
$this->widget($class,$pager);
|
||||
echo '</div>';
|
||||
}
|
||||
else
|
||||
$this->widget($class,$pager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers necessary client scripts.
|
||||
* This method is invoked by {@link run}.
|
||||
* Child classes may override this method to register customized client scripts.
|
||||
*/
|
||||
public function registerClientScript()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the data items for the view.
|
||||
* Each item is corresponding to a single data model instance.
|
||||
* Child classes should override this method to provide the actual item rendering logic.
|
||||
*/
|
||||
abstract public function renderItems();
|
||||
}
|
||||
132
framework/zii/widgets/CBreadcrumbs.php
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/**
|
||||
* CBreadcrumbs class file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CBreadcrumbs displays a list of links indicating the position of the current page in the whole website.
|
||||
*
|
||||
* For example, breadcrumbs like "Home > Sample Post > Edit" means the user is viewing an edit page
|
||||
* for the "Sample Post". He can click on "Sample Post" to view that page, or he can click on "Home"
|
||||
* to return to the homepage.
|
||||
*
|
||||
* To use CBreadcrumbs, one usually needs to configure its {@link links} property, which specifies
|
||||
* the links to be displayed. For example,
|
||||
*
|
||||
* <pre>
|
||||
* $this->widget('zii.widgets.CBreadcrumbs', array(
|
||||
* 'links'=>array(
|
||||
* 'Sample post'=>array('post/view', 'id'=>12),
|
||||
* 'Edit',
|
||||
* ),
|
||||
* ));
|
||||
* </pre>
|
||||
*
|
||||
* Because breadcrumbs usually appears in nearly every page of a website, the widget is better to be placed
|
||||
* in a layout view. One can define a property "breadcrumbs" in the base controller class and assign it to the widget
|
||||
* in the layout, like the following:
|
||||
*
|
||||
* <pre>
|
||||
* $this->widget('zii.widgets.CBreadcrumbs', array(
|
||||
* 'links'=>$this->breadcrumbs,
|
||||
* ));
|
||||
* </pre>
|
||||
*
|
||||
* Then, in each view script, one only needs to assign the "breadcrumbs" property as needed.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package zii.widgets
|
||||
* @since 1.1
|
||||
*/
|
||||
class CBreadcrumbs extends CWidget
|
||||
{
|
||||
/**
|
||||
* @var string the tag name for the breadcrumbs container tag. Defaults to 'div'.
|
||||
*/
|
||||
public $tagName='div';
|
||||
/**
|
||||
* @var array the HTML attributes for the breadcrumbs container tag.
|
||||
*/
|
||||
public $htmlOptions=array('class'=>'breadcrumbs');
|
||||
/**
|
||||
* @var boolean whether to HTML encode the link labels. Defaults to true.
|
||||
*/
|
||||
public $encodeLabel=true;
|
||||
/**
|
||||
* @var string the first hyperlink in the breadcrumbs (called home link).
|
||||
* If this property is not set, it defaults to a link pointing to {@link CWebApplication::homeUrl} with label 'Home'.
|
||||
* If this property is false, the home link will not be rendered.
|
||||
*/
|
||||
public $homeLink;
|
||||
/**
|
||||
* @var array list of hyperlinks to appear in the breadcrumbs. If this property is empty,
|
||||
* the widget will not render anything. Each key-value pair in the array
|
||||
* will be used to generate a hyperlink by calling CHtml::link(key, value). For this reason, the key
|
||||
* refers to the label of the link while the value can be a string or an array (used to
|
||||
* create a URL). For more details, please refer to {@link CHtml::link}.
|
||||
* If an element's key is an integer, it means the element will be rendered as a label only (meaning the current page).
|
||||
*
|
||||
* The following example will generate breadcrumbs as "Home > Sample post > Edit", where "Home" points to the homepage,
|
||||
* "Sample post" points to the "index.php?r=post/view&id=12" page, and "Edit" is a label. Note that the "Home" link
|
||||
* is specified via {@link homeLink} separately.
|
||||
*
|
||||
* <pre>
|
||||
* array(
|
||||
* 'Sample post'=>array('post/view', 'id'=>12),
|
||||
* 'Edit',
|
||||
* )
|
||||
* </pre>
|
||||
*/
|
||||
public $links=array();
|
||||
/**
|
||||
* @var string String, specifies how each active item is rendered. Defaults to
|
||||
* "<a href="{url}">{label}</a>", where "{label}" will be replaced by the corresponding item
|
||||
* label while "{url}" will be replaced by the URL of the item.
|
||||
* @since 1.1.11
|
||||
*/
|
||||
public $activeLinkTemplate='<a href="{url}">{label}</a>';
|
||||
/**
|
||||
* @var string String, specifies how each inactive item is rendered. Defaults to
|
||||
* "<span>{label}</span>", where "{label}" will be replaced by the corresponding item label.
|
||||
* Note that inactive template does not have "{url}" parameter.
|
||||
* @since 1.1.11
|
||||
*/
|
||||
public $inactiveLinkTemplate='<span>{label}</span>';
|
||||
/**
|
||||
* @var string the separator between links in the breadcrumbs. Defaults to ' » '.
|
||||
*/
|
||||
public $separator=' » ';
|
||||
|
||||
/**
|
||||
* Renders the content of the portlet.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
if(empty($this->links))
|
||||
return;
|
||||
|
||||
echo CHtml::openTag($this->tagName,$this->htmlOptions)."\n";
|
||||
$links=array();
|
||||
if($this->homeLink===null)
|
||||
$links[]=CHtml::link(Yii::t('zii','Home'),Yii::app()->homeUrl);
|
||||
elseif($this->homeLink!==false)
|
||||
$links[]=$this->homeLink;
|
||||
foreach($this->links as $label=>$url)
|
||||
{
|
||||
if(is_string($label) || is_array($url))
|
||||
$links[]=strtr($this->activeLinkTemplate,array(
|
||||
'{url}'=>CHtml::normalizeUrl($url),
|
||||
'{label}'=>$this->encodeLabel ? CHtml::encode($label) : $label,
|
||||
));
|
||||
else
|
||||
$links[]=str_replace('{label}',$this->encodeLabel ? CHtml::encode($url) : $url,$this->inactiveLinkTemplate);
|
||||
}
|
||||
echo implode($this->separator,$links);
|
||||
echo CHtml::closeTag($this->tagName);
|
||||
}
|
||||
}
|
||||
258
framework/zii/widgets/CDetailView.php
Normal file
@@ -0,0 +1,258 @@
|
||||
<?php
|
||||
/**
|
||||
* CDetailView class file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CDetailView displays the detail of a single data model.
|
||||
*
|
||||
* CDetailView is best used for displaying a model in a regular format (e.g. each model attribute
|
||||
* is displayed as a row in a table.) The model can be either an instance of {@link CModel}
|
||||
* or an associative array.
|
||||
*
|
||||
* CDetailView uses the {@link attributes} property to determines which model attributes
|
||||
* should be displayed and how they should be formatted.
|
||||
*
|
||||
* A typical usage of CDetailView is as follows:
|
||||
* <pre>
|
||||
* $this->widget('zii.widgets.CDetailView', array(
|
||||
* 'data'=>$model,
|
||||
* 'attributes'=>array(
|
||||
* 'title', // title attribute (in plain text)
|
||||
* 'owner.name', // an attribute of the related object "owner"
|
||||
* 'description:html', // description attribute in HTML
|
||||
* array( // related city displayed as a link
|
||||
* 'label'=>'City',
|
||||
* 'type'=>'raw',
|
||||
* 'value'=>CHtml::link(CHtml::encode($model->city->name),
|
||||
* array('city/view','id'=>$model->city->id)),
|
||||
* ),
|
||||
* ),
|
||||
* ));
|
||||
* </pre>
|
||||
*
|
||||
* @property CFormatter $formatter The formatter instance. Defaults to the 'format' application component.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package zii.widgets
|
||||
* @since 1.1
|
||||
*/
|
||||
class CDetailView extends CWidget
|
||||
{
|
||||
private $_formatter;
|
||||
|
||||
/**
|
||||
* @var mixed the data model whose details are to be displayed. This can be either a {@link CModel} instance
|
||||
* (e.g. a {@link CActiveRecord} object or a {@link CFormModel} object) or an associative array.
|
||||
*/
|
||||
public $data;
|
||||
/**
|
||||
* @var array a list of attributes to be displayed in the detail view. Each array element
|
||||
* represents the specification for displaying one particular attribute.
|
||||
*
|
||||
* An attribute can be specified as a string in the format of "Name:Type:Label".
|
||||
* Both "Type" and "Label" are optional.
|
||||
*
|
||||
* "Name" refers to the attribute name. It can be either a property (e.g. "title") or a sub-property (e.g. "owner.username").
|
||||
*
|
||||
* "Label" represents the label for the attribute display. If it is not given, "Name" will be used to generate the appropriate label.
|
||||
*
|
||||
* "Type" represents the type of the attribute. It determines how the attribute value should be formatted and displayed.
|
||||
* It is defaulted to be 'text'.
|
||||
* "Type" should be recognizable by the {@link formatter}. In particular, if "Type" is "xyz", then the "formatXyz" method
|
||||
* of {@link formatter} will be invoked to format the attribute value for display. By default when {@link CFormatter} is used,
|
||||
* these "Type" values are valid: raw, text, ntext, html, date, time, datetime, boolean, number, email, image, url.
|
||||
* For more details about these types, please refer to {@link CFormatter}.
|
||||
*
|
||||
* An attribute can also be specified in terms of an array with the following elements:
|
||||
* <ul>
|
||||
* <li>label: the label associated with the attribute. If this is not specified, the following "name" element
|
||||
* will be used to generate an appropriate label.</li>
|
||||
* <li>name: the name of the attribute. This can be either a property or a sub-property of the model.
|
||||
* If the below "value" element is specified, this will be ignored.</li>
|
||||
* <li>value: the value to be displayed. If this is not specified, the above "name" element will be used
|
||||
* to retrieve the corresponding attribute value for display. Note that this value will be formatted according
|
||||
* to the "type" option as described below.</li>
|
||||
* <li>type: the type of the attribute that determines how the attribute value would be formatted.
|
||||
* Please see above for possible values.
|
||||
* <li>cssClass: the CSS class to be used for this item. This option is available since version 1.1.3.</li>
|
||||
* <li>template: the template used to render the attribute. If this is not specified, {@link itemTemplate}
|
||||
* will be used instead. For more details on how to set this option, please refer to {@link itemTemplate}.
|
||||
* This option is available since version 1.1.1.</li>
|
||||
* <li>visible: whether the attribute is visible. If set to <code>false</code>, the table row for the attribute will not be rendered.
|
||||
* This option is available since version 1.1.5.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public $attributes;
|
||||
/**
|
||||
* @var string the text to be displayed when an attribute value is null. Defaults to "Not set".
|
||||
*/
|
||||
public $nullDisplay;
|
||||
/**
|
||||
* @var string the name of the tag for rendering the detail view. Defaults to 'table'.
|
||||
* If set to null, no tag will be rendered.
|
||||
* @see itemTemplate
|
||||
*/
|
||||
public $tagName='table';
|
||||
/**
|
||||
* @var string the template used to render a single attribute. Defaults to a table row.
|
||||
* These tokens are recognized: "{class}", "{label}" and "{value}". They will be replaced
|
||||
* with the CSS class name for the item, the label and the attribute value, respectively.
|
||||
* @see itemCssClass
|
||||
*/
|
||||
public $itemTemplate="<tr class=\"{class}\"><th>{label}</th><td>{value}</td></tr>\n";
|
||||
/**
|
||||
* @var array the CSS class names for the items displaying attribute values. If multiple CSS class names are given,
|
||||
* they will be assigned to the items sequentially and repeatedly.
|
||||
* Defaults to <code>array('odd', 'even')</code>.
|
||||
*/
|
||||
public $itemCssClass=array('odd','even');
|
||||
/**
|
||||
* @var array the HTML options used for {@link tagName}
|
||||
*/
|
||||
public $htmlOptions=array('class'=>'detail-view');
|
||||
/**
|
||||
* @var string the base script URL for all detail view resources (e.g. javascript, CSS file, images).
|
||||
* Defaults to null, meaning using the integrated detail view resources (which are published as assets).
|
||||
*/
|
||||
public $baseScriptUrl;
|
||||
/**
|
||||
* @var string the URL of the CSS file used by this detail view. Defaults to null, meaning using the integrated
|
||||
* CSS file. If this is set false, you are responsible to explicitly include the necessary CSS file in your page.
|
||||
*/
|
||||
public $cssFile;
|
||||
|
||||
/**
|
||||
* Initializes the detail view.
|
||||
* This method will initialize required property values.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if($this->data===null)
|
||||
throw new CException(Yii::t('zii','Please specify the "data" property.'));
|
||||
if($this->attributes===null)
|
||||
{
|
||||
if($this->data instanceof CModel)
|
||||
$this->attributes=$this->data->attributeNames();
|
||||
elseif(is_array($this->data))
|
||||
$this->attributes=array_keys($this->data);
|
||||
else
|
||||
throw new CException(Yii::t('zii','Please specify the "attributes" property.'));
|
||||
}
|
||||
if($this->nullDisplay===null)
|
||||
$this->nullDisplay='<span class="null">'.Yii::t('zii','Not set').'</span>';
|
||||
if(isset($this->htmlOptions['id']))
|
||||
$this->id=$this->htmlOptions['id'];
|
||||
else
|
||||
$this->htmlOptions['id']=$this->id;
|
||||
|
||||
if($this->baseScriptUrl===null)
|
||||
$this->baseScriptUrl=Yii::app()->getAssetManager()->publish(Yii::getPathOfAlias('zii.widgets.assets')).'/detailview';
|
||||
|
||||
if($this->cssFile!==false)
|
||||
{
|
||||
if($this->cssFile===null)
|
||||
$this->cssFile=$this->baseScriptUrl.'/styles.css';
|
||||
Yii::app()->getClientScript()->registerCssFile($this->cssFile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the detail view.
|
||||
* This is the main entry of the whole detail view rendering.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$formatter=$this->getFormatter();
|
||||
if ($this->tagName!==null)
|
||||
echo CHtml::openTag($this->tagName,$this->htmlOptions);
|
||||
|
||||
$i=0;
|
||||
$n=is_array($this->itemCssClass) ? count($this->itemCssClass) : 0;
|
||||
|
||||
foreach($this->attributes as $attribute)
|
||||
{
|
||||
if(is_string($attribute))
|
||||
{
|
||||
if(!preg_match('/^([\w\.]+)(:(\w*))?(:(.*))?$/',$attribute,$matches))
|
||||
throw new CException(Yii::t('zii','The attribute must be specified in the format of "Name:Type:Label", where "Type" and "Label" are optional.'));
|
||||
$attribute=array(
|
||||
'name'=>$matches[1],
|
||||
'type'=>isset($matches[3]) ? $matches[3] : 'text',
|
||||
);
|
||||
if(isset($matches[5]))
|
||||
$attribute['label']=$matches[5];
|
||||
}
|
||||
|
||||
if(isset($attribute['visible']) && !$attribute['visible'])
|
||||
continue;
|
||||
|
||||
$tr=array('{label}'=>'', '{class}'=>$n ? $this->itemCssClass[$i%$n] : '');
|
||||
if(isset($attribute['cssClass']))
|
||||
$tr['{class}']=$attribute['cssClass'].' '.($n ? $tr['{class}'] : '');
|
||||
|
||||
if(isset($attribute['label']))
|
||||
$tr['{label}']=$attribute['label'];
|
||||
elseif(isset($attribute['name']))
|
||||
{
|
||||
if($this->data instanceof CModel)
|
||||
$tr['{label}']=$this->data->getAttributeLabel($attribute['name']);
|
||||
else
|
||||
$tr['{label}']=ucwords(trim(strtolower(str_replace(array('-','_','.'),' ',preg_replace('/(?<![A-Z])[A-Z]/', ' \0', $attribute['name'])))));
|
||||
}
|
||||
|
||||
if(!isset($attribute['type']))
|
||||
$attribute['type']='text';
|
||||
if(isset($attribute['value']))
|
||||
$value=is_callable($attribute['value']) ? call_user_func($attribute['value'],$this->data) : $attribute['value'];
|
||||
elseif(isset($attribute['name']))
|
||||
$value=CHtml::value($this->data,$attribute['name']);
|
||||
else
|
||||
$value=null;
|
||||
|
||||
$tr['{value}']=$value===null ? $this->nullDisplay : $formatter->format($value,$attribute['type']);
|
||||
|
||||
$this->renderItem($attribute, $tr);
|
||||
|
||||
$i++;
|
||||
}
|
||||
|
||||
if ($this->tagName!==null)
|
||||
echo CHtml::closeTag($this->tagName);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used by run() to render item row
|
||||
*
|
||||
* @param array $options config options for this item/attribute from {@link attributes}
|
||||
* @param string $templateData data that will be inserted into {@link itemTemplate}
|
||||
* @since 1.1.11
|
||||
*/
|
||||
protected function renderItem($options,$templateData)
|
||||
{
|
||||
echo strtr(isset($options['template']) ? $options['template'] : $this->itemTemplate,$templateData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CFormatter the formatter instance. Defaults to the 'format' application component.
|
||||
*/
|
||||
public function getFormatter()
|
||||
{
|
||||
if($this->_formatter===null)
|
||||
$this->_formatter=Yii::app()->format;
|
||||
return $this->_formatter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CFormatter $value the formatter instance
|
||||
*/
|
||||
public function setFormatter($value)
|
||||
{
|
||||
$this->_formatter=$value;
|
||||
}
|
||||
}
|
||||
325
framework/zii/widgets/CListView.php
Normal file
@@ -0,0 +1,325 @@
|
||||
<?php
|
||||
/**
|
||||
* CListView class file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
Yii::import('zii.widgets.CBaseListView');
|
||||
|
||||
/**
|
||||
* CListView displays a list of data items in terms of a list.
|
||||
*
|
||||
* Unlike {@link CGridView} which displays the data items in a table, CListView allows one to use
|
||||
* a view template to render each data item. As a result, CListView could generate more flexible
|
||||
* rendering result.
|
||||
*
|
||||
* CListView supports both sorting and pagination of the data items. The sorting
|
||||
* and pagination can be done in AJAX mode or normal page request. A benefit of using CListView is that
|
||||
* when the user browser disables JavaScript, the sorting and pagination automatically degenerate
|
||||
* to normal page requests and are still functioning as expected.
|
||||
*
|
||||
* CListView should be used together with a {@link IDataProvider data provider}, preferrably a
|
||||
* {@link CActiveDataProvider}.
|
||||
*
|
||||
* The minimal code needed to use CListView is as follows:
|
||||
*
|
||||
* <pre>
|
||||
* $dataProvider=new CActiveDataProvider('Post');
|
||||
*
|
||||
* $this->widget('zii.widgets.CListView', array(
|
||||
* 'dataProvider'=>$dataProvider,
|
||||
* 'itemView'=>'_post', // refers to the partial view named '_post'
|
||||
* 'sortableAttributes'=>array(
|
||||
* 'title',
|
||||
* 'create_time'=>'Post Time',
|
||||
* ),
|
||||
* ));
|
||||
* </pre>
|
||||
*
|
||||
* The above code first creates a data provider for the <code>Post</code> ActiveRecord class.
|
||||
* It then uses CListView to display every data item as returned by the data provider.
|
||||
* The display is done via the partial view named '_post'. This partial view will be rendered
|
||||
* once for every data item. In the view, one can access the current data item via variable <code>$data</code>.
|
||||
* For more details, see {@link itemView}.
|
||||
*
|
||||
* In order to support sorting, one has to specify the {@link sortableAttributes} property.
|
||||
* By doing so, a list of hyperlinks that can sort the data will be displayed.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package zii.widgets
|
||||
* @since 1.1
|
||||
*/
|
||||
class CListView extends CBaseListView
|
||||
{
|
||||
/**
|
||||
* @var string the view used for rendering each data item.
|
||||
* This property value will be passed as the first parameter to either {@link CController::renderPartial}
|
||||
* or {@link CWidget::render} to render each data item.
|
||||
* In the corresponding view template, the following variables can be used in addition to those declared in {@link viewData}:
|
||||
* <ul>
|
||||
* <li><code>$this</code>: refers to the owner of this list view widget. For example, if the widget is in the view of a controller,
|
||||
* then <code>$this</code> refers to the controller.</li>
|
||||
* <li><code>$data</code>: refers to the data item currently being rendered.</li>
|
||||
* <li><code>$index</code>: refers to the zero-based index of the data item currently being rendered.</li>
|
||||
* <li><code>$widget</code>: refers to this list view widget instance.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public $itemView;
|
||||
/**
|
||||
* @var string the HTML code to be displayed between any two consecutive items.
|
||||
* @since 1.1.7
|
||||
*/
|
||||
public $separator;
|
||||
/**
|
||||
* @var array additional data to be passed to {@link itemView} when rendering each data item.
|
||||
* This array will be extracted into local PHP variables that can be accessed in the {@link itemView}.
|
||||
*/
|
||||
public $viewData=array();
|
||||
/**
|
||||
* @var array list of sortable attribute names. In order for an attribute to be sortable, it must also
|
||||
* appear as a sortable attribute in the {@link IDataProvider::sort} property of {@link dataProvider}.
|
||||
* @see enableSorting
|
||||
*/
|
||||
public $sortableAttributes;
|
||||
/**
|
||||
* @var string the template to be used to control the layout of various components in the list view.
|
||||
* These tokens are recognized: {summary}, {sorter}, {items} and {pager}. They will be replaced with the
|
||||
* summary text, the sort links, the data item list, and the pager.
|
||||
*/
|
||||
public $template="{summary}\n{sorter}\n{items}\n{pager}";
|
||||
/**
|
||||
* @var string the CSS class name that will be assigned to the widget container element
|
||||
* when the widget is updating its content via AJAX. Defaults to 'list-view-loading'.
|
||||
* @since 1.1.1
|
||||
*/
|
||||
public $loadingCssClass='list-view-loading';
|
||||
/**
|
||||
* @var string the CSS class name for the sorter container. Defaults to 'sorter'.
|
||||
*/
|
||||
public $sorterCssClass='sorter';
|
||||
/**
|
||||
* @var string the text shown before sort links. Defaults to 'Sort by: '.
|
||||
*/
|
||||
public $sorterHeader;
|
||||
/**
|
||||
* @var string the text shown after sort links. Defaults to empty.
|
||||
*/
|
||||
public $sorterFooter='';
|
||||
/**
|
||||
* @var mixed the ID of the container whose content may be updated with an AJAX response.
|
||||
* Defaults to null, meaning the container for this list view instance.
|
||||
* If it is set false, it means sorting and pagination will be performed in normal page requests
|
||||
* instead of AJAX requests. If the sorting and pagination should trigger the update of multiple
|
||||
* containers' content in AJAX fashion, these container IDs may be listed here (separated with comma).
|
||||
*/
|
||||
public $ajaxUpdate;
|
||||
/**
|
||||
* @var string the jQuery selector of the HTML elements that may trigger AJAX updates when they are clicked.
|
||||
* If not set, the pagination links and the sorting links will trigger AJAX updates.
|
||||
* @since 1.1.7
|
||||
*/
|
||||
public $updateSelector;
|
||||
/**
|
||||
* @var string a javascript function that will be invoked if an AJAX update error occurs.
|
||||
*
|
||||
* The function signature is <code>function(xhr, textStatus, errorThrown, errorMessage)</code>
|
||||
* <ul>
|
||||
* <li><code>xhr</code> is the XMLHttpRequest object.</li>
|
||||
* <li><code>textStatus</code> is a string describing the type of error that occurred.
|
||||
* Possible values (besides null) are "timeout", "error", "notmodified" and "parsererror"</li>
|
||||
* <li><code>errorThrown</code> is an optional exception object, if one occurred.</li>
|
||||
* <li><code>errorMessage</code> is the CGridView default error message derived from xhr and errorThrown.
|
||||
* Usefull if you just want to display this error differently. CGridView by default displays this error with an javascript.alert()</li>
|
||||
* </ul>
|
||||
* Note: This handler is not called for JSONP requests, because they do not use an XMLHttpRequest.
|
||||
*
|
||||
* Example (add in a call to CGridView):
|
||||
* <pre>
|
||||
* ...
|
||||
* 'ajaxUpdateError'=>'function(xhr,ts,et,err){ $("#myerrordiv").text(err); }',
|
||||
* ...
|
||||
* </pre>
|
||||
* @since 1.1.13
|
||||
*/
|
||||
public $ajaxUpdateError;
|
||||
/**
|
||||
* @var string the name of the GET variable that indicates the request is an AJAX request triggered
|
||||
* by this widget. Defaults to 'ajax'. This is effective only when {@link ajaxUpdate} is not false.
|
||||
*/
|
||||
public $ajaxVar='ajax';
|
||||
/**
|
||||
* @var mixed the URL for the AJAX requests should be sent to. {@link CHtml::normalizeUrl()} will be
|
||||
* called on this property. If not set, the current page URL will be used for AJAX requests.
|
||||
* @since 1.1.8
|
||||
*/
|
||||
public $ajaxUrl;
|
||||
/**
|
||||
* @var string the type ('GET' or 'POST') of the AJAX requests. If not set, 'GET' will be used.
|
||||
* You can set this to 'POST' if you are filtering by many fields at once and have a problem with GET query string length.
|
||||
* Note that in POST mode direct links and {@link enableHistory} feature may not work correctly!
|
||||
* @since 1.1.14
|
||||
*/
|
||||
public $ajaxType;
|
||||
/**
|
||||
* @var string a javascript function that will be invoked before an AJAX update occurs.
|
||||
* The function signature is <code>function(id)</code> where 'id' refers to the ID of the list view.
|
||||
*/
|
||||
public $beforeAjaxUpdate;
|
||||
/**
|
||||
* @var string a javascript function that will be invoked after a successful AJAX response is received.
|
||||
* The function signature is <code>function(id, data)</code> where 'id' refers to the ID of the list view
|
||||
* 'data' the received ajax response data.
|
||||
*/
|
||||
public $afterAjaxUpdate;
|
||||
/**
|
||||
* @var string the base script URL for all list view resources (e.g. javascript, CSS file, images).
|
||||
* Defaults to null, meaning using the integrated list view resources (which are published as assets).
|
||||
*/
|
||||
public $baseScriptUrl;
|
||||
/**
|
||||
* @var string the URL of the CSS file used by this list view. Defaults to null, meaning using the integrated
|
||||
* CSS file. If this is set false, you are responsible to explicitly include the necessary CSS file in your page.
|
||||
*/
|
||||
public $cssFile;
|
||||
/**
|
||||
* @var string the HTML tag name for the container of all data item display. Defaults to 'div'.
|
||||
* @since 1.1.4
|
||||
*/
|
||||
public $itemsTagName='div';
|
||||
|
||||
/**
|
||||
* @var boolean whether to leverage the {@link https://developer.mozilla.org/en/DOM/window.history DOM history object}. Set this property to true
|
||||
* to persist state of list across page revisits. Note, there are two limitations for this feature:
|
||||
* - this feature is only compatible with browsers that support HTML5.
|
||||
* - expect unexpected functionality (e.g. multiple ajax calls) if there is more than one grid/list on a single page with enableHistory turned on.
|
||||
* @since 1.1.11
|
||||
*/
|
||||
public $enableHistory=false;
|
||||
|
||||
/**
|
||||
* Initializes the list view.
|
||||
* This method will initialize required property values and instantiate {@link columns} objects.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if($this->itemView===null)
|
||||
throw new CException(Yii::t('zii','The property "itemView" cannot be empty.'));
|
||||
parent::init();
|
||||
|
||||
if(!isset($this->htmlOptions['class']))
|
||||
$this->htmlOptions['class']='list-view';
|
||||
|
||||
if($this->baseScriptUrl===null)
|
||||
$this->baseScriptUrl=Yii::app()->getAssetManager()->publish(Yii::getPathOfAlias('zii.widgets.assets')).'/listview';
|
||||
|
||||
if($this->cssFile!==false)
|
||||
{
|
||||
if($this->cssFile===null)
|
||||
$this->cssFile=$this->baseScriptUrl.'/styles.css';
|
||||
Yii::app()->getClientScript()->registerCssFile($this->cssFile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers necessary client scripts.
|
||||
*/
|
||||
public function registerClientScript()
|
||||
{
|
||||
$id=$this->getId();
|
||||
|
||||
if($this->ajaxUpdate===false)
|
||||
$ajaxUpdate=array();
|
||||
else
|
||||
$ajaxUpdate=array_unique(preg_split('/\s*,\s*/',$this->ajaxUpdate.','.$id,-1,PREG_SPLIT_NO_EMPTY));
|
||||
$options=array(
|
||||
'ajaxUpdate'=>$ajaxUpdate,
|
||||
'ajaxVar'=>$this->ajaxVar,
|
||||
'pagerClass'=>$this->pagerCssClass,
|
||||
'loadingClass'=>$this->loadingCssClass,
|
||||
'sorterClass'=>$this->sorterCssClass,
|
||||
'enableHistory'=>$this->enableHistory
|
||||
);
|
||||
if($this->ajaxUrl!==null)
|
||||
$options['url']=CHtml::normalizeUrl($this->ajaxUrl);
|
||||
if($this->ajaxType!==null)
|
||||
$options['ajaxType']=strtoupper($this->ajaxType);
|
||||
if($this->updateSelector!==null)
|
||||
$options['updateSelector']=$this->updateSelector;
|
||||
foreach(array('beforeAjaxUpdate', 'afterAjaxUpdate', 'ajaxUpdateError') as $event)
|
||||
{
|
||||
if($this->$event!==null)
|
||||
{
|
||||
if($this->$event instanceof CJavaScriptExpression)
|
||||
$options[$event]=$this->$event;
|
||||
else
|
||||
$options[$event]=new CJavaScriptExpression($this->$event);
|
||||
}
|
||||
}
|
||||
|
||||
$options=CJavaScript::encode($options);
|
||||
$cs=Yii::app()->getClientScript();
|
||||
$cs->registerCoreScript('jquery');
|
||||
$cs->registerCoreScript('bbq');
|
||||
if($this->enableHistory)
|
||||
$cs->registerCoreScript('history');
|
||||
$cs->registerScriptFile($this->baseScriptUrl.'/jquery.yiilistview.js',CClientScript::POS_END);
|
||||
$cs->registerScript(__CLASS__.'#'.$id,"jQuery('#$id').yiiListView($options);");
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the data item list.
|
||||
*/
|
||||
public function renderItems()
|
||||
{
|
||||
echo CHtml::openTag($this->itemsTagName,array('class'=>$this->itemsCssClass))."\n";
|
||||
$data=$this->dataProvider->getData();
|
||||
if(($n=count($data))>0)
|
||||
{
|
||||
$owner=$this->getOwner();
|
||||
$viewFile=$owner->getViewFile($this->itemView);
|
||||
$j=0;
|
||||
foreach($data as $i=>$item)
|
||||
{
|
||||
$data=$this->viewData;
|
||||
$data['index']=$i;
|
||||
$data['data']=$item;
|
||||
$data['widget']=$this;
|
||||
$owner->renderFile($viewFile,$data);
|
||||
if($j++ < $n-1)
|
||||
echo $this->separator;
|
||||
}
|
||||
}
|
||||
else
|
||||
$this->renderEmptyText();
|
||||
echo CHtml::closeTag($this->itemsTagName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the sorter.
|
||||
*/
|
||||
public function renderSorter()
|
||||
{
|
||||
if($this->dataProvider->getItemCount()<=0 || !$this->enableSorting || empty($this->sortableAttributes))
|
||||
return;
|
||||
echo CHtml::openTag('div',array('class'=>$this->sorterCssClass))."\n";
|
||||
echo $this->sorterHeader===null ? Yii::t('zii','Sort by: ') : $this->sorterHeader;
|
||||
echo "<ul>\n";
|
||||
$sort=$this->dataProvider->getSort();
|
||||
foreach($this->sortableAttributes as $name=>$label)
|
||||
{
|
||||
echo "<li>";
|
||||
if(is_integer($name))
|
||||
echo $sort->link($label);
|
||||
else
|
||||
echo $sort->link($name,$label);
|
||||
echo "</li>\n";
|
||||
}
|
||||
echo "</ul>";
|
||||
echo $this->sorterFooter;
|
||||
echo CHtml::closeTag('div');
|
||||
}
|
||||
}
|
||||
326
framework/zii/widgets/CMenu.php
Normal file
@@ -0,0 +1,326 @@
|
||||
<?php
|
||||
/**
|
||||
* CMenu class file.
|
||||
*
|
||||
* @author Jonah Turnquist <poppitypop@gmail.com>
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CMenu displays a multi-level menu using nested HTML lists.
|
||||
*
|
||||
* The main property of CMenu is {@link items}, which specifies the possible items in the menu.
|
||||
* A menu item has three main properties: visible, active and items. The "visible" property
|
||||
* specifies whether the menu item is currently visible. The "active" property specifies whether
|
||||
* the menu item is currently selected. And the "items" property specifies the child menu items.
|
||||
*
|
||||
* The following example shows how to use CMenu:
|
||||
* <pre>
|
||||
* $this->widget('zii.widgets.CMenu', array(
|
||||
* 'items'=>array(
|
||||
* // Important: you need to specify url as 'controller/action',
|
||||
* // not just as 'controller' even if default acion is used.
|
||||
* array('label'=>'Home', 'url'=>array('site/index')),
|
||||
* // 'Products' menu item will be selected no matter which tag parameter value is since it's not specified.
|
||||
* array('label'=>'Products', 'url'=>array('product/index'), 'items'=>array(
|
||||
* array('label'=>'New Arrivals', 'url'=>array('product/new', 'tag'=>'new')),
|
||||
* array('label'=>'Most Popular', 'url'=>array('product/index', 'tag'=>'popular')),
|
||||
* )),
|
||||
* array('label'=>'Login', 'url'=>array('site/login'), 'visible'=>Yii::app()->user->isGuest),
|
||||
* ),
|
||||
* ));
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @author Jonah Turnquist <poppitypop@gmail.com>
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package zii.widgets
|
||||
* @since 1.1
|
||||
*/
|
||||
class CMenu extends CWidget
|
||||
{
|
||||
/**
|
||||
* @var array list of menu items. Each menu item is specified as an array of name-value pairs.
|
||||
* Possible option names include the following:
|
||||
* <ul>
|
||||
* <li>label: string, optional, specifies the menu item label. When {@link encodeLabel} is true, the label
|
||||
* will be HTML-encoded. If the label is not specified, it defaults to an empty string.</li>
|
||||
* <li>url: string or array, optional, specifies the URL of the menu item. It is passed to {@link CHtml::normalizeUrl}
|
||||
* to generate a valid URL. If this is not set, the menu item will be rendered as a span text.</li>
|
||||
* <li>visible: boolean, optional, whether this menu item is visible. Defaults to true.
|
||||
* This can be used to control the visibility of menu items based on user permissions.</li>
|
||||
* <li>items: array, optional, specifies the sub-menu items. Its format is the same as the parent items.</li>
|
||||
* <li>active: boolean, optional, whether this menu item is in active state (currently selected).
|
||||
* If a menu item is active and {@link activeClass} is not empty, its CSS class will be appended with {@link activeClass}.
|
||||
* If this option is not set, the menu item will be set active automatically when the current request
|
||||
* is triggered by {@link url}. Note that the GET parameters not specified in the 'url' option will be ignored.</li>
|
||||
* <li>template: string, optional, the template used to render this menu item.
|
||||
* When this option is set, it will override the global setting {@link itemTemplate}.
|
||||
* Please see {@link itemTemplate} for more details. This option has been available since version 1.1.1.</li>
|
||||
* <li>linkOptions: array, optional, additional HTML attributes to be rendered for the link or span tag of the menu item.</li>
|
||||
* <li>itemOptions: array, optional, additional HTML attributes to be rendered for the container tag of the menu item.</li>
|
||||
* <li>submenuOptions: array, optional, additional HTML attributes to be rendered for the container of the submenu if this menu item has one.
|
||||
* When this option is set, the {@link submenuHtmlOptions} property will be ignored for this particular submenu.
|
||||
* This option has been available since version 1.1.6.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public $items=array();
|
||||
/**
|
||||
* @var string the template used to render an individual menu item. In this template,
|
||||
* the token "{menu}" will be replaced with the corresponding menu link or text.
|
||||
* If this property is not set, each menu will be rendered without any decoration.
|
||||
* This property will be overridden by the 'template' option set in individual menu items via {@items}.
|
||||
* @since 1.1.1
|
||||
*/
|
||||
public $itemTemplate;
|
||||
/**
|
||||
* @var boolean whether the labels for menu items should be HTML-encoded. Defaults to true.
|
||||
*/
|
||||
public $encodeLabel=true;
|
||||
/**
|
||||
* @var string the CSS class to be appended to the active menu item. Defaults to 'active'.
|
||||
* If empty, the CSS class of menu items will not be changed.
|
||||
*/
|
||||
public $activeCssClass='active';
|
||||
/**
|
||||
* @var boolean whether to automatically activate items according to whether their route setting
|
||||
* matches the currently requested route. Defaults to true.
|
||||
* @since 1.1.3
|
||||
*/
|
||||
public $activateItems=true;
|
||||
/**
|
||||
* @var boolean whether to activate parent menu items when one of the corresponding child menu items is active.
|
||||
* The activated parent menu items will also have its CSS classes appended with {@link activeCssClass}.
|
||||
* Defaults to false.
|
||||
*/
|
||||
public $activateParents=false;
|
||||
/**
|
||||
* @var boolean whether to hide empty menu items. An empty menu item is one whose 'url' option is not
|
||||
* set and which doesn't contain visible child menu items. Defaults to true.
|
||||
*/
|
||||
public $hideEmptyItems=true;
|
||||
/**
|
||||
* @var array HTML attributes for the menu's root container tag
|
||||
*/
|
||||
public $htmlOptions=array();
|
||||
/**
|
||||
* @var array HTML attributes for the submenu's container tag.
|
||||
*/
|
||||
public $submenuHtmlOptions=array();
|
||||
/**
|
||||
* @var string the HTML element name that will be used to wrap the label of all menu links.
|
||||
* For example, if this property is set as 'span', a menu item may be rendered as
|
||||
* <li><a href="url"><span>label</span></a></li>
|
||||
* This is useful when implementing menu items using the sliding window technique.
|
||||
* Defaults to null, meaning no wrapper tag will be generated.
|
||||
* @since 1.1.4
|
||||
*/
|
||||
public $linkLabelWrapper;
|
||||
/**
|
||||
* @var array HTML attributes for the links' wrap element specified in
|
||||
* {@link linkLabelWrapper}.
|
||||
* @since 1.1.13
|
||||
*/
|
||||
public $linkLabelWrapperHtmlOptions=array();
|
||||
/**
|
||||
* @var string the CSS class that will be assigned to the first item in the main menu or each submenu.
|
||||
* Defaults to null, meaning no such CSS class will be assigned.
|
||||
* @since 1.1.4
|
||||
*/
|
||||
public $firstItemCssClass;
|
||||
/**
|
||||
* @var string the CSS class that will be assigned to the last item in the main menu or each submenu.
|
||||
* Defaults to null, meaning no such CSS class will be assigned.
|
||||
* @since 1.1.4
|
||||
*/
|
||||
public $lastItemCssClass;
|
||||
/**
|
||||
* @var string the CSS class that will be assigned to every item.
|
||||
* Defaults to null, meaning no such CSS class will be assigned.
|
||||
* @since 1.1.9
|
||||
*/
|
||||
public $itemCssClass;
|
||||
|
||||
/**
|
||||
* Initializes the menu widget.
|
||||
* This method mainly normalizes the {@link items} property.
|
||||
* If this method is overridden, make sure the parent implementation is invoked.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if(isset($this->htmlOptions['id']))
|
||||
$this->id=$this->htmlOptions['id'];
|
||||
else
|
||||
$this->htmlOptions['id']=$this->id;
|
||||
$route=$this->getController()->getRoute();
|
||||
$this->items=$this->normalizeItems($this->items,$route,$hasActiveChild);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link renderMenu} to render the menu.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->renderMenu($this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the menu items.
|
||||
* @param array $items menu items. Each menu item will be an array with at least two elements: 'label' and 'active'.
|
||||
* It may have three other optional elements: 'items', 'linkOptions' and 'itemOptions'.
|
||||
*/
|
||||
protected function renderMenu($items)
|
||||
{
|
||||
if(count($items))
|
||||
{
|
||||
echo CHtml::openTag('ul',$this->htmlOptions)."\n";
|
||||
$this->renderMenuRecursive($items);
|
||||
echo CHtml::closeTag('ul');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively renders the menu items.
|
||||
* @param array $items the menu items to be rendered recursively
|
||||
*/
|
||||
protected function renderMenuRecursive($items)
|
||||
{
|
||||
$count=0;
|
||||
$n=count($items);
|
||||
foreach($items as $item)
|
||||
{
|
||||
$count++;
|
||||
$options=isset($item['itemOptions']) ? $item['itemOptions'] : array();
|
||||
$class=array();
|
||||
if($item['active'] && $this->activeCssClass!='')
|
||||
$class[]=$this->activeCssClass;
|
||||
if($count===1 && $this->firstItemCssClass!==null)
|
||||
$class[]=$this->firstItemCssClass;
|
||||
if($count===$n && $this->lastItemCssClass!==null)
|
||||
$class[]=$this->lastItemCssClass;
|
||||
if($this->itemCssClass!==null)
|
||||
$class[]=$this->itemCssClass;
|
||||
if($class!==array())
|
||||
{
|
||||
if(empty($options['class']))
|
||||
$options['class']=implode(' ',$class);
|
||||
else
|
||||
$options['class'].=' '.implode(' ',$class);
|
||||
}
|
||||
|
||||
echo CHtml::openTag('li', $options);
|
||||
|
||||
$menu=$this->renderMenuItem($item);
|
||||
if(isset($this->itemTemplate) || isset($item['template']))
|
||||
{
|
||||
$template=isset($item['template']) ? $item['template'] : $this->itemTemplate;
|
||||
echo strtr($template,array('{menu}'=>$menu));
|
||||
}
|
||||
else
|
||||
echo $menu;
|
||||
|
||||
if(isset($item['items']) && count($item['items']))
|
||||
{
|
||||
echo "\n".CHtml::openTag('ul',isset($item['submenuOptions']) ? $item['submenuOptions'] : $this->submenuHtmlOptions)."\n";
|
||||
$this->renderMenuRecursive($item['items']);
|
||||
echo CHtml::closeTag('ul')."\n";
|
||||
}
|
||||
|
||||
echo CHtml::closeTag('li')."\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the content of a menu item.
|
||||
* Note that the container and the sub-menus are not rendered here.
|
||||
* @param array $item the menu item to be rendered. Please see {@link items} on what data might be in the item.
|
||||
* @return string
|
||||
* @since 1.1.6
|
||||
*/
|
||||
protected function renderMenuItem($item)
|
||||
{
|
||||
if(isset($item['url']))
|
||||
{
|
||||
$label=$this->linkLabelWrapper===null ? $item['label'] : CHtml::tag($this->linkLabelWrapper, $this->linkLabelWrapperHtmlOptions, $item['label']);
|
||||
return CHtml::link($label,$item['url'],isset($item['linkOptions']) ? $item['linkOptions'] : array());
|
||||
}
|
||||
else
|
||||
return CHtml::tag('span',isset($item['linkOptions']) ? $item['linkOptions'] : array(), $item['label']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the {@link items} property so that the 'active' state is properly identified for every menu item.
|
||||
* @param array $items the items to be normalized.
|
||||
* @param string $route the route of the current request.
|
||||
* @param boolean $active whether there is an active child menu item.
|
||||
* @return array the normalized menu items
|
||||
*/
|
||||
protected function normalizeItems($items,$route,&$active)
|
||||
{
|
||||
foreach($items as $i=>$item)
|
||||
{
|
||||
if(isset($item['visible']) && !$item['visible'])
|
||||
{
|
||||
unset($items[$i]);
|
||||
continue;
|
||||
}
|
||||
if(!isset($item['label']))
|
||||
$item['label']='';
|
||||
if($this->encodeLabel)
|
||||
$items[$i]['label']=CHtml::encode($item['label']);
|
||||
$hasActiveChild=false;
|
||||
if(isset($item['items']))
|
||||
{
|
||||
$items[$i]['items']=$this->normalizeItems($item['items'],$route,$hasActiveChild);
|
||||
if(empty($items[$i]['items']) && $this->hideEmptyItems)
|
||||
{
|
||||
unset($items[$i]['items']);
|
||||
if(!isset($item['url']))
|
||||
{
|
||||
unset($items[$i]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!isset($item['active']))
|
||||
{
|
||||
if($this->activateParents && $hasActiveChild || $this->activateItems && $this->isItemActive($item,$route))
|
||||
$active=$items[$i]['active']=true;
|
||||
else
|
||||
$items[$i]['active']=false;
|
||||
}
|
||||
elseif($item['active'])
|
||||
$active=true;
|
||||
}
|
||||
return array_values($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a menu item is active.
|
||||
* This is done by checking if the currently requested URL is generated by the 'url' option
|
||||
* of the menu item. Note that the GET parameters not specified in the 'url' option will be ignored.
|
||||
* @param array $item the menu item to be checked
|
||||
* @param string $route the route of the current request
|
||||
* @return boolean whether the menu item is active
|
||||
*/
|
||||
protected function isItemActive($item,$route)
|
||||
{
|
||||
if(isset($item['url']) && is_array($item['url']) && !strcasecmp(trim($item['url'][0],'/'),$route))
|
||||
{
|
||||
unset($item['url']['#']);
|
||||
if(count($item['url'])>1)
|
||||
{
|
||||
foreach(array_splice($item['url'],1) as $name=>$value)
|
||||
{
|
||||
if(!isset($_GET[$name]) || $_GET[$name]!=$value)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
128
framework/zii/widgets/CPortlet.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
/**
|
||||
* CPortlet class file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CPortlet is the base class for portlet widgets.
|
||||
*
|
||||
* A portlet displays a fragment of content, usually in terms of a block
|
||||
* on the side bars of a Web page.
|
||||
*
|
||||
* To specify the content of the portlet, override the {@link renderContent}
|
||||
* method, or insert the content code between the {@link CController::beginWidget}
|
||||
* and {@link CController::endWidget} calls. For example,
|
||||
*
|
||||
* <pre>
|
||||
* <?php $this->beginWidget('zii.widgets.CPortlet'); ?>
|
||||
* ...insert content here...
|
||||
* <?php $this->endWidget(); ?>
|
||||
* </pre>
|
||||
*
|
||||
* A portlet also has an optional {@link title}. One may also override {@link renderDecoration}
|
||||
* to further customize the decorative display of a portlet (e.g. adding min/max buttons).
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package zii.widgets
|
||||
* @since 1.1
|
||||
*/
|
||||
class CPortlet extends CWidget
|
||||
{
|
||||
/**
|
||||
* @var string the tag name for the portlet container tag. Defaults to 'div'.
|
||||
*/
|
||||
public $tagName='div';
|
||||
/**
|
||||
* @var array the HTML attributes for the portlet container tag.
|
||||
*/
|
||||
public $htmlOptions=array('class'=>'portlet');
|
||||
/**
|
||||
* @var string the title of the portlet. Defaults to null.
|
||||
* When this is not set, Decoration will not be displayed.
|
||||
* Note that the title will not be HTML-encoded when rendering.
|
||||
*/
|
||||
public $title;
|
||||
/**
|
||||
* @var string the CSS class for the decoration container tag. Defaults to 'portlet-decoration'.
|
||||
*/
|
||||
public $decorationCssClass='portlet-decoration';
|
||||
/**
|
||||
* @var string the CSS class for the portlet title tag. Defaults to 'portlet-title'.
|
||||
*/
|
||||
public $titleCssClass='portlet-title';
|
||||
/**
|
||||
* @var string the CSS class for the content container tag. Defaults to 'portlet-content'.
|
||||
*/
|
||||
public $contentCssClass='portlet-content';
|
||||
/**
|
||||
* @var boolean whether to hide the portlet when the body content is empty. Defaults to true.
|
||||
* @since 1.1.4
|
||||
*/
|
||||
public $hideOnEmpty=true;
|
||||
|
||||
private $_openTag;
|
||||
|
||||
/**
|
||||
* Initializes the widget.
|
||||
* This renders the open tags needed by the portlet.
|
||||
* It also renders the decoration, if any.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
ob_start();
|
||||
ob_implicit_flush(false);
|
||||
|
||||
if(isset($this->htmlOptions['id']))
|
||||
$this->id=$this->htmlOptions['id'];
|
||||
else
|
||||
$this->htmlOptions['id']=$this->id;
|
||||
echo CHtml::openTag($this->tagName,$this->htmlOptions)."\n";
|
||||
$this->renderDecoration();
|
||||
echo "<div class=\"{$this->contentCssClass}\">\n";
|
||||
|
||||
$this->_openTag=ob_get_contents();
|
||||
ob_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the content of the portlet.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->renderContent();
|
||||
$content=ob_get_clean();
|
||||
if($this->hideOnEmpty && trim($content)==='')
|
||||
return;
|
||||
echo $this->_openTag;
|
||||
echo $content;
|
||||
echo "</div>\n";
|
||||
echo CHtml::closeTag($this->tagName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the decoration for the portlet.
|
||||
* The default implementation will render the title if it is set.
|
||||
*/
|
||||
protected function renderDecoration()
|
||||
{
|
||||
if($this->title!==null)
|
||||
{
|
||||
echo "<div class=\"{$this->decorationCssClass}\">\n";
|
||||
echo "<div class=\"{$this->titleCssClass}\">{$this->title}</div>\n";
|
||||
echo "</div>\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the content of the portlet.
|
||||
* Child classes should override this method to render the actual content.
|
||||
*/
|
||||
protected function renderContent()
|
||||
{
|
||||
}
|
||||
}
|
||||
44
framework/zii/widgets/assets/detailview/styles.css
Normal file
@@ -0,0 +1,44 @@
|
||||
table.detail-view .null
|
||||
{
|
||||
color: pink;
|
||||
}
|
||||
|
||||
table.detail-view
|
||||
{
|
||||
background: white;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
table.detail-view th, table.detail-view td
|
||||
{
|
||||
font-size: 0.9em;
|
||||
border: 1px white solid;
|
||||
padding: 0.3em 0.6em;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
table.detail-view th
|
||||
{
|
||||
text-align: right;
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
table.detail-view tr.odd
|
||||
{
|
||||
background:#E5F1F4;
|
||||
}
|
||||
|
||||
table.detail-view tr.even
|
||||
{
|
||||
background:#F8F8F8;
|
||||
}
|
||||
|
||||
table.detail-view tr.odd th
|
||||
{
|
||||
}
|
||||
|
||||
table.detail-view tr.even th
|
||||
{
|
||||
}
|
||||
BIN
framework/zii/widgets/assets/gridview/bg.gif
Normal file
|
After Width: | Height: | Size: 243 B |
BIN
framework/zii/widgets/assets/gridview/delete.png
Normal file
|
After Width: | Height: | Size: 715 B |
BIN
framework/zii/widgets/assets/gridview/down.gif
Normal file
|
After Width: | Height: | Size: 55 B |
475
framework/zii/widgets/assets/gridview/jquery.yiigridview.js
Normal file
@@ -0,0 +1,475 @@
|
||||
/**
|
||||
* jQuery Yii GridView plugin file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2010 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
(function ($) {
|
||||
var selectCheckedRows, methods,
|
||||
yiiXHR={},
|
||||
gridSettings = [];
|
||||
/**
|
||||
* 1. Selects rows that have checkbox checked (only checkbox that is connected with selecting a row)
|
||||
* 2. Check if "check all" need to be checked/unchecked
|
||||
* @return object the jQuery object
|
||||
*/
|
||||
selectCheckedRows = function (gridId) {
|
||||
var settings = gridSettings[gridId],
|
||||
table = $('#' + gridId).find('.' + settings.tableClass);
|
||||
|
||||
table.children('tbody').find('input.select-on-check').filter(':checked').each(function () {
|
||||
$(this).closest('tr').addClass('selected');
|
||||
});
|
||||
|
||||
table.children('thead').find('th input').filter('[type="checkbox"]').each(function () {
|
||||
var name = this.name.substring(0, this.name.length - 4) + '[]', //.. remove '_all' and add '[]''
|
||||
$checks = $("input[name='" + name + "']", table);
|
||||
this.checked = $checks.length > 0 && $checks.length === $checks.filter(':checked').length;
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
methods = {
|
||||
/**
|
||||
* yiiGridView set function.
|
||||
* @param options map settings for the grid view. Available options are as follows:
|
||||
* - ajaxUpdate: array, IDs of the containers whose content may be updated by ajax response
|
||||
* - ajaxVar: string, the name of the request variable indicating the ID of the element triggering the AJAX request
|
||||
* - ajaxType: string, the type (GET or POST) of the AJAX request
|
||||
* - pagerClass: string, the CSS class for the pager container
|
||||
* - tableClass: string, the CSS class for the table
|
||||
* - selectableRows: integer, the number of rows that can be selected
|
||||
* - updateSelector: string, the selector for choosing which elements can trigger ajax requests
|
||||
* - beforeAjaxUpdate: function, the function to be called before ajax request is sent
|
||||
* - afterAjaxUpdate: function, the function to be called after ajax response is received
|
||||
* - ajaxUpdateError: function, the function to be called if an ajax error occurs
|
||||
* - selectionChanged: function, the function to be called after the row selection is changed
|
||||
* @return object the jQuery object
|
||||
*/
|
||||
init: function (options) {
|
||||
var settings = $.extend({
|
||||
ajaxUpdate: [],
|
||||
ajaxVar: 'ajax',
|
||||
ajaxType: 'GET',
|
||||
pagerClass: 'pager',
|
||||
loadingClass: 'loading',
|
||||
filterClass: 'filters',
|
||||
tableClass: 'items',
|
||||
selectableRows: 1
|
||||
// updateSelector: '#id .pager a, '#id .grid thead th a',
|
||||
// beforeAjaxUpdate: function (id) {},
|
||||
// afterAjaxUpdate: function (id, data) {},
|
||||
// selectionChanged: function (id) {},
|
||||
// url: 'ajax request URL'
|
||||
}, options || {});
|
||||
|
||||
settings.tableClass = settings.tableClass.replace(/\s+/g, '.');
|
||||
|
||||
return this.each(function () {
|
||||
var eventType,
|
||||
$grid = $(this),
|
||||
id = $grid.attr('id'),
|
||||
pagerSelector = '#' + id + ' .' + settings.pagerClass.replace(/\s+/g, '.') + ' a',
|
||||
sortSelector = '#' + id + ' .' + settings.tableClass + ' thead th a.sort-link',
|
||||
inputSelector = '#' + id + ' .' + settings.filterClass + ' input, ' + '#' + id + ' .' + settings.filterClass + ' select';
|
||||
|
||||
settings.updateSelector = settings.updateSelector
|
||||
.replace('{page}', pagerSelector)
|
||||
.replace('{sort}', sortSelector);
|
||||
settings.filterSelector = settings.filterSelector
|
||||
.replace('{filter}', inputSelector);
|
||||
|
||||
gridSettings[id] = settings;
|
||||
|
||||
if (settings.ajaxUpdate.length > 0) {
|
||||
$(document).on('click.yiiGridView', settings.updateSelector, function () {
|
||||
// Check to see if History.js is enabled for our Browser
|
||||
if (settings.enableHistory && window.History.enabled) {
|
||||
// Ajaxify this link
|
||||
var url = $(this).attr('href').split('?'),
|
||||
params = $.deparam.querystring('?'+ (url[1] || ''));
|
||||
|
||||
delete params[settings.ajaxVar];
|
||||
window.History.pushState(null, document.title, decodeURIComponent($.param.querystring(url[0], params)));
|
||||
} else {
|
||||
$('#' + id).yiiGridView('update', {url: $(this).attr('href')});
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
$(document).on('change.yiiGridView keydown.yiiGridView', settings.filterSelector, function (event) {
|
||||
if (event.type === 'keydown') {
|
||||
if (event.keyCode !== 13) {
|
||||
return; // only react to enter key
|
||||
} else {
|
||||
eventType = 'keydown';
|
||||
}
|
||||
} else {
|
||||
// prevent processing for both keydown and change events
|
||||
if (eventType === 'keydown') {
|
||||
eventType = '';
|
||||
return;
|
||||
}
|
||||
}
|
||||
var data = $(settings.filterSelector).serialize();
|
||||
if (settings.pageVar !== undefined) {
|
||||
data += '&' + settings.pageVar + '=1';
|
||||
}
|
||||
if (settings.enableHistory && settings.ajaxUpdate !== false && window.History.enabled) {
|
||||
// Ajaxify this link
|
||||
var url = $('#' + id).yiiGridView('getUrl'),
|
||||
params = $.deparam.querystring($.param.querystring(url, data));
|
||||
|
||||
delete params[settings.ajaxVar];
|
||||
window.History.pushState(null, document.title, decodeURIComponent($.param.querystring(url.substr(0, url.indexOf('?')), params)));
|
||||
} else {
|
||||
$('#' + id).yiiGridView('update', {data: data});
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (settings.enableHistory && settings.ajaxUpdate !== false && window.History.enabled) {
|
||||
$(window).bind('statechange', function() { // Note: We are using statechange instead of popstate
|
||||
var State = window.History.getState(); // Note: We are using History.getState() instead of event.state
|
||||
$('#' + id).yiiGridView('update', {url: State.url});
|
||||
});
|
||||
}
|
||||
|
||||
if (settings.selectableRows > 0) {
|
||||
selectCheckedRows(this.id);
|
||||
$(document).on('click.yiiGridView', '#' + id + ' .' + settings.tableClass + ' > tbody > tr', function (e) {
|
||||
var $currentGrid, $row, isRowSelected, $checks,
|
||||
$target = $(e.target);
|
||||
|
||||
if ($target.closest('td').is('.empty,.button-column') || (e.target.type === 'checkbox' && !$target.hasClass('select-on-check'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
$row = $(this);
|
||||
$currentGrid = $('#' + id);
|
||||
$checks = $('input.select-on-check', $currentGrid);
|
||||
isRowSelected = $row.toggleClass('selected').hasClass('selected');
|
||||
|
||||
if (settings.selectableRows === 1) {
|
||||
$row.siblings().removeClass('selected');
|
||||
$checks.prop('checked', false);
|
||||
}
|
||||
$('input.select-on-check', $row).prop('checked', isRowSelected);
|
||||
$("input.select-on-check-all", $currentGrid).prop('checked', $checks.length === $checks.filter(':checked').length);
|
||||
|
||||
if (settings.selectionChanged !== undefined) {
|
||||
settings.selectionChanged(id);
|
||||
}
|
||||
});
|
||||
if (settings.selectableRows > 1) {
|
||||
$(document).on('click.yiiGridView', '#' + id + ' .select-on-check-all', function () {
|
||||
var $currentGrid = $('#' + id),
|
||||
$checks = $('input.select-on-check', $currentGrid),
|
||||
$checksAll = $('input.select-on-check-all', $currentGrid),
|
||||
$rows = $currentGrid.find('.' + settings.tableClass).children('tbody').children();
|
||||
if (this.checked) {
|
||||
$rows.addClass('selected');
|
||||
$checks.prop('checked', true);
|
||||
$checksAll.prop('checked', true);
|
||||
} else {
|
||||
$rows.removeClass('selected');
|
||||
$checks.prop('checked', false);
|
||||
$checksAll.prop('checked', false);
|
||||
}
|
||||
if (settings.selectionChanged !== undefined) {
|
||||
settings.selectionChanged(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
$(document).on('click.yiiGridView', '#' + id + ' .select-on-check', false);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the key value for the specified row
|
||||
* @param row integer the row number (zero-based index)
|
||||
* @return string the key value
|
||||
*/
|
||||
getKey: function (row) {
|
||||
return this.children('.keys').children('span').eq(row).text();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the URL that generates the grid view content.
|
||||
* @return string the URL that generates the grid view content.
|
||||
*/
|
||||
getUrl: function () {
|
||||
var sUrl = gridSettings[this.attr('id')].url;
|
||||
return sUrl || this.children('.keys').attr('title');
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the jQuery collection of the cells in the specified row.
|
||||
* @param row integer the row number (zero-based index)
|
||||
* @return jQuery the jQuery collection of the cells in the specified row.
|
||||
*/
|
||||
getRow: function (row) {
|
||||
var sClass = gridSettings[this.attr('id')].tableClass;
|
||||
return this.find('.' + sClass).children('tbody').children('tr').eq(row).children();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the jQuery collection of the cells in the specified column.
|
||||
* @param column integer the column number (zero-based index)
|
||||
* @return jQuery the jQuery collection of the cells in the specified column.
|
||||
*/
|
||||
getColumn: function (column) {
|
||||
var sClass = gridSettings[this.attr('id')].tableClass;
|
||||
return this.find('.' + sClass).children('tbody').children('tr').children('td:nth-child(' + (column + 1) + ')');
|
||||
},
|
||||
|
||||
/**
|
||||
* Performs an AJAX-based update of the grid view contents.
|
||||
* @param options map the AJAX request options (see jQuery.ajax API manual). By default,
|
||||
* the URL to be requested is the one that generates the current content of the grid view.
|
||||
* @return object the jQuery object
|
||||
*/
|
||||
update: function (options) {
|
||||
var customError;
|
||||
if (options && options.error !== undefined) {
|
||||
customError = options.error;
|
||||
delete options.error;
|
||||
}
|
||||
|
||||
return this.each(function () {
|
||||
var $form,
|
||||
$grid = $(this),
|
||||
id = $grid.attr('id'),
|
||||
settings = gridSettings[id];
|
||||
|
||||
options = $.extend({
|
||||
type: settings.ajaxType,
|
||||
url: $grid.yiiGridView('getUrl'),
|
||||
success: function (data) {
|
||||
var $data = $('<div>' + data + '</div>');
|
||||
$.each(settings.ajaxUpdate, function (i, el) {
|
||||
var updateId = '#' + el;
|
||||
$(updateId).replaceWith($(updateId, $data));
|
||||
});
|
||||
if (settings.afterAjaxUpdate !== undefined) {
|
||||
settings.afterAjaxUpdate(id, data);
|
||||
}
|
||||
if (settings.selectableRows > 0) {
|
||||
selectCheckedRows(id);
|
||||
}
|
||||
},
|
||||
complete: function () {
|
||||
yiiXHR[id] = null;
|
||||
$grid.removeClass(settings.loadingClass);
|
||||
},
|
||||
error: function (XHR, textStatus, errorThrown) {
|
||||
var ret, err;
|
||||
if (XHR.readyState === 0 || XHR.status === 0) {
|
||||
return;
|
||||
}
|
||||
if (customError !== undefined) {
|
||||
ret = customError(XHR);
|
||||
if (ret !== undefined && !ret) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
switch (textStatus) {
|
||||
case 'timeout':
|
||||
err = 'The request timed out!';
|
||||
break;
|
||||
case 'parsererror':
|
||||
err = 'Parser error!';
|
||||
break;
|
||||
case 'error':
|
||||
if (XHR.status && !/^\s*$/.test(XHR.status)) {
|
||||
err = 'Error ' + XHR.status;
|
||||
} else {
|
||||
err = 'Error';
|
||||
}
|
||||
if (XHR.responseText && !/^\s*$/.test(XHR.responseText)) {
|
||||
err = err + ': ' + XHR.responseText;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (settings.ajaxUpdateError !== undefined) {
|
||||
settings.ajaxUpdateError(XHR, textStatus, errorThrown, err);
|
||||
} else if (err) {
|
||||
alert(err);
|
||||
}
|
||||
}
|
||||
}, options || {});
|
||||
if (options.type === 'GET') {
|
||||
if (options.data !== undefined) {
|
||||
options.url = $.param.querystring(options.url, options.data);
|
||||
options.data = {};
|
||||
}
|
||||
} else {
|
||||
if (options.data === undefined) {
|
||||
options.data = $(settings.filterSelector).serialize();
|
||||
}
|
||||
}
|
||||
if(yiiXHR[id] != null){
|
||||
yiiXHR[id].abort();
|
||||
}
|
||||
//class must be added after yiiXHR.abort otherwise ajax.error will remove it
|
||||
$grid.addClass(settings.loadingClass);
|
||||
|
||||
if (settings.ajaxUpdate !== false) {
|
||||
if(settings.ajaxVar) {
|
||||
options.url = $.param.querystring(options.url, settings.ajaxVar + '=' + id);
|
||||
}
|
||||
if (settings.beforeAjaxUpdate !== undefined) {
|
||||
settings.beforeAjaxUpdate(id, options);
|
||||
}
|
||||
yiiXHR[id] = $.ajax(options);
|
||||
} else { // non-ajax mode
|
||||
if (options.type === 'GET') {
|
||||
window.location.href = options.url;
|
||||
} else { // POST mode
|
||||
$form = $('<form action="' + options.url + '" method="post"></form>').appendTo('body');
|
||||
if (options.data === undefined) {
|
||||
options.data = {};
|
||||
}
|
||||
|
||||
if (options.data.returnUrl === undefined) {
|
||||
options.data.returnUrl = window.location.href;
|
||||
}
|
||||
|
||||
$.each(options.data, function (name, value) {
|
||||
$form.append($('<input type="hidden" name="t" value="" />').attr('name', name).val(value));
|
||||
});
|
||||
$form.submit();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the key values of the currently selected rows.
|
||||
* @return array the key values of the currently selected rows.
|
||||
*/
|
||||
getSelection: function () {
|
||||
var settings = gridSettings[this.attr('id')],
|
||||
keys = this.find('.keys span'),
|
||||
selection = [];
|
||||
this.find('.' + settings.tableClass).children('tbody').children().each(function (i) {
|
||||
if ($(this).hasClass('selected')) {
|
||||
selection.push(keys.eq(i).text());
|
||||
}
|
||||
});
|
||||
return selection;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the key values of the currently checked rows.
|
||||
* @param column_id string the ID of the column
|
||||
* @return array the key values of the currently checked rows.
|
||||
*/
|
||||
getChecked: function (column_id) {
|
||||
var settings = gridSettings[this.attr('id')],
|
||||
keys = this.find('.keys span'),
|
||||
checked = [];
|
||||
if (column_id.substring(column_id.length - 2) !== '[]') {
|
||||
column_id = column_id + '[]';
|
||||
}
|
||||
this.find('.' + settings.tableClass).children('tbody').children('tr').children('td').children('input[name="' + column_id + '"]').each(function (i) {
|
||||
if (this.checked) {
|
||||
checked.push(keys.eq(i).text());
|
||||
}
|
||||
});
|
||||
return checked;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$.fn.yiiGridView = function (method) {
|
||||
if (methods[method]) {
|
||||
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
||||
} else if (typeof method === 'object' || !method) {
|
||||
return methods.init.apply(this, arguments);
|
||||
} else {
|
||||
$.error('Method ' + method + ' does not exist on jQuery.yiiGridView');
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
*** DEPRECATED METHODS
|
||||
*** used before Yii 1.1.9
|
||||
******************************************************************************/
|
||||
$.fn.yiiGridView.settings = gridSettings;
|
||||
/**
|
||||
* Returns the key value for the specified row
|
||||
* @param id string the ID of the grid view container
|
||||
* @param row integer the row number (zero-based index)
|
||||
* @return string the key value
|
||||
*/
|
||||
$.fn.yiiGridView.getKey = function (id, row) {
|
||||
return $('#' + id).yiiGridView('getKey', row);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the URL that generates the grid view content.
|
||||
* @param id string the ID of the grid view container
|
||||
* @return string the URL that generates the grid view content.
|
||||
*/
|
||||
$.fn.yiiGridView.getUrl = function (id) {
|
||||
return $('#' + id).yiiGridView('getUrl');
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the jQuery collection of the cells in the specified row.
|
||||
* @param id string the ID of the grid view container
|
||||
* @param row integer the row number (zero-based index)
|
||||
* @return jQuery the jQuery collection of the cells in the specified row.
|
||||
*/
|
||||
$.fn.yiiGridView.getRow = function (id, row) {
|
||||
return $('#' + id).yiiGridView('getRow', row);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the jQuery collection of the cells in the specified column.
|
||||
* @param id string the ID of the grid view container
|
||||
* @param column integer the column number (zero-based index)
|
||||
* @return jQuery the jQuery collection of the cells in the specified column.
|
||||
*/
|
||||
$.fn.yiiGridView.getColumn = function (id, column) {
|
||||
return $('#' + id).yiiGridView('getColumn', column);
|
||||
};
|
||||
|
||||
/**
|
||||
* Performs an AJAX-based update of the grid view contents.
|
||||
* @param id string the ID of the grid view container
|
||||
* @param options map the AJAX request options (see jQuery.ajax API manual). By default,
|
||||
* the URL to be requested is the one that generates the current content of the grid view.
|
||||
*/
|
||||
$.fn.yiiGridView.update = function (id, options) {
|
||||
$('#' + id).yiiGridView('update', options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the key values of the currently selected rows.
|
||||
* @param id string the ID of the grid view container
|
||||
* @return array the key values of the currently selected rows.
|
||||
*/
|
||||
$.fn.yiiGridView.getSelection = function (id) {
|
||||
return $('#' + id).yiiGridView('getSelection');
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the key values of the currently checked rows.
|
||||
* @param id string the ID of the grid view container
|
||||
* @param column_id string the ID of the column
|
||||
* @return array the key values of the currently checked rows.
|
||||
*/
|
||||
$.fn.yiiGridView.getChecked = function (id, column_id) {
|
||||
return $('#' + id).yiiGridView('getChecked', column_id);
|
||||
};
|
||||
})(jQuery);
|
||||
BIN
framework/zii/widgets/assets/gridview/loading.gif
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
125
framework/zii/widgets/assets/gridview/styles.css
Normal file
@@ -0,0 +1,125 @@
|
||||
.grid-view-loading
|
||||
{
|
||||
background:url(loading.gif) no-repeat;
|
||||
}
|
||||
|
||||
.grid-view
|
||||
{
|
||||
padding: 15px 0;
|
||||
}
|
||||
|
||||
.grid-view table.items
|
||||
{
|
||||
background: white;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
border: 1px #D0E3EF solid;
|
||||
}
|
||||
|
||||
.grid-view table.items th, .grid-view table.items td
|
||||
{
|
||||
font-size: 0.9em;
|
||||
border: 1px white solid;
|
||||
padding: 0.3em;
|
||||
}
|
||||
|
||||
.grid-view table.items th
|
||||
{
|
||||
color: white;
|
||||
background: url("bg.gif") repeat-x scroll left top white;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.grid-view table.items th a
|
||||
{
|
||||
color: #EEE;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.grid-view table.items th a:hover
|
||||
{
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.grid-view table.items th a.asc
|
||||
{
|
||||
background:url(up.gif) right center no-repeat;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.grid-view table.items th a.desc
|
||||
{
|
||||
background:url(down.gif) right center no-repeat;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.grid-view table.items tr.even
|
||||
{
|
||||
background: #F8F8F8;
|
||||
}
|
||||
|
||||
.grid-view table.items tr.odd
|
||||
{
|
||||
background: #E5F1F4;
|
||||
}
|
||||
|
||||
.grid-view table.items tr.selected
|
||||
{
|
||||
background: #BCE774;
|
||||
}
|
||||
|
||||
.grid-view table.items tr:hover.selected
|
||||
{
|
||||
background: #CCFF66;
|
||||
}
|
||||
|
||||
.grid-view table.items tbody tr:hover
|
||||
{
|
||||
background: #ECFBD4;
|
||||
}
|
||||
|
||||
.grid-view .link-column img
|
||||
{
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.grid-view .button-column
|
||||
{
|
||||
text-align: center;
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.grid-view .button-column img
|
||||
{
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.grid-view .checkbox-column
|
||||
{
|
||||
width: 15px;
|
||||
}
|
||||
|
||||
.grid-view .summary
|
||||
{
|
||||
margin: 0 0 5px 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.grid-view .pager
|
||||
{
|
||||
margin: 5px 0 0 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.grid-view .empty
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.grid-view .filters input,
|
||||
.grid-view .filters select
|
||||
{
|
||||
width: 100%;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
BIN
framework/zii/widgets/assets/gridview/up.gif
Normal file
|
After Width: | Height: | Size: 54 B |
BIN
framework/zii/widgets/assets/gridview/update.png
Normal file
|
After Width: | Height: | Size: 713 B |
BIN
framework/zii/widgets/assets/gridview/view.png
Normal file
|
After Width: | Height: | Size: 803 B |
BIN
framework/zii/widgets/assets/listview/down.gif
Normal file
|
After Width: | Height: | Size: 55 B |
181
framework/zii/widgets/assets/listview/jquery.yiilistview.js
Normal file
@@ -0,0 +1,181 @@
|
||||
/**
|
||||
* jQuery Yii ListView plugin file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2010 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
;(function($) {
|
||||
var yiiXHR = {};
|
||||
/**
|
||||
* yiiListView set function.
|
||||
* @param options map settings for the list view. Availablel options are as follows:
|
||||
* - ajaxUpdate: array, IDs of the containers whose content may be updated by ajax response
|
||||
* - ajaxVar: string, the name of the request variable indicating the ID of the element triggering the AJAX request
|
||||
* - ajaxType: string, the type (GET or POST) of the AJAX request
|
||||
* - pagerClass: string, the CSS class for the pager container
|
||||
* - sorterClass: string, the CSS class for the sorter container
|
||||
* - updateSelector: string, the selector for choosing which elements can trigger ajax requests
|
||||
* - beforeAjaxUpdate: function, the function to be called before ajax request is sent
|
||||
* - afterAjaxUpdate: function, the function to be called after ajax response is received
|
||||
*/
|
||||
$.fn.yiiListView = function(options) {
|
||||
return this.each(function(){
|
||||
var settings = $.extend({}, $.fn.yiiListView.defaults, options || {}),
|
||||
$this = $(this),
|
||||
id = $this.attr('id');
|
||||
|
||||
if(settings.updateSelector == undefined) {
|
||||
settings.updateSelector = '#'+id+' .'+settings.pagerClass.replace(/\s+/g,'.')+' a, #'+id+' .'+settings.sorterClass.replace(/\s+/g,'.')+' a';
|
||||
}
|
||||
$.fn.yiiListView.settings[id] = settings;
|
||||
|
||||
if(settings.ajaxUpdate.length > 0) {
|
||||
$(document).on('click.yiiListView', settings.updateSelector,function(){
|
||||
if(settings.enableHistory && window.History.enabled) {
|
||||
var url = $(this).attr('href').split('?'),
|
||||
params = $.deparam.querystring('?'+ (url[1] || ''));
|
||||
|
||||
delete params[settings.ajaxVar];
|
||||
window.History.pushState(null, document.title, decodeURIComponent($.param.querystring(url[0], params)));
|
||||
} else {
|
||||
$.fn.yiiListView.update(id, {url: $(this).attr('href')});
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if(settings.enableHistory && window.History.enabled) {
|
||||
$(window).bind('statechange', function() { // Note: We are using statechange instead of popstate
|
||||
var State = window.History.getState(); // Note: We are using History.getState() instead of event.state
|
||||
$.fn.yiiListView.update(id, {url: State.url});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.yiiListView.defaults = {
|
||||
ajaxUpdate: [],
|
||||
ajaxVar: 'ajax',
|
||||
ajaxType: 'GET',
|
||||
pagerClass: 'pager',
|
||||
loadingClass: 'loading',
|
||||
sorterClass: 'sorter'
|
||||
// updateSelector: '#id .pager a, '#id .sort a',
|
||||
// beforeAjaxUpdate: function(id) {},
|
||||
// afterAjaxUpdate: function(id, data) {},
|
||||
// url: 'ajax request URL'
|
||||
};
|
||||
|
||||
$.fn.yiiListView.settings = {};
|
||||
|
||||
/**
|
||||
* Returns the key value for the specified row
|
||||
* @param id string the ID of the list view container
|
||||
* @param index integer the zero-based index of the data item
|
||||
* @return string the key value
|
||||
*/
|
||||
$.fn.yiiListView.getKey = function(id, index) {
|
||||
return $('#'+id+' > div.keys > span:eq('+index+')').text();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the URL that generates the list view content.
|
||||
* @param id string the ID of the list view container
|
||||
* @return string the URL that generates the list view content.
|
||||
*/
|
||||
$.fn.yiiListView.getUrl = function(id) {
|
||||
var settings = $.fn.yiiListView.settings[id];
|
||||
return settings.url || $('#'+id+' > div.keys').attr('title');
|
||||
};
|
||||
|
||||
/**
|
||||
* Performs an AJAX-based update of the list view contents.
|
||||
* @param id string the ID of the list view container
|
||||
* @param options map the AJAX request options (see jQuery.ajax API manual). By default,
|
||||
* the URL to be requested is the one that generates the current content of the list view.
|
||||
*/
|
||||
$.fn.yiiListView.update = function(id, options) {
|
||||
var customError,
|
||||
settings = $.fn.yiiListView.settings[id];
|
||||
|
||||
if (options && options.error !== undefined) {
|
||||
customError = options.error;
|
||||
delete options.error;
|
||||
}
|
||||
|
||||
options = $.extend({
|
||||
type: settings.ajaxType,
|
||||
url: $.fn.yiiListView.getUrl(id),
|
||||
success: function(data,status) {
|
||||
$.each(settings.ajaxUpdate, function(i,v) {
|
||||
var id='#'+v;
|
||||
$(id).replaceWith($(id,'<div>'+data+'</div>'));
|
||||
});
|
||||
if(settings.afterAjaxUpdate != undefined)
|
||||
settings.afterAjaxUpdate(id, data);
|
||||
},
|
||||
complete: function() {
|
||||
$('#'+id).removeClass(settings.loadingClass);
|
||||
yiiXHR[id] = null;
|
||||
},
|
||||
error: function(XHR, textStatus, errorThrown) {
|
||||
var ret, err;
|
||||
if (XHR.readyState === 0 || XHR.status === 0) {
|
||||
return;
|
||||
}
|
||||
if (customError !== undefined) {
|
||||
ret = customError(XHR);
|
||||
if (ret !== undefined && !ret) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
switch (textStatus) {
|
||||
case 'timeout':
|
||||
err = 'The request timed out!';
|
||||
break;
|
||||
case 'parsererror':
|
||||
err = 'Parser error!';
|
||||
break;
|
||||
case 'error':
|
||||
if (XHR.status && !/^\s*$/.test(XHR.status)) {
|
||||
err = 'Error ' + XHR.status;
|
||||
} else {
|
||||
err = 'Error';
|
||||
}
|
||||
if (XHR.responseText && !/^\s*$/.test(XHR.responseText)) {
|
||||
err = err + ': ' + XHR.responseText;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (settings.ajaxUpdateError !== undefined) {
|
||||
settings.ajaxUpdateError(XHR, textStatus, errorThrown, err);
|
||||
} else if (err) {
|
||||
alert(err);
|
||||
}
|
||||
}
|
||||
}, options || {});
|
||||
|
||||
if(options.data!=undefined && options.type=='GET') {
|
||||
options.url = $.param.querystring(options.url, options.data);
|
||||
options.data = {};
|
||||
}
|
||||
|
||||
if(settings.ajaxVar)
|
||||
options.url = $.param.querystring(options.url, settings.ajaxVar+'='+id);
|
||||
|
||||
if(yiiXHR[id] != null) {
|
||||
yiiXHR[id].abort();
|
||||
}
|
||||
|
||||
$('#'+id).addClass(settings.loadingClass);
|
||||
|
||||
if(settings.beforeAjaxUpdate != undefined)
|
||||
settings.beforeAjaxUpdate(id);
|
||||
yiiXHR[id] = $.ajax(options);
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
BIN
framework/zii/widgets/assets/listview/loading.gif
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
56
framework/zii/widgets/assets/listview/styles.css
Normal file
@@ -0,0 +1,56 @@
|
||||
.list-view-loading
|
||||
{
|
||||
background:url(loading.gif) no-repeat;
|
||||
}
|
||||
|
||||
.list-view .summary
|
||||
{
|
||||
margin: 0 0 5px 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.list-view .sorter
|
||||
{
|
||||
margin: 0 0 5px 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.list-view .pager
|
||||
{
|
||||
margin: 5px 0 0 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.list-view .sorter
|
||||
{
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.list-view .sorter ul
|
||||
{
|
||||
display: inline;
|
||||
list-style-image:none;
|
||||
list-style-position:outside;
|
||||
list-style-type:none;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
.list-view .sorter li
|
||||
{
|
||||
display: inline;
|
||||
margin: 0 0 0 5px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.list-view .sorter a.asc
|
||||
{
|
||||
background:url(up.gif) right center no-repeat;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.list-view .sorter a.desc
|
||||
{
|
||||
background:url(down.gif) right center no-repeat;
|
||||
padding-right: 10px;
|
||||
}
|
||||
BIN
framework/zii/widgets/assets/listview/up.gif
Normal file
|
After Width: | Height: | Size: 54 B |
349
framework/zii/widgets/grid/CButtonColumn.php
Normal file
@@ -0,0 +1,349 @@
|
||||
<?php
|
||||
/**
|
||||
* CButtonColumn class file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
Yii::import('zii.widgets.grid.CGridColumn');
|
||||
|
||||
/**
|
||||
* CButtonColumn represents a grid view column that renders one or several buttons.
|
||||
*
|
||||
* By default, it will display three buttons, "view", "update" and "delete", which triggers the corresponding
|
||||
* actions on the model of the row.
|
||||
*
|
||||
* By configuring {@link buttons} and {@link template} properties, the column can display other buttons
|
||||
* and customize the display order of the buttons.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package zii.widgets.grid
|
||||
* @since 1.1
|
||||
*/
|
||||
class CButtonColumn extends CGridColumn
|
||||
{
|
||||
/**
|
||||
* @var array the HTML options for the data cell tags.
|
||||
*/
|
||||
public $htmlOptions=array('class'=>'button-column');
|
||||
/**
|
||||
* @var array the HTML options for the header cell tag.
|
||||
*/
|
||||
public $headerHtmlOptions=array('class'=>'button-column');
|
||||
/**
|
||||
* @var array the HTML options for the footer cell tag.
|
||||
*/
|
||||
public $footerHtmlOptions=array('class'=>'button-column');
|
||||
/**
|
||||
* @var string the template that is used to render the content in each data cell.
|
||||
* These default tokens are recognized: {view}, {update} and {delete}. If the {@link buttons} property
|
||||
* defines additional buttons, their IDs are also recognized here. For example, if a button named 'preview'
|
||||
* is declared in {@link buttons}, we can use the token '{preview}' here to specify where to display the button.
|
||||
*/
|
||||
public $template='{view} {update} {delete}';
|
||||
/**
|
||||
* @var string the label for the view button. Defaults to "View".
|
||||
* Note that the label will not be HTML-encoded when rendering.
|
||||
*/
|
||||
public $viewButtonLabel;
|
||||
/**
|
||||
* @var string the image URL for the view button. If not set, an integrated image will be used.
|
||||
* You may set this property to be false to render a text link instead.
|
||||
*/
|
||||
public $viewButtonImageUrl;
|
||||
/**
|
||||
* @var string a PHP expression that is evaluated for every view button and whose result is used
|
||||
* as the URL for the view button. In this expression, you can use the following variables:
|
||||
* <ul>
|
||||
* <li><code>$row</code> the row number (zero-based)</li>
|
||||
* <li><code>$data</code> the data model for the row</li>
|
||||
* <li><code>$this</code> the column object</li>
|
||||
* </ul>
|
||||
* The PHP expression will be evaluated using {@link evaluateExpression}.
|
||||
*
|
||||
* A PHP expression can be any PHP code that has a value. To learn more about what an expression is,
|
||||
* please refer to the {@link http://www.php.net/manual/en/language.expressions.php php manual}.
|
||||
*/
|
||||
public $viewButtonUrl='Yii::app()->controller->createUrl("view",array("id"=>$data->primaryKey))';
|
||||
/**
|
||||
* @var array the HTML options for the view button tag.
|
||||
*/
|
||||
public $viewButtonOptions=array('class'=>'view');
|
||||
|
||||
/**
|
||||
* @var string the label for the update button. Defaults to "Update".
|
||||
* Note that the label will not be HTML-encoded when rendering.
|
||||
*/
|
||||
public $updateButtonLabel;
|
||||
/**
|
||||
* @var string the image URL for the update button. If not set, an integrated image will be used.
|
||||
* You may set this property to be false to render a text link instead.
|
||||
*/
|
||||
public $updateButtonImageUrl;
|
||||
/**
|
||||
* @var string a PHP expression that is evaluated for every update button and whose result is used
|
||||
* as the URL for the update button. In this expression, you can use the following variables:
|
||||
* <ul>
|
||||
* <li><code>$row</code> the row number (zero-based)</li>
|
||||
* <li><code>$data</code> the data model for the row</li>
|
||||
* <li><code>$this</code> the column object</li>
|
||||
* </ul>
|
||||
* The PHP expression will be evaluated using {@link evaluateExpression}.
|
||||
*
|
||||
* A PHP expression can be any PHP code that has a value. To learn more about what an expression is,
|
||||
* please refer to the {@link http://www.php.net/manual/en/language.expressions.php php manual}.
|
||||
*/
|
||||
public $updateButtonUrl='Yii::app()->controller->createUrl("update",array("id"=>$data->primaryKey))';
|
||||
/**
|
||||
* @var array the HTML options for the update button tag.
|
||||
*/
|
||||
public $updateButtonOptions=array('class'=>'update');
|
||||
|
||||
/**
|
||||
* @var string the label for the delete button. Defaults to "Delete".
|
||||
* Note that the label will not be HTML-encoded when rendering.
|
||||
*/
|
||||
public $deleteButtonLabel;
|
||||
/**
|
||||
* @var string the image URL for the delete button. If not set, an integrated image will be used.
|
||||
* You may set this property to be false to render a text link instead.
|
||||
*/
|
||||
public $deleteButtonImageUrl;
|
||||
/**
|
||||
* @var string a PHP expression that is evaluated for every delete button and whose result is used
|
||||
* as the URL for the delete button. In this expression, you can use the following variables:
|
||||
* <ul>
|
||||
* <li><code>$row</code> the row number (zero-based)</li>
|
||||
* <li><code>$data</code> the data model for the row</li>
|
||||
* <li><code>$this</code> the column object</li>
|
||||
* </ul>
|
||||
* The PHP expression will be evaluated using {@link evaluateExpression}.
|
||||
*
|
||||
* A PHP expression can be any PHP code that has a value. To learn more about what an expression is,
|
||||
* please refer to the {@link http://www.php.net/manual/en/language.expressions.php php manual}.
|
||||
*/
|
||||
public $deleteButtonUrl='Yii::app()->controller->createUrl("delete",array("id"=>$data->primaryKey))';
|
||||
/**
|
||||
* @var array the HTML options for the delete button tag.
|
||||
*/
|
||||
public $deleteButtonOptions=array('class'=>'delete');
|
||||
/**
|
||||
* @var string the confirmation message to be displayed when delete button is clicked.
|
||||
* By setting this property to be false, no confirmation message will be displayed.
|
||||
* This property is used only if <code>$this->buttons['delete']['click']</code> is not set.
|
||||
*/
|
||||
public $deleteConfirmation;
|
||||
/**
|
||||
* @var string a javascript function that will be invoked after the delete ajax call.
|
||||
* This property is used only if <code>$this->buttons['delete']['click']</code> is not set.
|
||||
*
|
||||
* The function signature is <code>function(link, success, data)</code>
|
||||
* <ul>
|
||||
* <li><code>link</code> references the delete link.</li>
|
||||
* <li><code>success</code> status of the ajax call, true if the ajax call was successful, false if the ajax call failed.
|
||||
* <li><code>data</code> the data returned by the server in case of a successful call or XHR object in case of error.
|
||||
* </ul>
|
||||
* Note that if success is true it does not mean that the delete was successful, it only means that the ajax call was successful.
|
||||
*
|
||||
* Example:
|
||||
* <pre>
|
||||
* array(
|
||||
* class'=>'CButtonColumn',
|
||||
* 'afterDelete'=>'function(link,success,data){ if(success) alert("Delete completed successfuly"); }',
|
||||
* ),
|
||||
* </pre>
|
||||
*/
|
||||
public $afterDelete;
|
||||
/**
|
||||
* @var array the configuration for buttons. Each array element specifies a single button
|
||||
* which has the following format:
|
||||
* <pre>
|
||||
* 'buttonID' => array(
|
||||
* 'label'=>'...', // text label of the button
|
||||
* 'url'=>'...', // a PHP expression for generating the URL of the button
|
||||
* 'imageUrl'=>'...', // image URL of the button. If not set or false, a text link is used
|
||||
* 'options'=>array(...), // HTML options for the button tag
|
||||
* 'click'=>'...', // a JS function to be invoked when the button is clicked
|
||||
* 'visible'=>'...', // a PHP expression for determining whether the button is visible
|
||||
* )
|
||||
* </pre>
|
||||
*
|
||||
* In the PHP expression for the 'url' option and/or 'visible' option, the variable <code>$row</code>
|
||||
* refers to the current row number (zero-based), and <code>$data</code> refers to the data model for
|
||||
* the row.
|
||||
* The PHP expression will be evaluated using {@link evaluateExpression}.
|
||||
* A PHP expression can be any PHP code that has a value. To learn more about what an expression is,
|
||||
* please refer to the {@link http://www.php.net/manual/en/language.expressions.php php manual}.
|
||||
*
|
||||
* If the 'buttonID' is 'view', 'update' or 'delete' the options will be applied to the default buttons.
|
||||
*
|
||||
* Note that in order to display non-default buttons, the {@link template} property needs to
|
||||
* be configured so that the corresponding button IDs appear as tokens in the template.
|
||||
*/
|
||||
public $buttons=array();
|
||||
|
||||
/**
|
||||
* Initializes the column.
|
||||
* This method registers necessary client script for the button column.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->initDefaultButtons();
|
||||
|
||||
foreach($this->buttons as $id=>$button)
|
||||
{
|
||||
if(strpos($this->template,'{'.$id.'}')===false)
|
||||
unset($this->buttons[$id]);
|
||||
elseif(isset($button['click']))
|
||||
{
|
||||
if(!isset($button['options']['class']))
|
||||
$this->buttons[$id]['options']['class']=$id;
|
||||
if(!($button['click'] instanceof CJavaScriptExpression))
|
||||
$this->buttons[$id]['click']=new CJavaScriptExpression($button['click']);
|
||||
}
|
||||
}
|
||||
|
||||
$this->registerClientScript();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the default buttons (view, update and delete).
|
||||
*/
|
||||
protected function initDefaultButtons()
|
||||
{
|
||||
if($this->viewButtonLabel===null)
|
||||
$this->viewButtonLabel=Yii::t('zii','View');
|
||||
if($this->updateButtonLabel===null)
|
||||
$this->updateButtonLabel=Yii::t('zii','Update');
|
||||
if($this->deleteButtonLabel===null)
|
||||
$this->deleteButtonLabel=Yii::t('zii','Delete');
|
||||
if($this->viewButtonImageUrl===null)
|
||||
$this->viewButtonImageUrl=$this->grid->baseScriptUrl.'/view.png';
|
||||
if($this->updateButtonImageUrl===null)
|
||||
$this->updateButtonImageUrl=$this->grid->baseScriptUrl.'/update.png';
|
||||
if($this->deleteButtonImageUrl===null)
|
||||
$this->deleteButtonImageUrl=$this->grid->baseScriptUrl.'/delete.png';
|
||||
if($this->deleteConfirmation===null)
|
||||
$this->deleteConfirmation=Yii::t('zii','Are you sure you want to delete this item?');
|
||||
|
||||
foreach(array('view','update','delete') as $id)
|
||||
{
|
||||
$button=array(
|
||||
'label'=>$this->{$id.'ButtonLabel'},
|
||||
'url'=>$this->{$id.'ButtonUrl'},
|
||||
'imageUrl'=>$this->{$id.'ButtonImageUrl'},
|
||||
'options'=>$this->{$id.'ButtonOptions'},
|
||||
);
|
||||
if(isset($this->buttons[$id]))
|
||||
$this->buttons[$id]=array_merge($button,$this->buttons[$id]);
|
||||
else
|
||||
$this->buttons[$id]=$button;
|
||||
}
|
||||
|
||||
if(!isset($this->buttons['delete']['click']))
|
||||
{
|
||||
if(is_string($this->deleteConfirmation))
|
||||
$confirmation="if(!confirm(".CJavaScript::encode($this->deleteConfirmation).")) return false;";
|
||||
else
|
||||
$confirmation='';
|
||||
|
||||
if(Yii::app()->request->enableCsrfValidation)
|
||||
{
|
||||
$csrfTokenName = Yii::app()->request->csrfTokenName;
|
||||
$csrfToken = Yii::app()->request->csrfToken;
|
||||
$csrf = "\n\t\tdata:{ '$csrfTokenName':'$csrfToken' },";
|
||||
}
|
||||
else
|
||||
$csrf = '';
|
||||
|
||||
if($this->afterDelete===null)
|
||||
$this->afterDelete='function(){}';
|
||||
|
||||
$this->buttons['delete']['click']=<<<EOD
|
||||
function() {
|
||||
$confirmation
|
||||
var th = this,
|
||||
afterDelete = $this->afterDelete;
|
||||
jQuery('#{$this->grid->id}').yiiGridView('update', {
|
||||
type: 'POST',
|
||||
url: jQuery(this).attr('href'),$csrf
|
||||
success: function(data) {
|
||||
jQuery('#{$this->grid->id}').yiiGridView('update');
|
||||
afterDelete(th, true, data);
|
||||
},
|
||||
error: function(XHR) {
|
||||
return afterDelete(th, false, XHR);
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
EOD;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the client scripts for the button column.
|
||||
*/
|
||||
protected function registerClientScript()
|
||||
{
|
||||
$js=array();
|
||||
foreach($this->buttons as $id=>$button)
|
||||
{
|
||||
if(isset($button['click']))
|
||||
{
|
||||
$function=CJavaScript::encode($button['click']);
|
||||
$class=preg_replace('/\s+/','.',$button['options']['class']);
|
||||
$js[]="jQuery(document).on('click','#{$this->grid->id} a.{$class}',$function);";
|
||||
}
|
||||
}
|
||||
|
||||
if($js!==array())
|
||||
Yii::app()->getClientScript()->registerScript(__CLASS__.'#'.$this->id, implode("\n",$js));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the data cell content.
|
||||
* This method renders the view, update and delete buttons in the data cell.
|
||||
* @param integer $row the row number (zero-based)
|
||||
* @param mixed $data the data associated with the row
|
||||
*/
|
||||
protected function renderDataCellContent($row,$data)
|
||||
{
|
||||
$tr=array();
|
||||
ob_start();
|
||||
foreach($this->buttons as $id=>$button)
|
||||
{
|
||||
$this->renderButton($id,$button,$row,$data);
|
||||
$tr['{'.$id.'}']=ob_get_contents();
|
||||
ob_clean();
|
||||
}
|
||||
ob_end_clean();
|
||||
echo strtr($this->template,$tr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a link button.
|
||||
* @param string $id the ID of the button
|
||||
* @param array $button the button configuration which may contain 'label', 'url', 'imageUrl' and 'options' elements.
|
||||
* See {@link buttons} for more details.
|
||||
* @param integer $row the row number (zero-based)
|
||||
* @param mixed $data the data object associated with the row
|
||||
*/
|
||||
protected function renderButton($id,$button,$row,$data)
|
||||
{
|
||||
if (isset($button['visible']) && !$this->evaluateExpression($button['visible'],array('row'=>$row,'data'=>$data)))
|
||||
return;
|
||||
$label=isset($button['label']) ? $button['label'] : $id;
|
||||
$url=isset($button['url']) ? $this->evaluateExpression($button['url'],array('data'=>$data,'row'=>$row)) : '#';
|
||||
$options=isset($button['options']) ? $button['options'] : array();
|
||||
if(!isset($options['title']))
|
||||
$options['title']=$label;
|
||||
if(isset($button['imageUrl']) && is_string($button['imageUrl']))
|
||||
echo CHtml::link(CHtml::image($button['imageUrl'],$label),$url,$options);
|
||||
else
|
||||
echo CHtml::link($label,$url,$options);
|
||||
}
|
||||
}
|
||||
248
framework/zii/widgets/grid/CCheckBoxColumn.php
Normal file
@@ -0,0 +1,248 @@
|
||||
<?php
|
||||
/**
|
||||
* CCheckBoxColumn class file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
Yii::import('zii.widgets.grid.CGridColumn');
|
||||
|
||||
/**
|
||||
* CCheckBoxColumn represents a grid view column of checkboxes.
|
||||
*
|
||||
* CCheckBoxColumn supports no checking (read-only), single check and multiple checking.
|
||||
* The mode is determined according to {@link selectableRows}. When in multiple checking mode, the header cell will display
|
||||
* an additional checkbox, clicking on which will check or uncheck all of the checkboxes in the data cells.
|
||||
* The header cell can be customized by {@link headerTemplate}.
|
||||
*
|
||||
* Additionally selecting a checkbox can select a grid view row (depending on {@link CGridView::selectableRows} value) if
|
||||
* {@link selectableRows} is null (default).
|
||||
*
|
||||
* By default, the checkboxes rendered in data cells will have the values that are the same as
|
||||
* the key values of the data model. One may change this by setting either {@link name} or
|
||||
* {@link value}.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package zii.widgets.grid
|
||||
* @since 1.1
|
||||
*/
|
||||
class CCheckBoxColumn extends CGridColumn
|
||||
{
|
||||
/**
|
||||
* @var string the attribute name of the data model. The corresponding attribute value will be rendered
|
||||
* in each data cell as the checkbox value. Note that if {@link value} is specified, this property will be ignored.
|
||||
* @see value
|
||||
*/
|
||||
public $name;
|
||||
/**
|
||||
* @var string a PHP expression that will be evaluated for every data cell and whose result will be rendered
|
||||
* in each data cell as the checkbox value. In this expression, you can use the following variables:
|
||||
* <ul>
|
||||
* <li><code>$row</code> the row number (zero-based)</li>
|
||||
* <li><code>$data</code> the data model for the row</li>
|
||||
* <li><code>$this</code> the column object</li>
|
||||
* </ul>
|
||||
* The PHP expression will be evaluated using {@link evaluateExpression}.
|
||||
*
|
||||
* A PHP expression can be any PHP code that has a value. To learn more about what an expression is,
|
||||
* please refer to the {@link http://www.php.net/manual/en/language.expressions.php php manual}.
|
||||
*/
|
||||
public $value;
|
||||
/**
|
||||
* @var string a PHP expression that will be evaluated for every data cell and whose result will
|
||||
* determine if checkbox for each data cell is checked. In this expression, you can use the following variables:
|
||||
* <ul>
|
||||
* <li><code>$row</code> the row number (zero-based)</li>
|
||||
* <li><code>$data</code> the data model for the row</li>
|
||||
* <li><code>$this</code> the column object</li>
|
||||
* </ul>
|
||||
* The PHP expression will be evaluated using {@link evaluateExpression}.
|
||||
*
|
||||
* A PHP expression can be any PHP code that has a value. To learn more about what an expression is,
|
||||
* please refer to the {@link http://www.php.net/manual/en/language.expressions.php php manual}.
|
||||
* @since 1.1.4
|
||||
*/
|
||||
public $checked;
|
||||
/**
|
||||
* @var string a PHP expression that will be evaluated for every data cell and whose result will
|
||||
* determine if checkbox for each data cell is disabled. In this expression, you can use the following variables:
|
||||
* <ul>
|
||||
* <li><code>$row</code> the row number (zero-based)</li>
|
||||
* <li><code>$data</code> the data model for the row</li>
|
||||
* <li><code>$this</code> the column object</li>
|
||||
* </ul>
|
||||
* The PHP expression will be evaluated using {@link evaluateExpression}.
|
||||
*
|
||||
* A PHP expression can be any PHP code that has a value. To learn more about what an expression is,
|
||||
* please refer to the {@link http://www.php.net/manual/en/language.expressions.php php manual}.
|
||||
*
|
||||
* Note that expression result will overwrite value set with <code>checkBoxHtmlOptions['disabled']</code>.
|
||||
* @since 1.1.13
|
||||
*/
|
||||
public $disabled;
|
||||
/**
|
||||
* @var array the HTML options for the data cell tags.
|
||||
*/
|
||||
public $htmlOptions=array('class'=>'checkbox-column');
|
||||
/**
|
||||
* @var array the HTML options for the header cell tag.
|
||||
*/
|
||||
public $headerHtmlOptions=array('class'=>'checkbox-column');
|
||||
/**
|
||||
* @var array the HTML options for the footer cell tag.
|
||||
*/
|
||||
public $footerHtmlOptions=array('class'=>'checkbox-column');
|
||||
/**
|
||||
* @var array the HTML options for the checkboxes.
|
||||
*/
|
||||
public $checkBoxHtmlOptions=array();
|
||||
/**
|
||||
* @var integer the number of rows that can be checked.
|
||||
* Possible values:
|
||||
* <ul>
|
||||
* <li>0 - the state of the checkbox cannot be changed (read-only mode)</li>
|
||||
* <li>1 - only one row can be checked. Checking a checkbox has nothing to do with selecting the row</li>
|
||||
* <li>2 or more - multiple checkboxes can be checked. Checking a checkbox has nothing to do with selecting the row</li>
|
||||
* <li>null - {@link CGridView::selectableRows} is used to control how many checkboxes can be checked.
|
||||
* Checking a checkbox will also select the row.</li>
|
||||
* </ul>
|
||||
* You may also call the JavaScript function <code>$(gridID).yiiGridView('getChecked', columnID)</code>
|
||||
* to retrieve the key values of the checked rows.
|
||||
* @since 1.1.6
|
||||
*/
|
||||
public $selectableRows=null;
|
||||
/**
|
||||
* @var string the template to be used to control the layout of the header cell.
|
||||
* The token "{item}" is recognized and it will be replaced with a "check all" checkbox.
|
||||
* By default if in multiple checking mode, the header cell will display an additional checkbox,
|
||||
* clicking on which will check or uncheck all of the checkboxes in the data cells.
|
||||
* See {@link selectableRows} for more details.
|
||||
* @since 1.1.11
|
||||
*/
|
||||
public $headerTemplate='{item}';
|
||||
|
||||
/**
|
||||
* Initializes the column.
|
||||
* This method registers necessary client script for the checkbox column.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if(isset($this->checkBoxHtmlOptions['name']))
|
||||
$name=$this->checkBoxHtmlOptions['name'];
|
||||
else
|
||||
{
|
||||
$name=$this->id;
|
||||
if(substr($name,-2)!=='[]')
|
||||
$name.='[]';
|
||||
$this->checkBoxHtmlOptions['name']=$name;
|
||||
}
|
||||
$name=strtr($name,array('['=>"\\[",']'=>"\\]"));
|
||||
|
||||
if($this->selectableRows===null)
|
||||
{
|
||||
if(isset($this->checkBoxHtmlOptions['class']))
|
||||
$this->checkBoxHtmlOptions['class'].=' select-on-check';
|
||||
else
|
||||
$this->checkBoxHtmlOptions['class']='select-on-check';
|
||||
return;
|
||||
}
|
||||
|
||||
$cball=$cbcode='';
|
||||
if($this->selectableRows==0)
|
||||
{
|
||||
//.. read only
|
||||
$cbcode="return false;";
|
||||
}
|
||||
elseif($this->selectableRows==1)
|
||||
{
|
||||
//.. only one can be checked, uncheck all other
|
||||
$cbcode="jQuery(\"input:not(#\"+this.id+\")[name='$name']\").prop('checked',false);";
|
||||
}
|
||||
elseif(strpos($this->headerTemplate,'{item}')!==false)
|
||||
{
|
||||
//.. process check/uncheck all
|
||||
$cball=<<<CBALL
|
||||
jQuery(document).on('click','#{$this->id}_all',function() {
|
||||
var checked=this.checked;
|
||||
jQuery("input[name='$name']:enabled").each(function() {this.checked=checked;});
|
||||
});
|
||||
|
||||
CBALL;
|
||||
$cbcode="jQuery('#{$this->id}_all').prop('checked', jQuery(\"input[name='$name']\").length==jQuery(\"input[name='$name']:checked\").length);";
|
||||
}
|
||||
|
||||
if($cbcode!=='')
|
||||
{
|
||||
$js=$cball;
|
||||
$js.=<<<EOD
|
||||
jQuery(document).on('click', "input[name='$name']", function() {
|
||||
$cbcode
|
||||
});
|
||||
EOD;
|
||||
Yii::app()->getClientScript()->registerScript(__CLASS__.'#'.$this->id,$js);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the header cell content.
|
||||
* This method will render a checkbox in the header when {@link selectableRows} is greater than 1
|
||||
* or in case {@link selectableRows} is null when {@link CGridView::selectableRows} is greater than 1.
|
||||
*/
|
||||
protected function renderHeaderCellContent()
|
||||
{
|
||||
if(trim($this->headerTemplate)==='')
|
||||
{
|
||||
echo $this->grid->blankDisplay;
|
||||
return;
|
||||
}
|
||||
|
||||
$item = '';
|
||||
if($this->selectableRows===null && $this->grid->selectableRows>1)
|
||||
$item = CHtml::checkBox($this->id.'_all',false,array('class'=>'select-on-check-all'));
|
||||
elseif($this->selectableRows>1)
|
||||
$item = CHtml::checkBox($this->id.'_all',false);
|
||||
else
|
||||
{
|
||||
ob_start();
|
||||
parent::renderHeaderCellContent();
|
||||
$item = ob_get_clean();
|
||||
}
|
||||
|
||||
echo strtr($this->headerTemplate,array(
|
||||
'{item}'=>$item,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the data cell content.
|
||||
* This method renders a checkbox in the data cell.
|
||||
* @param integer $row the row number (zero-based)
|
||||
* @param mixed $data the data associated with the row
|
||||
*/
|
||||
protected function renderDataCellContent($row,$data)
|
||||
{
|
||||
if($this->value!==null)
|
||||
$value=$this->evaluateExpression($this->value,array('data'=>$data,'row'=>$row));
|
||||
elseif($this->name!==null)
|
||||
$value=CHtml::value($data,$this->name);
|
||||
else
|
||||
$value=$this->grid->dataProvider->keys[$row];
|
||||
|
||||
$checked = false;
|
||||
if($this->checked!==null)
|
||||
$checked=$this->evaluateExpression($this->checked,array('data'=>$data,'row'=>$row));
|
||||
|
||||
$options=$this->checkBoxHtmlOptions;
|
||||
if($this->disabled!==null)
|
||||
$options['disabled']=$this->evaluateExpression($this->disabled,array('data'=>$data,'row'=>$row));
|
||||
|
||||
$name=$options['name'];
|
||||
unset($options['name']);
|
||||
$options['value']=$value;
|
||||
$options['id']=$this->id.'_'.$row;
|
||||
echo CHtml::checkBox($name,$checked,$options);
|
||||
}
|
||||
}
|
||||
142
framework/zii/widgets/grid/CDataColumn.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
/**
|
||||
* CDataColumn class file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
Yii::import('zii.widgets.grid.CGridColumn');
|
||||
|
||||
/**
|
||||
* CDataColumn represents a grid view column that is associated with a data attribute or PHP expression.
|
||||
*
|
||||
* Either {@link name} or {@link value} should be specified. The former specifies
|
||||
* a data attribute name, while the latter a PHP expression whose value should be rendered instead.
|
||||
*
|
||||
* The property {@link sortable} determines whether the grid view can be sorted according to this column.
|
||||
* Note that the {@link name} should always be set if the column needs to be sortable. The {@link name}
|
||||
* value will be used by {@link CSort} to render a clickable link in the header cell to trigger the sorting.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package zii.widgets.grid
|
||||
* @since 1.1
|
||||
*/
|
||||
class CDataColumn extends CGridColumn
|
||||
{
|
||||
/**
|
||||
* @var string the attribute name of the data model. Used for column sorting, filtering and to render the corresponding
|
||||
* attribute value in each data cell. If {@link value} is specified it will be used to rendered the data cell instead of the attribute value.
|
||||
* @see value
|
||||
* @see sortable
|
||||
*/
|
||||
public $name;
|
||||
/**
|
||||
* @var string a PHP expression that will be evaluated for every data cell using {@link evaluateExpression} and whose result will be rendered
|
||||
* as the content of the data cell.
|
||||
* In this expression, you can use the following variables:
|
||||
* <ul>
|
||||
* <li><code>$row</code> the row number (zero-based).</li>
|
||||
* <li><code>$data</code> the data model for the row.</li>
|
||||
* <li><code>$this</code> the column object.</li>
|
||||
* </ul>
|
||||
* A PHP expression can be any PHP code that has a value. To learn more about what an expression is,
|
||||
* please refer to the {@link http://www.php.net/manual/en/language.expressions.php php manual}.
|
||||
*/
|
||||
public $value;
|
||||
/**
|
||||
* @var string the type of the attribute value. This determines how the attribute value is formatted for display.
|
||||
* Valid values include those recognizable by {@link CGridView::formatter}, such as: raw, text, ntext, html, date, time,
|
||||
* datetime, boolean, number, email, image, url. For more details, please refer to {@link CFormatter}.
|
||||
* Defaults to 'text' which means the attribute value will be HTML-encoded.
|
||||
*/
|
||||
public $type='text';
|
||||
/**
|
||||
* @var boolean whether the column is sortable. If so, the header cell will contain a link that may trigger the sorting.
|
||||
* Defaults to true. Note that if {@link name} is not set, or if {@link name} is not allowed by {@link CSort},
|
||||
* this property will be treated as false.
|
||||
* @see name
|
||||
*/
|
||||
public $sortable=true;
|
||||
/**
|
||||
* @var mixed the HTML code representing a filter input (eg a text field, a dropdown list)
|
||||
* that is used for this data column. This property is effective only when
|
||||
* {@link CGridView::filter} is set.
|
||||
* If this property is not set, a text field will be generated as the filter input;
|
||||
* If this property is an array, a dropdown list will be generated that uses this property value as
|
||||
* the list options.
|
||||
* If you don't want a filter for this data column, set this value to false.
|
||||
* @since 1.1.1
|
||||
*/
|
||||
public $filter;
|
||||
|
||||
/**
|
||||
* Initializes the column.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
if($this->name===null)
|
||||
$this->sortable=false;
|
||||
if($this->name===null && $this->value===null)
|
||||
throw new CException(Yii::t('zii','Either "name" or "value" must be specified for CDataColumn.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the filter cell content.
|
||||
* This method will render the {@link filter} as is if it is a string.
|
||||
* If {@link filter} is an array, it is assumed to be a list of options, and a dropdown selector will be rendered.
|
||||
* Otherwise if {@link filter} is not false, a text field is rendered.
|
||||
* @since 1.1.1
|
||||
*/
|
||||
protected function renderFilterCellContent()
|
||||
{
|
||||
if(is_string($this->filter))
|
||||
echo $this->filter;
|
||||
elseif($this->filter!==false && $this->grid->filter!==null && $this->name!==null && strpos($this->name,'.')===false)
|
||||
{
|
||||
if(is_array($this->filter))
|
||||
echo CHtml::activeDropDownList($this->grid->filter, $this->name, $this->filter, array('id'=>false,'prompt'=>''));
|
||||
elseif($this->filter===null)
|
||||
echo CHtml::activeTextField($this->grid->filter, $this->name, array('id'=>false));
|
||||
}
|
||||
else
|
||||
parent::renderFilterCellContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the header cell content.
|
||||
* This method will render a link that can trigger the sorting if the column is sortable.
|
||||
*/
|
||||
protected function renderHeaderCellContent()
|
||||
{
|
||||
if($this->grid->enableSorting && $this->sortable && $this->name!==null)
|
||||
echo $this->grid->dataProvider->getSort()->link($this->name,$this->header,array('class'=>'sort-link'));
|
||||
elseif($this->name!==null && $this->header===null)
|
||||
{
|
||||
if($this->grid->dataProvider instanceof CActiveDataProvider)
|
||||
echo CHtml::encode($this->grid->dataProvider->model->getAttributeLabel($this->name));
|
||||
else
|
||||
echo CHtml::encode($this->name);
|
||||
}
|
||||
else
|
||||
parent::renderHeaderCellContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the data cell content.
|
||||
* This method evaluates {@link value} or {@link name} and renders the result.
|
||||
* @param integer $row the row number (zero-based)
|
||||
* @param mixed $data the data associated with the row
|
||||
*/
|
||||
protected function renderDataCellContent($row,$data)
|
||||
{
|
||||
if($this->value!==null)
|
||||
$value=$this->evaluateExpression($this->value,array('data'=>$data,'row'=>$row));
|
||||
elseif($this->name!==null)
|
||||
$value=CHtml::value($data,$this->name);
|
||||
echo $value===null ? $this->grid->nullDisplay : $this->grid->getFormatter()->format($value,$this->type);
|
||||
}
|
||||
}
|
||||
206
framework/zii/widgets/grid/CGridColumn.php
Normal file
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
/**
|
||||
* CGridColumn class file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* CGridColumn is the base class for all grid view column classes.
|
||||
*
|
||||
* A CGridColumn object represents the specification for rendering the cells in
|
||||
* a particular grid view column.
|
||||
*
|
||||
* In a column, there is one header cell, multiple data cells, and an optional footer cell.
|
||||
* Child classes may override {@link renderHeaderCellContent}, {@link renderDataCellContent}
|
||||
* and {@link renderFooterCellContent} to customize how these cells are rendered.
|
||||
*
|
||||
* @property boolean $hasFooter Whether this column has a footer cell.
|
||||
* This is determined based on whether {@link footer} is set.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package zii.widgets.grid
|
||||
* @since 1.1
|
||||
*/
|
||||
abstract class CGridColumn extends CComponent
|
||||
{
|
||||
/**
|
||||
* @var string the ID of this column. This value should be unique among all grid view columns.
|
||||
* If this is not set, it will be assigned one automatically.
|
||||
*/
|
||||
public $id;
|
||||
/**
|
||||
* @var CGridView the grid view object that owns this column.
|
||||
*/
|
||||
public $grid;
|
||||
/**
|
||||
* @var string the header cell text. Note that it will not be HTML-encoded.
|
||||
*/
|
||||
public $header;
|
||||
/**
|
||||
* @var string the footer cell text. Note that it will not be HTML-encoded.
|
||||
*/
|
||||
public $footer;
|
||||
/**
|
||||
* @var boolean whether this column is visible. Defaults to true.
|
||||
*/
|
||||
public $visible=true;
|
||||
/**
|
||||
* @var string a PHP expression that is evaluated for every data cell and whose result
|
||||
* is used as the CSS class name for the data cell. In this expression, you can use the following variables:
|
||||
* <ul>
|
||||
* <li><code>$row</code> the row number (zero-based)</li>
|
||||
* <li><code>$data</code> the data model for the row</li>
|
||||
* <li><code>$this</code> the column object</li>
|
||||
* </ul>
|
||||
* The PHP expression will be evaluated using {@link evaluateExpression}.
|
||||
*
|
||||
* A PHP expression can be any PHP code that has a value. To learn more about what an expression is,
|
||||
* please refer to the {@link http://www.php.net/manual/en/language.expressions.php php manual}.
|
||||
*/
|
||||
public $cssClassExpression;
|
||||
/**
|
||||
* @var array the HTML options for the data cell tags.
|
||||
*/
|
||||
public $htmlOptions=array();
|
||||
/**
|
||||
* @var array the HTML options for the filter cell tag.
|
||||
*/
|
||||
public $filterHtmlOptions=array();
|
||||
/**
|
||||
* @var array the HTML options for the header cell tag.
|
||||
*/
|
||||
public $headerHtmlOptions=array();
|
||||
/**
|
||||
* @var array the HTML options for the footer cell tag.
|
||||
*/
|
||||
public $footerHtmlOptions=array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param CGridView $grid the grid view that owns this column.
|
||||
*/
|
||||
public function __construct($grid)
|
||||
{
|
||||
$this->grid=$grid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the column.
|
||||
* This method is invoked by the grid view when it initializes itself before rendering.
|
||||
* You may override this method to prepare the column for rendering.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean whether this column has a footer cell.
|
||||
* This is determined based on whether {@link footer} is set.
|
||||
*/
|
||||
public function getHasFooter()
|
||||
{
|
||||
return $this->footer!==null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the filter cell.
|
||||
* @since 1.1.1
|
||||
*/
|
||||
public function renderFilterCell()
|
||||
{
|
||||
echo CHtml::openTag('td',$this->filterHtmlOptions);
|
||||
$this->renderFilterCellContent();
|
||||
echo "</td>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the header cell.
|
||||
*/
|
||||
public function renderHeaderCell()
|
||||
{
|
||||
$this->headerHtmlOptions['id']=$this->id;
|
||||
echo CHtml::openTag('th',$this->headerHtmlOptions);
|
||||
$this->renderHeaderCellContent();
|
||||
echo "</th>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a data cell.
|
||||
* @param integer $row the row number (zero-based)
|
||||
*/
|
||||
public function renderDataCell($row)
|
||||
{
|
||||
$data=$this->grid->dataProvider->data[$row];
|
||||
$options=$this->htmlOptions;
|
||||
if($this->cssClassExpression!==null)
|
||||
{
|
||||
$class=$this->evaluateExpression($this->cssClassExpression,array('row'=>$row,'data'=>$data));
|
||||
if(!empty($class))
|
||||
{
|
||||
if(isset($options['class']))
|
||||
$options['class'].=' '.$class;
|
||||
else
|
||||
$options['class']=$class;
|
||||
}
|
||||
}
|
||||
echo CHtml::openTag('td',$options);
|
||||
$this->renderDataCellContent($row,$data);
|
||||
echo '</td>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the footer cell.
|
||||
*/
|
||||
public function renderFooterCell()
|
||||
{
|
||||
echo CHtml::openTag('td',$this->footerHtmlOptions);
|
||||
$this->renderFooterCellContent();
|
||||
echo '</td>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the header cell content.
|
||||
* The default implementation simply renders {@link header}.
|
||||
* This method may be overridden to customize the rendering of the header cell.
|
||||
*/
|
||||
protected function renderHeaderCellContent()
|
||||
{
|
||||
echo trim($this->header)!=='' ? $this->header : $this->grid->blankDisplay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the footer cell content.
|
||||
* The default implementation simply renders {@link footer}.
|
||||
* This method may be overridden to customize the rendering of the footer cell.
|
||||
*/
|
||||
protected function renderFooterCellContent()
|
||||
{
|
||||
echo trim($this->footer)!=='' ? $this->footer : $this->grid->blankDisplay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the data cell content.
|
||||
* This method SHOULD be overridden to customize the rendering of the data cell.
|
||||
* @param integer $row the row number (zero-based)
|
||||
* @param mixed $data the data associated with the row
|
||||
*/
|
||||
protected function renderDataCellContent($row,$data)
|
||||
{
|
||||
echo $this->grid->blankDisplay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the filter cell content.
|
||||
* The default implementation simply renders a space.
|
||||
* This method may be overridden to customize the rendering of the filter cell (if any).
|
||||
* @since 1.1.1
|
||||
*/
|
||||
protected function renderFilterCellContent()
|
||||
{
|
||||
echo $this->grid->blankDisplay;
|
||||
}
|
||||
}
|
||||
649
framework/zii/widgets/grid/CGridView.php
Normal file
@@ -0,0 +1,649 @@
|
||||
<?php
|
||||
/**
|
||||
* CGridView class file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
Yii::import('zii.widgets.CBaseListView');
|
||||
Yii::import('zii.widgets.grid.CDataColumn');
|
||||
Yii::import('zii.widgets.grid.CLinkColumn');
|
||||
Yii::import('zii.widgets.grid.CButtonColumn');
|
||||
Yii::import('zii.widgets.grid.CCheckBoxColumn');
|
||||
|
||||
/**
|
||||
* CGridView displays a list of data items in terms of a table.
|
||||
*
|
||||
* Each row of the table represents the data of a single data item, and a column usually represents
|
||||
* an attribute of the item (some columns may correspond to complex expression of attributes or static text).
|
||||
*
|
||||
* CGridView supports both sorting and pagination of the data items. The sorting
|
||||
* and pagination can be done in AJAX mode or normal page request. A benefit of using CGridView is that
|
||||
* when the user browser disables JavaScript, the sorting and pagination automatically degenerate
|
||||
* to normal page requests and are still functioning as expected.
|
||||
*
|
||||
* CGridView should be used together with a {@link IDataProvider data provider}, preferrably a
|
||||
* {@link CActiveDataProvider}.
|
||||
*
|
||||
* The minimal code needed to use CGridView is as follows:
|
||||
*
|
||||
* <pre>
|
||||
* $dataProvider=new CActiveDataProvider('Post');
|
||||
*
|
||||
* $this->widget('zii.widgets.grid.CGridView', array(
|
||||
* 'dataProvider'=>$dataProvider,
|
||||
* ));
|
||||
* </pre>
|
||||
*
|
||||
* The above code first creates a data provider for the <code>Post</code> ActiveRecord class.
|
||||
* It then uses CGridView to display every attribute in every <code>Post</code> instance.
|
||||
* The displayed table is equiped with sorting and pagination functionality.
|
||||
*
|
||||
* In order to selectively display attributes with different formats, we may configure the
|
||||
* {@link CGridView::columns} property. For example, we may specify only the <code>title</code>
|
||||
* and <code>create_time</code> attributes to be displayed, and the <code>create_time</code>
|
||||
* should be properly formatted to show as a time. We may also display the attributes of the related
|
||||
* objects using the dot-syntax as shown below:
|
||||
*
|
||||
* <pre>
|
||||
* $this->widget('zii.widgets.grid.CGridView', array(
|
||||
* 'dataProvider'=>$dataProvider,
|
||||
* 'columns'=>array(
|
||||
* 'title', // display the 'title' attribute
|
||||
* 'category.name', // display the 'name' attribute of the 'category' relation
|
||||
* 'content:html', // display the 'content' attribute as purified HTML
|
||||
* array( // display 'create_time' using an expression
|
||||
* 'name'=>'create_time',
|
||||
* 'value'=>'date("M j, Y", $data->create_time)',
|
||||
* ),
|
||||
* array( // display 'author.username' using an expression
|
||||
* 'name'=>'authorName',
|
||||
* 'value'=>'$data->author->username',
|
||||
* ),
|
||||
* array( // display a column with "view", "update" and "delete" buttons
|
||||
* 'class'=>'CButtonColumn',
|
||||
* ),
|
||||
* ),
|
||||
* ));
|
||||
* </pre>
|
||||
*
|
||||
* Please refer to {@link columns} for more details about how to configure this property.
|
||||
*
|
||||
* @property boolean $hasFooter Whether the table should render a footer.
|
||||
* This is true if any of the {@link columns} has a true {@link CGridColumn::hasFooter} value.
|
||||
* @property CFormatter $formatter The formatter instance. Defaults to the 'format' application component.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package zii.widgets.grid
|
||||
* @since 1.1
|
||||
*/
|
||||
class CGridView extends CBaseListView
|
||||
{
|
||||
const FILTER_POS_HEADER='header';
|
||||
const FILTER_POS_FOOTER='footer';
|
||||
const FILTER_POS_BODY='body';
|
||||
|
||||
private $_formatter;
|
||||
/**
|
||||
* @var array grid column configuration. Each array element represents the configuration
|
||||
* for one particular grid column which can be either a string or an array.
|
||||
*
|
||||
* When a column is specified as a string, it should be in the format of "name:type:header",
|
||||
* where "type" and "header" are optional. A {@link CDataColumn} instance will be created in this case,
|
||||
* whose {@link CDataColumn::name}, {@link CDataColumn::type} and {@link CDataColumn::header}
|
||||
* properties will be initialized accordingly.
|
||||
*
|
||||
* When a column is specified as an array, it will be used to create a grid column instance, where
|
||||
* the 'class' element specifies the column class name (defaults to {@link CDataColumn} if absent).
|
||||
* Currently, these official column classes are provided: {@link CDataColumn},
|
||||
* {@link CLinkColumn}, {@link CButtonColumn} and {@link CCheckBoxColumn}.
|
||||
*/
|
||||
public $columns=array();
|
||||
/**
|
||||
* @var array the CSS class names for the table body rows. If multiple CSS class names are given,
|
||||
* they will be assigned to the rows sequentially and repeatedly. This property is ignored
|
||||
* if {@link rowCssClassExpression} is set. Defaults to <code>array('odd', 'even')</code>.
|
||||
* @see rowCssClassExpression
|
||||
*/
|
||||
public $rowCssClass=array('odd','even');
|
||||
/**
|
||||
* @var string a PHP expression that is evaluated for every table body row and whose result
|
||||
* is used as the CSS class name for the row. In this expression, you can use the following variables:
|
||||
* <ul>
|
||||
* <li><code>$row</code> the row number (zero-based)</li>
|
||||
* <li><code>$data</code> the data model for the row</li>
|
||||
* <li><code>$this</code> the grid view object</li>
|
||||
* </ul>
|
||||
* The PHP expression will be evaluated using {@link evaluateExpression}.
|
||||
*
|
||||
* A PHP expression can be any PHP code that has a value. To learn more about what an expression is,
|
||||
* please refer to the {@link http://www.php.net/manual/en/language.expressions.php php manual}.
|
||||
* @see rowCssClass
|
||||
* @deprecated in 1.1.13 in favor of {@link rowHtmlOptionsExpression}
|
||||
*/
|
||||
public $rowCssClassExpression;
|
||||
/**
|
||||
* @var string a PHP expression that is evaluated for every table body row and whose result
|
||||
* is used as additional HTML attributes for the row. The expression should return an
|
||||
* array whose key value pairs correspond to html attribute and value.
|
||||
* In this expression, you can use the following variables:
|
||||
* <ul>
|
||||
* <li><code>$row</code> the row number (zero-based)</li>
|
||||
* <li><code>$data</code> the data model for the row</li>
|
||||
* <li><code>$this</code> the grid view object</li>
|
||||
* </ul>
|
||||
* The PHP expression will be evaluated using {@link evaluateExpression}.
|
||||
*
|
||||
* A PHP expression can be any PHP code that has a value. To learn more about what an expression is,
|
||||
* please refer to the {@link http://www.php.net/manual/en/language.expressions.php php manual}.
|
||||
* @since 1.1.13
|
||||
*/
|
||||
public $rowHtmlOptionsExpression;
|
||||
/**
|
||||
* @var boolean whether to display the table even when there is no data. Defaults to true.
|
||||
* The {@link emptyText} will be displayed to indicate there is no data.
|
||||
*/
|
||||
public $showTableOnEmpty=true;
|
||||
/**
|
||||
* @var mixed the ID of the container whose content may be updated with an AJAX response.
|
||||
* Defaults to null, meaning the container for this grid view instance.
|
||||
* If it is set false, it means sorting and pagination will be performed in normal page requests
|
||||
* instead of AJAX requests. If the sorting and pagination should trigger the update of multiple
|
||||
* containers' content in AJAX fashion, these container IDs may be listed here (separated with comma).
|
||||
*/
|
||||
public $ajaxUpdate;
|
||||
/**
|
||||
* @var string the jQuery selector of the HTML elements that may trigger AJAX updates when they are clicked.
|
||||
* These tokens are recognized: {page} and {sort}. They will be replaced with the pagination and sorting links selectors.
|
||||
* Defaults to '{page}, {sort}', that means that the pagination links and the sorting links will trigger AJAX updates.
|
||||
* Tokens are available from 1.1.11
|
||||
*
|
||||
* Note: if this value is empty an exception will be thrown.
|
||||
*
|
||||
* Example (adding a custom selector to the default ones):
|
||||
* <pre>
|
||||
* ...
|
||||
* 'updateSelector'=>'{page}, {sort}, #mybutton',
|
||||
* ...
|
||||
* </pre>
|
||||
* @since 1.1.7
|
||||
*/
|
||||
public $updateSelector='{page}, {sort}';
|
||||
/**
|
||||
* @var string a javascript function that will be invoked if an AJAX update error occurs.
|
||||
*
|
||||
* The function signature is <code>function(xhr, textStatus, errorThrown, errorMessage)</code>
|
||||
* <ul>
|
||||
* <li><code>xhr</code> is the XMLHttpRequest object.</li>
|
||||
* <li><code>textStatus</code> is a string describing the type of error that occurred.
|
||||
* Possible values (besides null) are "timeout", "error", "notmodified" and "parsererror"</li>
|
||||
* <li><code>errorThrown</code> is an optional exception object, if one occurred.</li>
|
||||
* <li><code>errorMessage</code> is the CGridView default error message derived from xhr and errorThrown.
|
||||
* Usefull if you just want to display this error differently. CGridView by default displays this error with an javascript.alert()</li>
|
||||
* </ul>
|
||||
* Note: This handler is not called for JSONP requests, because they do not use an XMLHttpRequest.
|
||||
*
|
||||
* Example (add in a call to CGridView):
|
||||
* <pre>
|
||||
* ...
|
||||
* 'ajaxUpdateError'=>'function(xhr,ts,et,err){ $("#myerrordiv").text(err); }',
|
||||
* ...
|
||||
* </pre>
|
||||
*/
|
||||
public $ajaxUpdateError;
|
||||
/**
|
||||
* @var string the name of the GET variable that indicates the request is an AJAX request triggered
|
||||
* by this widget. Defaults to 'ajax'. This is effective only when {@link ajaxUpdate} is not false.
|
||||
*/
|
||||
public $ajaxVar='ajax';
|
||||
/**
|
||||
* @var mixed the URL for the AJAX requests should be sent to. {@link CHtml::normalizeUrl()} will be
|
||||
* called on this property. If not set, the current page URL will be used for AJAX requests.
|
||||
* @since 1.1.8
|
||||
*/
|
||||
public $ajaxUrl;
|
||||
/**
|
||||
* @var string the type ('GET' or 'POST') of the AJAX requests. If not set, 'GET' will be used.
|
||||
* You can set this to 'POST' if you are filtering by many fields at once and have a problem with GET query string length.
|
||||
* Note that in POST mode direct links and {@link enableHistory} feature may not work correctly!
|
||||
* @since 1.1.14
|
||||
*/
|
||||
public $ajaxType;
|
||||
/**
|
||||
* @var string a javascript function that will be invoked before an AJAX update occurs.
|
||||
* The function signature is <code>function(id,options)</code> where 'id' refers to the ID of the grid view,
|
||||
* 'options' the AJAX request options (see jQuery.ajax api manual).
|
||||
*/
|
||||
public $beforeAjaxUpdate;
|
||||
/**
|
||||
* @var string a javascript function that will be invoked after a successful AJAX response is received.
|
||||
* The function signature is <code>function(id, data)</code> where 'id' refers to the ID of the grid view,
|
||||
* 'data' the received ajax response data.
|
||||
*/
|
||||
public $afterAjaxUpdate;
|
||||
/**
|
||||
* @var string a javascript function that will be invoked after the row selection is changed.
|
||||
* The function signature is <code>function(id)</code> where 'id' refers to the ID of the grid view.
|
||||
* In this function, you may use <code>$(gridID).yiiGridView('getSelection')</code> to get the key values
|
||||
* of the currently selected rows (gridID is the DOM selector of the grid).
|
||||
* @see selectableRows
|
||||
*/
|
||||
public $selectionChanged;
|
||||
/**
|
||||
* @var integer the number of table body rows that can be selected. If 0, it means rows cannot be selected.
|
||||
* If 1, only one row can be selected. If 2 or any other number, it means multiple rows can be selected.
|
||||
* A selected row will have a CSS class named 'selected'. You may also call the JavaScript function
|
||||
* <code>$(gridID).yiiGridView('getSelection')</code> to retrieve the key values of the currently selected
|
||||
* rows (gridID is the DOM selector of the grid).
|
||||
*/
|
||||
public $selectableRows=1;
|
||||
/**
|
||||
* @var string the base script URL for all grid view resources (eg javascript, CSS file, images).
|
||||
* Defaults to null, meaning using the integrated grid view resources (which are published as assets).
|
||||
*/
|
||||
public $baseScriptUrl;
|
||||
/**
|
||||
* @var string the URL of the CSS file used by this grid view. Defaults to null, meaning using the integrated
|
||||
* CSS file. If this is set false, you are responsible to explicitly include the necessary CSS file in your page.
|
||||
*/
|
||||
public $cssFile;
|
||||
/**
|
||||
* @var string the text to be displayed in a data cell when a data value is null. This property will NOT be HTML-encoded
|
||||
* when rendering. Defaults to an HTML blank.
|
||||
*/
|
||||
public $nullDisplay=' ';
|
||||
/**
|
||||
* @var string the text to be displayed in an empty grid cell. This property will NOT be HTML-encoded when rendering. Defaults to an HTML blank.
|
||||
* This differs from {@link nullDisplay} in that {@link nullDisplay} is only used by {@link CDataColumn} to render
|
||||
* null data values.
|
||||
* @since 1.1.7
|
||||
*/
|
||||
public $blankDisplay=' ';
|
||||
/**
|
||||
* @var string the CSS class name that will be assigned to the widget container element
|
||||
* when the widget is updating its content via AJAX. Defaults to 'grid-view-loading'.
|
||||
* @since 1.1.1
|
||||
*/
|
||||
public $loadingCssClass='grid-view-loading';
|
||||
/**
|
||||
* @var string the jQuery selector of filter input fields.
|
||||
* The token '{filter}' is recognized and it will be replaced with the grid filters selector.
|
||||
* Defaults to '{filter}'.
|
||||
*
|
||||
* Note: if this value is empty an exception will be thrown.
|
||||
*
|
||||
* Example (adding a custom selector to the default one):
|
||||
* <pre>
|
||||
* ...
|
||||
* 'filterSelector'=>'{filter}, #myfilter',
|
||||
* ...
|
||||
* </pre>
|
||||
* @since 1.1.13
|
||||
*/
|
||||
public $filterSelector='{filter}';
|
||||
/**
|
||||
* @var string the CSS class name for the table row element containing all filter input fields. Defaults to 'filters'.
|
||||
* @see filter
|
||||
* @since 1.1.1
|
||||
*/
|
||||
public $filterCssClass='filters';
|
||||
/**
|
||||
* @var string whether the filters should be displayed in the grid view. Valid values include:
|
||||
* <ul>
|
||||
* <li>header: the filters will be displayed on top of each column's header cell.</li>
|
||||
* <li>body: the filters will be displayed right below each column's header cell.</li>
|
||||
* <li>footer: the filters will be displayed below each column's footer cell.</li>
|
||||
* </ul>
|
||||
* @see filter
|
||||
* @since 1.1.1
|
||||
*/
|
||||
public $filterPosition='body';
|
||||
/**
|
||||
* @var CModel the model instance that keeps the user-entered filter data. When this property is set,
|
||||
* the grid view will enable column-based filtering. Each data column by default will display a text field
|
||||
* at the top that users can fill in to filter the data.
|
||||
* Note that in order to show an input field for filtering, a column must have its {@link CDataColumn::name}
|
||||
* property set or have {@link CDataColumn::filter} as the HTML code for the input field.
|
||||
* When this property is not set (null) the filtering is disabled.
|
||||
* @since 1.1.1
|
||||
*/
|
||||
public $filter;
|
||||
/**
|
||||
* @var boolean whether to hide the header cells of the grid. When this is true, header cells
|
||||
* will not be rendered, which means the grid cannot be sorted anymore since the sort links are located
|
||||
* in the header. Defaults to false.
|
||||
* @since 1.1.1
|
||||
*/
|
||||
public $hideHeader=false;
|
||||
/**
|
||||
* @var boolean whether to leverage the {@link https://developer.mozilla.org/en/DOM/window.history DOM history object}. Set this property to true
|
||||
* to persist state of grid across page revisits. Note, there are two limitations for this feature:
|
||||
* <ul>
|
||||
* <li>this feature is only compatible with browsers that support HTML5.</li>
|
||||
* <li>expect unexpected functionality (e.g. multiple ajax calls) if there is more than one grid/list on a single page with enableHistory turned on.</li>
|
||||
* </ul>
|
||||
* @since 1.1.11
|
||||
*/
|
||||
public $enableHistory=false;
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the grid view.
|
||||
* This method will initialize required property values and instantiate {@link columns} objects.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
if(empty($this->updateSelector))
|
||||
throw new CException(Yii::t('zii','The property updateSelector should be defined.'));
|
||||
if(empty($this->filterSelector))
|
||||
throw new CException(Yii::t('zii','The property filterSelector should be defined.'));
|
||||
|
||||
if(!isset($this->htmlOptions['class']))
|
||||
$this->htmlOptions['class']='grid-view';
|
||||
|
||||
if($this->baseScriptUrl===null)
|
||||
$this->baseScriptUrl=Yii::app()->getAssetManager()->publish(Yii::getPathOfAlias('zii.widgets.assets')).'/gridview';
|
||||
|
||||
if($this->cssFile!==false)
|
||||
{
|
||||
if($this->cssFile===null)
|
||||
$this->cssFile=$this->baseScriptUrl.'/styles.css';
|
||||
Yii::app()->getClientScript()->registerCssFile($this->cssFile);
|
||||
}
|
||||
|
||||
$this->initColumns();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates column objects and initializes them.
|
||||
*/
|
||||
protected function initColumns()
|
||||
{
|
||||
if($this->columns===array())
|
||||
{
|
||||
if($this->dataProvider instanceof CActiveDataProvider)
|
||||
$this->columns=$this->dataProvider->model->attributeNames();
|
||||
elseif($this->dataProvider instanceof IDataProvider)
|
||||
{
|
||||
// use the keys of the first row of data as the default columns
|
||||
$data=$this->dataProvider->getData();
|
||||
if(isset($data[0]) && is_array($data[0]))
|
||||
$this->columns=array_keys($data[0]);
|
||||
}
|
||||
}
|
||||
$id=$this->getId();
|
||||
foreach($this->columns as $i=>$column)
|
||||
{
|
||||
if(is_string($column))
|
||||
$column=$this->createDataColumn($column);
|
||||
else
|
||||
{
|
||||
if(!isset($column['class']))
|
||||
$column['class']='CDataColumn';
|
||||
$column=Yii::createComponent($column, $this);
|
||||
}
|
||||
if(!$column->visible)
|
||||
{
|
||||
unset($this->columns[$i]);
|
||||
continue;
|
||||
}
|
||||
if($column->id===null)
|
||||
$column->id=$id.'_c'.$i;
|
||||
$this->columns[$i]=$column;
|
||||
}
|
||||
|
||||
foreach($this->columns as $column)
|
||||
$column->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link CDataColumn} based on a shortcut column specification string.
|
||||
* @param string $text the column specification string
|
||||
* @return CDataColumn the column instance
|
||||
*/
|
||||
protected function createDataColumn($text)
|
||||
{
|
||||
if(!preg_match('/^([\w\.]+)(:(\w*))?(:(.*))?$/',$text,$matches))
|
||||
throw new CException(Yii::t('zii','The column must be specified in the format of "Name:Type:Label", where "Type" and "Label" are optional.'));
|
||||
$column=new CDataColumn($this);
|
||||
$column->name=$matches[1];
|
||||
if(isset($matches[3]) && $matches[3]!=='')
|
||||
$column->type=$matches[3];
|
||||
if(isset($matches[5]))
|
||||
$column->header=$matches[5];
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers necessary client scripts.
|
||||
*/
|
||||
public function registerClientScript()
|
||||
{
|
||||
$id=$this->getId();
|
||||
|
||||
if($this->ajaxUpdate===false)
|
||||
$ajaxUpdate=false;
|
||||
else
|
||||
$ajaxUpdate=array_unique(preg_split('/\s*,\s*/',$this->ajaxUpdate.','.$id,-1,PREG_SPLIT_NO_EMPTY));
|
||||
$options=array(
|
||||
'ajaxUpdate'=>$ajaxUpdate,
|
||||
'ajaxVar'=>$this->ajaxVar,
|
||||
'pagerClass'=>$this->pagerCssClass,
|
||||
'loadingClass'=>$this->loadingCssClass,
|
||||
'filterClass'=>$this->filterCssClass,
|
||||
'tableClass'=>$this->itemsCssClass,
|
||||
'selectableRows'=>$this->selectableRows,
|
||||
'enableHistory'=>$this->enableHistory,
|
||||
'updateSelector'=>$this->updateSelector,
|
||||
'filterSelector'=>$this->filterSelector
|
||||
);
|
||||
if($this->ajaxUrl!==null)
|
||||
$options['url']=CHtml::normalizeUrl($this->ajaxUrl);
|
||||
if($this->ajaxType!==null)
|
||||
$options['ajaxType']=strtoupper($this->ajaxType);
|
||||
if($this->enablePagination)
|
||||
$options['pageVar']=$this->dataProvider->getPagination()->pageVar;
|
||||
foreach(array('beforeAjaxUpdate', 'afterAjaxUpdate', 'ajaxUpdateError', 'selectionChanged') as $event)
|
||||
{
|
||||
if($this->$event!==null)
|
||||
{
|
||||
if($this->$event instanceof CJavaScriptExpression)
|
||||
$options[$event]=$this->$event;
|
||||
else
|
||||
$options[$event]=new CJavaScriptExpression($this->$event);
|
||||
}
|
||||
}
|
||||
|
||||
$options=CJavaScript::encode($options);
|
||||
$cs=Yii::app()->getClientScript();
|
||||
$cs->registerCoreScript('jquery');
|
||||
$cs->registerCoreScript('bbq');
|
||||
if($this->enableHistory)
|
||||
$cs->registerCoreScript('history');
|
||||
$cs->registerScriptFile($this->baseScriptUrl.'/jquery.yiigridview.js',CClientScript::POS_END);
|
||||
$cs->registerScript(__CLASS__.'#'.$id,"jQuery('#$id').yiiGridView($options);");
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the data items for the grid view.
|
||||
*/
|
||||
public function renderItems()
|
||||
{
|
||||
if($this->dataProvider->getItemCount()>0 || $this->showTableOnEmpty)
|
||||
{
|
||||
echo "<table class=\"{$this->itemsCssClass}\">\n";
|
||||
$this->renderTableHeader();
|
||||
ob_start();
|
||||
$this->renderTableBody();
|
||||
$body=ob_get_clean();
|
||||
$this->renderTableFooter();
|
||||
echo $body; // TFOOT must appear before TBODY according to the standard.
|
||||
echo "</table>";
|
||||
}
|
||||
else
|
||||
$this->renderEmptyText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the table header.
|
||||
*/
|
||||
public function renderTableHeader()
|
||||
{
|
||||
if(!$this->hideHeader)
|
||||
{
|
||||
echo "<thead>\n";
|
||||
|
||||
if($this->filterPosition===self::FILTER_POS_HEADER)
|
||||
$this->renderFilter();
|
||||
|
||||
echo "<tr>\n";
|
||||
foreach($this->columns as $column)
|
||||
$column->renderHeaderCell();
|
||||
echo "</tr>\n";
|
||||
|
||||
if($this->filterPosition===self::FILTER_POS_BODY)
|
||||
$this->renderFilter();
|
||||
|
||||
echo "</thead>\n";
|
||||
}
|
||||
elseif($this->filter!==null && ($this->filterPosition===self::FILTER_POS_HEADER || $this->filterPosition===self::FILTER_POS_BODY))
|
||||
{
|
||||
echo "<thead>\n";
|
||||
$this->renderFilter();
|
||||
echo "</thead>\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the filter.
|
||||
* @since 1.1.1
|
||||
*/
|
||||
public function renderFilter()
|
||||
{
|
||||
if($this->filter!==null)
|
||||
{
|
||||
echo "<tr class=\"{$this->filterCssClass}\">\n";
|
||||
foreach($this->columns as $column)
|
||||
$column->renderFilterCell();
|
||||
echo "</tr>\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the table footer.
|
||||
*/
|
||||
public function renderTableFooter()
|
||||
{
|
||||
$hasFilter=$this->filter!==null && $this->filterPosition===self::FILTER_POS_FOOTER;
|
||||
$hasFooter=$this->getHasFooter();
|
||||
if($hasFilter || $hasFooter)
|
||||
{
|
||||
echo "<tfoot>\n";
|
||||
if($hasFooter)
|
||||
{
|
||||
echo "<tr>\n";
|
||||
foreach($this->columns as $column)
|
||||
$column->renderFooterCell();
|
||||
echo "</tr>\n";
|
||||
}
|
||||
if($hasFilter)
|
||||
$this->renderFilter();
|
||||
echo "</tfoot>\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the table body.
|
||||
*/
|
||||
public function renderTableBody()
|
||||
{
|
||||
$data=$this->dataProvider->getData();
|
||||
$n=count($data);
|
||||
echo "<tbody>\n";
|
||||
|
||||
if($n>0)
|
||||
{
|
||||
for($row=0;$row<$n;++$row)
|
||||
$this->renderTableRow($row);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo '<tr><td colspan="'.count($this->columns).'" class="empty">';
|
||||
$this->renderEmptyText();
|
||||
echo "</td></tr>\n";
|
||||
}
|
||||
echo "</tbody>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a table body row.
|
||||
* @param integer $row the row number (zero-based).
|
||||
*/
|
||||
public function renderTableRow($row)
|
||||
{
|
||||
$htmlOptions=array();
|
||||
if($this->rowHtmlOptionsExpression!==null)
|
||||
{
|
||||
$data=$this->dataProvider->data[$row];
|
||||
$options=$this->evaluateExpression($this->rowHtmlOptionsExpression,array('row'=>$row,'data'=>$data));
|
||||
if(is_array($options))
|
||||
$htmlOptions = $options;
|
||||
}
|
||||
|
||||
if($this->rowCssClassExpression!==null)
|
||||
{
|
||||
$data=$this->dataProvider->data[$row];
|
||||
$class=$this->evaluateExpression($this->rowCssClassExpression,array('row'=>$row,'data'=>$data));
|
||||
}
|
||||
elseif(is_array($this->rowCssClass) && ($n=count($this->rowCssClass))>0)
|
||||
$class=$this->rowCssClass[$row%$n];
|
||||
|
||||
if(!empty($class))
|
||||
{
|
||||
if(isset($htmlOptions['class']))
|
||||
$htmlOptions['class'].=' '.$class;
|
||||
else
|
||||
$htmlOptions['class']=$class;
|
||||
}
|
||||
|
||||
echo CHtml::openTag('tr', $htmlOptions)."\n";
|
||||
foreach($this->columns as $column)
|
||||
$column->renderDataCell($row);
|
||||
echo "</tr>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean whether the table should render a footer.
|
||||
* This is true if any of the {@link columns} has a true {@link CGridColumn::hasFooter} value.
|
||||
*/
|
||||
public function getHasFooter()
|
||||
{
|
||||
foreach($this->columns as $column)
|
||||
if($column->getHasFooter())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CFormatter the formatter instance. Defaults to the 'format' application component.
|
||||
*/
|
||||
public function getFormatter()
|
||||
{
|
||||
if($this->_formatter===null)
|
||||
$this->_formatter=Yii::app()->format;
|
||||
return $this->_formatter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CFormatter $value the formatter instance
|
||||
*/
|
||||
public function setFormatter($value)
|
||||
{
|
||||
$this->_formatter=$value;
|
||||
}
|
||||
}
|
||||
111
framework/zii/widgets/grid/CLinkColumn.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/**
|
||||
* CLinkColumn class file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
Yii::import('zii.widgets.grid.CGridColumn');
|
||||
|
||||
/**
|
||||
* CLinkColumn represents a grid view column that renders a hyperlink in each of its data cells.
|
||||
*
|
||||
* The {@link label} and {@link url} properties determine how each hyperlink will be rendered.
|
||||
* The {@link labelExpression}, {@link urlExpression} properties may be used instead if they are available.
|
||||
* In addition, if {@link imageUrl} is set, an image link will be rendered.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package zii.widgets.grid
|
||||
* @since 1.1
|
||||
*/
|
||||
class CLinkColumn extends CGridColumn
|
||||
{
|
||||
/**
|
||||
* @var string the label to the hyperlinks in the data cells. Note that the label will not
|
||||
* be HTML-encoded when rendering. This property is ignored if {@link labelExpression} is set.
|
||||
* @see labelExpression
|
||||
*/
|
||||
public $label='Link';
|
||||
/**
|
||||
* @var string a PHP expression that will be evaluated for every data cell and whose result will be rendered
|
||||
* as the label of the hyperlink of the data cell.
|
||||
* In this expression, you can use the following variables:
|
||||
* <ul>
|
||||
* <li><code>$row</code> the row number (zero-based).</li>
|
||||
* <li><code>$data</code> the data model for the row.</li>
|
||||
* <li><code>$this</code> the column object.</li>
|
||||
* </ul>
|
||||
* The PHP expression will be evaluated using {@link evaluateExpression}.
|
||||
*
|
||||
* A PHP expression can be any PHP code that has a value. To learn more about what an expression is,
|
||||
* please refer to the {@link http://www.php.net/manual/en/language.expressions.php php manual}.
|
||||
*/
|
||||
public $labelExpression;
|
||||
/**
|
||||
* @var string the URL to the image. If this is set, an image link will be rendered.
|
||||
*/
|
||||
public $imageUrl;
|
||||
/**
|
||||
* @var string the URL of the hyperlinks in the data cells.
|
||||
* This property is ignored if {@link urlExpression} is set.
|
||||
* @see urlExpression
|
||||
*/
|
||||
public $url='javascript:void(0)';
|
||||
/**
|
||||
* @var string a PHP expression that will be evaluated for every data cell and whose result will be rendered
|
||||
* as the URL of the hyperlink of the data cells.
|
||||
* In this expression, you can use the following variables:
|
||||
* <ul>
|
||||
* <li><code>$row</code> the row number (zero-based).</li>
|
||||
* <li><code>$data</code> the data model for the row.</li>
|
||||
* <li><code>$this</code> the column object.</li>
|
||||
* </ul>
|
||||
* The PHP expression will be evaluated using {@link evaluateExpression}.
|
||||
*
|
||||
* A PHP expression can be any PHP code that has a value. To learn more about what an expression is,
|
||||
* please refer to the {@link http://www.php.net/manual/en/language.expressions.php php manual}.
|
||||
*/
|
||||
public $urlExpression;
|
||||
/**
|
||||
* @var array the HTML options for the data cell tags.
|
||||
*/
|
||||
public $htmlOptions=array('class'=>'link-column');
|
||||
/**
|
||||
* @var array the HTML options for the header cell tag.
|
||||
*/
|
||||
public $headerHtmlOptions=array('class'=>'link-column');
|
||||
/**
|
||||
* @var array the HTML options for the footer cell tag.
|
||||
*/
|
||||
public $footerHtmlOptions=array('class'=>'link-column');
|
||||
/**
|
||||
* @var array the HTML options for the hyperlinks
|
||||
*/
|
||||
public $linkHtmlOptions=array();
|
||||
|
||||
/**
|
||||
* Renders the data cell content.
|
||||
* This method renders a hyperlink in the data cell.
|
||||
* @param integer $row the row number (zero-based)
|
||||
* @param mixed $data the data associated with the row
|
||||
*/
|
||||
protected function renderDataCellContent($row,$data)
|
||||
{
|
||||
if($this->urlExpression!==null)
|
||||
$url=$this->evaluateExpression($this->urlExpression,array('data'=>$data,'row'=>$row));
|
||||
else
|
||||
$url=$this->url;
|
||||
if($this->labelExpression!==null)
|
||||
$label=$this->evaluateExpression($this->labelExpression,array('data'=>$data,'row'=>$row));
|
||||
else
|
||||
$label=$this->label;
|
||||
$options=$this->linkHtmlOptions;
|
||||
if(is_string($this->imageUrl))
|
||||
echo CHtml::link(CHtml::image($this->imageUrl,$label),$url,$options);
|
||||
else
|
||||
echo CHtml::link($label,$url,$options);
|
||||
}
|
||||
}
|
||||
95
framework/zii/widgets/jui/CJuiAccordion.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
* CJuiAccordion class file.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
Yii::import('zii.widgets.jui.CJuiWidget');
|
||||
|
||||
/**
|
||||
* CJuiAccordion displays an accordion widget.
|
||||
*
|
||||
* CJuiAccordion encapsulates the {@link http://jqueryui.com/accordion/ JUI Accordion}
|
||||
* plugin.
|
||||
*
|
||||
* To use this widget, you may insert the following code in a view:
|
||||
* <pre>
|
||||
* $this->widget('zii.widgets.jui.CJuiAccordion',array(
|
||||
* 'panels'=>array(
|
||||
* 'panel 1'=>'content for panel 1',
|
||||
* 'panel 2'=>'content for panel 2',
|
||||
* // panel 3 contains the content rendered by a partial view
|
||||
* 'panel 3'=>$this->renderPartial('_partial',null,true),
|
||||
* ),
|
||||
* // additional javascript options for the accordion plugin
|
||||
* 'options'=>array(
|
||||
* 'animated'=>'bounceslide',
|
||||
* ),
|
||||
* ));
|
||||
* </pre>
|
||||
*
|
||||
* By configuring the {@link options} property, you may specify the options
|
||||
* that need to be passed to the JUI accordion plugin. Please refer to
|
||||
* the {@link http://api.jqueryui.com/accordion/ JUI Accordion API}
|
||||
* documentation for possible options (name-value pairs) and
|
||||
* {@link http://jqueryui.com/accordion/ JUI Accordion page} for general
|
||||
* description and demo.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package zii.widgets.jui
|
||||
* @since 1.1
|
||||
*/
|
||||
class CJuiAccordion extends CJuiWidget
|
||||
{
|
||||
/**
|
||||
* @var array list of panels (panel title=>panel content).
|
||||
* Note that neither panel title nor panel content will be HTML-encoded.
|
||||
*/
|
||||
public $panels=array();
|
||||
/**
|
||||
* @var string the name of the container element that contains all panels. Defaults to 'div'.
|
||||
*/
|
||||
public $tagName='div';
|
||||
/**
|
||||
* @var string the template that is used to generated every panel header.
|
||||
* The token "{title}" in the template will be replaced with the panel title.
|
||||
* Note that if you make change to this template, you may also need to adjust
|
||||
* the 'header' setting in {@link options}.
|
||||
*/
|
||||
public $headerTemplate='<h3><a href="#">{title}</a></h3>';
|
||||
/**
|
||||
* @var string the template that is used to generated every panel content.
|
||||
* The token "{content}" in the template will be replaced with the panel content.
|
||||
*/
|
||||
public $contentTemplate='<div>{content}</div>';
|
||||
|
||||
/**
|
||||
* Run this widget.
|
||||
* This method registers necessary javascript and renders the needed HTML code.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$id=$this->getId();
|
||||
if(isset($this->htmlOptions['id']))
|
||||
$id=$this->htmlOptions['id'];
|
||||
else
|
||||
$this->htmlOptions['id']=$id;
|
||||
|
||||
echo CHtml::openTag($this->tagName,$this->htmlOptions)."\n";
|
||||
foreach($this->panels as $title=>$content)
|
||||
{
|
||||
echo strtr($this->headerTemplate,array('{title}'=>$title))."\n";
|
||||
echo strtr($this->contentTemplate,array('{content}'=>$content))."\n";
|
||||
}
|
||||
echo CHtml::closeTag($this->tagName);
|
||||
|
||||
$options=CJavaScript::encode($this->options);
|
||||
Yii::app()->getClientScript()->registerScript(__CLASS__.'#'.$id,"jQuery('#{$id}').accordion($options);");
|
||||
}
|
||||
}
|
||||
97
framework/zii/widgets/jui/CJuiAutoComplete.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* CJuiAutoComplete class file.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
Yii::import('zii.widgets.jui.CJuiInputWidget');
|
||||
|
||||
/**
|
||||
* CJuiAutoComplete displays an autocomplete field.
|
||||
*
|
||||
* CJuiAutoComplete encapsulates the {@link http://jqueryui.com/autocomplete/ JUI
|
||||
* autocomplete} plugin.
|
||||
*
|
||||
* To use this widget, you may insert the following code in a view:
|
||||
* <pre>
|
||||
* $this->widget('zii.widgets.jui.CJuiAutoComplete',array(
|
||||
* 'name'=>'city',
|
||||
* 'source'=>array('ac1','ac2','ac3'),
|
||||
* // additional javascript options for the autocomplete plugin
|
||||
* 'options'=>array(
|
||||
* 'minLength'=>'2',
|
||||
* ),
|
||||
* 'htmlOptions'=>array(
|
||||
* 'style'=>'height:20px;',
|
||||
* ),
|
||||
* ));
|
||||
* </pre>
|
||||
*
|
||||
* By configuring the {@link options} property, you may specify the options
|
||||
* that need to be passed to the JUI autocomplete plugin. Please refer to
|
||||
* the {@link http://api.jqueryui.com/autocomplete/ JUI AutoComplete API}
|
||||
* documentation for possible options (name-value pairs) and
|
||||
* {@link http://jqueryui.com/autocomplete/ JUI AutoComplete page} for
|
||||
* general description and demo.
|
||||
*
|
||||
* By configuring the {@link source} property, you may specify where to search
|
||||
* the autocomplete options for each item. If source is an array, the list is
|
||||
* used for autocomplete. You may also configure {@link sourceUrl} to retrieve
|
||||
* autocomplete items from an ajax response.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @package zii.widgets.jui
|
||||
* @since 1.1.2
|
||||
*/
|
||||
class CJuiAutoComplete extends CJuiInputWidget
|
||||
{
|
||||
/**
|
||||
* @var mixed the entries that the autocomplete should choose from. This can be
|
||||
* <ul>
|
||||
* <li>an Array with local data</li>
|
||||
* <li>a String, specifying a URL that returns JSON data as the entries.</li>
|
||||
* <li>a javascript callback. Please make sure you wrap the callback with
|
||||
* {@link CJavaScriptExpression} in this case.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public $source=array();
|
||||
/**
|
||||
* @var mixed the URL that will return JSON data as the autocomplete items.
|
||||
* CHtml::normalizeUrl() will be applied to this property to convert the property
|
||||
* into a proper URL. When this property is set, the {@link source} property will be ignored.
|
||||
*/
|
||||
public $sourceUrl;
|
||||
|
||||
/**
|
||||
* Run this widget.
|
||||
* This method registers necessary javascript and renders the needed HTML code.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
list($name,$id)=$this->resolveNameID();
|
||||
|
||||
if(isset($this->htmlOptions['id']))
|
||||
$id=$this->htmlOptions['id'];
|
||||
else
|
||||
$this->htmlOptions['id']=$id;
|
||||
if(isset($this->htmlOptions['name']))
|
||||
$name=$this->htmlOptions['name'];
|
||||
|
||||
if($this->hasModel())
|
||||
echo CHtml::activeTextField($this->model,$this->attribute,$this->htmlOptions);
|
||||
else
|
||||
echo CHtml::textField($name,$this->value,$this->htmlOptions);
|
||||
|
||||
if($this->sourceUrl!==null)
|
||||
$this->options['source']=CHtml::normalizeUrl($this->sourceUrl);
|
||||
else
|
||||
$this->options['source']=$this->source;
|
||||
|
||||
$options=CJavaScript::encode($this->options);
|
||||
Yii::app()->getClientScript()->registerScript(__CLASS__.'#'.$id,"jQuery('#{$id}').autocomplete($options);");
|
||||
}
|
||||
}
|
||||
174
framework/zii/widgets/jui/CJuiButton.php
Normal file
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
/**
|
||||
* CJuiButton class file.
|
||||
*
|
||||
* @author Sebastian Thierer <sebas@artfos.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
Yii::import('zii.widgets.jui.CJuiInputWidget');
|
||||
|
||||
/**
|
||||
* CJuiButton displays a button widget.
|
||||
*
|
||||
* CJuiButton encapsulates the {@link http://jqueryui.com/button/ JUI Button}
|
||||
* plugin.
|
||||
*
|
||||
* To use this widget as a submit button, you may insert the following code in a view:
|
||||
* <pre>
|
||||
* $this->widget('zii.widgets.jui.CJuiButton',array(
|
||||
* 'buttonType'=>'submit',
|
||||
* 'name'=>'btnSubmit',
|
||||
* 'value'=>'1',
|
||||
* 'caption'=>'Submit form',
|
||||
* 'htmlOptions'=>array('class'=>'ui-button-primary')
|
||||
* ),
|
||||
* ));
|
||||
* </pre>
|
||||
*
|
||||
* To use this widget as a button, you may insert the following code in a view:
|
||||
* <pre>
|
||||
* $this->widget('zii.widgets.jui.CJuiButton',array(
|
||||
* 'buttonType'=>'button',
|
||||
* 'name'=>'btnSave',
|
||||
* 'caption'=>'Save',
|
||||
* 'onclick'=>new CJavaScriptExpression('function(){alert("Save button clicked"); this.blur(); return false;}'),
|
||||
* ));
|
||||
* </pre>
|
||||
*
|
||||
* By configuring the {@link options} property, you may specify the options
|
||||
* that need to be passed to the JUI button plugin. Please refer to
|
||||
* the {@link http://api.jqueryui.com/button/ JUI Button API} documentation
|
||||
* for possible options (name-value pairs) and
|
||||
* {@link http://jqueryui.com/button/ JUI Button page} for general description
|
||||
* and demo.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @package zii.widgets.jui
|
||||
* @since 1.1.3
|
||||
*/
|
||||
class CJuiButton extends CJuiInputWidget
|
||||
{
|
||||
/**
|
||||
* @var string The button type (possible types: submit, button, link, radio, checkbox, buttonset).
|
||||
* "submit" is used as default.
|
||||
*/
|
||||
public $buttonType='submit';
|
||||
/**
|
||||
* @var string The default html tag for the buttonset
|
||||
*/
|
||||
public $htmlTag='div';
|
||||
/**
|
||||
* @var mixed a URL or an action route that can be used to create a URL. Used when a buttonType "link" is selected.
|
||||
* See {@link normalizeUrl} for more details about how to specify this parameter.
|
||||
*/
|
||||
public $url=null;
|
||||
/**
|
||||
* @var mixed The value of the current item. Used only for "radio" and "checkbox"
|
||||
*/
|
||||
public $value;
|
||||
/**
|
||||
* @var string The button text
|
||||
*/
|
||||
public $caption="";
|
||||
/**
|
||||
* @var string The javascript function to be raised when this item is clicked (client event).
|
||||
*/
|
||||
public $onclick;
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
* @see framework/zii/widgets/jui/CJuiWidget::init()
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
if($this->buttonType=='buttonset')
|
||||
{
|
||||
if(!isset($this->htmlOptions['id']))
|
||||
$this->htmlOptions['id']=$this->getId();
|
||||
|
||||
echo CHtml::openTag($this->htmlTag,$this->htmlOptions);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
* @see framework/CWidget::run()
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$cs=Yii::app()->getClientScript();
|
||||
list($name,$id)=$this->resolveNameID();
|
||||
|
||||
if(isset($this->htmlOptions['id']))
|
||||
$id=$this->htmlOptions['id'];
|
||||
else
|
||||
$this->htmlOptions['id']=$id;
|
||||
if(isset($this->htmlOptions['name']))
|
||||
$name=$this->htmlOptions['name'];
|
||||
else
|
||||
$this->htmlOptions['name']=$name;
|
||||
|
||||
if($this->buttonType=='buttonset')
|
||||
{
|
||||
echo CHtml::closeTag($this->htmlTag);
|
||||
$cs->registerScript(__CLASS__.'#'.$id,"jQuery('#{$id}').buttonset();");
|
||||
}
|
||||
else
|
||||
{
|
||||
switch($this->buttonType)
|
||||
{
|
||||
case 'submit':
|
||||
echo CHtml::submitButton($this->caption,$this->htmlOptions)."\n";
|
||||
break;
|
||||
case 'button':
|
||||
echo CHtml::htmlButton($this->caption,$this->htmlOptions)."\n";
|
||||
break;
|
||||
case 'link':
|
||||
echo CHtml::link($this->caption,$this->url,$this->htmlOptions)."\n";
|
||||
break;
|
||||
case 'radio':
|
||||
if($this->hasModel())
|
||||
{
|
||||
echo CHtml::activeRadioButton($this->model,$this->attribute,$this->htmlOptions);
|
||||
echo CHtml::label($this->caption,CHtml::activeId($this->model,$this->attribute))."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo CHtml::radioButton($name,$this->value,$this->htmlOptions);
|
||||
echo CHtml::label($this->caption,$id)."\n";
|
||||
}
|
||||
break;
|
||||
case 'checkbox':
|
||||
if($this->hasModel())
|
||||
{
|
||||
echo CHtml::activeCheckbox($this->model,$this->attribute,$this->htmlOptions);
|
||||
echo CHtml::label($this->caption,CHtml::activeId($this->model,$this->attribute))."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo CHtml::checkbox($name,$this->value,$this->htmlOptions);
|
||||
echo CHtml::label($this->caption,$id)."\n";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new CException(Yii::t('zii','The button type "{type}" is not supported.',array('{type}'=>$this->buttonType)));
|
||||
}
|
||||
|
||||
$options=CJavaScript::encode($this->options);
|
||||
if($this->onclick!==null)
|
||||
{
|
||||
if(!($this->onclick instanceof CJavaScriptExpression))
|
||||
$this->onclick=new CJavaScriptExpression($this->onclick);
|
||||
$click=CJavaScript::encode($this->onclick);
|
||||
$cs->registerScript(__CLASS__.'#'.$id,"jQuery('#{$id}').button($options).click($click);");
|
||||
}
|
||||
else
|
||||
$cs->registerScript(__CLASS__.'#'.$id,"jQuery('#{$id}').button($options);");
|
||||
}
|
||||
}
|
||||
}
|
||||
128
framework/zii/widgets/jui/CJuiDatePicker.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
/**
|
||||
* CJuiDatePicker class file.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
Yii::import('zii.widgets.jui.CJuiInputWidget');
|
||||
|
||||
/**
|
||||
* CJuiDatePicker displays a datepicker.
|
||||
*
|
||||
* CJuiDatePicker encapsulates the {@link http://jqueryui.com/datepicker/ JUI
|
||||
* datepicker} plugin.
|
||||
*
|
||||
* To use this widget, you may insert the following code in a view:
|
||||
* <pre>
|
||||
* $this->widget('zii.widgets.jui.CJuiDatePicker',array(
|
||||
* 'name'=>'publishDate',
|
||||
* // additional javascript options for the date picker plugin
|
||||
* 'options'=>array(
|
||||
* 'showAnim'=>'fold',
|
||||
* ),
|
||||
* 'htmlOptions'=>array(
|
||||
* 'style'=>'height:20px;'
|
||||
* ),
|
||||
* ));
|
||||
* </pre>
|
||||
*
|
||||
* By configuring the {@link options} property, you may specify the options
|
||||
* that need to be passed to the JUI datepicker plugin. Please refer to
|
||||
* the {@link http://api.jqueryui.com/datepicker/ JUI DatePicker API}
|
||||
* documentation for possible options (name-value pairs) and
|
||||
* {@link http://jqueryui.com/datepicker/ JUI DatePicker page} for general
|
||||
* description and demo.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @package zii.widgets.jui
|
||||
* @since 1.1
|
||||
*/
|
||||
class CJuiDatePicker extends CJuiInputWidget
|
||||
{
|
||||
/**
|
||||
* @var string the locale ID (eg 'fr', 'de') for the language to be used by the date picker.
|
||||
* If this property is not set, I18N will not be involved. That is, the date picker will show in English.
|
||||
* You can force English language by setting the language attribute as '' (empty string)
|
||||
*/
|
||||
public $language;
|
||||
/**
|
||||
* @var string The i18n Jquery UI script file. It uses scriptUrl property as base url.
|
||||
*/
|
||||
public $i18nScriptFile='jquery-ui-i18n.min.js';
|
||||
/**
|
||||
* @var array The default options called just one time per request. This options will alter every other CJuiDatePicker instance in the page.
|
||||
* It has to be set at the first call of CJuiDatePicker widget in the request.
|
||||
*/
|
||||
public $defaultOptions;
|
||||
/**
|
||||
* @var boolean If true, shows the widget as an inline calendar and the input as a hidden field.
|
||||
*/
|
||||
public $flat=false;
|
||||
|
||||
/**
|
||||
* Run this widget.
|
||||
* This method registers necessary javascript and renders the needed HTML code.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
list($name,$id)=$this->resolveNameID();
|
||||
|
||||
if(isset($this->htmlOptions['id']))
|
||||
$id=$this->htmlOptions['id'];
|
||||
else
|
||||
$this->htmlOptions['id']=$id;
|
||||
if(isset($this->htmlOptions['name']))
|
||||
$name=$this->htmlOptions['name'];
|
||||
|
||||
if($this->flat===false)
|
||||
{
|
||||
if($this->hasModel())
|
||||
echo CHtml::activeTextField($this->model,$this->attribute,$this->htmlOptions);
|
||||
else
|
||||
echo CHtml::textField($name,$this->value,$this->htmlOptions);
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->hasModel())
|
||||
{
|
||||
echo CHtml::activeHiddenField($this->model,$this->attribute,$this->htmlOptions);
|
||||
$attribute=$this->attribute;
|
||||
$this->options['defaultDate']=$this->model->$attribute;
|
||||
}
|
||||
else
|
||||
{
|
||||
echo CHtml::hiddenField($name,$this->value,$this->htmlOptions);
|
||||
$this->options['defaultDate']=$this->value;
|
||||
}
|
||||
|
||||
$this->options['altField']='#'.$id;
|
||||
|
||||
$id=$this->htmlOptions['id']=$id.'_container';
|
||||
$this->htmlOptions['name']=$name.'_container';
|
||||
|
||||
echo CHtml::tag('div',$this->htmlOptions,'');
|
||||
}
|
||||
|
||||
$options=CJavaScript::encode($this->options);
|
||||
$js = "jQuery('#{$id}').datepicker($options);";
|
||||
|
||||
if($this->language!='' && $this->language!='en')
|
||||
{
|
||||
$this->registerScriptFile($this->i18nScriptFile);
|
||||
$js = "jQuery('#{$id}').datepicker(jQuery.extend({showMonthAfterYear:false},jQuery.datepicker.regional['{$this->language}'],{$options}));";
|
||||
}
|
||||
|
||||
$cs = Yii::app()->getClientScript();
|
||||
|
||||
if(isset($this->defaultOptions))
|
||||
{
|
||||
$this->registerScriptFile($this->i18nScriptFile);
|
||||
$cs->registerScript(__CLASS__,$this->defaultOptions!==null?'jQuery.datepicker.setDefaults('.CJavaScript::encode($this->defaultOptions).');':'');
|
||||
}
|
||||
$cs->registerScript(__CLASS__.'#'.$id,$js);
|
||||
}
|
||||
}
|
||||
85
framework/zii/widgets/jui/CJuiDialog.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/**
|
||||
* CJuiDialog class file.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
Yii::import('zii.widgets.jui.CJuiWidget');
|
||||
|
||||
/**
|
||||
* CJuiDialog displays a dialog widget.
|
||||
*
|
||||
* CJuiDialog encapsulates the {@link http://jqueryui.com/dialog/ JUI Dialog}
|
||||
* plugin.
|
||||
*
|
||||
* To use this widget, you may insert the following code in a view:
|
||||
* <pre>
|
||||
* $this->beginWidget('zii.widgets.jui.CJuiDialog',array(
|
||||
* 'id'=>'mydialog',
|
||||
* // additional javascript options for the dialog plugin
|
||||
* 'options'=>array(
|
||||
* 'title'=>'Dialog box 1',
|
||||
* 'autoOpen'=>false,
|
||||
* ),
|
||||
* ));
|
||||
*
|
||||
* echo 'dialog content here';
|
||||
*
|
||||
* $this->endWidget('zii.widgets.jui.CJuiDialog');
|
||||
*
|
||||
* // the link that may open the dialog
|
||||
* echo CHtml::link('open dialog', '#', array(
|
||||
* 'onclick'=>'$("#mydialog").dialog("open"); return false;',
|
||||
* ));
|
||||
* </pre>
|
||||
*
|
||||
* By configuring the {@link options} property, you may specify the options
|
||||
* that need to be passed to the JUI dialog plugin. Please refer to
|
||||
* the {@link http://api.jqueryui.com/dialog/ JUI Dialog API} documentation
|
||||
* for possible options (name-value pairs) and
|
||||
* {@link http://jqueryui.com/dialog/ JUI Dialog page} for general description
|
||||
* and demo.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @package zii.widgets.jui
|
||||
* @since 1.1
|
||||
*/
|
||||
class CJuiDialog extends CJuiWidget
|
||||
{
|
||||
/**
|
||||
* @var string the name of the container element that contains all panels. Defaults to 'div'.
|
||||
*/
|
||||
public $tagName='div';
|
||||
|
||||
/**
|
||||
* Renders the open tag of the dialog.
|
||||
* This method also registers the necessary javascript code.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
$id=$this->getId();
|
||||
if(isset($this->htmlOptions['id']))
|
||||
$id=$this->htmlOptions['id'];
|
||||
else
|
||||
$this->htmlOptions['id']=$id;
|
||||
|
||||
$options=CJavaScript::encode($this->options);
|
||||
Yii::app()->getClientScript()->registerScript(__CLASS__.'#'.$id,"jQuery('#{$id}').dialog($options);");
|
||||
|
||||
echo CHtml::openTag($this->tagName,$this->htmlOptions)."\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the close tag of the dialog.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
echo CHtml::closeTag($this->tagName);
|
||||
}
|
||||
}
|
||||
78
framework/zii/widgets/jui/CJuiDraggable.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
* CJuiDraggable class file.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
Yii::import('zii.widgets.jui.CJuiWidget');
|
||||
|
||||
/**
|
||||
* CJuiDraggable displays a draggable widget.
|
||||
*
|
||||
* CJuiDraggable encapsulates the {@link http://jqueryui.com/draggable/ JUI Draggable}
|
||||
* plugin.
|
||||
*
|
||||
* To use this widget, you may insert the following code in a view:
|
||||
* <pre>
|
||||
* $this->beginWidget('zii.widgets.jui.CJuiDraggable',array(
|
||||
* // additional javascript options for the draggable plugin
|
||||
* 'options'=>array(
|
||||
* 'scope'=>'myScope',
|
||||
* ),
|
||||
* ));
|
||||
* echo 'Your draggable content here';
|
||||
*
|
||||
* $this->endWidget();
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* By configuring the {@link options} property, you may specify the options
|
||||
* that need to be passed to the JUI Draggable plugin. Please refer to
|
||||
* the {@link http://api.jqueryui.com/draggable/ JUI Draggable API} documentation
|
||||
* for possible options (name-value pairs) and
|
||||
* {@link http://jqueryui.com/draggable/ JUI Draggable page} for general
|
||||
* description and demo.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @package zii.widgets.jui
|
||||
* @since 1.1
|
||||
*/
|
||||
class CJuiDraggable extends CJuiWidget
|
||||
{
|
||||
/**
|
||||
* @var string the name of the Draggable element. Defaults to 'div'.
|
||||
*/
|
||||
public $tagName='div';
|
||||
|
||||
/**
|
||||
* Renders the open tag of the draggable element.
|
||||
* This method also registers the necessary javascript code.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
$id=$this->getId();
|
||||
if(isset($this->htmlOptions['id']))
|
||||
$id=$this->htmlOptions['id'];
|
||||
else
|
||||
$this->htmlOptions['id']=$id;
|
||||
|
||||
$options=CJavaScript::encode($this->options);
|
||||
Yii::app()->getClientScript()->registerScript(__CLASS__.'#'.$id,"jQuery('#{$id}').draggable($options);");
|
||||
|
||||
echo CHtml::openTag($this->tagName,$this->htmlOptions)."\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the close tag of the draggable element.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
echo CHtml::closeTag($this->tagName);
|
||||
}
|
||||
}
|
||||
78
framework/zii/widgets/jui/CJuiDroppable.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
* CJuiDroppable class file.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
Yii::import('zii.widgets.jui.CJuiWidget');
|
||||
|
||||
/**
|
||||
* CJuiDroppable displays a droppable widget.
|
||||
*
|
||||
* CJuiDroppable encapsulates the {@link http://jqueryui.com/droppable/ JUI Droppable}
|
||||
* plugin.
|
||||
*
|
||||
* To use this widget, you may insert the following code in a view:
|
||||
* <pre>
|
||||
* $this->beginWidget('zii.widgets.jui.CJuiDroppable',array(
|
||||
* // additional javascript options for the droppable plugin
|
||||
* 'options'=>array(
|
||||
* 'scope'=>'myScope',
|
||||
* ),
|
||||
* ));
|
||||
* echo 'Your droppable content here';
|
||||
*
|
||||
* $this->endWidget();
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* By configuring the {@link options} property, you may specify the options
|
||||
* that need to be passed to the JUI Droppable plugin. Please refer to
|
||||
* the {@link http://api.jqueryui.com/droppable/ JUI Droppable API} documentation
|
||||
* for possible options (name-value pairs) and
|
||||
* {@link http://jqueryui.com/droppable/ JUI Droppable page} for general
|
||||
* description and demo.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @package zii.widgets.jui
|
||||
* @since 1.1
|
||||
*/
|
||||
class CJuiDroppable extends CJuiWidget
|
||||
{
|
||||
/**
|
||||
* @var string the HTML tag name of the Droppable element. Defaults to 'div'.
|
||||
*/
|
||||
public $tagName='div';
|
||||
|
||||
/**
|
||||
* Renders the open tag of the droppable element.
|
||||
* This method also registers the necessary javascript code.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
$id=$this->getId();
|
||||
if(isset($this->htmlOptions['id']))
|
||||
$id=$this->htmlOptions['id'];
|
||||
else
|
||||
$this->htmlOptions['id']=$id;
|
||||
|
||||
$options=CJavaScript::encode($this->options);
|
||||
Yii::app()->getClientScript()->registerScript(__CLASS__.'#'.$id,"jQuery('#{$id}').droppable($options);");
|
||||
|
||||
echo CHtml::openTag($this->tagName,$this->htmlOptions)."\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the close tag of the droppable element.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
echo CHtml::closeTag($this->tagName);
|
||||
}
|
||||
}
|
||||
80
framework/zii/widgets/jui/CJuiInputWidget.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* CJuiInputWidget class file.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
Yii::import('zii.widgets.jui.CJuiWidget');
|
||||
|
||||
/**
|
||||
* CJuiInputWidget is the base class for JUI widgets that can collect user input.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @package zii.widgets.jui
|
||||
* @since 1.1
|
||||
*/
|
||||
abstract class CJuiInputWidget extends CJuiWidget
|
||||
{
|
||||
/**
|
||||
* @var CModel the data model associated with this widget.
|
||||
*/
|
||||
public $model;
|
||||
/**
|
||||
* @var string the attribute associated with this widget.
|
||||
* The name can contain square brackets (e.g. 'name[1]') which is used to collect tabular data input.
|
||||
*/
|
||||
public $attribute;
|
||||
/**
|
||||
* @var string the input name. This must be set if {@link model} is not set.
|
||||
*/
|
||||
public $name;
|
||||
/**
|
||||
* @var string the input value.
|
||||
*/
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* Resolves name and ID of the input. Source property of the name and/or source property of the attribute
|
||||
* could be customized by specifying first and/or second parameter accordingly.
|
||||
* @param string $nameProperty class property name which holds element name to be used. This parameter
|
||||
* is available since 1.1.14.
|
||||
* @param string $attributeProperty class property name which holds model attribute name to be used. This
|
||||
* parameter is available since 1.1.14.
|
||||
* @return array name and ID of the input: array('name','id').
|
||||
* @throws CException in case model and attribute property or name property cannot be resolved.
|
||||
*/
|
||||
protected function resolveNameID($nameProperty='name',$attributeProperty='attribute')
|
||||
{
|
||||
if($this->$nameProperty!==null)
|
||||
$name=$this->$nameProperty;
|
||||
elseif(isset($this->htmlOptions[$nameProperty]))
|
||||
$name=$this->htmlOptions[$nameProperty];
|
||||
elseif($this->hasModel())
|
||||
$name=CHtml::activeName($this->model,$this->$attributeProperty);
|
||||
else
|
||||
throw new CException(Yii::t('zii','{class} must specify "model" and "{attribute}" or "{name}" property values.',
|
||||
array('{class}'=>get_class($this),'{attribute}'=>$attributeProperty,'{name}'=>$nameProperty)));
|
||||
|
||||
if(($id=$this->getId(false))===null)
|
||||
{
|
||||
if(isset($this->htmlOptions['id']))
|
||||
$id=$this->htmlOptions['id'];
|
||||
else
|
||||
$id=CHtml::getIdByName($name);
|
||||
}
|
||||
|
||||
return array($name,$id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean whether this widget is associated with a data model.
|
||||
*/
|
||||
protected function hasModel()
|
||||
{
|
||||
return $this->model instanceof CModel && $this->attribute!==null;
|
||||
}
|
||||
}
|
||||
74
framework/zii/widgets/jui/CJuiProgressBar.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* CJuiProgressBar class file.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
Yii::import('zii.widgets.jui.CJuiWidget');
|
||||
|
||||
/**
|
||||
* CJuiProgressBar displays a progress bar widget.
|
||||
*
|
||||
* CJuiProgressBar encapsulates the {@link http://jqueryui.com/progressbar/ JUI
|
||||
* Progressbar} plugin.
|
||||
*
|
||||
* To use this widget, you may insert the following code in a view:
|
||||
* <pre>
|
||||
* $this->widget('zii.widgets.jui.CJuiProgressBar',array(
|
||||
* 'value'=>75,
|
||||
* // additional javascript options for the progress bar plugin
|
||||
* 'options'=>array(
|
||||
* 'change'=>new CJavaScriptExpression('function(event, ui) {...}'),
|
||||
* ),
|
||||
* 'htmlOptions'=>array(
|
||||
* 'style'=>'height:20px;',
|
||||
* ),
|
||||
* ));
|
||||
* </pre>
|
||||
*
|
||||
* By configuring the {@link options} property, you may specify the options
|
||||
* that need to be passed to the JUI progressbar plugin. Please refer to
|
||||
* the {@link http://api.jqueryui.com/progressbar/ JUI ProgressBar} documentation
|
||||
* for possible options (name-value pairs) and
|
||||
* {@link http://jqueryui.com/progressbar/ JUI ProgressBar page} for general
|
||||
* description and demo.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @package zii.widgets.jui
|
||||
* @since 1.1
|
||||
*/
|
||||
class CJuiProgressBar extends CJuiWidget
|
||||
{
|
||||
/**
|
||||
* @var string the name of the container element that contains the progress bar. Defaults to 'div'.
|
||||
*/
|
||||
public $tagName='div';
|
||||
/**
|
||||
* @var integer the percentage of the progress. This must be an integer between 0 and 100. Defaults to 0.
|
||||
*/
|
||||
public $value=0;
|
||||
|
||||
/**
|
||||
* Run this widget.
|
||||
* This method registers necessary javascript and renders the needed HTML code.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$id=$this->getId();
|
||||
if(isset($this->htmlOptions['id']))
|
||||
$id=$this->htmlOptions['id'];
|
||||
else
|
||||
$this->htmlOptions['id']=$id;
|
||||
|
||||
echo CHtml::openTag($this->tagName,$this->htmlOptions);
|
||||
echo CHtml::closeTag($this->tagName);
|
||||
|
||||
$this->options['value']=$this->value;
|
||||
$options=CJavaScript::encode($this->options);
|
||||
Yii::app()->getClientScript()->registerScript(__CLASS__.'#'.$id,"jQuery('#{$id}').progressbar($options);");
|
||||
}
|
||||
}
|
||||
78
framework/zii/widgets/jui/CJuiResizable.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
* CJuiResizable class file.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
Yii::import('zii.widgets.jui.CJuiWidget');
|
||||
|
||||
/**
|
||||
* CJuiResizable displays a resizable widget.
|
||||
*
|
||||
* CJuiResizable encapsulates the {@link http://jqueryui.com/resizable/ JUI Resizable}
|
||||
* plugin.
|
||||
*
|
||||
* To use this widget, you may insert the following code in a view:
|
||||
* <pre>
|
||||
* $this->beginWidget('zii.widgets.jui.CJuiResizable',array(
|
||||
* // additional javascript options for the resizable plugin
|
||||
* 'options'=>array(
|
||||
* 'minHeight'=>'150',
|
||||
* ),
|
||||
* ));
|
||||
* echo 'Your Resizable content here';
|
||||
*
|
||||
* $this->endWidget();
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* By configuring the {@link options} property, you may specify the options
|
||||
* that need to be passed to the JUI Resizable plugin. Please refer to
|
||||
* the {@link http://api.jqueryui.com/resizable/ JUI Resizable API} documentation
|
||||
* for possible options (name-value pairs) and
|
||||
* {@link http://jqueryui.com/resizable/ JUI Resizable page} for general
|
||||
* description and demo.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @package zii.widgets.jui
|
||||
* @since 1.1
|
||||
*/
|
||||
class CJuiResizable extends CJuiWidget
|
||||
{
|
||||
/**
|
||||
* @var string the name of the Resizable element. Defaults to 'div'.
|
||||
*/
|
||||
public $tagName='div';
|
||||
|
||||
/**
|
||||
* Renders the open tag of the resizable element.
|
||||
* This method also registers the necessary javascript code.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
$id=$this->getId();
|
||||
if(isset($this->htmlOptions['id']))
|
||||
$id=$this->htmlOptions['id'];
|
||||
else
|
||||
$this->htmlOptions['id']=$id;
|
||||
|
||||
$options=CJavaScript::encode($this->options);
|
||||
Yii::app()->getClientScript()->registerScript(__CLASS__.'#'.$id,"jQuery('#{$id}').resizable($options);");
|
||||
|
||||
echo CHtml::openTag($this->tagName,$this->htmlOptions)."\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the close tag of the resizable element.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
echo CHtml::closeTag($this->tagName);
|
||||
}
|
||||
}
|
||||
82
framework/zii/widgets/jui/CJuiSelectable.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/**
|
||||
* CJuiSelectable class file.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
Yii::import('zii.widgets.jui.CJuiWidget');
|
||||
|
||||
/**
|
||||
* CJuiSelectable displays an accordion widget.
|
||||
*
|
||||
* CJuiSelectable encapsulates the {@link http://jqueryui.com/selectable/ JUI Selectable}
|
||||
* plugin.
|
||||
*
|
||||
* To use this widget, you may insert the following code in a view:
|
||||
* <pre>
|
||||
* $this->widget('zii.widgets.jui.CJuiSelectable',array(
|
||||
* 'items'=>array(
|
||||
* 'id1'=>'Item 1',
|
||||
* 'id2'=>'Item 2',
|
||||
* 'id3'=>'Item 3',
|
||||
* ),
|
||||
* // additional javascript options for the selectable plugin
|
||||
* 'options'=>array(
|
||||
* 'delay'=>'300',
|
||||
* ),
|
||||
* ));
|
||||
* </pre>
|
||||
*
|
||||
* By configuring the {@link options} property, you may specify the options
|
||||
* that need to be passed to the JUI Selectable plugin. Please refer to
|
||||
* the {@link http://api.jqueryui.com/selectable/ JUI Selectable API}
|
||||
* documentation for possible options (name-value pairs) and
|
||||
* {@link http://jqueryui.com/selectable/ JUI Selectable page} for general
|
||||
* description and demo.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @package zii.widgets.jui
|
||||
* @since 1.1
|
||||
*/
|
||||
class CJuiSelectable extends CJuiWidget {
|
||||
/**
|
||||
* @var array list of selectable items (id=>item content).
|
||||
* Note that the item contents will not be HTML-encoded.
|
||||
*/
|
||||
public $items=array();
|
||||
/**
|
||||
* @var string the name of the container element that contains all items. Defaults to 'ol'.
|
||||
*/
|
||||
public $tagName='ol';
|
||||
/**
|
||||
* @var string the template that is used to generated every selectable item.
|
||||
* The token "{content}" in the template will be replaced with the item content,
|
||||
* while "{id}" will be replaced with the item ID.
|
||||
*/
|
||||
public $itemTemplate='<li id="{id}">{content}</li>';
|
||||
|
||||
/**
|
||||
* Run this widget.
|
||||
* This method registers necessary javascript and renders the needed HTML code.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$id=$this->getId();
|
||||
if(isset($this->htmlOptions['id']))
|
||||
$id=$this->htmlOptions['id'];
|
||||
else
|
||||
$this->htmlOptions['id']=$id;
|
||||
|
||||
$options=CJavaScript::encode($this->options);
|
||||
Yii::app()->getClientScript()->registerScript(__CLASS__.'#'.$id,"jQuery('#{$id}').selectable({$options});");
|
||||
|
||||
echo CHtml::openTag($this->tagName,$this->htmlOptions)."\n";
|
||||
foreach($this->items as $id=>$content)
|
||||
echo strtr($this->itemTemplate,array('{id}'=>$id,'{content}'=>$content))."\n";
|
||||
echo CHtml::closeTag($this->tagName);
|
||||
}
|
||||
}
|
||||
76
framework/zii/widgets/jui/CJuiSlider.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* CJuiSlider class file.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
Yii::import('zii.widgets.jui.CJuiWidget');
|
||||
|
||||
/**
|
||||
* CJuiSlider displays a slider.
|
||||
*
|
||||
* CJuiSlider encapsulates the {@link http://jqueryui.com/slider/ JUI
|
||||
* slider} plugin.
|
||||
*
|
||||
* To use this widget, you may insert the following code in a view:
|
||||
* <pre>
|
||||
* $this->widget('zii.widgets.jui.CJuiSlider',array(
|
||||
* 'value'=>37,
|
||||
* // additional javascript options for the slider plugin
|
||||
* 'options'=>array(
|
||||
* 'min'=>10,
|
||||
* 'max'=>50,
|
||||
* ),
|
||||
* 'htmlOptions'=>array(
|
||||
* 'style'=>'height:20px;',
|
||||
* ),
|
||||
* ));
|
||||
* </pre>
|
||||
*
|
||||
* By configuring the {@link options} property, you may specify the options
|
||||
* that need to be passed to the JUI slider plugin. Please refer to
|
||||
* the {@link http://api.jqueryui.com/slider/ JUI Slider API} documentation
|
||||
* for possible options (name-value pairs) and
|
||||
* {@link http://jqueryui.com/slider/ JUI Slider page} for general
|
||||
* description and demo.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package zii.widgets.jui
|
||||
* @since 1.1
|
||||
*/
|
||||
class CJuiSlider extends CJuiWidget
|
||||
{
|
||||
/**
|
||||
* @var string the name of the container element that contains the slider. Defaults to 'div'.
|
||||
*/
|
||||
public $tagName='div';
|
||||
/**
|
||||
* @var integer determines the value of the slider, if there's only one handle. If there is more than one handle, determines the value of the first handle.
|
||||
*/
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* Run this widget.
|
||||
* This method registers necessary javascript and renders the needed HTML code.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$id=$this->getId();
|
||||
if(isset($this->htmlOptions['id']))
|
||||
$id=$this->htmlOptions['id'];
|
||||
else
|
||||
$this->htmlOptions['id']=$id;
|
||||
|
||||
echo CHtml::tag($this->tagName,$this->htmlOptions,'');
|
||||
|
||||
if($this->value!==null)
|
||||
$this->options['value']=$this->value;
|
||||
|
||||
$options=CJavaScript::encode($this->options);
|
||||
Yii::app()->getClientScript()->registerScript(__CLASS__.'#'.$id,"jQuery('#{$id}').slider($options);");
|
||||
}
|
||||
}
|
||||
168
framework/zii/widgets/jui/CJuiSliderInput.php
Normal file
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
/**
|
||||
* CJuiSliderInput class file.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
Yii::import('zii.widgets.jui.CJuiInputWidget');
|
||||
|
||||
/**
|
||||
* CJuiSliderInput displays a slider. It can be used in forms and post its value.
|
||||
*
|
||||
* CJuiSlider encapsulates the {@link http://jqueryui.com/slider/ JUI
|
||||
* slider} plugin.
|
||||
*
|
||||
* To use this widget, you may insert the following code in a view:
|
||||
* <pre>
|
||||
* $this->widget('zii.widgets.jui.CJuiSliderInput',array(
|
||||
* 'name'=>'rate',
|
||||
* 'value'=>37,
|
||||
* // additional javascript options for the slider plugin
|
||||
* 'options'=>array(
|
||||
* 'min'=>10,
|
||||
* 'max'=>50,
|
||||
* ),
|
||||
* 'htmlOptions'=>array(
|
||||
* 'style'=>'height:20px;',
|
||||
* ),
|
||||
* ));
|
||||
* </pre>
|
||||
*
|
||||
* The widget can also be used in range mode which uses 2 sliders to set a range.
|
||||
* In this mode, {@link attribute} and {@link maxAttribute} will define the attribute
|
||||
* names for the minimum and maximum range values, respectively. For example:
|
||||
*
|
||||
* <pre>
|
||||
* $this->widget('zii.widgets.jui.CJuiSliderInput',array(
|
||||
* 'model'=>$model,
|
||||
* 'attribute'=>'timeMin',
|
||||
* 'maxAttribute'=>'timeMax',
|
||||
* // additional javascript options for the slider plugin
|
||||
* 'options'=>array(
|
||||
* 'range'=>true,
|
||||
* 'min'=>0,
|
||||
* 'max'=>24,
|
||||
* ),
|
||||
* ));
|
||||
* </pre>
|
||||
*
|
||||
* If you need to use the slider event, please change the event value for 'stop' or 'change'.
|
||||
*
|
||||
* By configuring the {@link options} property, you may specify the options
|
||||
* that need to be passed to the JUI slider plugin. Please refer to
|
||||
* the {@link http://api.jqueryui.com/slider/ JUI Slider API} documentation
|
||||
* for possible options (name-value pairs) and
|
||||
* {@link http://jqueryui.com/slider/ JUI Slider page} for general
|
||||
* description and demo.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @package zii.widgets.jui
|
||||
* @since 1.1
|
||||
*/
|
||||
class CJuiSliderInput extends CJuiInputWidget
|
||||
{
|
||||
/**
|
||||
* @var string the name of the container element that contains the slider. Defaults to 'div'.
|
||||
*/
|
||||
public $tagName='div';
|
||||
/**
|
||||
* @var integer determines the value of the slider, if there's only one handle. If there is more than one handle,
|
||||
* determines the value of the first handle.
|
||||
*/
|
||||
public $value;
|
||||
/**
|
||||
* @var string the name of the event where the input will be attached to the slider. It
|
||||
* can be 'slide', 'stop' or 'change'. If you want to use 'slide' event change $event property to 'change'.
|
||||
*/
|
||||
public $event='slide';
|
||||
/**
|
||||
* @var string name of attribute for max value if slider is used in range mode.
|
||||
*/
|
||||
public $maxAttribute;
|
||||
/**
|
||||
* @var string the input name to be used for max value attribute when using slider in range mode.
|
||||
* This must be set in case {@link model} isn't used.
|
||||
* @since 1.1.14
|
||||
*/
|
||||
public $maxName;
|
||||
/**
|
||||
* @var integer determines the max value of the slider, if there's two handles (range mode). Ignored if there's
|
||||
* only one handle.
|
||||
* @since 1.1.14
|
||||
*/
|
||||
public $maxValue;
|
||||
/**
|
||||
* @var string the suffix to be appended to the ID of the max value input element
|
||||
* when slider used in range mode.
|
||||
* @since 1.1.14
|
||||
*/
|
||||
public $maxIdSuffix='_end';
|
||||
|
||||
/**
|
||||
* Run this widget.
|
||||
* This method registers necessary javascript and renders the needed HTML code.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
list($name,$id)=$this->resolveNameID();
|
||||
if(isset($this->htmlOptions['id']))
|
||||
$id=$this->htmlOptions['id'];
|
||||
else
|
||||
$this->htmlOptions['id']=$id;
|
||||
|
||||
$isRange=isset($this->options['range']) && $this->options['range'] &&
|
||||
$this->options['range']!=='max' && $this->options['range']!=='min';
|
||||
|
||||
if($this->hasModel())
|
||||
{
|
||||
$attribute=$this->attribute;
|
||||
if($isRange)
|
||||
{
|
||||
$options=$this->htmlOptions;
|
||||
echo CHtml::activeHiddenField($this->model,$this->attribute,$options);
|
||||
$options['id'].=$this->maxIdSuffix;
|
||||
echo CHtml::activeHiddenField($this->model,$this->maxAttribute,$options);
|
||||
$maxAttribute=$this->maxAttribute;
|
||||
$this->options['values']=array($this->model->$attribute,$this->model->$maxAttribute);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo CHtml::activeHiddenField($this->model,$this->attribute,$this->htmlOptions);
|
||||
$this->options['value']=$this->model->$attribute;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($isRange)
|
||||
{
|
||||
list($maxName,$maxId)=$this->resolveNameID('maxName','maxAttribute');
|
||||
$options=$this->htmlOptions;
|
||||
echo CHtml::hiddenField($name,$this->value,$options);
|
||||
$options['id'].=$this->maxIdSuffix;
|
||||
echo CHtml::hiddenField($maxName,$this->maxValue,$options);
|
||||
$this->options['values']=array($this->value,$this->maxValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo CHtml::hiddenField($name,$this->value,$this->htmlOptions);
|
||||
if($this->value!==null)
|
||||
$this->options['value']=$this->value;
|
||||
}
|
||||
}
|
||||
|
||||
$idHidden=$this->htmlOptions['id'];
|
||||
$this->htmlOptions['id']=$idHidden.'_slider';
|
||||
echo CHtml::tag($this->tagName,$this->htmlOptions,'');
|
||||
|
||||
$this->options[$this->event]=$isRange
|
||||
? new CJavaScriptExpression("function(e,ui){ v=ui.values; jQuery('#{$idHidden}').val(v[0]); jQuery('#{$idHidden}{$this->maxIdSuffix}').val(v[1]); }")
|
||||
: new CJavaScriptExpression("function(event, ui) { jQuery('#{$idHidden}').val(ui.value); }");
|
||||
|
||||
$options=CJavaScript::encode($this->options);
|
||||
Yii::app()->getClientScript()->registerScript(__CLASS__.'#'.$id,"jQuery('#{$id}_slider').slider($options);");
|
||||
}
|
||||
}
|
||||
86
framework/zii/widgets/jui/CJuiSortable.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
* CJuiSortable class file.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
Yii::import('zii.widgets.jui.CJuiWidget');
|
||||
|
||||
/**
|
||||
* CJuiSortable makes selected elements sortable by dragging with the mouse.
|
||||
*
|
||||
* CJuiSortable encapsulates the {@link http://jqueryui.com/sortable/ JUI Sortable}
|
||||
* plugin.
|
||||
*
|
||||
* To use this widget, you may insert the following code in a view:
|
||||
* <pre>
|
||||
* $this->widget('zii.widgets.jui.CJuiSortable',array(
|
||||
* 'items'=>array(
|
||||
* 'id1'=>'Item 1',
|
||||
* 'id2'=>'Item 2',
|
||||
* 'id3'=>'Item 3',
|
||||
* ),
|
||||
* // additional javascript options for the JUI Sortable plugin
|
||||
* 'options'=>array(
|
||||
* 'delay'=>'300',
|
||||
* ),
|
||||
* ));
|
||||
* </pre>
|
||||
*
|
||||
* By configuring the {@link options} property, you may specify the options
|
||||
* that need to be passed to the JUI Sortable plugin. Please refer to
|
||||
* the {@link http://api.jqueryui.com/sortable/ JUI Sortable API} documentation
|
||||
* for possible options (name-value pairs) and
|
||||
* {@link http://jqueryui.com/sortable/ JUI Sortable page} for general
|
||||
* description and demo.
|
||||
*
|
||||
* If you are using JavaScript expressions anywhere in the code, please wrap it
|
||||
* with {@link CJavaScriptExpression} and Yii will use it as code.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @package zii.widgets.jui
|
||||
* @since 1.1
|
||||
*/
|
||||
class CJuiSortable extends CJuiWidget
|
||||
{
|
||||
/**
|
||||
* @var array list of sortable items (id=>item content).
|
||||
* Note that the item contents will not be HTML-encoded.
|
||||
*/
|
||||
public $items=array();
|
||||
/**
|
||||
* @var string the name of the container element that contains all items. Defaults to 'ul'.
|
||||
*/
|
||||
public $tagName='ul';
|
||||
/**
|
||||
* @var string the template that is used to generated every sortable item.
|
||||
* The token "{content}" in the template will be replaced with the item content,
|
||||
* while "{id}" be replaced with the item ID.
|
||||
*/
|
||||
public $itemTemplate='<li id="{id}">{content}</li>';
|
||||
|
||||
/**
|
||||
* Run this widget.
|
||||
* This method registers necessary javascript and renders the needed HTML code.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$id=$this->getId();
|
||||
if(isset($this->htmlOptions['id']))
|
||||
$id=$this->htmlOptions['id'];
|
||||
else
|
||||
$this->htmlOptions['id']=$id;
|
||||
|
||||
$options=CJavaScript::encode($this->options);
|
||||
Yii::app()->getClientScript()->registerScript(__CLASS__.'#'.$id,"jQuery('#{$id}').sortable({$options});");
|
||||
|
||||
echo CHtml::openTag($this->tagName,$this->htmlOptions)."\n";
|
||||
foreach($this->items as $id=>$content)
|
||||
echo strtr($this->itemTemplate,array('{id}'=>$id,'{content}'=>$content))."\n";
|
||||
echo CHtml::closeTag($this->tagName);
|
||||
}
|
||||
}
|
||||
149
framework/zii/widgets/jui/CJuiTabs.php
Normal file
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
/**
|
||||
* CJuiTabs class file.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
Yii::import('zii.widgets.jui.CJuiWidget');
|
||||
|
||||
/**
|
||||
* CJuiTabs displays a tabs widget.
|
||||
*
|
||||
* CJuiTabs encapsulates the {@link http://jqueryui.com/tabs/ JUI tabs}
|
||||
* plugin.
|
||||
*
|
||||
* To use this widget, you may insert the following code in a view:
|
||||
* <pre>
|
||||
* $this->widget('zii.widgets.jui.CJuiTabs',array(
|
||||
* 'tabs'=>array(
|
||||
* 'StaticTab 1'=>'Content for tab 1',
|
||||
* 'StaticTab 2'=>array('content'=>'Content for tab 2', 'id'=>'tab2'),
|
||||
* // panel 3 contains the content rendered by a partial view
|
||||
* 'AjaxTab'=>array('ajax'=>$ajaxUrl),
|
||||
* ),
|
||||
* // additional javascript options for the tabs plugin
|
||||
* 'options'=>array(
|
||||
* 'collapsible'=>true,
|
||||
* ),
|
||||
* ));
|
||||
* </pre>
|
||||
*
|
||||
* By configuring the {@link options} property, you may specify the options
|
||||
* that need to be passed to the JUI tabs plugin. Please refer to
|
||||
* the {@link http://api.jqueryui.com/tabs/ JUI Tabs API} documentation
|
||||
* for possible options (name-value pairs) and
|
||||
* {@link http://jqueryui.com/tabs/ JUI Tabs page} for general
|
||||
* description and demo.
|
||||
*
|
||||
* Note, in case you're using <base/> HTML tag you may run into the
|
||||
* issue when jQuery UI uses altered base URL to load content, but not
|
||||
* the base URL content was loaded from. (Developer may expect both behavior
|
||||
* in different cases.) For this occasion consider using absolute URL
|
||||
* generation as follows:
|
||||
*
|
||||
* <pre>
|
||||
* $this->widget('zii.widgets.jui.CJuiTabs',array(
|
||||
* 'tabs'=>array(
|
||||
* 'Dynamic Tab'=>array('ajax'=>$this->createAbsoluteUrl('tab/content/route')),
|
||||
* ),
|
||||
* ));
|
||||
* </pre>
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @package zii.widgets.jui
|
||||
* @since 1.1
|
||||
*/
|
||||
class CJuiTabs extends CJuiWidget
|
||||
{
|
||||
/**
|
||||
* @var array list of tabs (tab title=>tab content).
|
||||
* Note that the tab title will not be HTML-encoded.
|
||||
* The tab content can be either a string or an array. When it is an array, it can
|
||||
* be in one of the following two formats:
|
||||
* <pre>
|
||||
* array('id'=>'myTabID', 'content'=>'tab content')
|
||||
* array('id'=>'myTabID', 'ajax'=>URL)
|
||||
* </pre>
|
||||
* where the 'id' element is optional. The second format allows the tab content
|
||||
* to be dynamically fetched from the specified URL via AJAX. The URL can be either
|
||||
* a string or an array. If an array, it will be normalized into a URL using {@link CHtml::normalizeUrl}.
|
||||
*/
|
||||
public $tabs=array();
|
||||
/**
|
||||
* @var string the name of the container element that contains all panels. Defaults to 'div'.
|
||||
*/
|
||||
public $tagName='div';
|
||||
/**
|
||||
* @var string the template that is used to generated every panel title.
|
||||
* The token "{title}" in the template will be replaced with the panel title and
|
||||
* the token "{url}" will be replaced with "#TabID" or with the url of the ajax request.
|
||||
*/
|
||||
public $headerTemplate='<li><a href="{url}" title="{id}">{title}</a></li>';
|
||||
/**
|
||||
* @var string the template that is used to generated every tab content.
|
||||
* The token "{content}" in the template will be replaced with the panel content
|
||||
* and the token "{id}" with the tab ID.
|
||||
*/
|
||||
public $contentTemplate='<div id="{id}">{content}</div>';
|
||||
|
||||
/**
|
||||
* Run this widget.
|
||||
* This method registers necessary javascript and renders the needed HTML code.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$id=$this->getId();
|
||||
if(isset($this->htmlOptions['id']))
|
||||
$id=$this->htmlOptions['id'];
|
||||
else
|
||||
$this->htmlOptions['id']=$id;
|
||||
|
||||
echo CHtml::openTag($this->tagName,$this->htmlOptions)."\n";
|
||||
|
||||
$tabsOut="";
|
||||
$contentOut="";
|
||||
$tabCount=0;
|
||||
|
||||
foreach($this->tabs as $title=>$content)
|
||||
{
|
||||
$tabId=(is_array($content) && isset($content['id']))?$content['id']:$id.'_tab_'.$tabCount++;
|
||||
|
||||
if(!is_array($content))
|
||||
{
|
||||
$tabsOut.=strtr($this->headerTemplate,array('{title}'=>$title,'{url}'=>'#'.$tabId,'{id}'=>'#'.$tabId))."\n";
|
||||
$contentOut.=strtr($this->contentTemplate,array('{content}'=>$content,'{id}'=>$tabId))."\n";
|
||||
}
|
||||
elseif(isset($content['ajax']))
|
||||
{
|
||||
$tabsOut.=strtr($this->headerTemplate,array('{title}'=>$title,'{url}'=>CHtml::normalizeUrl($content['ajax']),'{id}'=>'#'.$tabId))."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$tabsOut.=strtr($this->headerTemplate,array('{title}'=>$title,'{url}'=>'#'.$tabId,'{id}'=>$tabId))."\n";
|
||||
if(isset($content['content']))
|
||||
$contentOut.=strtr($this->contentTemplate,array('{content}'=>$content['content'],'{id}'=>$tabId))."\n";
|
||||
}
|
||||
}
|
||||
echo "<ul>\n".$tabsOut."</ul>\n";
|
||||
echo $contentOut;
|
||||
echo CHtml::closeTag($this->tagName)."\n";
|
||||
|
||||
$options=CJavaScript::encode($this->options);
|
||||
Yii::app()->getClientScript()->registerScript(__CLASS__.'#'.$id,"jQuery('#{$id}').tabs($options);");
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the core script files.
|
||||
* This method overrides the parent implementation by registering the cookie plugin when cookie option is used.
|
||||
*/
|
||||
protected function registerCoreScripts()
|
||||
{
|
||||
parent::registerCoreScripts();
|
||||
if(isset($this->options['cookie']))
|
||||
Yii::app()->getClientScript()->registerCoreScript('cookie');
|
||||
}
|
||||
}
|
||||
144
framework/zii/widgets/jui/CJuiWidget.php
Normal file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
/**
|
||||
* CJuiWidget class file.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008-2013 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is the base class for all JUI widget classes.
|
||||
*
|
||||
* @author Sebastian Thierer <sebathi@gmail.com>
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @package zii.widgets.jui
|
||||
* @since 1.1
|
||||
*/
|
||||
abstract class CJuiWidget extends CWidget
|
||||
{
|
||||
/**
|
||||
* @var string the root URL that contains all JUI JavaScript files.
|
||||
* If this property is not set (default), Yii will publish the JUI package included in the zii release and use
|
||||
* that to infer the root script URL. You should set this property if you intend to use
|
||||
* a JUI package whose version is different from the one included in zii.
|
||||
* Note that under this URL, there must be a file whose name is specified by {@link scriptFile}.
|
||||
* Do not append any slash character to the URL.
|
||||
*/
|
||||
public $scriptUrl;
|
||||
/**
|
||||
* @var string the root URL that contains all JUI theme folders.
|
||||
* If this property is not set (default), Yii will publish the JUI package included in the zii release and use
|
||||
* that to infer the root theme URL. You should set this property if you intend to use
|
||||
* a theme that is not found in the JUI package included in zii.
|
||||
* Note that under this URL, there must be a directory whose name is specified by {@link theme}.
|
||||
* Do not append any slash character to the URL.
|
||||
*/
|
||||
public $themeUrl;
|
||||
/**
|
||||
* @var string the JUI theme name. Defaults to 'base'. Make sure that under {@link themeUrl} there
|
||||
* is a directory whose name is the same as this property value (case-sensitive).
|
||||
*/
|
||||
public $theme='base';
|
||||
/**
|
||||
* @var mixed the main JUI JavaScript file. Defaults to 'jquery-ui.min.js'.
|
||||
* Note the file must exist under the URL specified by {@link scriptUrl}.
|
||||
* If you need to include multiple script files (e.g. during development, you want to include individual
|
||||
* plugin script files rather than the minized JUI script file), you may set this property
|
||||
* as an array of the script file names.
|
||||
* This property can also be set as false, which means the widget will not include any script file,
|
||||
* and it is your responsibility to explicitly include it somewhere else.
|
||||
*/
|
||||
public $scriptFile='jquery-ui.min.js';
|
||||
/**
|
||||
* @var mixed the theme CSS file name. Defaults to 'jquery-ui.css'.
|
||||
* Note the file must exist under the URL specified by {@link themeUrl}/{@link theme}.
|
||||
* If you need to include multiple theme CSS files (e.g. during development, you want to include individual
|
||||
* plugin CSS files), you may set this property as an array of the CSS file names.
|
||||
* This property can also be set as false, which means the widget will not include any theme CSS file,
|
||||
* and it is your responsibility to explicitly include it somewhere else.
|
||||
*/
|
||||
public $cssFile='jquery-ui.css';
|
||||
/**
|
||||
* @var array the initial JavaScript options that should be passed to the JUI plugin.
|
||||
*/
|
||||
public $options=array();
|
||||
/**
|
||||
* @var array the HTML attributes that should be rendered in the HTML tag representing the JUI widget.
|
||||
*/
|
||||
public $htmlOptions=array();
|
||||
|
||||
/**
|
||||
* Initializes the widget.
|
||||
* This method will publish JUI assets if necessary.
|
||||
* It will also register jquery and JUI JavaScript files and the theme CSS file.
|
||||
* If you override this method, make sure you call the parent implementation first.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->resolvePackagePath();
|
||||
$this->registerCoreScripts();
|
||||
parent::init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the JUI package installation path.
|
||||
* This method will identify the JavaScript root URL and theme root URL.
|
||||
* If they are not explicitly specified, it will publish the included JUI package
|
||||
* and use that to resolve the needed paths.
|
||||
*/
|
||||
protected function resolvePackagePath()
|
||||
{
|
||||
if($this->scriptUrl===null || $this->themeUrl===null)
|
||||
{
|
||||
$cs=Yii::app()->getClientScript();
|
||||
if($this->scriptUrl===null)
|
||||
$this->scriptUrl=$cs->getCoreScriptUrl().'/jui/js';
|
||||
if($this->themeUrl===null)
|
||||
$this->themeUrl=$cs->getCoreScriptUrl().'/jui/css';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the core script files.
|
||||
* This method registers jquery and JUI JavaScript files and the theme CSS file.
|
||||
*/
|
||||
protected function registerCoreScripts()
|
||||
{
|
||||
$cs=Yii::app()->getClientScript();
|
||||
if(is_string($this->cssFile))
|
||||
$cs->registerCssFile($this->themeUrl.'/'.$this->theme.'/'.$this->cssFile);
|
||||
elseif(is_array($this->cssFile))
|
||||
{
|
||||
foreach($this->cssFile as $cssFile)
|
||||
$cs->registerCssFile($this->themeUrl.'/'.$this->theme.'/'.$cssFile);
|
||||
}
|
||||
|
||||
$cs->registerCoreScript('jquery');
|
||||
if(is_string($this->scriptFile))
|
||||
$this->registerScriptFile($this->scriptFile);
|
||||
elseif(is_array($this->scriptFile))
|
||||
{
|
||||
foreach($this->scriptFile as $scriptFile)
|
||||
$this->registerScriptFile($scriptFile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a JavaScript file under {@link scriptUrl}.
|
||||
* Note that by default, the script file will be rendered at the end of a page to improve page loading speed.
|
||||
* @param string $fileName JavaScript file name
|
||||
* @param integer $position the position of the JavaScript file. Valid values include the following:
|
||||
* <ul>
|
||||
* <li>CClientScript::POS_HEAD : the script is inserted in the head section right before the title element.</li>
|
||||
* <li>CClientScript::POS_BEGIN : the script is inserted at the beginning of the body section.</li>
|
||||
* <li>CClientScript::POS_END : the script is inserted at the end of the body section.</li>
|
||||
* </ul>
|
||||
*/
|
||||
protected function registerScriptFile($fileName,$position=CClientScript::POS_END)
|
||||
{
|
||||
Yii::app()->getClientScript()->registerScriptFile($this->scriptUrl.'/'.$fileName,$position);
|
||||
}
|
||||
}
|
||||