You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
5.5 KiB

5 years ago
  1. <?php
  2. /*
  3. * The MIT License
  4. *
  5. * Copyright 2019 Blobt.
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. * THE SOFTWARE.
  24. */
  25. namespace blobt\grid;
  26. use Closure;
  27. use yii\base\InvalidConfigException;
  28. use yii\helpers\Html;
  29. use yii\helpers\Json;
  30. use blobt\grid\DataColumn;
  31. class CheckboxColumn extends Column {
  32. /**
  33. * @var string the name of the input checkbox input fields. This will be appended with `[]` to ensure it is an array.
  34. */
  35. public $name = 'selection';
  36. /**
  37. * @var array|\Closure the HTML attributes for checkboxes. This can either be an array of
  38. * attributes or an anonymous function ([[Closure]]) that returns such an array.
  39. * The signature of the function should be the following: `function ($model, $key, $index, $column)`.
  40. * Where `$model`, `$key`, and `$index` refer to the model, key and index of the row currently being rendered
  41. * and `$column` is a reference to the [[CheckboxColumn]] object.
  42. * A function may be used to assign different attributes to different rows based on the data in that row.
  43. * Specifically if you want to set a different value for the checkbox
  44. * you can use this option in the following way (in this example using the `name` attribute of the model):
  45. *
  46. * ```php
  47. * 'checkboxOptions' => function ($model, $key, $index, $column) {
  48. * return ['value' => $model->name];
  49. * }
  50. * ```
  51. *
  52. * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
  53. */
  54. public $checkboxOptions = [];
  55. /**
  56. * @var bool whether it is possible to select multiple rows. Defaults to `true`.
  57. */
  58. public $multiple = true;
  59. /**
  60. * @var string the css class that will be used to find the checkboxes.
  61. * @since 2.0.9
  62. */
  63. public $cssClass;
  64. /**
  65. * {@inheritdoc}
  66. * @throws \yii\base\InvalidConfigException if [[name]] is not set.
  67. */
  68. public function init() {
  69. parent::init();
  70. if (empty($this->name)) {
  71. throw new InvalidConfigException('The "name" property must be set.');
  72. }
  73. if (substr_compare($this->name, '[]', -2, 2)) {
  74. $this->name .= '[]';
  75. }
  76. $this->registerClientScript();
  77. }
  78. /**
  79. * Renders the header cell content.
  80. * The default implementation simply renders [[header]].
  81. * This method may be overridden to customize the rendering of the header cell.
  82. * @return string the rendering result
  83. */
  84. protected function renderHeaderCellContent() {
  85. if ($this->header !== null || !$this->multiple) {
  86. return parent::renderHeaderCellContent();
  87. }
  88. return Html::checkbox($this->getHeaderCheckBoxName(), false, ['class' => 'select-on-check-all']);
  89. }
  90. /**
  91. * {@inheritdoc}
  92. */
  93. protected function renderDataCellContent($model, $key, $index) {
  94. if ($this->content !== null) {
  95. return parent::renderDataCellContent($model, $key, $index);
  96. }
  97. if ($this->checkboxOptions instanceof Closure) {
  98. $options = call_user_func($this->checkboxOptions, $model, $key, $index, $this);
  99. } else {
  100. $options = $this->checkboxOptions;
  101. }
  102. if (!isset($options['value'])) {
  103. $options['value'] = is_array($key) ? Json::encode($key) : $key;
  104. }
  105. if ($this->cssClass !== null) {
  106. Html::addCssClass($options, $this->cssClass);
  107. }
  108. return Html::checkbox($this->name, !empty($options['checked']), $options);
  109. }
  110. /**
  111. * Returns header checkbox name.
  112. * @return string header checkbox name
  113. * @since 2.0.8
  114. */
  115. protected function getHeaderCheckBoxName() {
  116. $name = $this->name;
  117. if (substr_compare($name, '[]', -2, 2) === 0) {
  118. $name = substr($name, 0, -2);
  119. }
  120. if (substr_compare($name, ']', -1, 1) === 0) {
  121. $name = substr($name, 0, -1) . '_all]';
  122. } else {
  123. $name .= '_all';
  124. }
  125. return $name;
  126. }
  127. /**
  128. * Registers the needed JavaScript.
  129. * @since 2.0.8
  130. */
  131. public function registerClientScript() {
  132. $id = $this->grid->options['id'];
  133. $options = Json::encode([
  134. 'name' => $this->name,
  135. 'class' => $this->cssClass,
  136. 'multiple' => $this->multiple,
  137. 'checkAll' => $this->grid->showHeader ? $this->getHeaderCheckBoxName() : null,
  138. ]);
  139. $this->grid->getView()->registerJs("jQuery('#$id').yiiGridView('setSelectionColumn', $options);");
  140. }
  141. }