├── .gitignore ├── widgets ├── EuiNumberSpinner.php ├── EuiSplitButton.php ├── EuiViewPort.php ├── EuiLabel.php ├── EuiAccordion.php ├── EuiComboItem.php ├── EuiDatetimeBox.php ├── EuiMenuButton.php ├── EuiControl.php ├── EuiTreeGrid.php ├── EuiProgressBar.php ├── EuiTimeSpinner.php ├── EuiTabs.php ├── EuiPropertyGrid.php ├── EuiLayout.php ├── EuiLinkButton.php ├── EuiMenu.php ├── EuiWindow.php ├── EuiTabPanel.php ├── EuiDatebox.php ├── EuiCalendar.php ├── EuiSpinner.php ├── EuiButton.php ├── EuiSearchBox.php ├── EuiTree.php ├── EuiRegion.php ├── EuiMenuItem.php ├── EuiNumberBox.php ├── EuiSlider.php ├── EuiComboTree.php ├── EuiContainer.php ├── EuiPagination.php ├── EuiValidateBox.php ├── EuiComboBox.php ├── EuiDataColumn.php ├── EuiComboGrid.php ├── EuiPanel.php ├── EuiWidget.php ├── EuiForm.php └── EuiDataGrid.php ├── data ├── EuiActiveDataProvider.php ├── EuiPagination.php ├── EuiSort.php └── EuiActiveRecord.php ├── README.md ├── web ├── EuiJavaScript.php └── EuiController.php └── assets └── js └── jquery.crud.js /.gitignore: -------------------------------------------------------------------------------- 1 | .settings 2 | .project 3 | .buildpath -------------------------------------------------------------------------------- /widgets/EuiNumberSpinner.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /widgets/EuiSplitButton.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /widgets/EuiViewPort.php: -------------------------------------------------------------------------------- 1 | toOptions())."\n"; 9 | foreach ($this->regions as $region) 10 | $region->run(); 11 | echo CHtml::closeTag('body')."\n"; 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /widgets/EuiLabel.php: -------------------------------------------------------------------------------- 1 | value, $this->for)."\n"; 14 | } 15 | } 16 | 17 | ?> -------------------------------------------------------------------------------- /widgets/EuiAccordion.php: -------------------------------------------------------------------------------- 1 | toOptions())."\n"; 16 | } 17 | 18 | 19 | public function run() 20 | { 21 | echo CHtml::closeTag('div')."\n"; 22 | } 23 | } -------------------------------------------------------------------------------- /widgets/EuiComboItem.php: -------------------------------------------------------------------------------- 1 | $this->value), $this->description)."\n"; 21 | } 22 | } -------------------------------------------------------------------------------- /widgets/EuiDatetimeBox.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /widgets/EuiMenuButton.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /widgets/EuiControl.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /widgets/EuiTreeGrid.php: -------------------------------------------------------------------------------- 1 | toOptions())."\n"; 25 | echo CHtml::closeTag('div')."\n"; 26 | } 27 | 28 | } 29 | 30 | ?> -------------------------------------------------------------------------------- /widgets/EuiTimeSpinner.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/EuiActiveDataProvider.php: -------------------------------------------------------------------------------- 1 | setPagination(array( 17 | 'class' => 'EuiPagination' 18 | )); 19 | 20 | $this->setSort(array( 21 | 'class' => 'EuiSort', 22 | )); 23 | } 24 | } -------------------------------------------------------------------------------- /widgets/EuiTabs.php: -------------------------------------------------------------------------------- 1 | toOptions())."\n"; 25 | } 26 | 27 | 28 | public function run() 29 | { 30 | echo CHtml::closeTag('div')."\n"; 31 | } 32 | } 33 | 34 | ?> -------------------------------------------------------------------------------- /widgets/EuiPropertyGrid.php: -------------------------------------------------------------------------------- 1 | addInvalidOptions('regions'); 23 | echo CHtml::openTag('div', $this->toOptions())."\n"; 24 | } 25 | 26 | /** 27 | * (non-PHPdoc) 28 | * @see CWidget::run() 29 | */ 30 | public function run() 31 | { 32 | echo CHtml::closeTag('div')."\n"; 33 | } 34 | 35 | } 36 | 37 | ?> -------------------------------------------------------------------------------- /widgets/EuiLinkButton.php: -------------------------------------------------------------------------------- 1 | addInvalidOptions('url'); 27 | } 28 | 29 | public function run() 30 | { 31 | $options = $this->toOptions(); 32 | unset($options['text']); 33 | unset($options['inline']); 34 | unset($options['url']); 35 | echo CHtml::link(CHtml::encode($this->text), CHtml::normalizeUrl($this->url), $options)."\n"; 36 | } 37 | } 38 | 39 | ?> -------------------------------------------------------------------------------- /widgets/EuiMenu.php: -------------------------------------------------------------------------------- 1 | toOptions())."\n"; 44 | } 45 | 46 | public function run() 47 | { 48 | parent::run(); 49 | echo CHtml::closeTag('div')."\n"; 50 | } 51 | } -------------------------------------------------------------------------------- /widgets/EuiWindow.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/EuiPagination.php: -------------------------------------------------------------------------------- 1 | validateCurrentPage) 34 | { 35 | $pageCount=$this->getPageCount(); 36 | if($currentPage>=$pageCount) 37 | $currentPage=$pageCount-1; 38 | } 39 | 40 | if($currentPage<0) 41 | $currentPage=0; 42 | 43 | return $currentPage; 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /widgets/EuiTabPanel.php: -------------------------------------------------------------------------------- 1 | toOptions())."\n"; 41 | } 42 | 43 | 44 | public function run() 45 | { 46 | echo CHtml::closeTag('div')."\n"; 47 | } 48 | 49 | } 50 | 51 | ?> -------------------------------------------------------------------------------- /widgets/EuiDatebox.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /widgets/EuiCalendar.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/EuiSort.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /widgets/EuiButton.php: -------------------------------------------------------------------------------- 1 | handler)) 30 | { 31 | if (!is_string($this->handler)) 32 | throw new CException ( Yii::t ('easyui', 'Invalid type of property "handler".') ); 33 | 34 | if (strpos($this->handler, 'js:') !== 0) 35 | $this->handler = 'js:'.$this->handler; 36 | } 37 | } 38 | 39 | /** 40 | * (non-PHPdoc) 41 | * @see CWidget::init() 42 | */ 43 | public function init() { 44 | $this->initHandler(); 45 | $this->addInvalidOptions('text'); 46 | } 47 | 48 | /** 49 | * (non-PHPdoc) 50 | * @see EuiWidget::run() 51 | */ 52 | public function run() 53 | { 54 | $options = $this->toOptions(); 55 | echo CHtml::Tag('button', $options, CHtml::encode($this->text))."\n"; 56 | } 57 | } 58 | ?> -------------------------------------------------------------------------------- /widgets/EuiSearchBox.php: -------------------------------------------------------------------------------- 1 | addInvalidOptions('menu'); 36 | } 37 | 38 | public function run() 39 | { 40 | $options = $this->toOptions(); 41 | 42 | if (is_array($this->menu)){ 43 | $id = $this->id.'_menu'; 44 | $options['menu'] = EuiJavaScript::encodeRefId($id); 45 | 46 | echo CHtml::openTag('div', array('id'=>$id)). "\n"; 47 | foreach ($this->menu as $item) 48 | { 49 | $text = $item['text']; 50 | unset($item['text']); 51 | echo CHtml::tag('div', $item, $text)."\n"; 52 | } 53 | echo CHtml::closeTag('div'). "\n"; 54 | } 55 | echo CHtml::Tag('input', $options, null); 56 | } 57 | } 58 | 59 | ?> -------------------------------------------------------------------------------- /widgets/EuiTree.php: -------------------------------------------------------------------------------- 1 | toOptions()); 63 | echo CHtml::closeTag('ul')."\n"; 64 | } 65 | } 66 | 67 | ?> -------------------------------------------------------------------------------- /widgets/EuiRegion.php: -------------------------------------------------------------------------------- 1 | toOptions())."\n"; 40 | } 41 | 42 | public function run() 43 | { 44 | echo CHtml::closeTag('div')."\n"; 45 | } 46 | } 47 | 48 | ?> -------------------------------------------------------------------------------- /widgets/EuiMenuItem.php: -------------------------------------------------------------------------------- 1 | addInvalidOptions('text'); 44 | } 45 | 46 | public function run() 47 | { 48 | if ($this->separator) 49 | echo CHtml::Tag('div', array('class'=>'menu-sep'), '')."\n"; 50 | 51 | else if (empty($this->items)) 52 | echo CHtml::Tag('div', $this->toOptions(), $this->text)."\n"; 53 | 54 | else { 55 | echo CHtml::openTag('div')."\n"; 56 | echo CHtml::Tag('span', $this->toOptions(), $this->text)."\n"; 57 | echo CHtml::openTag('div')."\n"; 58 | $this->renderItems(); 59 | echo CHtml::closeTag('div')."\n"; 60 | echo CHtml::closeTag('div')."\n"; 61 | } 62 | } 63 | 64 | } -------------------------------------------------------------------------------- /widgets/EuiNumberBox.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /widgets/EuiSlider.php: -------------------------------------------------------------------------------- 1 | toOptions())."\n"; 66 | echo CHtml::closeTag('div')."\n"; 67 | } 68 | } 69 | ?> -------------------------------------------------------------------------------- /widgets/EuiComboTree.php: -------------------------------------------------------------------------------- 1 | addInvalidOptions('name'); 66 | } 67 | 68 | public function run() 69 | { 70 | $options = $this->toOptions(); 71 | $options['name'] = $this->name; 72 | 73 | echo CHtml::openTag('select', $options); 74 | echo CHtml::closeTag('select'); 75 | } 76 | } 77 | 78 | ?> -------------------------------------------------------------------------------- /widgets/EuiContainer.php: -------------------------------------------------------------------------------- 1 | items as $it){ 20 | 21 | if (is_object($it)) 22 | $it->run(); 23 | else if (is_array($it)) 24 | { 25 | echo CHtml::openTag('div', $it)."\n"; 26 | echo CHtml::closeTag('div', $it)."\n"; 27 | } 28 | } 29 | } 30 | 31 | /** 32 | * Return the name of item class.If not definied class in item of elements 33 | * @return string 34 | */ 35 | protected function getDefaultItemClass() 36 | { 37 | return null; 38 | } 39 | 40 | /** 41 | * Creates items objects and initializes them. 42 | */ 43 | protected function initItems($parent) 44 | { 45 | if (property_exists(get_class($parent), 'items')) 46 | { 47 | foreach($parent->items as $i => $item) 48 | { 49 | if (is_array($item)) 50 | { 51 | if (!isset($item['class']) && $this->getDefaultItemClass()!== null) 52 | $item['class'] = $this->getDefaultItemClass(); 53 | 54 | if (isset($item['class'])) 55 | { 56 | $newItem = Yii::createComponent($item, $parent); 57 | $newItem->init(); 58 | $parent->items[$i]= $newItem; 59 | $this->initItems($newItem); 60 | } 61 | } 62 | } 63 | } 64 | } 65 | 66 | 67 | /** 68 | * Initializes the container. 69 | * This method will initialize required property values and instantiate {@link items} objects. 70 | */ 71 | public function init() 72 | { 73 | parent::init(); 74 | $this->addInvalidOptions(array('inline', 'items')); 75 | $this->initItems($this); 76 | } 77 | 78 | 79 | public function run() 80 | { 81 | $this->renderItems(); 82 | } 83 | } 84 | 85 | ?> -------------------------------------------------------------------------------- /widgets/EuiPagination.php: -------------------------------------------------------------------------------- 1 | toOptions(); 67 | unset($options['buttons']); 68 | 69 | if ($this->buttons) 70 | $btns = "buttons:".CJavaScript::encode($this->buttons); 71 | 72 | if (isset($options['data-options'])) 73 | $options['data-options'] = $btns .",". $options['data-options']; 74 | else 75 | $options['data-options'] = $btns; 76 | 77 | echo CHtml::openTag('div', $options); 78 | echo CHtml::closeTag('div'); 79 | } 80 | 81 | } 82 | 83 | ?> -------------------------------------------------------------------------------- /widgets/EuiValidateBox.php: -------------------------------------------------------------------------------- 1 | addInvalidOptions(array( 66 | 'name', 67 | 'size', 68 | 'maxlength', 69 | 'placeholder' 70 | )); 71 | } 72 | 73 | public function run() 74 | { 75 | $options = $this->toOptions(); 76 | $options['name'] = $this->name; 77 | $options['size'] = $this->size; 78 | $options['maxlength'] = $this->maxlength; 79 | $options['placeholder'] = $this->placeholder; 80 | echo CHtml::Tag('input', $options)."\n"; 81 | } 82 | } 83 | 84 | ?> -------------------------------------------------------------------------------- /widgets/EuiComboBox.php: -------------------------------------------------------------------------------- 1 | options = $this->initCollection($this->options, 'EuiComboItem'); 72 | } 73 | 74 | public function run() 75 | { 76 | if (empty($this->options)) 77 | parent::run(); 78 | else { 79 | $options = $this->toOptions(); 80 | 81 | echo CHtml::openTag('select', $options)."\n"; 82 | foreach ($this->options as $item) 83 | $item->run(); 84 | echo CHtml::closeTag('select')."\n"; 85 | } 86 | } 87 | } 88 | ?> -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Yii EasyUI 2 | ========== 3 | 4 | Yii EasyUI is a extension of [Yii](http://www.yiiframework.com) that helps to work with [jQuery EasyUI](http://www.jeasyui.com) library. 5 | 6 | The extension implements widgets for writing the componentes javascript. 7 | 8 | Including the resources 9 | ------------------------ 10 | 11 | Download http://www.jeasyui.com/download/, extracting content in ```js/jquery-easyui``` 12 | Download [yii-easyui](https://github.com/leandrogehlen/yii-easyui/archive/master.zip) extracting content in ```protected/extensions``` 13 | 14 | Configuration 15 | ------------- 16 | Is necessary that the controllers extends of class ```EuiController``` 17 | 18 | ```php 19 | Yii::import('ext.yii-easyui.base.EuiController'); 20 | 21 | class SiteController extends EuiController { 22 | 23 | public function actionIndex() 24 | { 25 | $this->render('index'); 26 | } 27 | } 28 | ``` 29 | 30 | ####Important! 31 | 32 | The native css files used by [Yii](http://www.yiiframework.com) generate conflicts with [jQuery EasyUI](http://www.jeasyui.com) 33 | To avoid conflict **REMOVE** the following lines in ```protected/views/layouts/main.php``` 34 | 35 | ```php 36 | 37 | 38 | 39 | 40 | 43 | 44 | 45 | 46 | ``` 47 | 48 | Widgets 49 | ------ 50 | 51 | In view files is possible to write widget components to render JQuery Easyui format, according to the following example: 52 | 53 | ```php 54 | $this->widget('ext.yii-easyui.widgets.EuiWindow', array( 55 | 'id' => 'win', 56 | 'title' => 'My Window', 57 | 'style' => 'width:500px;height:250px;padding:10px;' 58 | )); 59 | 60 | ``` 61 | 62 | Results: 63 | 64 | ![Hello World](https://jquery-easyui.googlecode.com/svn/trunk/share/tutorial/window/win1_1.png) 65 | -------------------------------------------------------------------------------- /widgets/EuiDataColumn.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /widgets/EuiComboGrid.php: -------------------------------------------------------------------------------- 1 | columns as $col) 81 | { 82 | $js[] = $col->toArray(); 83 | } 84 | 85 | $js = EuiJavaScript::encodeId($this->getId()).'.combogrid({columns:['.CJavaScript::jsonEncode($js).']});'; 86 | Yii::app()->getClientScript()->registerScript($this->getId(), $js); 87 | } 88 | 89 | public function getCssClass() 90 | { 91 | return 'easyui-combogrid'; 92 | } 93 | 94 | public function init() 95 | { 96 | parent::init(); 97 | $this->addInvalidOptions('name'); 98 | } 99 | 100 | public function run() 101 | { 102 | $options = $this->toOptions(); 103 | $options['name'] = $this->name; 104 | 105 | $this->registerColumnsScript(); 106 | echo CHtml::Tag('input', $options); 107 | } 108 | } -------------------------------------------------------------------------------- /web/EuiJavaScript.php: -------------------------------------------------------------------------------- 1 | getClientScript(); 23 | 24 | $scriptUrl = Yii::app()->baseUrl.'/js/jquery-easyui'; 25 | $themeUrl = $scriptUrl.'/themes'; 26 | $localeUrl = $scriptUrl.'/locale'; 27 | 28 | $cs->registerCoreScript('jquery'); 29 | $cs->registerScriptFile($scriptUrl.'/jquery.easyui.min.js'); 30 | 31 | $cs->registerCssFile($themeUrl.'/'.$theme.'/easyui.css'); 32 | $cs->registerCssFile($themeUrl.'/'.$theme.'/combo.css'); 33 | $cs->registerCssFile($themeUrl.'/icon.css'); 34 | 35 | $cs->registerScriptFile($localeUrl.'/'.$locale.'.js'); 36 | } 37 | 38 | public static function registerCrudScripts() 39 | { 40 | $path = Yii::getPathOfAlias('ext.yii-easyui.assets'); 41 | 42 | $am = Yii::app()->getAssetManager(); 43 | $cs = Yii::app()->getClientScript(); 44 | 45 | $cs->registerScriptFile($am->publish($path.'/js/jquery.crud.js')); 46 | } 47 | 48 | 49 | /** 50 | * Encodes a PHP variable into javascript JQuery id representation 51 | * @param string $id 52 | */ 53 | public static function encodeId($id) 54 | { 55 | return "$('#{$id}')"; 56 | } 57 | 58 | /** 59 | * Encodes a PHP variable into javascript JQuery referenced id representation 60 | * @param string $id 61 | */ 62 | public static function encodeRefId($id) 63 | { 64 | return "#{$id}"; 65 | } 66 | 67 | /** 68 | * Render JavaScript code the messege 69 | * @param string $category 70 | * @param string $msg 71 | */ 72 | private static function message($category, $msg, $type) 73 | { 74 | $msg = Yii::t($category, $msg); 75 | return "$.messager.alert('".Yii::app()->name."','{$msg}','{$type}');"; 76 | } 77 | 78 | /** 79 | * Render JavaScript code the info messege 80 | * @param string $category 81 | * @param string $msg 82 | */ 83 | public static function info($category, $msg) 84 | { 85 | return self::message($category, $msg, 'info'); 86 | } 87 | 88 | /** 89 | * Render JavaScript code the alert messege 90 | * @param string $category 91 | * @param string $msg 92 | */ 93 | public static function alert($category, $msg) 94 | { 95 | return self::message($category, $msg, 'warning'); 96 | } 97 | 98 | /** 99 | * Render JavaScript code the error messege 100 | * @param string $category 101 | * @param string $msg 102 | */ 103 | public static function error($category, $msg) 104 | { 105 | return self::message($category, $msg, 'error'); 106 | } 107 | 108 | /** 109 | * Render JavaScript code the alert messege 110 | * @param string $category 111 | * @param string $msg 112 | * @param string $function 113 | */ 114 | public static function question($category, $msg, $function=null) 115 | { 116 | $js = "$.messager.confirm('".Yii::app()->name."','{$msg}'"; 117 | 118 | if ($function) 119 | $js .=", function(r){ if(r){ {$function} }});"; 120 | else 121 | $js .= ");"; 122 | 123 | return $js; 124 | } 125 | } 126 | 127 | ?> -------------------------------------------------------------------------------- /widgets/EuiPanel.php: -------------------------------------------------------------------------------- 1 | toOptions(); 144 | 145 | if ($this->internal) 146 | unset($options['class']); 147 | 148 | echo CHtml::openTag('div', $options)."\n"; 149 | } 150 | 151 | 152 | public function run() 153 | { 154 | echo CHtml::closeTag('div')."\n"; 155 | } 156 | } 157 | 158 | ?> -------------------------------------------------------------------------------- /data/EuiActiveRecord.php: -------------------------------------------------------------------------------- 1 | label) 21 | */ 22 | public function attributeExports() 23 | { 24 | return array(); 25 | } 26 | 27 | /** 28 | * Returns the query criteria associated with this model used by {@link search()} 29 | * @return CDbCriteria 30 | */ 31 | protected function getSearchCriteria() 32 | { 33 | return $this->getDbCriteria(); 34 | } 35 | 36 | /** 37 | * Returns the field names that used in search 38 | * @return array search field names 39 | */ 40 | public function searchAttributes() 41 | { 42 | return array(); 43 | } 44 | 45 | /** 46 | * Retrieves a list of models based on the current search/filter conditions. 47 | * @return CDbCriteria return the criteria models based on the search/filter conditions. 48 | */ 49 | public function search($value) 50 | { 51 | $with = array(); 52 | $criteria = $this->getSearchCriteria(); 53 | $attributes = $this->searchAttributes(); 54 | 55 | foreach ($attributes as $attr) 56 | { 57 | $column = self::getColumnByAttributeName($this, $attr); 58 | if (isset($column)) 59 | { 60 | $search = $value; 61 | if (strpos($attr, '.')) 62 | { 63 | $tokens = explode('.', $attr); 64 | array_pop($tokens); 65 | $with[] = implode('.', $tokens); 66 | } else 67 | $attr = $this->getTableAlias(true).'.'.$attr; 68 | 69 | if (!empty($search)) { 70 | if ($column->type == 'integer' || $column->type == 'double') 71 | { 72 | if (is_numeric($search)) 73 | { 74 | switch ($column->type) 75 | { 76 | case 'integer': $search = (int)$value;break; 77 | case 'double': $search = (double)$value;break; 78 | } 79 | $criteria->compare($attr, $search, false, 'OR'); 80 | } 81 | } 82 | else if (!empty($search)) 83 | $criteria->compare("LOWER({$attr})", $search, $column->type == 'string', 'OR'); 84 | } 85 | } 86 | } 87 | 88 | $criteria->with = $with; 89 | 90 | return new EuiActiveDataProvider($this, array( 91 | 'criteria'=>$criteria, 92 | )); 93 | } 94 | 95 | /** 96 | * Gets the column metadata by attribute name 97 | * This is a convenient method for retrieving a named column even if it does not exist. 98 | * @param CActiveRecord $model 99 | * @param String $attribute 100 | */ 101 | public static function getColumnByAttributeName($model, $attribute) 102 | { 103 | $pos = strpos($attribute, '.'); 104 | if($pos) 105 | { 106 | $relationName = substr($attribute, 0, $pos); 107 | $relations = $model->relations(); 108 | 109 | if (isset($relations[$relationName])) 110 | { 111 | $attribute = substr($attribute, $pos+1); 112 | $relations = array($relationName => $relations[$relationName]); 113 | } 114 | foreach ($relations as $relation) 115 | { 116 | if ($relation[0] === CActiveRecord::BELONGS_TO) 117 | { 118 | $relationModel = new $relation[1]; 119 | $column = self::getColumnByAttributeName($relationModel, $attribute); 120 | if (isset($column)) 121 | return $column; 122 | } 123 | } 124 | } 125 | else { 126 | $column = $model->getTableSchema()->getColumn($attribute); 127 | if (isset($column)) 128 | return $column; 129 | } 130 | return null; 131 | } 132 | } -------------------------------------------------------------------------------- /web/EuiController.php: -------------------------------------------------------------------------------- 1 | encodeData($model); 24 | foreach ($data as $k => $v) 25 | { 26 | $className = get_class($model); 27 | $data[$className.'['.$k.']'] = $v; 28 | unset($data[$k]); 29 | } 30 | return CJSON::encode($data); 31 | } 32 | 33 | /** 34 | * Exports an array to a special readable JSON object. 35 | *

The $total parameter indicates the total number of records. This is useful is case of pagination where 36 | * the total number of records is needed by the control to create the correct pagination
37 | * @param array|IDataProvider $data the data to generate a JSON object from it 38 | * @param int $total total number of records in the entire data-source 39 | * @return string Data representation in JSON format 40 | */ 41 | public function exportData($data, $total=null) 42 | { 43 | $exports = array(); 44 | $model = null; 45 | 46 | if ($data instanceof IDataProvider) 47 | { 48 | $total = $data->getTotalItemCount(); 49 | $data = $data->getData(); 50 | } 51 | 52 | if (is_object($data)) 53 | $model = $data; 54 | else if (is_array($data) && !empty($data)) 55 | $model = current($data); 56 | 57 | if ($model !== null && $model instanceof CActiveRecord && method_exists($model, 'attributeExports')) 58 | { 59 | $attrs = $model->attributeExports(); 60 | 61 | if (!is_array($attrs) || (!empty($attrs) && !is_string(current($attrs))) ) 62 | throw new CException(Yii::t('easyui', 'Invalid return of method "attributeExports" of class "{class}"', 63 | array('{class}'=>get_class($model)))); 64 | 65 | foreach ($attrs as $at) 66 | $exports = array_merge($exports, explode('.', $at)); 67 | } 68 | 69 | if (is_array($data)) 70 | { 71 | $rows = array(); 72 | foreach ($data as $item) 73 | $rows[] = $this->encodeData($item, null, false, $exports); 74 | 75 | return CJSON::encode(array('total'=>(isset($total)) ? $total: sizeof($data),'rows'=>$rows)); 76 | } 77 | else 78 | return CJSON::encode($this->encodeData($data)); 79 | } 80 | 81 | /** 82 | * Convert model to array for export JSON format 83 | * @param $model the model to encode 84 | * @param boolean $hidePk whether to export primary key attribute 85 | * @param array $exports attribute names of export 86 | */ 87 | private function encodeData($model, $alias=null, $hidePk=false, $exports=array()) 88 | { 89 | $data = array(); 90 | foreach ($model as $key => $value) 91 | { 92 | if ($hidePk && $key == $model->getTableSchema()->primaryKey) 93 | continue; 94 | 95 | if (empty($exports) || in_array($key, $exports)) 96 | { 97 | $key = ($alias) ? strtolower($alias).'_'.$key : $key; 98 | $data[$key] = $value; 99 | } 100 | } 101 | 102 | if ($model instanceof CActiveRecord) 103 | { 104 | foreach ($model->relations() as $k => $relation) 105 | { 106 | if ($relation[0] === CActiveRecord::BELONGS_TO) 107 | { 108 | $fk = $model->{$k}; 109 | if ((empty($exports) || in_array($k, $exports)) && $fk !== null){ 110 | $cls = get_class($fk); 111 | $alias = ($alias !== null) ? $alias.'_'.$cls : $cls; 112 | $data = array_merge($data, $this->encodeData($fk, $alias, true, $exports)); 113 | } 114 | } 115 | } 116 | } 117 | return $data; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /widgets/EuiWidget.php: -------------------------------------------------------------------------------- 1 | $v) 30 | { 31 | if (is_bool($v)) 32 | $v = $v? 'true' : 'false'; 33 | else if (is_array($v)) 34 | $v = !empty($v) ? CJavaScript::encode($v) : null; 35 | else if (is_string($v)) 36 | { 37 | if (strpos($v, 'js:') === 0) 38 | $v = substr($v, 3); 39 | else 40 | $v = "'".$v."'"; 41 | } 42 | 43 | if ($v !== null) 44 | $es[] = $i.':'.$v; 45 | } 46 | 47 | if (!empty($es)) 48 | return implode(',', $es); 49 | else 50 | return null; 51 | } 52 | 53 | /** 54 | * Return if property is ignored 55 | * @param string $propName the property name 56 | * @return bool 57 | */ 58 | private function isInvalidOption($optionName) 59 | { 60 | foreach ($this->_invalidOptions as $opt) 61 | { 62 | if ($opt === $optionName) 63 | return true; 64 | } 65 | return false; 66 | } 67 | 68 | /** 69 | * Add property of self class to ignored list 70 | * @param mixed $props property name or arry of property name 71 | */ 72 | protected function addInvalidOptions($options) 73 | { 74 | if (is_array($options)) 75 | $this->_invalidOptions = array_merge($this->_invalidOptions, $options); 76 | else 77 | $this->_invalidOptions[] = $options; 78 | } 79 | 80 | /** 81 | * Check of item class name is valid 82 | * @param array $config represents configuration object 83 | * @param string $itemClassName name of class item 84 | * @throws CException 85 | */ 86 | protected function prepareConfig(array $config, $itemClassName=null) 87 | { 88 | if (!isset($config['class']) && $itemClassName === null) 89 | throw new CException(Yii::t('easyui','Object configuration not definied "class" value.')); 90 | 91 | if (!isset($config['class'])) 92 | $config['class'] = $itemClassName; 93 | 94 | if ($itemClassName !== null) 95 | { 96 | if ($config['class'] !== $itemClassName) 97 | throw new CException(Yii::t('easyui','Object configuration contain "class" with wrong value.')); 98 | } 99 | 100 | return $config; 101 | } 102 | 103 | 104 | /** 105 | * Return a new collection with elements configuration substuidos of objects 106 | * @param array $collection The elements configuration 107 | * @param string $itemClassName The class name of items 108 | * @param string $prefix The prefix of generation item name 109 | * @return array 110 | */ 111 | protected function initCollection(array $collection, $itemClassName=null, $prefix='_i') 112 | { 113 | $items = array(); 114 | foreach($collection as $i => $item) 115 | { 116 | $item = $this->prepareConfig($item, $itemClassName); 117 | $item = Yii::createComponent($item, $this); 118 | 119 | $items[$i]= $item; 120 | $item->init(); 121 | } 122 | return $items; 123 | } 124 | 125 | /** 126 | * @return string the CSS class that will be added to this component's Element 127 | */ 128 | protected function getCssClass() 129 | { 130 | return $this->cssClass; 131 | } 132 | 133 | /** 134 | * @return array Represents configuration this component 135 | */ 136 | public function toArray() 137 | { 138 | $props = array(); 139 | 140 | foreach ($this as $key => $value) 141 | { 142 | if ($value === null || is_object($value)) 143 | continue; 144 | 145 | if (!$this->isInvalidOption($key)) 146 | $props[$key] = $value; 147 | } 148 | 149 | unset($props['skin']); 150 | unset($props['cssClass']); 151 | unset($props['htmlOptions']); 152 | unset($props['_invalidOptions']); 153 | 154 | return $props; 155 | } 156 | 157 | /** 158 | * @return array Represents options this component 159 | */ 160 | public function toOptions() 161 | { 162 | $options = array(); 163 | $props = $this->toArray(); 164 | 165 | if ($this->getCssClass()) 166 | $options['class'] = $this->getCssClass(); 167 | 168 | if (isset($props['style'])) 169 | { 170 | $options['style'] = $props['style']; 171 | unset($props['style']); 172 | } 173 | 174 | $options['id'] = $this->getId(); 175 | $options['data-options'] = $this->encodeOptions($props); 176 | $options = array_merge($options, $this->htmlOptions); 177 | return $options; 178 | } 179 | } 180 | 181 | ?> 182 | -------------------------------------------------------------------------------- /assets/js/jquery.crud.js: -------------------------------------------------------------------------------- 1 | var locale = { 2 | crud: { 3 | noRecordsSelectedMsg: "No records selected", 4 | onlyOneRecordSelectedMsg: "Only one record should be selected", 5 | removeConfirmationMsg : "Are you sure you want to remove the selected(s) record(s)", 6 | alertTitle: "Alert", 7 | confirmTitle: "Confirm" 8 | } 9 | }; 10 | 11 | var Crud = function(options) { 12 | this.init(options); 13 | }; 14 | 15 | Crud.prototype = { 16 | 17 | init: function(options) { 18 | var that = this, 19 | defaults = { 20 | window: null, 21 | route: "", 22 | grid: null, 23 | onBeforeEdit: function(isNewRecord, data){}, 24 | onAfterEdit: function(isNewRecord){}, 25 | onBeforeRemove: function(rows){}, 26 | onAfterRemove: function(){}, 27 | onBeforeRefresh: function(){}, 28 | onAfterRefresh: function(){}, 29 | onBeforeSave: function(param){}, 30 | onAfterSave: function(){} 31 | }; 32 | 33 | that.options = $.extend({}, defaults, options); 34 | that.route = options.route.replace(/\/index$/,''); 35 | that.form = options.window.find('form:first'); 36 | 37 | that.noRecordsSelectedMsg = locale.crud.noRecordsSelectedMsg; 38 | that.onlyOneRecordSelectedMsg = locale.crud.onlyOneRecordSelectedMsg; 39 | that.removeConfirmationMsg = locale.crud.removeConfirmationMsg; 40 | that.alertTitle = locale.crud.alertTitle; 41 | that.confirmTitle = locale.crud.confirmTitle; 42 | 43 | that.form.form({ 44 | onLoadSuccess: function(data){ 45 | $.messager.progress('close'); 46 | if (data.success === false) 47 | $.messager.alert(that.alertTitle, data.error, 'error'); 48 | else { 49 | that.options.onBeforeEdit(false, data); 50 | that.options.window.dialog('open'); 51 | that.options.onAfterEdit(false); 52 | } 53 | } 54 | }); 55 | }, 56 | 57 | validate: function() { 58 | var that = this, 59 | selected = that.options.grid.datagrid('getSelected'), 60 | rows = that.options.grid.datagrid('getSelected'), 61 | valid = false; 62 | 63 | if (!selected) 64 | $.messager.alert(that.alertTitle, that.noRecordsSelectedMsg, 'warning'); 65 | else if (rows.length > 1) 66 | $.messager.alert(that.alertTitle, that.onlyOneRecordSelectedMsg, 'warning'); 67 | else 68 | valid = true; 69 | 70 | return valid; 71 | }, 72 | 73 | clearErrors: function() { 74 | var div = $('.errorMessage'); 75 | if (div.length) div.remove(); 76 | }, 77 | 78 | showErrors: function(errors) { 79 | var that = this; 80 | for (var i in errors) { 81 | var div = that.form.find('#' + i).closest('div'); 82 | div.append('

'+errors[i]+'
'); 83 | } 84 | }, 85 | 86 | add: function() { 87 | var that = this; 88 | that.form.form('clear'); 89 | that.form.attr('action', that.route+'/create'); 90 | that.options.onBeforeEdit(true, {}); 91 | that.options.window.dialog('open'); 92 | that.options.onAfterEdit(true); 93 | }, 94 | 95 | edit: function() { 96 | var that = this; 97 | 98 | if (that.validate(true)) { 99 | $.messager.progress(); 100 | 101 | var selected = that.options.grid.datagrid('getSelected'), 102 | url = that.route+"/view&id="+selected.id, 103 | action = that.route+"/update&id="+selected.id; 104 | 105 | that.form.attr('action', action); 106 | that.form.form('reset'); 107 | that.form.form('load', url); 108 | } 109 | }, 110 | 111 | remove: function(){ 112 | var that = this; 113 | 114 | if (!that.validate()) 115 | return 116 | 117 | $.messager.confirm(that.confirmTitle, that.removeConfirmationMsg, function(r){ 118 | if (r) { 119 | var row = that.options.grid.datagrid('getSelected'); 120 | that.options.onBeforeRemove(row); 121 | 122 | $.ajax({type: "POST", url: that.route +'/delete/&id='+row.id, 123 | success: function(data) { 124 | data = $.parseJSON(data); 125 | if (!data.success) { 126 | $.messager.alert(that.alertTitle, data.error, 'error'); 127 | } 128 | else { 129 | that.options.grid.datagrid('clearSelections'); 130 | that.options.grid.datagrid('reload'); 131 | } 132 | }, 133 | 134 | error: function (xhr, status, error){ 135 | $.messager.alert(that.alertTitle, error, 'error'); 136 | } 137 | }); 138 | 139 | that.options.onAfterRemove(); 140 | } 141 | }); 142 | 143 | }, 144 | 145 | refresh: function() { 146 | var that = this; 147 | that.options.grid.datagrid('clearSelections'); 148 | that.options.grid.datagrid('reload'); 149 | }, 150 | 151 | save: function() { 152 | var that = this, 153 | param = {ajax: that.form.attr('id')}; 154 | 155 | if (!that.form.form('validate')) 156 | return; 157 | 158 | that.clearErrors(); 159 | that.options.onBeforeSave(param); 160 | param = (!$.isEmptyObject(param)) ? '&' + $.param(param, true) : ''; 161 | 162 | $.post(that.form.attr('action'), that.form.serialize() + param, function(data) { 163 | data = $.parseJSON(data); 164 | if (data.success) { 165 | that.options.onAfterSave(); 166 | that.options.window.window('close'); 167 | that.options.grid.datagrid('reload'); 168 | } 169 | else { 170 | if (data.error) 171 | $.messager.alert(that.alertTitle, data.error, 'error'); 172 | else 173 | that.showErrors(data); 174 | } 175 | }); 176 | }, 177 | 178 | search: function(value) { 179 | var grid = this.options.grid; 180 | grid.datagrid('clearSelections'); 181 | grid.datagrid('options').queryParams = {'__q': value}; 182 | grid.datagrid('load'); 183 | } 184 | }; -------------------------------------------------------------------------------- /widgets/EuiForm.php: -------------------------------------------------------------------------------- 1 | widget('ext.yii-easyui.widgets.EuiValidateBox', $options, true); 17 | } 18 | 19 | /** 20 | * Renders a number field for a model attribute. 21 | * This method is a wrapper of {@link EuiNumberbox}. 22 | * @param CModel $model the data model 23 | * @param string $attribute the attribute 24 | * @param array $options widget options. 25 | * @return string the generated input field 26 | */ 27 | public function numberBox($model,$attribute,$options=array()) 28 | { 29 | CHtml::resolveNameID($model,$attribute,$options); 30 | return $this->widget('ext.yii-easyui.widgets.EuiNumberBox', $options, true); 31 | } 32 | 33 | /** 34 | * Renders a date field for a model attribute. 35 | * This method is a wrapper of {@link EuiDatebox}. 36 | * @param CModel $model the data model 37 | * @param string $attribute the attribute 38 | * @param array @param array $options widget options 39 | * @return string the generated input field 40 | */ 41 | public function dateBox($model,$attribute,$options=array()) 42 | { 43 | CHtml::resolveNameID($model,$attribute,$options); 44 | return $this->widget('ext.yii-easyui.widgets.EuiDateBox', $options, true); 45 | } 46 | 47 | /** 48 | * Renders a datetime field for a model attribute. 49 | * This method is a wrapper of {@link EuiDatetimebox}. 50 | * @param CModel $model the data model 51 | * @param string $attribute the attribute 52 | * @param array @param array $options widget options 53 | * @return string the generated input field 54 | */ 55 | public function dateTimeBox($model,$attribute,$options=array()) 56 | { 57 | CHtml::resolveNameID($model,$attribute,$options); 58 | return $this->widget('ext.yii-easyui.widgets.EuiDatetimeBox', $options, true); 59 | } 60 | 61 | /** 62 | * Renders a numberspinner field for a model attribute. 63 | * This method is a wrapper of {@link EuiNumberspinner}. 64 | * @param CModel $model the data model 65 | * @param string $attribute the attribute 66 | * @param array @param array $options widget options 67 | * @return string the generated input field 68 | */ 69 | public function numberSpinner($model,$attribute,$options=array()) 70 | { 71 | CHtml::resolveNameID($model,$attribute,$options); 72 | return $this->widget('ext.yii-easyui.widgets.EuiNumberSpinner', $options, true); 73 | } 74 | 75 | /** 76 | * Renders a datespinner field for a model attribute. 77 | * This method is a wrapper of {@link EuiTimespinner}. 78 | * @param CModel $model the data model 79 | * @param string $attribute the attribute 80 | * @param array @param array $options widget options 81 | * @return string the generated input field 82 | */ 83 | public function timeSpinner($model,$attribute,$options=array()) 84 | { 85 | CHtml::resolveNameID($model,$attribute,$options); 86 | return $this->widget('ext.yii-easyui.widgets.EuiTimeSpinner', $options, true); 87 | } 88 | 89 | /** 90 | * Renders a combobox field for a model attribute. 91 | * This method is a wrapper of {@link EuiNumberspinner}. 92 | * @param CModel $model the data model 93 | * @param string $attribute the attribute 94 | * @param array @param array $options widget options 95 | * @return string the generated input field 96 | */ 97 | public function comboBox($model,$attribute,$options=array()) 98 | { 99 | CHtml::resolveNameID($model,$attribute,$options); 100 | return $this->widget('ext.yii-easyui.widgets.EuiComboBox', $options, true); 101 | } 102 | 103 | /** 104 | * Renders a combogrid field for a model attribute. 105 | * This method is a wrapper of {@link EuiNumberspinner}. 106 | * @param CModel $model the data model 107 | * @param string $attribute the attribute 108 | * @param array @param array $options widget options 109 | * @return string the generated input field 110 | */ 111 | public function comboGrid($model,$attribute,$options=array()) 112 | { 113 | CHtml::resolveNameID($model,$attribute,$options); 114 | return $this->widget('ext.yii-easyui.widgets.EuiComboGrid', $options, true); 115 | } 116 | 117 | /** 118 | * Renders a combogrid field for a model attribute. 119 | * This method is a wrapper of {@link EuiNumberspinner}. 120 | * @param CModel $model the data model 121 | * @param string $attribute the attribute 122 | * @param array @param array $options widget options 123 | * @return string the generated input field 124 | */ 125 | public function comboTree($model,$attribute,$options=array()) 126 | { 127 | CHtml::resolveNameID($model,$attribute,$options); 128 | return $this->widget('ext.yii-easyui.widgets.EuiComboTree', $options, true); 129 | } 130 | 131 | 132 | public function init() 133 | { 134 | if(!isset($this->htmlOptions['id'])) 135 | $this->htmlOptions['id']=$this->id; 136 | else 137 | $this->id=$this->htmlOptions['id']; 138 | 139 | if($this->stateful) 140 | echo CHtml::statefulForm($this->action, $this->method, $this->htmlOptions); 141 | else 142 | echo CHtml::beginForm($this->action, $this->method, $this->htmlOptions); 143 | } 144 | 145 | /** 146 | * Runs the widget. 147 | * This registers the necessary javascript code and renders the form close tag. 148 | */ 149 | public function run() 150 | { 151 | echo CHtml::endForm(); 152 | 153 | if(is_array($this->focus)) 154 | $this->focus="#".CHtml::activeId($this->focus[0],$this->focus[1]); 155 | 156 | if($this->focus!==null) 157 | { 158 | Yii::app()->clientScript->registerScript('EuiForm#focus'," 159 | if(!window.location.hash) 160 | $('".$this->focus."').focus(); 161 | "); 162 | } 163 | 164 | } 165 | } 166 | 167 | ?> -------------------------------------------------------------------------------- /widgets/EuiDataGrid.php: -------------------------------------------------------------------------------- 1 | frozenColumns as $col) 160 | $cols[] = array($col->toArray(false)); 161 | 162 | return $cols; 163 | } 164 | 165 | /** 166 | * Render the columns for this datagrid 167 | */ 168 | protected function renderColumns() 169 | { 170 | echo CHtml::openTag('thead')."\n"; 171 | echo CHtml::openTag('tr')."\n"; 172 | 173 | foreach ($this->columns as $col) 174 | echo CHtml::Tag('th', $col->toOptions(), $col->title)."\n"; 175 | 176 | echo CHtml::closeTag('tr')."\n"; 177 | echo CHtml::closeTag('thead')."\n"; 178 | } 179 | 180 | /** 181 | * Create toolbar object and initialize them 182 | */ 183 | protected function initToolbar() 184 | { 185 | if (!empty($this->toolbar) && is_array($this->toolbar)) 186 | { 187 | $tbar = array(); 188 | foreach ($this->toolbar as $key => $value) 189 | { 190 | $item = $this->prepareConfig($value, 'EuiLinkButton'); 191 | $item = Yii::createComponent($item, $this); 192 | $item->init(); 193 | 194 | $cfg = $item->toArray(); 195 | $cfg['text'] = $item->text; 196 | $tbar[$key] = $cfg; 197 | } 198 | $this->toolbar = "js:".CJavaScript::encode($tbar); 199 | } 200 | } 201 | 202 | /** 203 | * Creates columns and frozenColumns objects and initializes them. 204 | */ 205 | public function init() 206 | { 207 | $this->addInvalidOptions('columns'); 208 | $this->initToolbar(); 209 | $this->columns = $this->initCollection($this->columns, 'EuiDataColumn'); 210 | $this->frozenColumns = $this->initCollection($this->frozenColumns, 'EuiDataColumn'); 211 | //parent::init(); 212 | } 213 | 214 | /** 215 | * Run this widget. 216 | * This method registers necessary javascript and renders the needed HTML code. 217 | */ 218 | public function run() 219 | { 220 | $options = $this->toOptions(); 221 | $config = array(); 222 | 223 | if (!empty($this->frozenColumns)) 224 | $config['frozenColumns'] = $this->frozenColumnsToArray(); 225 | 226 | if (isset($this->loadFilter)) 227 | { 228 | $config['loadFilter'] = 'js:'.$this->loadFilter; 229 | unset($options['loadFilter']); 230 | } 231 | 232 | if (!empty($config)) 233 | { 234 | $script = EuiJavaScript::encodeId($this->id).".datagrid(\n"; 235 | $script .= CJavaScript::encode($config)."\n"; 236 | $script .= ");\n"; 237 | Yii::app()->getClientScript()->registerScript($this->getId(), $script); 238 | } 239 | 240 | echo CHtml::openTag('table', $options)."\n"; 241 | $this->renderColumns(); 242 | echo CHtml::closeTag('table')."\n"; 243 | } 244 | } 245 | 246 | ?> --------------------------------------------------------------------------------