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.

277 lines
7.8 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\widgets;
  26. use yii\widgets\InputWidget;
  27. use Yii;
  28. use yii\base\InvalidConfigException;
  29. use yii\helpers\ArrayHelper;
  30. use yii\helpers\Html;
  31. use yii\web\JsExpression;
  32. use blobt\helpers\DatetimeHelper;
  33. use blobt\web\DaterangeBootstrapAsset;
  34. use yii\helpers\Json;
  35. /**
  36. *
  37. *
  38. * @author Blobt
  39. * @email 380255922@qq.com
  40. * @created Aug 13, 2019
  41. */
  42. class DateRangePicker extends InputWidget {
  43. /**
  44. * @var boolean 是否需要把值做转义
  45. */
  46. public $encodeValue = true;
  47. /**
  48. * @var array input的html属性
  49. */
  50. public $options = [];
  51. /**
  52. * @var string label
  53. */
  54. public $label = "日期范围";
  55. /**
  56. * @var string 确定按钮显示内容
  57. */
  58. public $applyLabel = "确定";
  59. /**
  60. * @var string 关闭按钮显示内容
  61. */
  62. public $cancelLabel = "关闭";
  63. /**
  64. * @var string 自定义按钮显示内容
  65. */
  66. public $customRangeLabel = "自定义";
  67. /**
  68. * @var array 星期一到星期日的显示
  69. */
  70. public $daysOfWeek = ["", "", "", "", "", "", ""];
  71. /**
  72. * @var array 12个月份的显示
  73. */
  74. public $monthNames = ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"];
  75. /**
  76. * @var array 选择器的基础配置参数
  77. */
  78. protected $locale = [];
  79. /**
  80. * @var 快捷选择建
  81. */
  82. public $ranges = [];
  83. /**
  84. * @var string 选择器默认选中的开始日期
  85. */
  86. public $startDate;
  87. /**
  88. * @var string 选择器默认选中的结束日期
  89. */
  90. public $endDate;
  91. /**
  92. * @var string 左侧显示的图标
  93. */
  94. public $iconClass = "fa fa-calendar";
  95. /**
  96. * @var string 日期显示格式
  97. */
  98. public $format = "Y-m-d";
  99. /**
  100. * @var string 选择框打开的位置
  101. */
  102. public $opens = 'left';
  103. /**
  104. * @var bool 是否自动填入日期
  105. */
  106. public $autoFill = false;
  107. /**
  108. * @inheritdoc
  109. * @throws InvalidConfigException
  110. * @throws \ReflectionException
  111. */
  112. public function run() {
  113. $this->initSetting();
  114. $this->registerAsset();
  115. echo $this->renderInputHtml('text');
  116. }
  117. /**
  118. * @inheritdoc
  119. */
  120. public function init() {
  121. parent::init();
  122. }
  123. /**
  124. * 初始化小物件的配置
  125. */
  126. protected function initSetting() {
  127. //初始化日期格式
  128. if (empty($this->format)) {
  129. $this->format = Yii::$app->formatter->dateFormat;
  130. }
  131. $this->format = $this->convertDateFormat($this->format);
  132. //初始化基础配置
  133. $this->locale = [
  134. 'cancelLabel' => $this->cancelLabel,
  135. 'applyLabel' => $this->applyLabel,
  136. "customRangeLabel" => $this->customRangeLabel,
  137. "daysOfWeek" => $this->daysOfWeek,
  138. "monthNames" => $this->monthNames,
  139. "format" => $this->format
  140. ];
  141. //初始化快捷键
  142. $this->initRange();
  143. //关闭自动提示
  144. $this->options = ArrayHelper::merge($this->options, [
  145. "autocomplete" => "off",
  146. "class" => "form-control",
  147. "style" => "width:190px;"
  148. ]);
  149. }
  150. /**
  151. * 注册js和css
  152. */
  153. protected function registerAsset() {
  154. $view = $this->getView();
  155. DaterangeBootstrapAsset::register($view);
  156. $options = [
  157. "opens" => $this->opens,
  158. "autoUpdateInput" => $this->autoFill,
  159. "locale" => $this->locale,
  160. "ranges" => $this->ranges
  161. ];
  162. if (!empty($this->startDate)) {
  163. $options["startDate"] = new JsExpression("moment('{$this->startDate}')");
  164. }
  165. if (!empty($this->endDate)) {
  166. $options["endDate"] = new JsExpression("moment('{$this->endDate}')");
  167. }
  168. $jsOptions = Json::encode($options);
  169. $js = <<< SCRIPT
  170. $('#{$this->options['id']}').daterangepicker({$jsOptions});
  171. $('#{$this->options['id']}').on('apply.daterangepicker', function(ev, picker) {
  172. $(this).val(picker.startDate.format('{$this->format}') + ' ~ ' + picker.endDate.format('{$this->format}'));
  173. });
  174. $('#{$this->options['id']}').on('cancel.daterangepicker', function(ev, picker) {
  175. $(this).val('');
  176. });
  177. SCRIPT;
  178. $view->registerJs($js);
  179. }
  180. /**
  181. * 初始化快捷按键数组
  182. */
  183. protected function initRange() {
  184. $this->ranges = [
  185. '今天' => [new JsExpression("moment()"), new JsExpression("moment()")],
  186. '昨天' => [new JsExpression("moment().subtract(1, 'days')"), new JsExpression("moment().subtract(1, 'days')")],
  187. '最近7天' => [new JsExpression("moment().subtract(6, 'days')"), new JsExpression("moment()")],
  188. '最近30天' => [new JsExpression("moment().subtract(29, 'days')"), new JsExpression("moment()")],
  189. '本月' => [new JsExpression("moment().startOf('month')"), new JsExpression("moment().endOf('month')")],
  190. '上月' => [new JsExpression("moment().subtract(1, 'month').startOf('month')"), new JsExpression("moment().subtract(1, 'month').endOf('month')")]
  191. ];
  192. }
  193. /**
  194. * 转换php日期格式为Moment.js 日期格式
  195. * @param string $format PHP日期格式字符串
  196. * @return string
  197. */
  198. protected static function convertDateFormat($format) {
  199. $conversions = [
  200. // second (带有前导零)
  201. 's' => 'ss',
  202. // minute (带有前导零)
  203. 'i' => 'mm',
  204. // hour in 12-hour format (没带前导零)
  205. 'g' => 'h',
  206. // hour in 12-hour format (带有前导零)
  207. 'h' => 'hh',
  208. // hour in 24-hour format (没带前导零)
  209. 'G' => 'H',
  210. // hour in 24-hour format (带有前导零)
  211. 'H' => 'HH',
  212. // day of the week locale
  213. 'w' => 'e',
  214. // day of the week ISO
  215. 'W' => 'E',
  216. // day of month (没带前导零)
  217. 'j' => 'D',
  218. // day of month (带有前导零)
  219. 'd' => 'DD',
  220. // day name short
  221. 'D' => 'DDD',
  222. // day name long
  223. 'l' => 'DDDD',
  224. // month of year (没带前导零)
  225. 'n' => 'M',
  226. // month of year (带有前导零)
  227. 'm' => 'MM',
  228. // month name short
  229. 'M' => 'MMM',
  230. // month name long
  231. 'F' => 'MMMM',
  232. // year (2位年)
  233. 'y' => 'YY',
  234. // year (4位年)
  235. 'Y' => 'YYYY',
  236. // unix timestamp
  237. 'U' => 'X',
  238. ];
  239. return strtr($format, $conversions);
  240. }
  241. }