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

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

新規登録して質問してみよう
ただいま回答率
85.50%
jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

1回答

3696閲覧

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

memimemi

総合スコア25

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2019/06/08 12:31

前提・実現したいこと

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

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

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

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

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

該当のソースコード

jquery

1$(function () { 2 $("#timepicker_b").timepicker({ 3 timeFormat: 'HH:mm', 4 interval: 15, 5 minTime: '8.3', 6 maxTime: '19:00pm', 7 dynamic: false, 8 dropdown: true, 9 scrollbar: true, 10 11 change: function(time) { 12 var b = $("#timepicker_a"); 13 var instance = b.timepicker(); 14 instance.option('minTime', time); 15 instance.option('defaultTime', time); 16 if (b.val() < this.val()) { 17 b.val(this.val()); 18 $("#timepicker_a").prop('disabled', false); 19 } 20 } 21 22 }); 23 24 $("#timepicker_a").timepicker({ 25 timeFormat: 'HH:mm', 26 interval: 15, 27 minTime: '8.3', 28 maxTime: '19:00pm', 29 dynamic: false, 30 dropdown: true, 31 scrollbar: true, 32 33 change: function(time) { 34 var a = $("#timepicker_b"); 35 var instance = a.timepicker(); 36 instance.option('defaultTime', time); 37 38 if (a.val() > this.val()) { 39 a.val(this.val()); 40 41 var b = $("#timepicker_a"); 42 var instance2 = b.timepicker(); 43 instance2.option('minTime', time); 44 b.val(this.val()); 45 } 46 } 47 }); 48}); 49

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは

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

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

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

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

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

javascript

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

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

html

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <title>Q193894</title> 6 <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script> 7 <script src="https://cdnjs.cloudflare.com/ajax/libs/timepicker/1.3.5/jquery.timepicker.min.js"></script> 8 <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script> 9 <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/timepicker/1.3.5/jquery.timepicker.min.css"> 10 <style> 11 input, div { font-size: 16pt; } 12 span { color: red; } 13 </style> 14 <script> 15 $(function(){ 16 17 $("#timepicker").timepicker({ 18 timeFormat: 'HH:mm', 19 interval: 15, 20 minTime: '8.3', 21 maxTime: '19:00pm', 22 dynamic: false, 23 dropdown: true, 24 scrollbar: true, 25 26 change: function(time) { 27 $('#after15min').text(moment(time).add(15, 'minutes').format('HH:mm')); 28 $('#before30min').text(moment(time).subtract(30, 'minutes').format('HH:mm')); 29 $('#after1andAHalfhours').text(moment(time).add(1.5, 'hours').format('HH:mm')); 30 } 31 }); 32 33 }); 34 </script> 35</head> 36<body> 37 <input id='timepicker' /> 38 <ul> 39 <li>15分後: <span id="after15min" /></li> 40 <li>30分前: <span id="before30min" /></li> 41 <li>1.5時間後: <span id="after1andAHalfhours" /></li> 42 </ul> 43</body> 44</html>

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

イメージ説明

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

追記

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

html

1開始時刻:<input class="timepicker start" /> 23終了時刻:<input class="timepicker end" />

javascript

1 $(".timepicker").timepicker({ 2 timeFormat: 'HH:mm', 3 interval: 15, 4 minTime: '08:30', 5 maxTime: '19:00', 6 dynamic: false, 7 dropdown: true, 8 scrollbar: true, 9 10 change: function(time) { 11 const start = moment($('.start').val(), 'HH:mm'); 12 const end = moment($('.end').val(), 'HH:mm'); 13 if (start.isAfter(end)) { 14 $('.start').val(end.subtract(15, 'minutes').format('HH:mm')); 15 } 16 } 17 });

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

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

投稿2019/06/09 02:17

編集2019/06/09 07:36
jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

memimemi

2019/06/09 07:49

検証しておりまして、回答が遅くなりすみません。 まさに、私の望んでいる内容でサンプルまでつけていただきありがとうございました。 教えていただいたサンプルから、最後の一文のところを if (start.isAfter(end)) { $('.end').val(start.add(15, 'minutes').format('HH:mm')); } に書き換えたら一番理想の形となりました! ですが、一番最初にページを開いたタイミングで開始時間を変更すると if (start.isAfter(end)) が発動しなかったので現在検証中です。
jun68ykt

2019/06/09 08:06

どういたしまして。 > まさに、私の望んでいる内容 とのことでよかったです。 > 一番最初にページを開いたタイミングで開始時間を変更 すると、終了時刻には何も入っておらず、その場合 const end = moment($('.end').val(), 'HH:mm'); によって、 end は undefined や nul lにはならずに、 日時として無効な値を保持する Momentオブジェクトが入り、その場合 start.isAfter(end) をふくめ、 end を使った比較判定はどれも false を返します。 Momentを使えば、時刻(あるいは日時)の処理がかなり楽に行えると思いますので、質問者さまの要件にあわせて色々、試してみて頂ければと思います。
jun68ykt

2019/06/09 12:37 編集

補足です。 Moment の便利なメソッドで、もうひとつ、 isValid というのがあります。 変数 x が、有効な日時を保持するmomentオブジェクトであるとき、 x.isValid() は true になります。( FYI: https://momentjs.com/docs/#/parsing/is-valid/ ) 逆にこれが false のとき x は日時として無効な値が入っています。 これを使って、先のサンプルで、if 条件を if (start.isAfter(end) || !end.isValid()) {  ・・・ } とすれば、初期状態で終了時刻が選ばれてない状態で開始時刻を選んだときも、if 条件が true になって、終了時刻が設定されます。
memimemi

2019/06/09 09:20

補足たすかります、実際進まずに詰まってました…笑 あとは同じ時刻の時もendを15分送らせたいのと、endから入力した際にはstartが15分前に表示させるというのを同時にやりたいです
memimemi

2019/06/09 09:33 編集

if (moment(start).isSame(end)) { $('.end').val(start.add(15, 'minutes').format('HH:mm')); }else{ if (start.isAfter(end) || !end.isValid()) { $('.end').val(start.add(15, 'minutes').format('HH:mm')); } } で前者はいけました!
jun68ykt

2019/06/09 09:56 編集

なるほどです。 Momentには、「等しいか後」あるいは「等しいか前」のためのメソッドが用意されています。 2つのMomentオブジェクト a, b があったときに、 a は b と等しいまたは後である: a.isSameOrAfter(b) が true ???? FYI: https://momentjs.com/docs/#/query/is-same-or-after/ a は b と等しいまたは前である: a.isSameOrBefore(b) が true ???? FYI: https://momentjs.com/docs/#/query/is-same-or-before/ 上記の isSameOrAfter を使い、 > endから入力した際にはstartが15分前に表示させる もあわせてやるとしたら、たとえば以下のようになるかと思います。 https://jsfiddle.net/jun68ykt/j9ntco13/7/ ちょっと if 条件が込み入ってきたので、もう少し短いコードにリファクタできるかもしれません。
jun68ykt

2019/06/09 09:41

> 前者はいけました! ???? はい。それでもOKです!
memimemi

2019/06/09 11:04

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

2019/06/09 12:05

どういたしまして! そういって頂けると回答者冥利に尽きます。 それと、もうひとつだけお節介といいますか、以下をちょっとお遊びで作ってみました。 https://jsfiddle.net/jun68ykt/j9ntco13/12/ 上記は、 ・初期表示のときに、   開始時刻 08:30, 終了時刻 19:00 が選ばれた状態で表示され、   かつ、開始時刻の選択肢に、19:00 は表示されず、   かつ、終了時刻の選択肢に、08:30 は表示されない。 ・その後、終了時刻をたとえば 14:00 に変更してから、次に開始時刻を変更しようとすると、  終了の15分前の 13:45 までしか選択肢に表示されない。 ・次に、開始時刻として、13:00 を選ぶと、終了時刻の選択肢に13:15 よりも前は表示されない。 という動作をさせるコードです。 かなりトリッキーなコードですので、まくまで参考に留めて頂ければと思います。
memimemi

2019/06/09 12:50

このコードを自分のアプリに組み込んだらバリデーション不要でかなり便利です! ここから開始時間の下に○時間等のボタンを用意して押せばそれが終了時間に入るとかのプログラムも 面白そうですね! ありがとうございます^^ javascriptかなりお詳しいようで、もしよろしければ私の回答がついてない質問も見ていただけると嬉しいです・・・!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問