LoginSignup
5
3

More than 5 years have passed since last update.

lightning:input の DatePicker は入力可能な日を制限できない場合がある

Posted at

[祝GA] lightning:input の DatePicker は入力可能な日を制限できる という投稿をしておきながら、「お前は何を言ってるんだ?」という気がしなくもないですが、気付いてしまったのでメモしておきます:disappointed_relieved:

TL;DR

  • どんな場合?
    • Datepicker と他のフォーム (例えば SUBMIT ボタン) があるような場合
    • Datepicker にテキスト入力して SUBMIT すると、範囲外の日付を入力できてしまう (下の gif 参照)
  • 回避方法?
    • controller.js or helper.js で validation かなと

以下、時間がある人向け

どんな場合?

以下の gif を見ていただくと早いかと思いますが、Datepicker の入力範囲外 (グレーアウト) の 7/25 という値は、キーボード入力できてしまうのですね。。。
「範囲外は入力できないはず」と安心しきって SUBMIT ボタンのハンドラでバリデーションをかけていないと、範囲外の値が流れていってしまうことになります:cold_sweat:
before.gif

ちなみに、ソースは以下です。

<!-- コンポーネント -->
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes">

    <!-- body -->
    <div class="row">
        <h2 class="header">Datepicker</h2>
        <lightning:input type="date" aura:id="datepicker1" name="input1"
                         label="Date field with min and max values"
                         value="2018-07-10" min="2018-07-05" max="2018-07-20" />

        <!-- SUBMIT ボタン -->
        <div class="gutter"/>
        <lightning:button variant="brand" label="SUBMIT" onclick="{! c.handleClick }"/>

        <!-- SUBMIT ボタンクリックで日付を表示する -->
        <div class="gutter"/>               
        <div aura:id="msg">
            You entered: <ui:outputDate aura:id="oDate" value="" />
        </div>

    </div>

</aura:component>
// controller.js
({
  handleClick: function(cmp, event, helper) {
    // Datepicker の日付を取得して
    const value = cmp.find("datepicker1").get("v.value");
    // outputDate にセットする
    cmp.find("oDate").set("v.value", value);
  }
})
// style.css
.THIS {
    background-color: white;
    margin: 5rem;
    height: 25rem;
    padding: 2rem;
}

.THIS .gutter {
    margin-top: 2rem;
}

回避方法

lightning:inpu type="date"の属性でそれらしいものが見つからなかったので、地道にハンドラ (controller.js or helper.js) 内で validation が手っ取り早いかなと思います。

日付については moment.js (v2.22.2) のお世話になります。moment.min.js 16.4k を右クリックで保存して、静的リソースに momentjs のように入れました。

挙動はシンプルに「max を超えている場合は何もしない」ことにしました。

<!-- コンポーネント -->
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes">
    <!-- lib -->
    <ltng:require scripts="{!$Resource.momentjs}" />

    <!-- body -->
    <div class="row">
        <h2 class="header">Datepicker</h2>
        <lightning:input type="date" aura:id="datepicker1" name="input1"
                         label="Date field with min and max values"
                         value="2018-07-10" min="2018-07-05" max="2018-07-20" />

        <!-- SUBMIT ボタン -->
        <div class="gutter"/>
        <lightning:button variant="brand" label="SUBMIT" onclick="{! c.handleClick }"/>

        <!-- SUBMIT ボタンクリックで日付を表示する -->
        <div class="gutter"/>               
        <div aura:id="msg">
            You entered: <ui:outputDate aura:id="oDate" value="" />
        </div>

    </div>

</aura:component>
// controller.js
({
  handleClick: function(cmp, event, helper) {
    // 説明簡略化のため、max の値をここでも定義
    const maxDateObj = moment("2018-07-20");
    // 入力された日付を moment にセット
    const inputObj = moment(cmp.find("datepicker1").get("v.value"));

    // max を超えていないか判定
    if (maxDateObj.diff(inputObj) < 0) {
      // max 以降の日付が入力された場合、何もしない
      return;
    }

    // max 以内の日付であれば、反映する
    cmp.find("oDate").set("v.value", inputObj.format("YYYY-MM-DD"));
  }
})

after.gif

2018-07-25 を入力した場合は、SUBMIT ボタン下の You entered: に反映されないことが確認できました。

まとめ

max 以降の日付が入力された場合の挙動を制御することができました。min についても同様です。
将来的に今回のような部分までケアされると良いですね:sweat_smile:

蛇足

本投稿を書きながら思ったのですが業務では
「範囲外が入力された時点で SUBMIT ボタンを非活性にする」
などという要件も考えられますね。。。

Datepicker からフォーカスが外れた (onblur) 場合と、値が更新された場合 (onchange) を活用すれば実現できるのですが・・・長くなってしまったので、余力があればまたいつか:flushed:

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3