From f2851d244a8d266ff2946cc795e43466558293bd Mon Sep 17 00:00:00 2001 From: zouyi Date: Sun, 8 May 2022 16:55:43 +0800 Subject: [PATCH] grid view work done: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1 特性:NAME、CODE支持下拉匹配搜索 2 特性:t_status用下拉列表筛选 3 特性:本页的50条数据已全部选中 选中所有符合条件数据 4 特性:所有符合条件的数据都已被选中 取消 --- components/GridView.php | 165 +++++++++++++++++++++++++++++ composer.json | 5 +- composer.lock | 132 ++++++++++++++++++++++- config/messages.php | 50 +++++++++ config/web.php | 9 ++ controllers/SupplierController.php | 110 ++++++++++++++----- helpers/ZHtml.php | 33 ++++++ messages/en/enumItem.php | 5 + views/supplier/_search.php | 34 ++++-- views/supplier/create.php | 20 ++++ views/supplier/index.php | 106 ++++++++++++++++-- 11 files changed, 621 insertions(+), 48 deletions(-) create mode 100644 components/GridView.php create mode 100644 config/messages.php create mode 100644 helpers/ZHtml.php create mode 100644 messages/en/enumItem.php create mode 100644 views/supplier/create.php diff --git a/components/GridView.php b/components/GridView.php new file mode 100644 index 0000000..bbbb3b2 --- /dev/null +++ b/components/GridView.php @@ -0,0 +1,165 @@ +{export}
{items}
{pager}'; + + + /** + * @var string the HTML content to be displayed as the export of the list view. + * If you do not want to show the export, you may set it with an empty string. + * + * The following tokens will be replaced with the corresponding values: + * + * - `{begin}`: the starting row number (1-based) currently being displayed + * - `{end}`: the ending row number (1-based) currently being displayed + * - `{count}`: the number of rows currently being displayed + * - `{totalCount}`: the total number of rows available + * - `{page}`: the page number (1-based) current being displayed + * - `{pageCount}`: the number of pages available + */ + public $export = true; + /** + * @var array the HTML attributes for the export of the list view. + * The "tag" element specifies the tag name of the export element and defaults to "div". + * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered. + */ + public $exportOptions = ['class' => 'export']; + public $summaryOptions = ['class' => 'summary float-left']; + + /** + * {@inheritdoc} + */ + public function renderSection($name) + { + switch ($name) { + case '{errors}': + return $this->renderErrors(); + case '{export}': + return $this->renderExport(); + default: + return parent::renderSection($name); + } + } + + public function renderExport() + { + $exportContent = $this->export; + if ($exportContent === false) { + return ''; + } + $exportOptions = $this->exportOptions; + $count = $this->dataProvider->getCount(); + $pagination = $this->dataProvider->getPagination(); + $tag = ArrayHelper::remove($exportOptions, 'tag', 'div'); + + if($pagination === false) { + $begin = $page = $pageCount = 1; + $end = $totalCount = $count; + } else { + $totalCount = $this->dataProvider->getTotalCount(); + $begin = $pagination->getPage() * $pagination->pageSize + 1; + $end = $begin + $count - 1; + if ($begin > $end) { + $begin = $end; + } + $page = $pagination->getPage() + 1; + $pageCount = $pagination->pageCount; + } + + $id = $this->options['id'] ?? 'grid'; + $exportAction = $this->options['exportUrl'] ?? Url::toRoute([Yii::$app->controller->id . '/export']); + $this->getView()->registerJs(" +$('[name=\'selection[]\']').on('change', function(){ + var CheckedLabel = jQuery('.checked-label'); + if(CheckedLabel.html() == null){ + $('
').prependTo($('#$id')); + } + jQuery('#ExportAllIsChecked').val(0); + var rows = jQuery('#$id').yiiGridView('getSelectedRows'); + $('.checked-label').html(rows.length + ' items selected'); +}); +$('.select-on-check-all').on('change', function(){ + var CheckedLabel = jQuery('.checked-label'); + if(CheckedLabel.html() == null){ + $('
').prependTo($('#$id')); + } + var rows = jQuery('#$id').yiiGridView('getSelectedRows'); + jQuery('#ExportAllIsChecked').val(0); + if($(this).prop('checked') == true) { + $('.checked-label').html(rows.length + ' items in this page selected.' + ' select all conversations that match this search'); + }else { + $('.checked-label').html('0 items selected'); + } +}); + +$( document ).on('click', '.select-all-data', function(){ + jQuery('#ExportAllIsChecked').val(1); + $('.checked-label').html('All conversations in this search have been selected.' + ' clear selection'); +}); +$( document ).on('click', '.unselect-all-data', function(){ + var rows = jQuery('#$id').yiiGridView('getSelectedRows'); + jQuery('#ExportAllIsChecked').val(0); + $('.checked-label').html(rows.length + ' items in this page selected.' + ' select all conversations that match this search'); +}); +$('#export-btn').on('click', function(){ + var rows = jQuery('#$id').yiiGridView('getSelectedRows'); + if(rows.length == 0) { + alert('no checked rows.') + return + } + var isChecked = jQuery('#ExportAllIsChecked').val(); + var url = '$exportAction'; + var jQform = $(\"\"); + jQform.attr(\"action\",url); + $('body').append(jQform); + var jQinput1 = $(\"\"); + jQinput1.attr(\"value\",JSON.stringify(rows)); + $(\"#csv-download\").append(jQinput1); + var jQinput2 = $(\"\"); + jQinput2.attr(\"value\",isChecked); + $('#csv-download').append(jQinput2); + jQform.submit(); +});",View::POS_READY); + + + $options = Json::encode([ + ]); + if ($exportContent == true) { + $exportContent = Html::button('Export', [ + 'class' => 'btn btn-primary export-btn', + 'id' => 'export-btn', + ]); + } + return Html::tag($tag, Yii::$app->getI18n()->format($exportContent, [ + 'begin' => $begin, + 'end' => $end, + 'count' => $count, + 'totalCount' => $totalCount, + 'page' => $page, + 'pageCount' => $pageCount, + ], Yii::$app->language), $exportOptions); + } + +} diff --git a/composer.json b/composer.json index 5838fb0..d11ae05 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,10 @@ "php": "^7.4.0", "yiisoft/yii2": "~2.0.45", "yiisoft/yii2-bootstrap4": "~2.0.10", - "yiisoft/yii2-swiftmailer": "~2.1.3" + "yiisoft/yii2-swiftmailer": "~2.1.3", + "yii2tech/csv-grid": "^1.0", + "yiisoft/yii2-jui": "^2.0", + "ext-json": "*" }, "require-dev": { "yiisoft/yii2-debug": "~2.1.0", diff --git a/composer.lock b/composer.lock index 63b9063..69608dc 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a973addecfa2040a73918abda938727c", + "content-hash": "3161671581c4988aa64ece68595d31b8", "packages": [ { "name": "bower-asset/inputmask", @@ -45,6 +45,27 @@ "MIT" ] }, + { + "name": "bower-asset/jquery-ui", + "version": "1.12.1", + "source": { + "type": "git", + "url": "git@github.com:components/jqueryui.git", + "reference": "44ecf3794cc56b65954cc19737234a3119d036cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/components/jqueryui/zipball/44ecf3794cc56b65954cc19737234a3119d036cc", + "reference": "44ecf3794cc56b65954cc19737234a3119d036cc" + }, + "require": { + "bower-asset/jquery": ">=1.6" + }, + "type": "bower-asset", + "license": [ + "MIT" + ] + }, { "name": "bower-asset/punycode", "version": "v1.3.2", @@ -851,6 +872,67 @@ ], "time": "2021-05-27T09:17:38+00:00" }, + { + "name": "yii2tech/csv-grid", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/yii2tech/csv-grid.git", + "reference": "6d10b2b7590affd95ae2bacf20562c24d59d0ece" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yii2tech/csv-grid/zipball/6d10b2b7590affd95ae2bacf20562c24d59d0ece", + "reference": "6d10b2b7590affd95ae2bacf20562c24d59d0ece", + "shasum": "" + }, + "require": { + "yiisoft/yii2": "~2.0.13" + }, + "require-dev": { + "phpunit/phpunit": "4.8.27 || ^5.0 || ^6.0" + }, + "type": "yii2-extension", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "yii2tech\\csvgrid\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Paul Klimov", + "email": "klimov.paul@gmail.com" + } + ], + "description": "Yii2 extension data export to CSV file", + "keywords": [ + "csv", + "export", + "large data", + "yii2" + ], + "funding": [ + { + "url": "https://github.com/klimov-paul", + "type": "github" + }, + { + "url": "https://www.patreon.com/klimov_paul", + "type": "patreon" + } + ], + "abandoned": true, + "time": "2020-03-04T11:17:11+00:00" + }, { "name": "yiisoft/yii2", "version": "2.0.45", @@ -1128,6 +1210,52 @@ ], "time": "2020-06-24T00:04:01+00:00" }, + { + "name": "yiisoft/yii2-jui", + "version": "2.0.7", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/yii2-jui.git", + "reference": "ce45c16d4fbbe7d1c516d8d0e8311e07f6138eed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/yii2-jui/zipball/ce45c16d4fbbe7d1c516d8d0e8311e07f6138eed", + "reference": "ce45c16d4fbbe7d1c516d8d0e8311e07f6138eed", + "shasum": "" + }, + "require": { + "bower-asset/jquery-ui": "~1.12.1", + "yiisoft/yii2": "~2.0.4" + }, + "type": "yii2-extension", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "yii\\jui\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Qiang Xue", + "email": "qiang.xue@gmail.com" + } + ], + "description": "The Jquery UI extension for the Yii framework", + "keywords": [ + "jQuery UI", + "yii2" + ], + "time": "2017-11-25T15:32:29+00:00" + }, { "name": "yiisoft/yii2-swiftmailer", "version": "2.1.3", @@ -5154,7 +5282,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=5.6.0" + "php": "^7.4.0" }, "platform-dev": [], "plugin-api-version": "1.1.0" diff --git a/config/messages.php b/config/messages.php new file mode 100644 index 0000000..fe5bbed --- /dev/null +++ b/config/messages.php @@ -0,0 +1,50 @@ + null, + 'interactive' => true, + 'help' => false, + 'silentExitOnException' => null, + 'sourcePath' => '@yii', + 'messagePath' => 'messages', + 'languages' => [ + 'en', + ], + 'translator' => [ + 'Yii::t', + '\\Yii::t', + ], + 'sort' => false, + 'overwrite' => true, + 'removeUnused' => false, + 'markUnused' => true, + 'except' => [ + '.*', + '/.*', + '/messages', + '/tests', + '/runtime', + '/vendor', + '/BaseYii.php', + ], + 'only' => [ + '*.php', + ], + 'format' => 'php', + 'db' => 'db', + 'sourceMessageTable' => '{{%source_message}}', + 'messageTable' => '{{%message}}', + 'catalog' => 'messages', + 'ignoreCategories' => [], + 'phpFileHeader' => '', + 'phpDocBlock' => null, +]; diff --git a/config/web.php b/config/web.php index 862f18c..f191cb1 100644 --- a/config/web.php +++ b/config/web.php @@ -12,6 +12,15 @@ '@npm' => '@vendor/npm-asset', ], 'components' => [ + 'i18n' => [ + 'translations' => [ + '*' => [ + 'class' => 'yii\i18n\PhpMessageSource', + 'sourceLanguage' => 'en', + 'basePath' => '@app/messages' + ], + ], + ], 'request' => [ // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation 'cookieValidationKey' => '6fCiHYlTgcst6OgiM_BGNedCKC0I2R9x', diff --git a/controllers/SupplierController.php b/controllers/SupplierController.php index c753c31..820abf9 100644 --- a/controllers/SupplierController.php +++ b/controllers/SupplierController.php @@ -4,15 +4,19 @@ use app\models\Supplier; use app\models\SupplierSearch; +use yii\data\ActiveDataProvider; +use yii\helpers\ArrayHelper; use yii\web\Controller; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; +use yii2tech\csvgrid\CsvGrid; /** * SupplierController implements the CRUD actions for Supplier model. */ class SupplierController extends Controller { + public $enableCsrfValidation = false; /** * @inheritDoc */ @@ -47,18 +51,44 @@ public function actionIndex() ]); } + public function actionSearchCode() + { + $listdata = SupplierSearch::find() + ->andFilterWhere(['like', 'code', $this->request->queryParams['query']]) + ->select(['code as value', 'code as label']) + ->distinct('code') + ->asArray() + ->all(); + + + return $this->asJson(['listdata' => $listdata]); + } + + public function actionSearchName() + { + $listdata = SupplierSearch::find() + ->andFilterWhere(['like', 'name', $this->request->queryParams['query']]) + ->select(['name as value', 'name as label']) + ->distinct('name') + ->asArray() + ->all(); + + + return $this->asJson(['listdata' => $listdata]); + } + /** * Displays a single Supplier model. * @param int $id ID * @return string * @throws NotFoundHttpException if the model cannot be found */ - public function actionView($id) - { - return $this->render('view', [ - 'model' => $this->findModel($id), - ]); - } +// public function actionView($id) +// { +// return $this->render('view', [ +// 'model' => $this->findModel($id), +// ]); +// } /** * Creates a new Supplier model. @@ -71,7 +101,7 @@ public function actionCreate() if ($this->request->isPost) { if ($model->load($this->request->post()) && $model->save()) { - return $this->redirect(['view', 'id' => $model->id]); + return $this->redirect(['index']); } } else { $model->loadDefaultValues(); @@ -89,18 +119,18 @@ public function actionCreate() * @return string|\yii\web\Response * @throws NotFoundHttpException if the model cannot be found */ - public function actionUpdate($id) - { - $model = $this->findModel($id); - - if ($this->request->isPost && $model->load($this->request->post()) && $model->save()) { - return $this->redirect(['view', 'id' => $model->id]); - } - - return $this->render('update', [ - 'model' => $model, - ]); - } +// public function actionUpdate($id) +// { +// $model = $this->findModel($id); +// +// if ($this->request->isPost && $model->load($this->request->post()) && $model->save()) { +// return $this->redirect(['view', 'id' => $model->id]); +// } +// +// return $this->render('update', [ +// 'model' => $model, +// ]); +// } /** * Deletes an existing Supplier model. @@ -109,12 +139,12 @@ public function actionUpdate($id) * @return \yii\web\Response * @throws NotFoundHttpException if the model cannot be found */ - public function actionDelete($id) - { - $this->findModel($id)->delete(); - - return $this->redirect(['index']); - } +// public function actionDelete($id) +// { +// $this->findModel($id)->delete(); +// +// return $this->redirect(['index']); +// } /** * Finds the Supplier model based on its primary key value. @@ -129,6 +159,34 @@ protected function findModel($id) return $model; } - throw new NotFoundHttpException(Yii::t('app', 'The requested page does not exist.')); + throw new NotFoundHttpException(\Yii::t('app', 'The requested page does not exist.')); + } + + public function actionExport() + { +// print_r($this->request->getBodyParams());exit; + $getAll = $this->request->getBodyParam('checkall', false); + $getIds = $this->request->getBodyParam('rows', ''); + $getIds = json_decode($getIds,true); + $name = $this->request->getBodyParam('name'); + $code = $this->request->getBodyParam('code'); + $t_status = $this->request->getBodyParam('t_status'); + + $query = SupplierSearch::find(); + $query->andFilterWhere(['like', 'name', $name]) + ->andFilterWhere(['like', 'code', $code]) + ->andFilterWhere(['like', 't_status', $t_status]); + if ($getAll != true) { + $query->andFilterWhere(['in', 'id', $getIds]); + } + if (empty($getIds)) { + throw new NotFoundHttpException(\Yii::t('app', 'The requested page does not exist.')); + } + $exporter = new CsvGrid([ + 'dataProvider' => new ActiveDataProvider([ + 'query' => $query, + ]), + ]); + return $exporter->export()->send(sprintf('suppliers%s.csv',date("YmdHis"))); } } diff --git a/helpers/ZHtml.php b/helpers/ZHtml.php new file mode 100644 index 0000000..85b380d --- /dev/null +++ b/helpers/ZHtml.php @@ -0,0 +1,33 @@ + + */ +class ZHtml extends Html +{ + public static function enumDropDownList($model, $attribute, $htmlOptions=array()) + { + return Html::activeDropDownList( $model, $attribute, self::enumItem($model, $attribute), $htmlOptions); + } + + public static function enumItem($model,$attribute) { + preg_match('/\((.*)\)/',$model->tableSchema->columns[$attribute]->dbType,$matches); + foreach(explode("','", $matches[1]) as $value) { + $value=str_replace("'",null,$value); + $values[$value]=\Yii::t('enumItem',$value); + } + return $values; + } +} diff --git a/messages/en/enumItem.php b/messages/en/enumItem.php new file mode 100644 index 0000000..18c2eae --- /dev/null +++ b/messages/en/enumItem.php @@ -0,0 +1,5 @@ + '', + 'hold' => '', +]; diff --git a/views/supplier/_search.php b/views/supplier/_search.php index d6e2daf..7fbe6fb 100644 --- a/views/supplier/_search.php +++ b/views/supplier/_search.php @@ -13,18 +13,36 @@ ['index'], 'method' => 'get', +// 'enableAjaxValidation'=>false, + 'fieldConfig' => [ + 'template' => "{label}\n
{input}
", +// 'labelOptions' => ['class' => 'col-lg-2'], + ], 'options' => [ - 'data-pjax' => 1 + 'class'=>'form-inline', + 'data-pjax' => 1, ], ]); ?> - field($model, 'id') ?> - - field($model, 'name') ?> - - field($model, 'code') ?> - - field($model, 't_status') ?> + field($model, 'id')->dropdownList([ + '1' => '<10', + '2' => '>10' + ], + ['prompt'=>'Select']) ?> + + field($model, 'name')->textInput([ + 'option' => ['maxlength' => true] + ]) ?> + + field($model, 'code')->textInput([ + 'option' => ['maxlength' => true] + ]) ?> + + field($model, 't_status')->dropDownList([ + 'ok' => 'ok', + 'hold' => 'hold' + ], + ['prompt'=>'Select']) ?>
'btn btn-primary']) ?> diff --git a/views/supplier/create.php b/views/supplier/create.php new file mode 100644 index 0000000..07e083d --- /dev/null +++ b/views/supplier/create.php @@ -0,0 +1,20 @@ +title = Yii::t('app', 'Create Supplier'); +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Suppliers'), 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +

title) ?>

+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/views/supplier/index.php b/views/supplier/index.php index a7fa0ea..510e5af 100644 --- a/views/supplier/index.php +++ b/views/supplier/index.php @@ -3,8 +3,9 @@ use yii\helpers\Html; use yii\helpers\Url; use yii\grid\ActionColumn; -use yii\grid\GridView; +use app\components\GridView; use yii\widgets\Pjax; + /* @var $this yii\web\View */ /* @var $searchModel app\models\SupplierSearch */ /* @var $dataProvider yii\data\ActiveDataProvider */ @@ -21,26 +22,109 @@

- render('_search', ['model' => $searchModel]); ?> + render('_search', ['model' => $searchModel]); ?> 'supplier-table', 'dataProvider' => $dataProvider, 'filterModel' => $searchModel, + 'exportOptions' => [], 'columns' => [ - ['class' => 'yii\grid\SerialColumn'], +// [ +// 'attribute' => '', +// 'format' => ['raw'], +// 'label' => "全/反选", +// 'header'=>"", +// 'value' => function ($data) { +// return ""; +// }, +// ], + [ + 'class' => \yii\grid\CheckboxColumn::class, +// 'label' => "全/反选", + 'headerOptions' => ['width' => '50','style'=>'cursor:pointer'], + 'contentOptions' => ['align'=>'center'], + ], 'id', - 'name', - 'code', - 't_status', [ - 'class' => ActionColumn::className(), - 'urlCreator' => function ($action, Supplier $model, $key, $index, $column) { - return Url::toRoute([$action, 'id' => $model->id]); - } + 'attribute' => 'name', + 'value' => 'name', + 'filter' => \yii\jui\AutoComplete::widget([ + 'model' => $searchModel, + 'attribute' => 'name', + 'clientOptions' => [ + 'minLength' => 2, + 'autoFill' => true, + 'source' => new \yii\web\JsExpression(' + function(request, response) { + jQuery.getJSON("'.Url::to(['supplier/search-name']).'", + {query: request.term}, function(data) { + var suggestions = []; + jQuery.each(data.listdata, function(index, ele) { + suggestions.push({ + label: ele.label, + value: ele.value + }); + }); + response(suggestions); + }); + }' + ), + 'select' => new \yii\web\JsExpression(' + function(event, ui) { + jQuery("#'.Html::getInputId($searchModel, 'name').'") + .val(ui.item.value); + jQuery("#supplier-table").yiiGridView("applyFilter"); + }' + ) + ] + ]), + ], + [ + 'attribute' => 'code', + 'value' => 'code', + 'filter' => \yii\jui\AutoComplete::widget([ + 'model' => $searchModel, + 'attribute' => 'code', + 'clientOptions' => [ + 'minLength' => 1, + 'autoFill' => true, + 'source' => new \yii\web\JsExpression(' + function(request, response) { + jQuery.getJSON("'.Url::to(['supplier/search-code']).'", + {query: request.term}, function(data) { + var suggestions = []; + jQuery.each(data.listdata, function(index, ele) { + suggestions.push({ + label: ele.label, + value: ele.value + }); + }); + response(suggestions); + }); + }' + ), + 'select' => new \yii\web\JsExpression(' + function(event, ui) { + jQuery("#'.Html::getInputId($searchModel, 'code').'") + .val(ui.item.value); + jQuery("#supplier-table").yiiGridView("applyFilter"); + }' + ) + ] + ]), + ], +// 'code', +// 't_status', + [ + 'attribute' => 't_status', + 'value' => 't_status', + 'filter' => \app\helpers\ZHtml::enumDropDownList($searchModel, 't_status'), ], ], - ]); ?> + ]); + ?>