1
0

【個人開発】「情報処理技術者試験ドットコム」の通知をBootstrap5のポップオーバーの中身をHTMLにして、外側クリックで閉じた件

Posted at

情報処理技術者試験ドットコムの紹介

はじめまして、5月に還暦を迎え、定年退職したプログラマ 泓原敏夫@toshio_fukeharaと申します。

転職後の九州国際情報ビジネス専門学校での講師業務のために「情報処理技術者試験ドットコム」というサービスを個人開発して立ち上げました。

通知機能の実装

増えてきた機能を紹介したい…そういや通知がなかったなと。仕様としては Qiita などと同様にベルのアイコンを出して、未読の数を表示する。アイコンをクリックしたらポップオーバーで一覧表示して、全件表示は別画面へのリンクにする。
ということで、とっととコーディング開始

  • ベルのアイコンを表示する
    • Bootstrap5 のクラスだけではうまく位置調整できず
    • 専用のクラス(wx-notice-read)でstyleを定義
  • 未読の数は非同期でバッジに表示する
    • 未読の通知を取得するAPIをサーバー側にささっと書く
    • どこまで表示したかは cookie に持たせる
    • Laravel のおかげで、まあ楽勝
  • ポップオーバーの中身をリスト表示にする
    • むむっ…Popover のコンテンツは data-bs-content に文字列指定となっている
  • ベルのアイコンをクリックすると、ポップオーバーを表示させる
    • むむっ…Popover は外側クリックでは閉じない。いちいちベルのボタンを押さないと消せない

ということで、実現するのに少しだけ大変だったので、記事として起こしました。

ポップオーバーのコンテンツを HTML にする

ベルアイコンの表示部分

show-notice.html
<style>
  .wx-notice-read {
    position: relative;
    top: 7px;
    left: -3px;
    padding: 2px 5px 3px 5px;
    opacity: 0.75;
  }
</style>

<a href="#" class="show-notice text-decoration-none me-1" title="お知らせ" data-bs-toggle="popover">
  <i class="bi bi-bell-fill text-secondary opacity-75"></i>
  <span class="wx-notice-read badge rounded-pill bg-danger"></span>
</a>

結論から言うと、popover メソッドの option の html を true にして、content に HTML を入れればOKです。非同期で表示するので、いったん中身をスピナーにしています。

popover-option.js
$('.show-notice').popover({
    html: true,
    content: `<div class="list-notice d-flex justify-content-center"><div class="spinner-border"></div></div>`,
    placement: 'left',
    trigger: 'manual',
});

非同期でデータ取得後に list-notice クラスの中身を入れ替えてます。

外側クリックで閉じる

option の trigger を 'manual' にして制御できるようにしておきます。

popover-click.js
$('.show-notice').on('click', function(e) {
  e.stopPropagation();

  const isShow = document.querySelector('.popover.show');
  if (isShow) {
    $(this).popover('hide');
  } else {
    $(this).popover('show');
  }
});

$('.popover').on('click', function(e) {
  e.stopPropagation();
});

$('html').on('click', function(e) {
  $('.show-notice').popover('hide');
});
  • ポップオーバーを表示しているかどうかは、'.popover.show'のクラスを持つ要素があるかで判断しています
  • 外側で閉じることは、'html'のclickで行なっています
    • そのままではポップオーバーのウィンドウをクリックしても閉じてしまうので、'.popover'クラスのクリックでは、e.stopPropagation(); で現在のイベントのさらなる伝播を阻止しています

実装の結果

モバイル表示

app-notice-1.png

デスクトップ表示

app-notice-2.png

終わりに

最後まで読んで頂いてありがとうございます!
無料でも結構使えます。情報処理技術者試験にトライされる際はぜひ使ってみてください。
副業で開発を請け負ってますので、ご依頼などありましたらご連絡ください。
情報処理技術者試験ドットコム お問い合わせ

1
0
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
1
0