You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Yii2中DateRangePicker取值并自动计算日期时长的实现

嘿,我来帮你搞定这个Yii2表单里的日期范围自动计算需求!下面是一步步的实现方案,涵盖了日期选择后自动算时长,还能联动已有数据做运算:

Yii2 ActiveForm + DateRangePicker 自动计算时长&联动数据实现

1. 完善后端表单代码

首先补全你的DateRangePicker组件,确保绑定正确的模型属性,同时添加用于展示计算结果的字段(比如时长天数、总金额等):

<div class="pelaksana-form">
    <?php $form = ActiveForm::begin([
        'options'=>['id'=>'pelaksanaForm', 'data-pjax'=>true,]
    ]); ?>

    <label class="control-label">Range Perjalanan Dinas</label>
    <?= DatePicker::widget([
        'type' => DatePicker::TYPE_RANGE,
        'model' => $model,
        'attribute' => 'start_date',
        'attribute2' => 'end_date', // 对应模型的end_date属性
        'pluginOptions' => [
            'autoclose' => true,
            'format' => 'yyyy-mm-dd', // 统一日期格式,避免JS解析出错
            'todayHighlight' => true,
        ],
        'options' => [
            'class' => 'date-range-input',
        ]
    ]) ?>

    <!-- 自动计算的日期时长(天数) -->
    <?= $form->field($model, 'duration_days')->textInput([
        'readonly' => true,
        'placeholder' => '选择日期后自动计算'
    ])->label('时长(天数)') ?>

    <!-- 已有数据:每日补贴 -->
    <?= $form->field($model, 'daily_allowance')->textInput([
        'type' => 'number',
        'min' => 0
    ])->label('每日补贴') ?>

    <!-- 自动计算的总补贴 -->
    <?= $form->field($model, 'total_allowance')->textInput([
        'readonly' => true,
        'placeholder' => '自动计算总金额'
    ])->label('总补贴') ?>

    <div class="form-group">
        <?= Html::submitButton('Save', ['class' => 'btn btn-success']) ?>
    </div>

    <?php ActiveForm::end(); ?>
</div>

⚠️ 注意:你的模型(比如Pelaksana)需要包含start_date、end_date、duration_days、daily_allowance、total_allowance这些属性,若是临时字段可以定义为模型的虚拟属性。

2. 添加前端JavaScript逻辑

在视图文件底部添加JS代码,监听日期选择和已有数据的变化,自动完成计算:

<?php
$script = <<< JS
$(document).ready(function() {
    // 监听日期范围选择变化
    $('.date-range-input').on('change', function() {
        const startDate = $('#pelaksana-start_date').val();
        const endDate = $('#pelaksana-end_date').val();
        const dailyAllowance = parseFloat($('#pelaksana-daily_allowance').val()) || 0;

        if (startDate && endDate) {
            // 计算包含起止日期的天数差
            const start = new Date(startDate);
            const end = new Date(endDate);
            const timeDiff = Math.abs(end.getTime() - start.getTime());
            const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24)) + 1;

            // 填充时长字段
            $('#pelaksana-duration_days').val(daysDiff);
            // 联动计算总补贴
            $('#pelaksana-total_allowance').val((daysDiff * dailyAllowance).toFixed(2));
        } else {
            // 清空计算结果
            $('#pelaksana-duration_days').val('');
            $('#pelaksana-total_allowance').val('');
        }
    });

    // 监听每日补贴变化,重新计算总金额
    $('#pelaksana-daily_allowance').on('input', function() {
        const daysDiff = parseInt($('#pelaksana-duration_days').val()) || 0;
        const dailyAllowance = parseFloat($(this).val()) || 0;
        $('#pelaksana-total_allowance').val((daysDiff * dailyAllowance).toFixed(2));
    });
});
JS;
$this->registerJs($script, \yii\web\View::POS_END);
?>

3. 后端兜底验证(可选)

为了确保数据准确性,你可以在模型的beforeSave方法里添加后端计算逻辑,避免前端计算异常:

public function beforeSave($insert)
{
    if (parent::beforeSave($insert)) {
        if ($this->start_date && $this->end_date) {
            $start = new \DateTime($this->start_date);
            $end = new \DateTime($this->end_date);
            $interval = $start->diff($end);
            $this->duration_days = $interval->days + 1; // 包含起止日期
            $this->total_allowance = $this->duration_days * $this->daily_allowance;
        }
        return true;
    }
    return false;
}

小提示

  • 日期格式一定要统一,这里用yyyy-mm-dd是为了避免JS解析不同格式日期出现错误;
  • 如果需要计算小时/分钟级别的时长,可以调整JS里的时间差计算逻辑;
  • 因为表单启用了data-pjax,如果PJAX刷新后JS失效,可以监听pjax:success事件重新绑定逻辑。

内容的提问来源于stack exchange,提问作者Yanuar Ihsan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:55:50