質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.19%

Jquery timepickerで別フィールドに+15分した値を表示したい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,253

memimemi

score 25

前提・実現したいこと

現在、jquery timepickerというタイムピッカープラグインを使用しております。
ライブラリ

このプラグインで2つのフィールドを選択するとお互いの時間に応じて、選択されている
時刻が変動するというコードを記述しております。

開始時刻は終了時刻より後に絶対ならないように動いています。

発生している問題・エラーメッセージ

現在のままのコードだと、開始時刻が終了時刻を上回って入力されると
開始時刻=終了時刻になるようになっており、出来れば終了時刻の15分前になるようにしたいです。

該当のソースコード

$(function () {
    $("#timepicker_b").timepicker({
        timeFormat: 'HH:mm',
        interval: 15,
        minTime: '8.3',
        maxTime: '19:00pm',
        dynamic: false,
        dropdown: true,
        scrollbar: true,

        change: function(time) {
          var b = $("#timepicker_a");
          var instance = b.timepicker();
          instance.option('minTime', time);
          instance.option('defaultTime', time);
          if (b.val() < this.val()) {
            b.val(this.val());
            $("#timepicker_a").prop('disabled', false);
          }
        }

    });

    $("#timepicker_a").timepicker({
        timeFormat: 'HH:mm',
        interval: 15,
        minTime: '8.3',
        maxTime: '19:00pm',
        dynamic: false,
        dropdown: true,
        scrollbar: true,

        change: function(time) {
          var a = $("#timepicker_b");
          var instance = a.timepicker();
          instance.option('defaultTime', time);

          if (a.val() > this.val()) {
            a.val(this.val());

            var b = $("#timepicker_a");
            var instance2 = b.timepicker();
            instance2.option('minTime', time);
            b.val(this.val());
          }
        }
    });
});

ご存知でしたらご教授いただけると幸いです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

こんにちは

timepicker  を初期化するときに与えるchange コールバックの引数 time には、Dateオブジェクトが入ってきます。これを踏まえてご質問の主旨としては、 

  • Dateオブジェクトであるtime で与えられる時刻に 15分を加えた時刻を求めて、さらに表示形式の文字列に変換するにはどうしたらいいか?

ということかなと思われました。以下、これに対する回答になります。

与えられた時刻に何らかの時間を加えたり引いたりしたいというときは、Moment.js の add やsubtractを使うとすっきり書けます。また、formatを使えば様々な形式の文字列へ変換できます。

例えば、Dateオブジェクトtime で与えられる時刻に 15分を加えた時刻を HH:mm 形式の文字列にしたいときは以下のようにすれば得られます。

moment(time).add(15, 'minutes').format('HH:mm')

サンプルを挙げておきます。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Q193894</title>
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/timepicker/1.3.5/jquery.timepicker.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/timepicker/1.3.5/jquery.timepicker.min.css">
    <style>
        input, div { font-size: 16pt; }
        span { color: red; }
    </style>
    <script>
      $(function(){

        $("#timepicker").timepicker({
          timeFormat: 'HH:mm',
          interval: 15,
          minTime: '8.3',
          maxTime: '19:00pm',
          dynamic: false,
          dropdown: true,
          scrollbar: true,

          change: function(time) {
            $('#after15min').text(moment(time).add(15, 'minutes').format('HH:mm'));
            $('#before30min').text(moment(time).subtract(30, 'minutes').format('HH:mm'));
            $('#after1andAHalfhours').text(moment(time).add(1.5, 'hours').format('HH:mm'));
          }
        });

      });
    </script>
</head>
<body>
    <input id='timepicker' />
    <ul>
        <li>15分後: <span id="after15min" /></li>
        <li>30分前: <span id="before30min" /></li>
        <li>1.5時間後: <span id="after1andAHalfhours" /></li>
    </ul>
</body>
</html>

上記のサンプルでは、timepicker から時刻を選ぶと、その時刻に対して、15分後、30分前、1.5時間(90分)後の時刻を求めて HH:mm形式の文字列として、以下のように表示されます。

イメージ説明

以上、参考になれば幸いです。

追記

上記で説明した Moment.js  を使って、開始時刻と終了時刻の入力に timepicker を使い、開始時刻が終了時刻を越えるような選択をした場合に、開始時刻を終了時刻の15分前に修正するサンプルを作成しました。

開始時刻:<input class="timepicker start" />
〜
終了時刻:<input class="timepicker end" />
    $(".timepicker").timepicker({
        timeFormat: 'HH:mm',
        interval: 15,
        minTime: '08:30',
        maxTime: '19:00',
        dynamic: false,
        dropdown: true,
        scrollbar: true,

        change: function(time) {
            const start = moment($('.start').val(), 'HH:mm');         
            const end = moment($('.end').val(), 'HH:mm');           
            if (start.isAfter(end)) {
                $('.start').val(end.subtract(15, 'minutes').format('HH:mm'));
            }
        }
    });

このサンプルでは、 開始時刻、終了時刻、いずれを変更した場合にも、開始時刻が終了時刻を越えていたら開始時刻を終了時刻の15分前に変更します。また、 change  コールバックに渡される引数time は使用しませんでした。

上記のように、Moment.js を使うと、ある時刻(日時)がある時刻(日時)の後であることの判定に、 isAfter というような、より自然な名前のメソッドで比較することができます。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/09 20:04

    素晴らしい回答で助かりました!
    やりたかったこと全て解決しました。

    Momentのドキュメントだけでかなりの量があるので、把握するまで大変そうです^^;
    現状はこちらで実装して今後勉強しつつリファクタ出来たらと思います。

    ありがとうございました!

    キャンセル

  • 2019/06/09 21:05

    どういたしまして!
    そういって頂けると回答者冥利に尽きます。

    それと、もうひとつだけお節介といいますか、以下をちょっとお遊びで作ってみました。

    https://jsfiddle.net/jun68ykt/j9ntco13/12/


    上記は、

    ・初期表示のときに、
      開始時刻 08:30, 終了時刻 19:00 が選ばれた状態で表示され、
      かつ、開始時刻の選択肢に、19:00 は表示されず、
      かつ、終了時刻の選択肢に、08:30 は表示されない。

    ・その後、終了時刻をたとえば 14:00 に変更してから、次に開始時刻を変更しようとすると、
     終了の15分前の 13:45 までしか選択肢に表示されない。

    ・次に、開始時刻として、13:00 を選ぶと、終了時刻の選択肢に13:15 よりも前は表示されない。

    という動作をさせるコードです。
    かなりトリッキーなコードですので、まくまで参考に留めて頂ければと思います。

    キャンセル

  • 2019/06/09 21:50

    このコードを自分のアプリに組み込んだらバリデーション不要でかなり便利です!
    ここから開始時間の下に○時間等のボタンを用意して押せばそれが終了時間に入るとかのプログラムも
    面白そうですね!

    ありがとうございます^^
    javascriptかなりお詳しいようで、もしよろしければ私の回答がついてない質問も見ていただけると嬉しいです・・・!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.19%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る