From c85a047f77c16b29776179c17d21669cb9bf850b Mon Sep 17 00:00:00 2001 From: akosse Date: Fri, 24 Jan 2020 12:05:34 +0300 Subject: [PATCH 1/5] console generate-user --- .../modules/card/controllers/UserCardController.php | 11 ----------- backend/modules/card/models/UserCard.php | 4 ++-- backend/modules/card/views/user-card/index.php | 1 - console/controllers/SqlController.php | 7 +++++++ 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/backend/modules/card/controllers/UserCardController.php b/backend/modules/card/controllers/UserCardController.php index 4469b0c..a8b3909 100755 --- a/backend/modules/card/controllers/UserCardController.php +++ b/backend/modules/card/controllers/UserCardController.php @@ -162,17 +162,6 @@ class UserCardController extends Controller return $this->redirect(['index']); } - /** - * Lists all UserCard models. - * @return mixed - */ - public function actionGenerate() - { - $massage = UserCard::generateUserForUserCard(); - return $this->render('generate', ['massage' => $massage]); - } - - /** * Finds the UserCard model based on its primary key value. * If the model is not found, a 404 HTTP exception will be thrown. diff --git a/backend/modules/card/models/UserCard.php b/backend/modules/card/models/UserCard.php index 1cf853c..13a289f 100755 --- a/backend/modules/card/models/UserCard.php +++ b/backend/modules/card/models/UserCard.php @@ -161,8 +161,8 @@ class UserCard extends \common\models\UserCard } } - if ($user_card_array) return "Данные успешно сгенерированы"; - else return "Нет данных для генерации"; + if ($user_card_array) return "data generated successfully"; + else return "no data to generate"; } public static function getParameter($params, $key) diff --git a/backend/modules/card/views/user-card/index.php b/backend/modules/card/views/user-card/index.php index d55159b..f3242bb 100755 --- a/backend/modules/card/views/user-card/index.php +++ b/backend/modules/card/views/user-card/index.php @@ -16,7 +16,6 @@ $this->params['breadcrumbs'][] = $this->title;

'btn btn-success']) ?> - 'btn btn-success']) ?>

db->createCommand($sql)->execute(); + echo "script completed successfully\n"; + } + + public function actionGenerateUser() + { + echo UserCard::generateUserForUserCard() . "\n"; } } \ No newline at end of file From c5227f1ee4c44009ce2e239ff3a9ca95aeb48c0b Mon Sep 17 00:00:00 2001 From: akosse Date: Fri, 24 Jan 2020 17:38:25 +0300 Subject: [PATCH 2/5] frontend user-card view --- .../controllers/AccessesController.php | 5 ++++ .../modules/card/views/user-card/_form.php | 3 --- .../modules/card/views/user-card/view.php | 23 ------------------- 3 files changed, 5 insertions(+), 26 deletions(-) diff --git a/backend/modules/accesses/controllers/AccessesController.php b/backend/modules/accesses/controllers/AccessesController.php index 54a59db..63f10bb 100755 --- a/backend/modules/accesses/controllers/AccessesController.php +++ b/backend/modules/accesses/controllers/AccessesController.php @@ -112,6 +112,11 @@ class AccessesController extends Controller return $this->redirect(['index']); } + public function actionCustomDelete($id) + { + + } + /** * Finds the Accesses model based on its primary key value. * If the model is not found, a 404 HTTP exception will be thrown. diff --git a/frontend/modules/card/views/user-card/_form.php b/frontend/modules/card/views/user-card/_form.php index e510d86..4cc1194 100755 --- a/frontend/modules/card/views/user-card/_form.php +++ b/frontend/modules/card/views/user-card/_form.php @@ -33,9 +33,6 @@ use yii\helpers\ArrayHelper; [ 'data' => ArrayHelper::map(Skill::find()->all(), 'id', 'name'), 'options' => ['placeholder' => '...', 'class' => 'form-control', 'multiple' => true], - 'pluginOptions' => [ - 'allowClear' => true - ], ] )->label('Навыки'); ?> diff --git a/frontend/modules/card/views/user-card/view.php b/frontend/modules/card/views/user-card/view.php index ee26b36..bc8d557 100755 --- a/frontend/modules/card/views/user-card/view.php +++ b/frontend/modules/card/views/user-card/view.php @@ -21,34 +21,11 @@ $this->title = 'Профиль'; 'attributes' => [ ['label' => 'ФИО', 'attribute' => 'fio',], ['label' => 'Email', 'attribute' => 'email',], - [ - 'attribute' => 'gender', - 'value' => $model->gendersText, - ], ['label' => 'Дата рождения', 'attribute' => 'dob',], - [ - 'attribute' => 'status', - 'value' => $model->status0->name, - ], [ 'attribute' => 'position_id', 'value' => (isset($model->position->name)) ? $model->position->name : 'Без должности', ], - [ - 'attribute' => 'Фото', - 'format' => 'raw', - 'value' => function ($model) { - return Html::tag('img', null, ['src' => $model->photo, 'width' => '100px']); - } - ], - [ - 'attribute' => 'Резюме', - 'format' => 'raw', - 'value' => function ($model) { - return Html::a('Скачать', $model->resume, ['target' => '_blank']); - } - ], - ['label' => 'Добвлен', 'attribute' => 'created_at',], ], ]); ?> From 75ccbff934abeeda88f468b451846fc5cd2cba05 Mon Sep 17 00:00:00 2001 From: akosse Date: Mon, 27 Jan 2020 10:30:26 +0300 Subject: [PATCH 3/5] accesses custom delete & validation --- .../accesses/controllers/AccessesController.php | 4 ++++ backend/modules/accesses/views/accesses/index.php | 12 +++++++++++- common/models/Accesses.php | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/backend/modules/accesses/controllers/AccessesController.php b/backend/modules/accesses/controllers/AccessesController.php index 63f10bb..966c5c5 100755 --- a/backend/modules/accesses/controllers/AccessesController.php +++ b/backend/modules/accesses/controllers/AccessesController.php @@ -114,7 +114,11 @@ class AccessesController extends Controller public function actionCustomDelete($id) { + $clean_id = str_replace('=', "", stristr($id, '=')); + UserCardAccesses::deleteAll(['accesses_id' => $clean_id]); + Accesses::deleteAll(['id' => $clean_id]); + return $this->redirect(['index']); } /** diff --git a/backend/modules/accesses/views/accesses/index.php b/backend/modules/accesses/views/accesses/index.php index 0507d75..ba31495 100755 --- a/backend/modules/accesses/views/accesses/index.php +++ b/backend/modules/accesses/views/accesses/index.php @@ -43,7 +43,17 @@ $this->params['breadcrumbs'][] = $this->title; // return $model->getProjectName(); // }, // ], - ['class' => 'yii\grid\ActionColumn'], + [ + 'class' => 'yii\grid\ActionColumn', + 'template' => '{view} {update} {delete}', + 'buttons' => [ + 'delete' => function ($data) { + return Html::a("", + ['/accesses/accesses/custom-delete', 'id' => $data]); + }, + ], + ], +// ['class' => 'yii\grid\ActionColumn'], ], ]); ?> diff --git a/common/models/Accesses.php b/common/models/Accesses.php index 3d49c97..d732767 100755 --- a/common/models/Accesses.php +++ b/common/models/Accesses.php @@ -40,6 +40,7 @@ class Accesses extends \yii\db\ActiveRecord [['info'], 'string'], [['_projects'], 'safe'], [['_users'], 'safe'], + [['name', 'login', 'password', 'link', 'project', 'info'], 'required'], ]; } From aa501900e4a465d445fd9c447f41c2e1592680ab Mon Sep 17 00:00:00 2001 From: akosse Date: Wed, 29 Jan 2020 11:26:01 +0300 Subject: [PATCH 4/5] closed admin panel --- backend/controllers/SiteController.php | 23 +- .../controllers/AccessesController.php | 10 + .../balance/controllers/BalanceController.php | 27 ++ .../controllers/CalendarController.php | 26 ++ .../card/controllers/UserCardController.php | 10 + .../company/controllers/CompanyController.php | 10 + .../modules/hh/controllers/HhController.php | 10 + .../hh/controllers/HhJobController.php | 10 + .../holiday/controllers/HolidayController.php | 10 + .../notes/controllers/NotesController.php | 26 ++ .../project/controllers/ProjectController.php | 10 + .../AdditionalFieldsController.php | 10 + .../controllers/PositionController.php | 10 + .../settings/controllers/SkillController.php | 10 + .../settings/controllers/StatusController.php | 10 + common/config/main.php | 6 + common/models/AuthAssignment.php | 59 ++++ common/models/UserCard.php | 1 + composer.json | 2 +- console/config/main.php | 6 + console/controllers/RbacController.php | 36 ++ frontend/models/SignupForm.php | 7 + .../sticky-table-headers/composer.json | 20 ++ .../js/jquery.stickytableheaders.js | 325 ++++++++++++++++++ .../js/jquery.stickytableheaders.min.js | 6 + node_modules/sticky-table-headers/license.txt | 20 ++ .../sticky-table-headers/package.json | 63 ++++ node_modules/sticky-table-headers/readme.md | 119 +++++++ package-lock.json | 11 + 29 files changed, 876 insertions(+), 17 deletions(-) create mode 100644 common/models/AuthAssignment.php create mode 100644 console/controllers/RbacController.php create mode 100644 node_modules/sticky-table-headers/composer.json create mode 100644 node_modules/sticky-table-headers/js/jquery.stickytableheaders.js create mode 100644 node_modules/sticky-table-headers/js/jquery.stickytableheaders.min.js create mode 100644 node_modules/sticky-table-headers/license.txt create mode 100644 node_modules/sticky-table-headers/package.json create mode 100644 node_modules/sticky-table-headers/readme.md create mode 100644 package-lock.json diff --git a/backend/controllers/SiteController.php b/backend/controllers/SiteController.php index 6d0a165..19fb2a2 100755 --- a/backend/controllers/SiteController.php +++ b/backend/controllers/SiteController.php @@ -6,6 +6,7 @@ use yii\web\Controller; use yii\filters\VerbFilter; use yii\filters\AccessControl; use common\models\LoginForm; +use yii\helpers\Url; /** * Site controller @@ -18,20 +19,6 @@ class SiteController extends Controller public function behaviors() { return [ - 'access' => [ - 'class' => AccessControl::className(), - 'rules' => [ - [ - 'actions' => ['login', 'error'], - 'allow' => true, - ], - [ - 'actions' => ['logout', 'index'], - 'allow' => true, - 'roles' => ['@'], - ], - ], - ], 'verbs' => [ 'class' => VerbFilter::className(), 'actions' => [ @@ -76,10 +63,14 @@ class SiteController extends Controller $model = new LoginForm(); if ($model->load(Yii::$app->request->post()) && $model->login()) { - return $this->goBack(); + if (\Yii::$app->user->can('secure')) { + return $this->goBack(); + } else { + Yii::$app->user->logout(); + return $this->redirect(Url::to('/card/user-card')); + } } else { $model->password = ''; - return $this->render('login', [ 'model' => $model, ]); diff --git a/backend/modules/accesses/controllers/AccessesController.php b/backend/modules/accesses/controllers/AccessesController.php index 966c5c5..513f530 100755 --- a/backend/modules/accesses/controllers/AccessesController.php +++ b/backend/modules/accesses/controllers/AccessesController.php @@ -8,6 +8,7 @@ use common\models\UserCardAccesses; use Yii; use common\models\Accesses; use app\modules\accesses\models\AccessesSearch; +use yii\filters\AccessControl; use yii\web\Controller; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; @@ -29,6 +30,15 @@ class AccessesController extends Controller 'delete' => ['POST'], ], ], + 'access' => [ + 'class' => AccessControl::className(), + 'rules' => [ + [ + 'allow' => true, + 'roles' => ['admin'], + ], + ], + ], ]; } diff --git a/backend/modules/balance/controllers/BalanceController.php b/backend/modules/balance/controllers/BalanceController.php index ed760b5..56332c7 100755 --- a/backend/modules/balance/controllers/BalanceController.php +++ b/backend/modules/balance/controllers/BalanceController.php @@ -10,12 +10,39 @@ use common\models\FieldsValueNew; use DateTime; use Yii; use yii\data\ActiveDataProvider; +use yii\filters\AccessControl; +use yii\filters\VerbFilter; use yii\web\Controller; use yii\web\NotFoundHttpException; use yii\db\Query; class BalanceController extends Controller { + /** + * {@inheritdoc} + */ + public function behaviors() + { + return [ + 'verbs' => [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => ['POST'], + ], + ], + 'access' => [ + 'class' => AccessControl::className(), + 'rules' => [ + [ + 'allow' => true, + 'roles' => ['admin'], + ], + ], + ], + ]; + } + + public function actionIndex() { $searchModel = new BalanceSearch(); diff --git a/backend/modules/calendar/controllers/CalendarController.php b/backend/modules/calendar/controllers/CalendarController.php index 99dbbaf..86ae7e3 100644 --- a/backend/modules/calendar/controllers/CalendarController.php +++ b/backend/modules/calendar/controllers/CalendarController.php @@ -6,6 +6,8 @@ use backend\modules\card\models\UserCardSearch; use common\classes\Debug; use Yii; use yii\data\ArrayDataProvider; +use yii\filters\AccessControl; +use yii\filters\VerbFilter; use yii\web\Controller; /** @@ -13,6 +15,30 @@ use yii\web\Controller; */ class CalendarController extends Controller { + /** + * {@inheritdoc} + */ + public function behaviors() + { + return [ + 'verbs' => [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => ['POST'], + ], + ], + 'access' => [ + 'class' => AccessControl::className(), + 'rules' => [ + [ + 'allow' => true, + 'roles' => ['admin'], + ], + ], + ], + ]; + } + /** * Renders the index view for the module * @return string diff --git a/backend/modules/card/controllers/UserCardController.php b/backend/modules/card/controllers/UserCardController.php index a8b3909..e748257 100755 --- a/backend/modules/card/controllers/UserCardController.php +++ b/backend/modules/card/controllers/UserCardController.php @@ -14,6 +14,7 @@ use backend\modules\card\models\UserCard; use backend\modules\card\models\UserCardSearch; use yii\data\ActiveDataProvider; use yii\db\Expression; +use yii\filters\AccessControl; use yii\web\Controller; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; @@ -35,6 +36,15 @@ class UserCardController extends Controller 'delete' => ['POST'], ], ], + 'access' => [ + 'class' => AccessControl::className(), + 'rules' => [ + [ + 'allow' => true, + 'roles' => ['admin'], + ], + ], + ], ]; } diff --git a/backend/modules/company/controllers/CompanyController.php b/backend/modules/company/controllers/CompanyController.php index 2ee9ff7..62587e7 100755 --- a/backend/modules/company/controllers/CompanyController.php +++ b/backend/modules/company/controllers/CompanyController.php @@ -7,6 +7,7 @@ use Yii; use backend\modules\company\models\Company; use backend\modules\company\models\CompanySearch; use yii\data\ActiveDataProvider; +use yii\filters\AccessControl; use yii\web\Controller; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; @@ -28,6 +29,15 @@ class CompanyController extends Controller 'delete' => ['POST'], ], ], + 'access' => [ + 'class' => AccessControl::className(), + 'rules' => [ + [ + 'allow' => true, + 'roles' => ['admin'], + ], + ], + ], ]; } diff --git a/backend/modules/hh/controllers/HhController.php b/backend/modules/hh/controllers/HhController.php index 971fd5e..e3d90fb 100755 --- a/backend/modules/hh/controllers/HhController.php +++ b/backend/modules/hh/controllers/HhController.php @@ -9,6 +9,7 @@ use Yii; use backend\modules\hh\models\Hh; use backend\modules\hh\models\HhSearch; use yii\data\ActiveDataProvider; +use yii\filters\AccessControl; use yii\web\Controller; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; @@ -30,6 +31,15 @@ class HhController extends Controller 'delete' => ['POST'], ], ], + 'access' => [ + 'class' => AccessControl::className(), + 'rules' => [ + [ + 'allow' => true, + 'roles' => ['admin'], + ], + ], + ], ]; } diff --git a/backend/modules/hh/controllers/HhJobController.php b/backend/modules/hh/controllers/HhJobController.php index be5cf6e..92d065d 100755 --- a/backend/modules/hh/controllers/HhJobController.php +++ b/backend/modules/hh/controllers/HhJobController.php @@ -6,6 +6,7 @@ use common\models\Hh; use Yii; use backend\modules\hh\models\HhJob; use backend\modules\hh\models\HhJobSearch; +use yii\filters\AccessControl; use yii\helpers\ArrayHelper; use yii\web\Controller; use yii\web\NotFoundHttpException; @@ -28,6 +29,15 @@ class HhJobController extends Controller 'delete' => ['POST'], ], ], + 'access' => [ + 'class' => AccessControl::className(), + 'rules' => [ + [ + 'allow' => true, + 'roles' => ['admin'], + ], + ], + ], ]; } diff --git a/backend/modules/holiday/controllers/HolidayController.php b/backend/modules/holiday/controllers/HolidayController.php index a2afc39..908a606 100755 --- a/backend/modules/holiday/controllers/HolidayController.php +++ b/backend/modules/holiday/controllers/HolidayController.php @@ -6,6 +6,7 @@ use backend\modules\holiday\models\Holiday; use backend\modules\holiday\models\HolidaySearch; use common\classes\Debug; use Yii; +use yii\filters\AccessControl; use yii\filters\VerbFilter; use yii\web\Controller; use yii\web\NotFoundHttpException; @@ -24,6 +25,15 @@ class HolidayController extends Controller 'delete' => ['POST'], ], ], + 'access' => [ + 'class' => AccessControl::className(), + 'rules' => [ + [ + 'allow' => true, + 'roles' => ['admin'], + ], + ], + ], ]; } diff --git a/backend/modules/notes/controllers/NotesController.php b/backend/modules/notes/controllers/NotesController.php index d42033e..74bff12 100755 --- a/backend/modules/notes/controllers/NotesController.php +++ b/backend/modules/notes/controllers/NotesController.php @@ -7,6 +7,8 @@ use Yii; use backend\modules\notes\models\Note; use common\models\FieldsValueNew; use yii\data\ActiveDataProvider; +use yii\filters\AccessControl; +use yii\filters\VerbFilter; use yii\web\Controller; use yii\web\NotFoundHttpException; @@ -15,6 +17,30 @@ use yii\web\NotFoundHttpException; */ class NotesController extends Controller { + /** + * {@inheritdoc} + */ + public function behaviors() + { + return [ + 'verbs' => [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => ['POST'], + ], + ], + 'access' => [ + 'class' => AccessControl::className(), + 'rules' => [ + [ + 'allow' => true, + 'roles' => ['admin'], + ], + ], + ], + ]; + } + /** * Renders the index view for the module * @return string diff --git a/backend/modules/project/controllers/ProjectController.php b/backend/modules/project/controllers/ProjectController.php index 1db532d..1cdd5c7 100755 --- a/backend/modules/project/controllers/ProjectController.php +++ b/backend/modules/project/controllers/ProjectController.php @@ -11,6 +11,7 @@ use Yii; use backend\modules\project\models\Project; use backend\modules\project\models\ProjectSearch; use yii\data\ActiveDataProvider; +use yii\filters\AccessControl; use yii\web\Controller; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; @@ -32,6 +33,15 @@ class ProjectController extends Controller 'delete' => ['POST'], ], ], + 'access' => [ + 'class' => AccessControl::className(), + 'rules' => [ + [ + 'allow' => true, + 'roles' => ['admin'], + ], + ], + ], ]; } diff --git a/backend/modules/settings/controllers/AdditionalFieldsController.php b/backend/modules/settings/controllers/AdditionalFieldsController.php index aac3dce..526880e 100755 --- a/backend/modules/settings/controllers/AdditionalFieldsController.php +++ b/backend/modules/settings/controllers/AdditionalFieldsController.php @@ -7,6 +7,7 @@ use common\models\UseField; use Yii; use backend\modules\settings\models\AdditionalFields; use backend\modules\settings\models\AdditionalFieldsSearch; +use yii\filters\AccessControl; use yii\helpers\ArrayHelper; use yii\web\Controller; use yii\web\NotFoundHttpException; @@ -29,6 +30,15 @@ class AdditionalFieldsController extends Controller 'delete' => ['POST'], ], ], + 'access' => [ + 'class' => AccessControl::className(), + 'rules' => [ + [ + 'allow' => true, + 'roles' => ['admin'], + ], + ], + ], ]; } diff --git a/backend/modules/settings/controllers/PositionController.php b/backend/modules/settings/controllers/PositionController.php index 0582978..c1093f6 100755 --- a/backend/modules/settings/controllers/PositionController.php +++ b/backend/modules/settings/controllers/PositionController.php @@ -5,6 +5,7 @@ namespace backend\modules\settings\controllers; use Yii; use backend\modules\settings\models\Position; use backend\modules\settings\models\PositionSearch; +use yii\filters\AccessControl; use yii\web\Controller; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; @@ -26,6 +27,15 @@ class PositionController extends Controller 'delete' => ['POST'], ], ], + 'access' => [ + 'class' => AccessControl::className(), + 'rules' => [ + [ + 'allow' => true, + 'roles' => ['admin'], + ], + ], + ], ]; } diff --git a/backend/modules/settings/controllers/SkillController.php b/backend/modules/settings/controllers/SkillController.php index 5bced31..3786a54 100755 --- a/backend/modules/settings/controllers/SkillController.php +++ b/backend/modules/settings/controllers/SkillController.php @@ -5,6 +5,7 @@ namespace backend\modules\settings\controllers; use Yii; use backend\modules\settings\models\Skill; use backend\modules\settings\models\SkillSearch; +use yii\filters\AccessControl; use yii\web\Controller; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; @@ -26,6 +27,15 @@ class SkillController extends Controller 'delete' => ['POST'], ], ], + 'access' => [ + 'class' => AccessControl::className(), + 'rules' => [ + [ + 'allow' => true, + 'roles' => ['admin'], + ], + ], + ], ]; } diff --git a/backend/modules/settings/controllers/StatusController.php b/backend/modules/settings/controllers/StatusController.php index f2da4c4..f184091 100755 --- a/backend/modules/settings/controllers/StatusController.php +++ b/backend/modules/settings/controllers/StatusController.php @@ -6,6 +6,7 @@ use common\models\UseStatus; use Yii; use backend\modules\settings\models\Status; use backend\modules\settings\models\StatusSearch; +use yii\filters\AccessControl; use yii\helpers\ArrayHelper; use yii\web\Controller; use yii\web\NotFoundHttpException; @@ -28,6 +29,15 @@ class StatusController extends Controller 'delete' => ['POST'], ], ], + 'access' => [ + 'class' => AccessControl::className(), + 'rules' => [ + [ + 'allow' => true, + 'roles' => ['admin'], + ], + ], + ], ]; } diff --git a/common/config/main.php b/common/config/main.php index 88ac995..0cf53ca 100755 --- a/common/config/main.php +++ b/common/config/main.php @@ -9,6 +9,12 @@ return [ 'cache' => [ 'class' => 'yii\caching\FileCache', ], + 'authManager' => [ + 'class' => 'yii\rbac\DbManager', +// 'itemFile' => '@common/components/rbac/items.php', +// 'assignmentFile' => '@common/components/rbac/assignments.php', +// 'ruleFile' => '@common/components/rbac/rules.php' + ], ], 'controllerMap' => [ 'elfinder' => [ diff --git a/common/models/AuthAssignment.php b/common/models/AuthAssignment.php new file mode 100644 index 0000000..2f61253 --- /dev/null +++ b/common/models/AuthAssignment.php @@ -0,0 +1,59 @@ + 64], + [['item_name', 'user_id'], 'unique', 'targetAttribute' => ['item_name', 'user_id']], + [['item_name'], 'exist', 'skipOnError' => true, 'targetClass' => AuthItem::className(), 'targetAttribute' => ['item_name' => 'name']], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'item_name' => 'Item Name', + 'user_id' => 'User ID', + 'created_at' => 'Created At', + ]; + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getItemName() + { + return $this->hasOne(AuthItem::className(), ['name' => 'item_name']); + } +} diff --git a/common/models/UserCard.php b/common/models/UserCard.php index d2f3555..abc862c 100755 --- a/common/models/UserCard.php +++ b/common/models/UserCard.php @@ -6,6 +6,7 @@ use common\classes\Debug; use Yii; use yii\behaviors\TimestampBehavior; use yii\db\Expression; +use yii\filters\AccessControl; use yii\helpers\ArrayHelper; /** diff --git a/composer.json b/composer.json index be9888b..4cc4779 100755 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "nkovacs/yii2-datetimepicker": "*", "mirocow/yii2-eav": "*", "kartik-v/yii2-widget-fileinput": "^1.0", - "2amigos/yii2-file-upload-widget": "~1.0" + "2amigos/yii2-file-upload-widget": "~1.0", }, "require-dev": { "yiisoft/yii2-debug": "~2.0.0", diff --git a/console/config/main.php b/console/config/main.php index a67be5c..16d8dcf 100755 --- a/console/config/main.php +++ b/console/config/main.php @@ -22,6 +22,12 @@ return [ ], ], 'components' => [ + 'user' => [ + 'identityClass' => 'common\models\User', + 'class' => 'yii\web\User', + 'enableSession' => false, + 'enableAutoLogin' => false, + ], 'log' => [ 'targets' => [ [ diff --git a/console/controllers/RbacController.php b/console/controllers/RbacController.php new file mode 100644 index 0000000..3e0fe75 --- /dev/null +++ b/console/controllers/RbacController.php @@ -0,0 +1,36 @@ +authManager; + + $secure = $auth->createPermission('secure'); + $secure->description = 'Admin panel'; + $auth->add($secure); + + $front = $auth->createPermission('front'); + $front->description = 'Frontend'; + $auth->add($front); + + $user = $auth->createRole('user'); + $auth->add($user); + $auth->addChild($user, $front); + + $admin = $auth->createRole('admin'); + $auth->add($admin); + $auth->addChild($admin, $secure); + $auth->addChild($admin, $user); + + $auth->assign($user, 2); + $auth->assign($admin, 1); + } +} \ No newline at end of file diff --git a/frontend/models/SignupForm.php b/frontend/models/SignupForm.php index a66a875..5eec1cc 100755 --- a/frontend/models/SignupForm.php +++ b/frontend/models/SignupForm.php @@ -1,6 +1,8 @@ email = $this->email; $user->setPassword($this->password); $user->generateAuthKey(); + $user->save(); + + $auth = Yii::$app->authManager; + $authorRole = $auth->getRole('user'); + $auth->assign($authorRole, $user->id); return $user->save() ? $user : null; } diff --git a/node_modules/sticky-table-headers/composer.json b/node_modules/sticky-table-headers/composer.json new file mode 100644 index 0000000..390ac5a --- /dev/null +++ b/node_modules/sticky-table-headers/composer.json @@ -0,0 +1,20 @@ +{ + "name": "jmosbech/sticky-table-headers", + "description": "jQuery sticky table headers plugin", + "keywords": [ + "jquery", + "sticky", + "table", + "headers" + ], + "homepage": "https://github.com/jmosbech/StickyTableHeaders", + "authors": [ + { + "name": "Jonas Mosbech" + } + ], + "support": { + "issues": "https://github.com/jmosbech/StickyTableHeaders/issues" + }, + "license": "MIT" +} diff --git a/node_modules/sticky-table-headers/js/jquery.stickytableheaders.js b/node_modules/sticky-table-headers/js/jquery.stickytableheaders.js new file mode 100644 index 0000000..4d742f1 --- /dev/null +++ b/node_modules/sticky-table-headers/js/jquery.stickytableheaders.js @@ -0,0 +1,325 @@ +/*! Copyright (c) Jonas Mosbech - https://github.com/jmosbech/StickyTableHeaders + MIT license info: https://github.com/jmosbech/StickyTableHeaders/blob/master/license.txt */ + +;(function ($, window, undefined) { + 'use strict'; + + var name = 'stickyTableHeaders', + id = 0, + defaults = { + fixedOffset: 0, + leftOffset: 0, + marginTop: 0, + objDocument: document, + objHead: 'head', + objWindow: window, + scrollableArea: window, + cacheHeaderHeight: false, + zIndex: 3 + }; + + function Plugin (el, options) { + // To avoid scope issues, use 'base' instead of 'this' + // to reference this class from internal events and functions. + var base = this; + + // Access to jQuery and DOM versions of element + base.$el = $(el); + base.el = el; + base.id = id++; + + // Listen for destroyed, call teardown + base.$el.bind('destroyed', + $.proxy(base.teardown, base)); + + // Cache DOM refs for performance reasons + base.$clonedHeader = null; + base.$originalHeader = null; + + // Cache header height for performance reasons + base.cachedHeaderHeight = null; + + // Keep track of state + base.isSticky = false; + base.hasBeenSticky = false; + base.leftOffset = null; + base.topOffset = null; + + base.init = function () { + base.setOptions(options); + + base.$el.each(function () { + var $this = $(this); + + // remove padding on to fix issue #7 + $this.css('padding', 0); + + base.$originalHeader = $('thead:first', this); + base.$clonedHeader = base.$originalHeader.clone(); + $this.trigger('clonedHeader.' + name, [base.$clonedHeader]); + + base.$clonedHeader.addClass('tableFloatingHeader'); + base.$clonedHeader.css({display: 'none', opacity: 0.0}); + + base.$originalHeader.addClass('tableFloatingHeaderOriginal'); + + base.$originalHeader.after(base.$clonedHeader); + + base.$printStyle = $(''); + base.$head.append(base.$printStyle); + }); + + base.$clonedHeader.find("input, select").attr("disabled", true); + + base.updateWidth(); + base.toggleHeaders(); + base.bind(); + }; + + base.destroy = function (){ + base.$el.unbind('destroyed', base.teardown); + base.teardown(); + }; + + base.teardown = function(){ + if (base.isSticky) { + base.$originalHeader.css('position', 'static'); + } + $.removeData(base.el, 'plugin_' + name); + base.unbind(); + + base.$clonedHeader.remove(); + base.$originalHeader.removeClass('tableFloatingHeaderOriginal'); + base.$originalHeader.css('visibility', 'visible'); + base.$printStyle.remove(); + + base.el = null; + base.$el = null; + }; + + base.bind = function(){ + base.$scrollableArea.on('scroll.' + name, base.toggleHeaders); + if (!base.isWindowScrolling) { + base.$window.on('scroll.' + name + base.id, base.setPositionValues); + base.$window.on('resize.' + name + base.id, base.toggleHeaders); + } + base.$scrollableArea.on('resize.' + name, base.toggleHeaders); + base.$scrollableArea.on('resize.' + name, base.updateWidth); + }; + + base.unbind = function(){ + // unbind window events by specifying handle so we don't remove too much + base.$scrollableArea.off('.' + name, base.toggleHeaders); + if (!base.isWindowScrolling) { + base.$window.off('.' + name + base.id, base.setPositionValues); + base.$window.off('.' + name + base.id, base.toggleHeaders); + } + base.$scrollableArea.off('.' + name, base.updateWidth); + }; + + // We debounce the functions bound to the scroll and resize events + base.debounce = function (fn, delay) { + var timer = null; + return function () { + var context = this, args = arguments; + clearTimeout(timer); + timer = setTimeout(function () { + fn.apply(context, args); + }, delay); + }; + }; + + base.toggleHeaders = base.debounce(function () { + if (base.$el) { + base.$el.each(function () { + var $this = $(this), + newLeft, + newTopOffset = base.isWindowScrolling ? ( + isNaN(base.options.fixedOffset) ? + base.options.fixedOffset.outerHeight() : + base.options.fixedOffset + ) : + base.$scrollableArea.offset().top + (!isNaN(base.options.fixedOffset) ? base.options.fixedOffset : 0), + offset = $this.offset(), + + scrollTop = base.$scrollableArea.scrollTop() + newTopOffset, + scrollLeft = base.$scrollableArea.scrollLeft(), + + headerHeight, + + scrolledPastTop = base.isWindowScrolling ? + scrollTop > offset.top : + newTopOffset > offset.top, + notScrolledPastBottom; + + if (scrolledPastTop) { + headerHeight = base.options.cacheHeaderHeight ? base.cachedHeaderHeight : base.$clonedHeader.height(); + notScrolledPastBottom = (base.isWindowScrolling ? scrollTop : 0) < + (offset.top + $this.height() - headerHeight - (base.isWindowScrolling ? 0 : newTopOffset)); + } + + if (scrolledPastTop && notScrolledPastBottom) { + newLeft = offset.left - scrollLeft + base.options.leftOffset; + base.$originalHeader.css({ + 'position': 'fixed', + 'margin-top': base.options.marginTop, + 'top': 0, + 'left': newLeft, + 'z-index': base.options.zIndex + }); + base.leftOffset = newLeft; + base.topOffset = newTopOffset; + base.$clonedHeader.css('display', ''); + if (!base.isSticky) { + base.isSticky = true; + // make sure the width is correct: the user might have resized the browser while in static mode + base.updateWidth(); + $this.trigger('enabledStickiness.' + name); + } + base.setPositionValues(); + } else if (base.isSticky) { + base.$originalHeader.css('position', 'static'); + base.$clonedHeader.css('display', 'none'); + base.isSticky = false; + base.resetWidth($('td,th', base.$clonedHeader), $('td,th', base.$originalHeader)); + $this.trigger('disabledStickiness.' + name); + } + }); + } + }, 0); + + base.setPositionValues = base.debounce(function () { + var winScrollTop = base.$window.scrollTop(), + winScrollLeft = base.$window.scrollLeft(); + if (!base.isSticky || + winScrollTop < 0 || winScrollTop + base.$window.height() > base.$document.height() || + winScrollLeft < 0 || winScrollLeft + base.$window.width() > base.$document.width()) { + return; + } + base.$originalHeader.css({ + 'top': base.topOffset - (base.isWindowScrolling ? 0 : winScrollTop), + 'left': base.leftOffset - (base.isWindowScrolling ? 0 : winScrollLeft) + }); + }, 0); + + base.updateWidth = base.debounce(function () { + if (!base.isSticky) { + return; + } + // Copy cell widths from clone + if (!base.$originalHeaderCells) { + base.$originalHeaderCells = $('th,td', base.$originalHeader); + } + if (!base.$clonedHeaderCells) { + base.$clonedHeaderCells = $('th,td', base.$clonedHeader); + } + var cellWidths = base.getWidth(base.$clonedHeaderCells); + base.setWidth(cellWidths, base.$clonedHeaderCells, base.$originalHeaderCells); + + // Copy row width from whole table + base.$originalHeader.css('width', base.$clonedHeader.width()); + + // If we're caching the height, we need to update the cached value when the width changes + if (base.options.cacheHeaderHeight) { + base.cachedHeaderHeight = base.$clonedHeader.height(); + } + }, 0); + + base.getWidth = function ($clonedHeaders) { + var widths = []; + $clonedHeaders.each(function (index) { + var width, $this = $(this); + + if ($this.css('box-sizing') === 'border-box') { + var boundingClientRect = $this[0].getBoundingClientRect(); + if(boundingClientRect.width) { + width = boundingClientRect.width; // #39: border-box bug + } else { + width = boundingClientRect.right - boundingClientRect.left; // ie8 bug: getBoundingClientRect() does not have a width property + } + } else { + var $origTh = $('th', base.$originalHeader); + if ($origTh.css('border-collapse') === 'collapse') { + if (window.getComputedStyle) { + width = parseFloat(window.getComputedStyle(this, null).width); + } else { + // ie8 only + var leftPadding = parseFloat($this.css('padding-left')); + var rightPadding = parseFloat($this.css('padding-right')); + // Needs more investigation - this is assuming constant border around this cell and it's neighbours. + var border = parseFloat($this.css('border-width')); + width = $this.outerWidth() - leftPadding - rightPadding - border; + } + } else { + width = $this.width(); + } + } + + widths[index] = width; + }); + return widths; + }; + + base.setWidth = function (widths, $clonedHeaders, $origHeaders) { + $clonedHeaders.each(function (index) { + var width = widths[index]; + $origHeaders.eq(index).css({ + 'min-width': width, + 'max-width': width + }); + }); + }; + + base.resetWidth = function ($clonedHeaders, $origHeaders) { + $clonedHeaders.each(function (index) { + var $this = $(this); + $origHeaders.eq(index).css({ + 'min-width': $this.css('min-width'), + 'max-width': $this.css('max-width') + }); + }); + }; + + base.setOptions = function (options) { + base.options = $.extend({}, defaults, options); + base.$window = $(base.options.objWindow); + base.$head = $(base.options.objHead); + base.$document = $(base.options.objDocument); + base.$scrollableArea = $(base.options.scrollableArea); + base.isWindowScrolling = base.$scrollableArea[0] === base.$window[0]; + }; + + base.updateOptions = function (options) { + base.setOptions(options); + // scrollableArea might have changed + base.unbind(); + base.bind(); + base.updateWidth(); + base.toggleHeaders(); + }; + + // Run initializer + base.init(); + } + + // A plugin wrapper around the constructor, + // preventing against multiple instantiations + $.fn[name] = function ( options ) { + return this.each(function () { + var instance = $.data(this, 'plugin_' + name); + if (instance) { + if (typeof options === 'string') { + instance[options].apply(instance); + } else { + instance.updateOptions(options); + } + } else if(options !== 'destroy') { + $.data(this, 'plugin_' + name, new Plugin( this, options )); + } + }); + }; + +})(jQuery, window); diff --git a/node_modules/sticky-table-headers/js/jquery.stickytableheaders.min.js b/node_modules/sticky-table-headers/js/jquery.stickytableheaders.min.js new file mode 100644 index 0000000..6579c01 --- /dev/null +++ b/node_modules/sticky-table-headers/js/jquery.stickytableheaders.min.js @@ -0,0 +1,6 @@ +/*! + * StickyTableHeaders 0.1.24 (2018-01-14 23:29) + * MIT licensed + * Copyright (C) Jonas Mosbech - https://github.com/jmosbech/StickyTableHeaders + */ +!function(e,i,t){"use strict";var o="stickyTableHeaders",n=0,d={fixedOffset:0,leftOffset:0,marginTop:0,objDocument:document,objHead:"head",objWindow:i,scrollableArea:i,cacheHeaderHeight:!1,zIndex:3};e.fn[o]=function(t){return this.each(function(){var l=e.data(this,"plugin_"+o);l?"string"==typeof t?l[t].apply(l):l.updateOptions(t):"destroy"!==t&&e.data(this,"plugin_"+o,new function(t,l){var a=this;a.$el=e(t),a.el=t,a.id=n++,a.$el.bind("destroyed",e.proxy(a.teardown,a)),a.$clonedHeader=null,a.$originalHeader=null,a.cachedHeaderHeight=null,a.isSticky=!1,a.hasBeenSticky=!1,a.leftOffset=null,a.topOffset=null,a.init=function(){a.setOptions(l),a.$el.each(function(){var i=e(this);i.css("padding",0),a.$originalHeader=e("thead:first",this),a.$clonedHeader=a.$originalHeader.clone(),i.trigger("clonedHeader."+o,[a.$clonedHeader]),a.$clonedHeader.addClass("tableFloatingHeader"),a.$clonedHeader.css({display:"none",opacity:0}),a.$originalHeader.addClass("tableFloatingHeaderOriginal"),a.$originalHeader.after(a.$clonedHeader),a.$printStyle=e(''),a.$head.append(a.$printStyle)}),a.$clonedHeader.find("input, select").attr("disabled",!0),a.updateWidth(),a.toggleHeaders(),a.bind()},a.destroy=function(){a.$el.unbind("destroyed",a.teardown),a.teardown()},a.teardown=function(){a.isSticky&&a.$originalHeader.css("position","static"),e.removeData(a.el,"plugin_"+o),a.unbind(),a.$clonedHeader.remove(),a.$originalHeader.removeClass("tableFloatingHeaderOriginal"),a.$originalHeader.css("visibility","visible"),a.$printStyle.remove(),a.el=null,a.$el=null},a.bind=function(){a.$scrollableArea.on("scroll."+o,a.toggleHeaders),a.isWindowScrolling||(a.$window.on("scroll."+o+a.id,a.setPositionValues),a.$window.on("resize."+o+a.id,a.toggleHeaders)),a.$scrollableArea.on("resize."+o,a.toggleHeaders),a.$scrollableArea.on("resize."+o,a.updateWidth)},a.unbind=function(){a.$scrollableArea.off("."+o,a.toggleHeaders),a.isWindowScrolling||(a.$window.off("."+o+a.id,a.setPositionValues),a.$window.off("."+o+a.id,a.toggleHeaders)),a.$scrollableArea.off("."+o,a.updateWidth)},a.debounce=function(e,i){var t=null;return function(){var o=this,n=arguments;clearTimeout(t),t=setTimeout(function(){e.apply(o,n)},i)}},a.toggleHeaders=a.debounce(function(){a.$el&&a.$el.each(function(){var i,t,n,d=e(this),l=a.isWindowScrolling?isNaN(a.options.fixedOffset)?a.options.fixedOffset.outerHeight():a.options.fixedOffset:a.$scrollableArea.offset().top+(isNaN(a.options.fixedOffset)?0:a.options.fixedOffset),s=d.offset(),r=a.$scrollableArea.scrollTop()+l,c=a.$scrollableArea.scrollLeft(),f=a.isWindowScrolling?r>s.top:l>s.top;f&&(t=a.options.cacheHeaderHeight?a.cachedHeaderHeight:a.$clonedHeader.height(),n=(a.isWindowScrolling?r:0)a.$document.height()||i<0||i+a.$window.width()>a.$document.width()||a.$originalHeader.css({top:a.topOffset-(a.isWindowScrolling?0:e),left:a.leftOffset-(a.isWindowScrolling?0:i)})},0),a.updateWidth=a.debounce(function(){if(a.isSticky){a.$originalHeaderCells||(a.$originalHeaderCells=e("th,td",a.$originalHeader)),a.$clonedHeaderCells||(a.$clonedHeaderCells=e("th,td",a.$clonedHeader));var i=a.getWidth(a.$clonedHeaderCells);a.setWidth(i,a.$clonedHeaderCells,a.$originalHeaderCells),a.$originalHeader.css("width",a.$clonedHeader.width()),a.options.cacheHeaderHeight&&(a.cachedHeaderHeight=a.$clonedHeader.height())}},0),a.getWidth=function(t){var o=[];return t.each(function(t){var n,d=e(this);if("border-box"===d.css("box-sizing")){var l=d[0].getBoundingClientRect();n=l.width?l.width:l.right-l.left}else if("collapse"===e("th",a.$originalHeader).css("border-collapse"))if(i.getComputedStyle)n=parseFloat(i.getComputedStyle(this,null).width);else{var s=parseFloat(d.css("padding-left")),r=parseFloat(d.css("padding-right")),c=parseFloat(d.css("border-width"));n=d.outerWidth()-s-r-c}else n=d.width();o[t]=n}),o},a.setWidth=function(e,i,t){i.each(function(i){var o=e[i];t.eq(i).css({"min-width":o,"max-width":o})})},a.resetWidth=function(i,t){i.each(function(i){var o=e(this);t.eq(i).css({"min-width":o.css("min-width"),"max-width":o.css("max-width")})})},a.setOptions=function(i){a.options=e.extend({},d,i),a.$window=e(a.options.objWindow),a.$head=e(a.options.objHead),a.$document=e(a.options.objDocument),a.$scrollableArea=e(a.options.scrollableArea),a.isWindowScrolling=a.$scrollableArea[0]===a.$window[0]},a.updateOptions=function(e){a.setOptions(e),a.unbind(),a.bind(),a.updateWidth(),a.toggleHeaders()},a.init()}(this,t))})}}(jQuery,window); \ No newline at end of file diff --git a/node_modules/sticky-table-headers/license.txt b/node_modules/sticky-table-headers/license.txt new file mode 100644 index 0000000..a9da71c --- /dev/null +++ b/node_modules/sticky-table-headers/license.txt @@ -0,0 +1,20 @@ +Copyright (c) 2011 Jonas Mosbech + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/sticky-table-headers/package.json b/node_modules/sticky-table-headers/package.json new file mode 100644 index 0000000..1c3e293 --- /dev/null +++ b/node_modules/sticky-table-headers/package.json @@ -0,0 +1,63 @@ +{ + "_from": "sticky-table-headers", + "_id": "sticky-table-headers@0.1.24", + "_inBundle": false, + "_integrity": "sha1-euofB5HKOgKwhgzYhe11ehrL84E=", + "_location": "/sticky-table-headers", + "_phantomChildren": {}, + "_requested": { + "type": "tag", + "registry": true, + "raw": "sticky-table-headers", + "name": "sticky-table-headers", + "escapedName": "sticky-table-headers", + "rawSpec": "", + "saveSpec": null, + "fetchSpec": "latest" + }, + "_requiredBy": [ + "#USER", + "/" + ], + "_resolved": "https://registry.npmjs.org/sticky-table-headers/-/sticky-table-headers-0.1.24.tgz", + "_shasum": "7aea1f0791ca3a02b0860cd885ed757a1acbf381", + "_spec": "sticky-table-headers", + "_where": "/var/www/domains/guild", + "author": { + "name": "Jonas Mosbech", + "email": "https://github.com/jmosbech" + }, + "bugs": { + "url": "https://github.com/jmosbech/StickyTableHeaders/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "jQuery sticky table headers plugin", + "devDependencies": { + "grunt": "~1.0.1", + "grunt-bower-version": "^0.1.1", + "grunt-contrib-jshint": "~1.1.0", + "grunt-contrib-uglify": "~3.3.0" + }, + "homepage": "https://github.com/jmosbech/StickyTableHeaders#readme", + "keywords": [ + "jquery", + "sticky", + "table", + "headers", + "jquery-plugin", + "ecosystem:jquery" + ], + "license": "MIT", + "main": "js/jquery.stickytableheaders.js", + "name": "sticky-table-headers", + "repository": { + "type": "git", + "url": "git+https://github.com/jmosbech/StickyTableHeaders.git" + }, + "scripts": { + "build": "grunt" + }, + "unpkg": "js/jquery.stickytableheaders.min.js", + "version": "0.1.24" +} diff --git a/node_modules/sticky-table-headers/readme.md b/node_modules/sticky-table-headers/readme.md new file mode 100644 index 0000000..0a91908 --- /dev/null +++ b/node_modules/sticky-table-headers/readme.md @@ -0,0 +1,119 @@ +StickyTableHeaders +================== +So what's it good for? Well, let's say you want to display a long list of fairly uniform tabluar data, like [stock exchange listings](http://online.barrons.com/public/page/majormarket-nysecomposite-A.html) or [sport statistics](https://sports.yahoo.com/nfl/stats/weekly/?sortStatId=PASSING_YARDS&selectedTable=7) but you don't want your users to get lost in the data as they scroll down on the page. + +StickyTableHeaders to the rescue: By applying the StickyTableHeaders jQuery plugin to the table, the column headers will stick to the top of the viewport as you scroll down. + +Go ahead and [try out a demo](http://jsfiddle.net/jmosbech/stFcx/). + +The code is based on [this proof of concept](http://stackoverflow.com/questions/1030043/html-table-headers-always-visible-at-top-of-window-when-viewing-a-large-table/1041566#1041566). + +Installation +------------ +The best way to install is using [npm](https://www.npmjs.com/): + +```bash +npm install sticky-table-headers +``` + +or [Bower](http://bower.io/): + +```bash +bower install StickyTableHeaders +``` + +or by loading it directly from the [unpkg CDN](https://unpkg.com/sticky-table-headers): + +``` + +``` + +Usage +----- +Initializing the plugin is pretty straight forward: + +```js +$('table').stickyTableHeaders(); +``` + +### Tear down +To remove the plugin: + +```js +$('table').stickyTableHeaders('destroy'); +``` + +### Trigger an update manually +```js +$(window).trigger('resize.stickyTableHeaders'); +``` + +### Options +You can initialize the plugin with an options map to tweak the behavior. The following options are supported: + +#### `fixedOffset` +A number or jQuery object specifying how much the sticky header should be offset from the top of the page: + +```js +$('table').stickyTableHeaders({fixedOffset: $('#header')}); +``` + +#### `scrollableArea` +A DOM element or jQuery object. Allows you to overwrite which surrounding element is scrolling. Defaults to `window`. [Check this demo for an example](https://github.com/jmosbech/StickyTableHeaders/tree/master/demo/scrollable-div.html): + +```js +$('table').stickyTableHeaders({scrollableArea: $('.scrollable-area')}); +``` + +#### `cacheHeaderHeight` +Performance tweak: When set to `true` the plugin will only recalculate the height of the header cells when the width of the table changes. + +Default value: `false` + +```js +$('table').stickyTableHeaders({cacheHeaderHeight: true}); +``` + +#### z-index +The plugin uses z-index to make the thead overlay the body. You can override the z-index value by passing in a `zIndex` option: + +```js +$('table').stickyTableHeaders({zIndex: 999}); +``` + +### Reinitialize +As described in [pull request #33](https://github.com/jmosbech/StickyTableHeaders/pull/33) responsive pages might need to reinitialize the plugin when the user resizes his browser. This is can be done by calling the plugin with the new options: + +```js +$('table').stickyTableHeaders({fixedOffset: [new-offset]}); +``` + +### Events +The plugin triggers the following events on the targeted `
` element: + + - `clonedHeader.stickyTableHeaders`: When the header clone is created. + - `enabledStickiness.stickyTableHeaders`: When the sticky header is enabled. + - `disabledStickiness.stickyTableHeaders`: When the sticky header is disabled. + +Confused? +--------- + +If any of this is confusing, please check out the [/demo](https://github.com/jmosbech/StickyTableHeaders/tree/master/demo) folder. There are a couple of examples in there. E.g. you can see how to use it with Twitter Bootstrap. + +Known Issues +------------ +- Internet Explorer: You need to set the padding of the `
`s explicitly in the css in order to make the plugin work +- Internet Explorer: Adding horizontal margin to the table causes the header to be misaligned when scrolling. (Issue #10) +- Using the plugin together with [tablesorter](http://tablesorter.com/docs/) breaks in Internet Explorer 8 + + +Browser Support +--------------- +The plugin has been verified to work in: + +- Chrome 35 +- Firefox 29 +- Internet Explorer 8-11 +- Safari 5 + +NOTE: It does not work in Internet Explorer 7 (but it degrades nicely) diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..e4ee320 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,11 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "sticky-table-headers": { + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/sticky-table-headers/-/sticky-table-headers-0.1.24.tgz", + "integrity": "sha1-euofB5HKOgKwhgzYhe11ehrL84E=" + } + } +} From f647a4905c9af9a138640e48dc91fb8d923bccfc Mon Sep 17 00:00:00 2001 From: akosse Date: Wed, 29 Jan 2020 11:41:29 +0300 Subject: [PATCH 5/5] closed admin panel --- .../sticky-table-headers/composer.json | 20 -- .../js/jquery.stickytableheaders.js | 325 ------------------ .../js/jquery.stickytableheaders.min.js | 6 - node_modules/sticky-table-headers/license.txt | 20 -- .../sticky-table-headers/package.json | 63 ---- node_modules/sticky-table-headers/readme.md | 119 ------- 6 files changed, 553 deletions(-) delete mode 100644 node_modules/sticky-table-headers/composer.json delete mode 100644 node_modules/sticky-table-headers/js/jquery.stickytableheaders.js delete mode 100644 node_modules/sticky-table-headers/js/jquery.stickytableheaders.min.js delete mode 100644 node_modules/sticky-table-headers/license.txt delete mode 100644 node_modules/sticky-table-headers/package.json delete mode 100644 node_modules/sticky-table-headers/readme.md diff --git a/node_modules/sticky-table-headers/composer.json b/node_modules/sticky-table-headers/composer.json deleted file mode 100644 index 390ac5a..0000000 --- a/node_modules/sticky-table-headers/composer.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "jmosbech/sticky-table-headers", - "description": "jQuery sticky table headers plugin", - "keywords": [ - "jquery", - "sticky", - "table", - "headers" - ], - "homepage": "https://github.com/jmosbech/StickyTableHeaders", - "authors": [ - { - "name": "Jonas Mosbech" - } - ], - "support": { - "issues": "https://github.com/jmosbech/StickyTableHeaders/issues" - }, - "license": "MIT" -} diff --git a/node_modules/sticky-table-headers/js/jquery.stickytableheaders.js b/node_modules/sticky-table-headers/js/jquery.stickytableheaders.js deleted file mode 100644 index 4d742f1..0000000 --- a/node_modules/sticky-table-headers/js/jquery.stickytableheaders.js +++ /dev/null @@ -1,325 +0,0 @@ -/*! Copyright (c) Jonas Mosbech - https://github.com/jmosbech/StickyTableHeaders - MIT license info: https://github.com/jmosbech/StickyTableHeaders/blob/master/license.txt */ - -;(function ($, window, undefined) { - 'use strict'; - - var name = 'stickyTableHeaders', - id = 0, - defaults = { - fixedOffset: 0, - leftOffset: 0, - marginTop: 0, - objDocument: document, - objHead: 'head', - objWindow: window, - scrollableArea: window, - cacheHeaderHeight: false, - zIndex: 3 - }; - - function Plugin (el, options) { - // To avoid scope issues, use 'base' instead of 'this' - // to reference this class from internal events and functions. - var base = this; - - // Access to jQuery and DOM versions of element - base.$el = $(el); - base.el = el; - base.id = id++; - - // Listen for destroyed, call teardown - base.$el.bind('destroyed', - $.proxy(base.teardown, base)); - - // Cache DOM refs for performance reasons - base.$clonedHeader = null; - base.$originalHeader = null; - - // Cache header height for performance reasons - base.cachedHeaderHeight = null; - - // Keep track of state - base.isSticky = false; - base.hasBeenSticky = false; - base.leftOffset = null; - base.topOffset = null; - - base.init = function () { - base.setOptions(options); - - base.$el.each(function () { - var $this = $(this); - - // remove padding on to fix issue #7 - $this.css('padding', 0); - - base.$originalHeader = $('thead:first', this); - base.$clonedHeader = base.$originalHeader.clone(); - $this.trigger('clonedHeader.' + name, [base.$clonedHeader]); - - base.$clonedHeader.addClass('tableFloatingHeader'); - base.$clonedHeader.css({display: 'none', opacity: 0.0}); - - base.$originalHeader.addClass('tableFloatingHeaderOriginal'); - - base.$originalHeader.after(base.$clonedHeader); - - base.$printStyle = $(''); - base.$head.append(base.$printStyle); - }); - - base.$clonedHeader.find("input, select").attr("disabled", true); - - base.updateWidth(); - base.toggleHeaders(); - base.bind(); - }; - - base.destroy = function (){ - base.$el.unbind('destroyed', base.teardown); - base.teardown(); - }; - - base.teardown = function(){ - if (base.isSticky) { - base.$originalHeader.css('position', 'static'); - } - $.removeData(base.el, 'plugin_' + name); - base.unbind(); - - base.$clonedHeader.remove(); - base.$originalHeader.removeClass('tableFloatingHeaderOriginal'); - base.$originalHeader.css('visibility', 'visible'); - base.$printStyle.remove(); - - base.el = null; - base.$el = null; - }; - - base.bind = function(){ - base.$scrollableArea.on('scroll.' + name, base.toggleHeaders); - if (!base.isWindowScrolling) { - base.$window.on('scroll.' + name + base.id, base.setPositionValues); - base.$window.on('resize.' + name + base.id, base.toggleHeaders); - } - base.$scrollableArea.on('resize.' + name, base.toggleHeaders); - base.$scrollableArea.on('resize.' + name, base.updateWidth); - }; - - base.unbind = function(){ - // unbind window events by specifying handle so we don't remove too much - base.$scrollableArea.off('.' + name, base.toggleHeaders); - if (!base.isWindowScrolling) { - base.$window.off('.' + name + base.id, base.setPositionValues); - base.$window.off('.' + name + base.id, base.toggleHeaders); - } - base.$scrollableArea.off('.' + name, base.updateWidth); - }; - - // We debounce the functions bound to the scroll and resize events - base.debounce = function (fn, delay) { - var timer = null; - return function () { - var context = this, args = arguments; - clearTimeout(timer); - timer = setTimeout(function () { - fn.apply(context, args); - }, delay); - }; - }; - - base.toggleHeaders = base.debounce(function () { - if (base.$el) { - base.$el.each(function () { - var $this = $(this), - newLeft, - newTopOffset = base.isWindowScrolling ? ( - isNaN(base.options.fixedOffset) ? - base.options.fixedOffset.outerHeight() : - base.options.fixedOffset - ) : - base.$scrollableArea.offset().top + (!isNaN(base.options.fixedOffset) ? base.options.fixedOffset : 0), - offset = $this.offset(), - - scrollTop = base.$scrollableArea.scrollTop() + newTopOffset, - scrollLeft = base.$scrollableArea.scrollLeft(), - - headerHeight, - - scrolledPastTop = base.isWindowScrolling ? - scrollTop > offset.top : - newTopOffset > offset.top, - notScrolledPastBottom; - - if (scrolledPastTop) { - headerHeight = base.options.cacheHeaderHeight ? base.cachedHeaderHeight : base.$clonedHeader.height(); - notScrolledPastBottom = (base.isWindowScrolling ? scrollTop : 0) < - (offset.top + $this.height() - headerHeight - (base.isWindowScrolling ? 0 : newTopOffset)); - } - - if (scrolledPastTop && notScrolledPastBottom) { - newLeft = offset.left - scrollLeft + base.options.leftOffset; - base.$originalHeader.css({ - 'position': 'fixed', - 'margin-top': base.options.marginTop, - 'top': 0, - 'left': newLeft, - 'z-index': base.options.zIndex - }); - base.leftOffset = newLeft; - base.topOffset = newTopOffset; - base.$clonedHeader.css('display', ''); - if (!base.isSticky) { - base.isSticky = true; - // make sure the width is correct: the user might have resized the browser while in static mode - base.updateWidth(); - $this.trigger('enabledStickiness.' + name); - } - base.setPositionValues(); - } else if (base.isSticky) { - base.$originalHeader.css('position', 'static'); - base.$clonedHeader.css('display', 'none'); - base.isSticky = false; - base.resetWidth($('td,th', base.$clonedHeader), $('td,th', base.$originalHeader)); - $this.trigger('disabledStickiness.' + name); - } - }); - } - }, 0); - - base.setPositionValues = base.debounce(function () { - var winScrollTop = base.$window.scrollTop(), - winScrollLeft = base.$window.scrollLeft(); - if (!base.isSticky || - winScrollTop < 0 || winScrollTop + base.$window.height() > base.$document.height() || - winScrollLeft < 0 || winScrollLeft + base.$window.width() > base.$document.width()) { - return; - } - base.$originalHeader.css({ - 'top': base.topOffset - (base.isWindowScrolling ? 0 : winScrollTop), - 'left': base.leftOffset - (base.isWindowScrolling ? 0 : winScrollLeft) - }); - }, 0); - - base.updateWidth = base.debounce(function () { - if (!base.isSticky) { - return; - } - // Copy cell widths from clone - if (!base.$originalHeaderCells) { - base.$originalHeaderCells = $('th,td', base.$originalHeader); - } - if (!base.$clonedHeaderCells) { - base.$clonedHeaderCells = $('th,td', base.$clonedHeader); - } - var cellWidths = base.getWidth(base.$clonedHeaderCells); - base.setWidth(cellWidths, base.$clonedHeaderCells, base.$originalHeaderCells); - - // Copy row width from whole table - base.$originalHeader.css('width', base.$clonedHeader.width()); - - // If we're caching the height, we need to update the cached value when the width changes - if (base.options.cacheHeaderHeight) { - base.cachedHeaderHeight = base.$clonedHeader.height(); - } - }, 0); - - base.getWidth = function ($clonedHeaders) { - var widths = []; - $clonedHeaders.each(function (index) { - var width, $this = $(this); - - if ($this.css('box-sizing') === 'border-box') { - var boundingClientRect = $this[0].getBoundingClientRect(); - if(boundingClientRect.width) { - width = boundingClientRect.width; // #39: border-box bug - } else { - width = boundingClientRect.right - boundingClientRect.left; // ie8 bug: getBoundingClientRect() does not have a width property - } - } else { - var $origTh = $('th', base.$originalHeader); - if ($origTh.css('border-collapse') === 'collapse') { - if (window.getComputedStyle) { - width = parseFloat(window.getComputedStyle(this, null).width); - } else { - // ie8 only - var leftPadding = parseFloat($this.css('padding-left')); - var rightPadding = parseFloat($this.css('padding-right')); - // Needs more investigation - this is assuming constant border around this cell and it's neighbours. - var border = parseFloat($this.css('border-width')); - width = $this.outerWidth() - leftPadding - rightPadding - border; - } - } else { - width = $this.width(); - } - } - - widths[index] = width; - }); - return widths; - }; - - base.setWidth = function (widths, $clonedHeaders, $origHeaders) { - $clonedHeaders.each(function (index) { - var width = widths[index]; - $origHeaders.eq(index).css({ - 'min-width': width, - 'max-width': width - }); - }); - }; - - base.resetWidth = function ($clonedHeaders, $origHeaders) { - $clonedHeaders.each(function (index) { - var $this = $(this); - $origHeaders.eq(index).css({ - 'min-width': $this.css('min-width'), - 'max-width': $this.css('max-width') - }); - }); - }; - - base.setOptions = function (options) { - base.options = $.extend({}, defaults, options); - base.$window = $(base.options.objWindow); - base.$head = $(base.options.objHead); - base.$document = $(base.options.objDocument); - base.$scrollableArea = $(base.options.scrollableArea); - base.isWindowScrolling = base.$scrollableArea[0] === base.$window[0]; - }; - - base.updateOptions = function (options) { - base.setOptions(options); - // scrollableArea might have changed - base.unbind(); - base.bind(); - base.updateWidth(); - base.toggleHeaders(); - }; - - // Run initializer - base.init(); - } - - // A plugin wrapper around the constructor, - // preventing against multiple instantiations - $.fn[name] = function ( options ) { - return this.each(function () { - var instance = $.data(this, 'plugin_' + name); - if (instance) { - if (typeof options === 'string') { - instance[options].apply(instance); - } else { - instance.updateOptions(options); - } - } else if(options !== 'destroy') { - $.data(this, 'plugin_' + name, new Plugin( this, options )); - } - }); - }; - -})(jQuery, window); diff --git a/node_modules/sticky-table-headers/js/jquery.stickytableheaders.min.js b/node_modules/sticky-table-headers/js/jquery.stickytableheaders.min.js deleted file mode 100644 index 6579c01..0000000 --- a/node_modules/sticky-table-headers/js/jquery.stickytableheaders.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * StickyTableHeaders 0.1.24 (2018-01-14 23:29) - * MIT licensed - * Copyright (C) Jonas Mosbech - https://github.com/jmosbech/StickyTableHeaders - */ -!function(e,i,t){"use strict";var o="stickyTableHeaders",n=0,d={fixedOffset:0,leftOffset:0,marginTop:0,objDocument:document,objHead:"head",objWindow:i,scrollableArea:i,cacheHeaderHeight:!1,zIndex:3};e.fn[o]=function(t){return this.each(function(){var l=e.data(this,"plugin_"+o);l?"string"==typeof t?l[t].apply(l):l.updateOptions(t):"destroy"!==t&&e.data(this,"plugin_"+o,new function(t,l){var a=this;a.$el=e(t),a.el=t,a.id=n++,a.$el.bind("destroyed",e.proxy(a.teardown,a)),a.$clonedHeader=null,a.$originalHeader=null,a.cachedHeaderHeight=null,a.isSticky=!1,a.hasBeenSticky=!1,a.leftOffset=null,a.topOffset=null,a.init=function(){a.setOptions(l),a.$el.each(function(){var i=e(this);i.css("padding",0),a.$originalHeader=e("thead:first",this),a.$clonedHeader=a.$originalHeader.clone(),i.trigger("clonedHeader."+o,[a.$clonedHeader]),a.$clonedHeader.addClass("tableFloatingHeader"),a.$clonedHeader.css({display:"none",opacity:0}),a.$originalHeader.addClass("tableFloatingHeaderOriginal"),a.$originalHeader.after(a.$clonedHeader),a.$printStyle=e(''),a.$head.append(a.$printStyle)}),a.$clonedHeader.find("input, select").attr("disabled",!0),a.updateWidth(),a.toggleHeaders(),a.bind()},a.destroy=function(){a.$el.unbind("destroyed",a.teardown),a.teardown()},a.teardown=function(){a.isSticky&&a.$originalHeader.css("position","static"),e.removeData(a.el,"plugin_"+o),a.unbind(),a.$clonedHeader.remove(),a.$originalHeader.removeClass("tableFloatingHeaderOriginal"),a.$originalHeader.css("visibility","visible"),a.$printStyle.remove(),a.el=null,a.$el=null},a.bind=function(){a.$scrollableArea.on("scroll."+o,a.toggleHeaders),a.isWindowScrolling||(a.$window.on("scroll."+o+a.id,a.setPositionValues),a.$window.on("resize."+o+a.id,a.toggleHeaders)),a.$scrollableArea.on("resize."+o,a.toggleHeaders),a.$scrollableArea.on("resize."+o,a.updateWidth)},a.unbind=function(){a.$scrollableArea.off("."+o,a.toggleHeaders),a.isWindowScrolling||(a.$window.off("."+o+a.id,a.setPositionValues),a.$window.off("."+o+a.id,a.toggleHeaders)),a.$scrollableArea.off("."+o,a.updateWidth)},a.debounce=function(e,i){var t=null;return function(){var o=this,n=arguments;clearTimeout(t),t=setTimeout(function(){e.apply(o,n)},i)}},a.toggleHeaders=a.debounce(function(){a.$el&&a.$el.each(function(){var i,t,n,d=e(this),l=a.isWindowScrolling?isNaN(a.options.fixedOffset)?a.options.fixedOffset.outerHeight():a.options.fixedOffset:a.$scrollableArea.offset().top+(isNaN(a.options.fixedOffset)?0:a.options.fixedOffset),s=d.offset(),r=a.$scrollableArea.scrollTop()+l,c=a.$scrollableArea.scrollLeft(),f=a.isWindowScrolling?r>s.top:l>s.top;f&&(t=a.options.cacheHeaderHeight?a.cachedHeaderHeight:a.$clonedHeader.height(),n=(a.isWindowScrolling?r:0)a.$document.height()||i<0||i+a.$window.width()>a.$document.width()||a.$originalHeader.css({top:a.topOffset-(a.isWindowScrolling?0:e),left:a.leftOffset-(a.isWindowScrolling?0:i)})},0),a.updateWidth=a.debounce(function(){if(a.isSticky){a.$originalHeaderCells||(a.$originalHeaderCells=e("th,td",a.$originalHeader)),a.$clonedHeaderCells||(a.$clonedHeaderCells=e("th,td",a.$clonedHeader));var i=a.getWidth(a.$clonedHeaderCells);a.setWidth(i,a.$clonedHeaderCells,a.$originalHeaderCells),a.$originalHeader.css("width",a.$clonedHeader.width()),a.options.cacheHeaderHeight&&(a.cachedHeaderHeight=a.$clonedHeader.height())}},0),a.getWidth=function(t){var o=[];return t.each(function(t){var n,d=e(this);if("border-box"===d.css("box-sizing")){var l=d[0].getBoundingClientRect();n=l.width?l.width:l.right-l.left}else if("collapse"===e("th",a.$originalHeader).css("border-collapse"))if(i.getComputedStyle)n=parseFloat(i.getComputedStyle(this,null).width);else{var s=parseFloat(d.css("padding-left")),r=parseFloat(d.css("padding-right")),c=parseFloat(d.css("border-width"));n=d.outerWidth()-s-r-c}else n=d.width();o[t]=n}),o},a.setWidth=function(e,i,t){i.each(function(i){var o=e[i];t.eq(i).css({"min-width":o,"max-width":o})})},a.resetWidth=function(i,t){i.each(function(i){var o=e(this);t.eq(i).css({"min-width":o.css("min-width"),"max-width":o.css("max-width")})})},a.setOptions=function(i){a.options=e.extend({},d,i),a.$window=e(a.options.objWindow),a.$head=e(a.options.objHead),a.$document=e(a.options.objDocument),a.$scrollableArea=e(a.options.scrollableArea),a.isWindowScrolling=a.$scrollableArea[0]===a.$window[0]},a.updateOptions=function(e){a.setOptions(e),a.unbind(),a.bind(),a.updateWidth(),a.toggleHeaders()},a.init()}(this,t))})}}(jQuery,window); \ No newline at end of file diff --git a/node_modules/sticky-table-headers/license.txt b/node_modules/sticky-table-headers/license.txt deleted file mode 100644 index a9da71c..0000000 --- a/node_modules/sticky-table-headers/license.txt +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2011 Jonas Mosbech - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/sticky-table-headers/package.json b/node_modules/sticky-table-headers/package.json deleted file mode 100644 index 1c3e293..0000000 --- a/node_modules/sticky-table-headers/package.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "_from": "sticky-table-headers", - "_id": "sticky-table-headers@0.1.24", - "_inBundle": false, - "_integrity": "sha1-euofB5HKOgKwhgzYhe11ehrL84E=", - "_location": "/sticky-table-headers", - "_phantomChildren": {}, - "_requested": { - "type": "tag", - "registry": true, - "raw": "sticky-table-headers", - "name": "sticky-table-headers", - "escapedName": "sticky-table-headers", - "rawSpec": "", - "saveSpec": null, - "fetchSpec": "latest" - }, - "_requiredBy": [ - "#USER", - "/" - ], - "_resolved": "https://registry.npmjs.org/sticky-table-headers/-/sticky-table-headers-0.1.24.tgz", - "_shasum": "7aea1f0791ca3a02b0860cd885ed757a1acbf381", - "_spec": "sticky-table-headers", - "_where": "/var/www/domains/guild", - "author": { - "name": "Jonas Mosbech", - "email": "https://github.com/jmosbech" - }, - "bugs": { - "url": "https://github.com/jmosbech/StickyTableHeaders/issues" - }, - "bundleDependencies": false, - "deprecated": false, - "description": "jQuery sticky table headers plugin", - "devDependencies": { - "grunt": "~1.0.1", - "grunt-bower-version": "^0.1.1", - "grunt-contrib-jshint": "~1.1.0", - "grunt-contrib-uglify": "~3.3.0" - }, - "homepage": "https://github.com/jmosbech/StickyTableHeaders#readme", - "keywords": [ - "jquery", - "sticky", - "table", - "headers", - "jquery-plugin", - "ecosystem:jquery" - ], - "license": "MIT", - "main": "js/jquery.stickytableheaders.js", - "name": "sticky-table-headers", - "repository": { - "type": "git", - "url": "git+https://github.com/jmosbech/StickyTableHeaders.git" - }, - "scripts": { - "build": "grunt" - }, - "unpkg": "js/jquery.stickytableheaders.min.js", - "version": "0.1.24" -} diff --git a/node_modules/sticky-table-headers/readme.md b/node_modules/sticky-table-headers/readme.md deleted file mode 100644 index 0a91908..0000000 --- a/node_modules/sticky-table-headers/readme.md +++ /dev/null @@ -1,119 +0,0 @@ -StickyTableHeaders -================== -So what's it good for? Well, let's say you want to display a long list of fairly uniform tabluar data, like [stock exchange listings](http://online.barrons.com/public/page/majormarket-nysecomposite-A.html) or [sport statistics](https://sports.yahoo.com/nfl/stats/weekly/?sortStatId=PASSING_YARDS&selectedTable=7) but you don't want your users to get lost in the data as they scroll down on the page. - -StickyTableHeaders to the rescue: By applying the StickyTableHeaders jQuery plugin to the table, the column headers will stick to the top of the viewport as you scroll down. - -Go ahead and [try out a demo](http://jsfiddle.net/jmosbech/stFcx/). - -The code is based on [this proof of concept](http://stackoverflow.com/questions/1030043/html-table-headers-always-visible-at-top-of-window-when-viewing-a-large-table/1041566#1041566). - -Installation ------------- -The best way to install is using [npm](https://www.npmjs.com/): - -```bash -npm install sticky-table-headers -``` - -or [Bower](http://bower.io/): - -```bash -bower install StickyTableHeaders -``` - -or by loading it directly from the [unpkg CDN](https://unpkg.com/sticky-table-headers): - -``` - -``` - -Usage ------ -Initializing the plugin is pretty straight forward: - -```js -$('table').stickyTableHeaders(); -``` - -### Tear down -To remove the plugin: - -```js -$('table').stickyTableHeaders('destroy'); -``` - -### Trigger an update manually -```js -$(window).trigger('resize.stickyTableHeaders'); -``` - -### Options -You can initialize the plugin with an options map to tweak the behavior. The following options are supported: - -#### `fixedOffset` -A number or jQuery object specifying how much the sticky header should be offset from the top of the page: - -```js -$('table').stickyTableHeaders({fixedOffset: $('#header')}); -``` - -#### `scrollableArea` -A DOM element or jQuery object. Allows you to overwrite which surrounding element is scrolling. Defaults to `window`. [Check this demo for an example](https://github.com/jmosbech/StickyTableHeaders/tree/master/demo/scrollable-div.html): - -```js -$('table').stickyTableHeaders({scrollableArea: $('.scrollable-area')}); -``` - -#### `cacheHeaderHeight` -Performance tweak: When set to `true` the plugin will only recalculate the height of the header cells when the width of the table changes. - -Default value: `false` - -```js -$('table').stickyTableHeaders({cacheHeaderHeight: true}); -``` - -#### z-index -The plugin uses z-index to make the thead overlay the body. You can override the z-index value by passing in a `zIndex` option: - -```js -$('table').stickyTableHeaders({zIndex: 999}); -``` - -### Reinitialize -As described in [pull request #33](https://github.com/jmosbech/StickyTableHeaders/pull/33) responsive pages might need to reinitialize the plugin when the user resizes his browser. This is can be done by calling the plugin with the new options: - -```js -$('table').stickyTableHeaders({fixedOffset: [new-offset]}); -``` - -### Events -The plugin triggers the following events on the targeted `
` element: - - - `clonedHeader.stickyTableHeaders`: When the header clone is created. - - `enabledStickiness.stickyTableHeaders`: When the sticky header is enabled. - - `disabledStickiness.stickyTableHeaders`: When the sticky header is disabled. - -Confused? ---------- - -If any of this is confusing, please check out the [/demo](https://github.com/jmosbech/StickyTableHeaders/tree/master/demo) folder. There are a couple of examples in there. E.g. you can see how to use it with Twitter Bootstrap. - -Known Issues ------------- -- Internet Explorer: You need to set the padding of the `
`s explicitly in the css in order to make the plugin work -- Internet Explorer: Adding horizontal margin to the table causes the header to be misaligned when scrolling. (Issue #10) -- Using the plugin together with [tablesorter](http://tablesorter.com/docs/) breaks in Internet Explorer 8 - - -Browser Support ---------------- -The plugin has been verified to work in: - -- Chrome 35 -- Firefox 29 -- Internet Explorer 8-11 -- Safari 5 - -NOTE: It does not work in Internet Explorer 7 (but it degrades nicely)