bootstrap5を使ってみたよ

# bootstrap5をちょいつまみぐい(GUI)

追加:
 [2020/7/1]Codepanで、実装されていたので、さっそく簡易版を書いてみました。

現在、自社システムを絶賛開発中で、UI周りはbootstrapにしようかと思っており、
バージョン4で作っていたのですが、先日アルファー版公開されたってことで早速突っ込んでみた。
これは実験的なもので、システムもデモ版なので安定性より動作優先なので、
今後のメンテナンスなどによるバージョンアップを考慮して、導入検討したものとなります。
つまみぐいなので、紹介コードは「アラート」と「トースト」のみです。

時期みて、バージョン対応していこうかと思っていますので
今回は、バージョン別で書くのではなく、実行環境バージョンを調べ、
自動処理による未来処理コードで対応してます。

では早速、jsのコードを書いていきます。
ちなみに5系では、実際にjQueryの読み込みなしで動きました。
なお、注意して欲しいことは5系の場合、
この状態でjQueryが読み込まれているとバッディングしてうまく動かないかもしれません。

ただ、4系までは、jQueryの読み込みは必須ですので、
実際に試す際はしっかりと各バージョンにあった[公式ドキュメント][bs]を読んで実装方法に従ってお試しください。

```javascript:main.js
/*---------------------------------------------------- format ---------------------------------------------------------------*/
/** @:description 文字列フォーマットです。
 * String.prototype.format
 * @param  ex:) '{year}/{month}/{day}'.format({'year':year,'month':month,'day':day}) or '{year}/{month}/{day}'.format({'2017','11','01'})
 * @return {Object} or {String}
 */
// 存在チェック

if (String.prototype.format == undefined) {  
  /**
   * フォーマット関数
   */
  String.prototype.format = function(arg)
  {
    // 置換ファンク
    var rep_fn = undefined;
    // オブジェクトの場合
    if (typeof arg == "object") {
      rep_fn = function(m, k) { return arg[k]; }
    }
    // 複数引数だった場合
    else {
      var args = arguments;
      rep_fn = function(m, k) { return args[ parseInt(k) ]; }
    }
    return this.replace( /\{(\w+)\}/g, rep_fn );
  }
}
/*---------------------------------------------------- $ ---------------------------------------------------------------*/
/** @:description ID と Classを変換する関数。これはjQueryもどきで大幅な変更しないための策。
 * $('#id') or $('.className') or $('+name')
 * @param  ex:) {String} - let id = $('#id') or let classname = $('.className') or let name = $('+name')
 * @return {Object} - id OR class OR name Object.
 */
if (String.prototype.$ == undefined){
  $ = (x) => {
    const nem = /^[+]/g
    if (typeof x == "string") {
      if(x.match(nem)) return document.querySelector("input[name='{0}']".format(x.replace(nem, "")))
      return document.querySelector(x)
    }
    return x
  }
}


/*---------------------------------------------------- alertMessage ---------------------------------------------------------------*/
/** アラートメッセージを表示させる関数
 * alertMessage("Title", "Message", flag, delay)
 * @param  ({String},{Number},{Number}) - ex:) alertMessage("Message", flag, delay)
 * @return "undefined"
 */

let alertMessage = (msg, f, delay) => {
  let alertFlag = ["alert-primary","alert-secondary","alert-success","alert-danger","alert-warning","alert-info","alert-light","alert-dark"]
  let alertTag  = $("#alert_tag")
  let alertLen  = "alert_{0}".format(((parseInt(bootstrap.Tooltip.VERSION)>4)? alertTag.querySelectorAll("alert").length:$(".alert").length))
  let tagMsg    = `<div class="alert {1} alert-dismissible fade show {2}" role="alert" data-delay="{3}">
                    {0}
                    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                      <span aria-hidden="true">&times;</span>
                    </button>
                  </div>
                  `.format(msg.toString(), alertFlag[f], alertLen, delay)
  if((parseInt(bootstrap.Tooltip.VERSION)>4)){
    alertTag.insertAdjacentHTML('beforeend',tagMsg)
    var alertNode = document.querySelector('.{0}'.format(alertLen))
    var alert     = new bootstrap.Alert(alertNode)
    setTimeout(() => {alert.close()}, delay);
  }else{
    $(tagMsg).prependTo(alertTag)
    $("."+alertLen).toast('show')
  }
}

/*---------------------------------------------------- toastMessage ---------------------------------------------------------------*/
/** トーストを表示させる関数
 * toastMessage("Title", "Message", flag, delay)
 * @param  ({String},{String},{Number},{Number/min:500[ms]}) - :) toastMessage("Title", "Message", 1, 3000)
 * @return "undefined"
 */
let toastMessage = (title, msg, f, delay)  => {
  let toastTag = $("#toast_tag")
  let toastLen = "toast_{0}".format(((parseInt(bootstrap.Tooltip.VERSION)>4)? toastTag.querySelectorAll("toast").length:$(".toast").length))
  let tagMsg   = `<div class="toast {2}" role="alert" aria-live="assertive" aria-atomic="true" data-animation="true" data-delay="{3}">
                  <div class="toast-header">
                    <strong class="mr-auto">{0}</strong>
                    <button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
                      <span aria-hidden="true">&times;</span>
                    </button>
                  </div>
                  <div class="toast-body">{1}</div>
                </div>
                `.format(title.toString(), msg.toString(), toastLen, delay)
  if((parseInt(bootstrap.Tooltip.VERSION)>4)){
    toastTag.insertAdjacentHTML('beforeend',tagMsg)
    var toastNode = document.querySelector('.{0}'.format(toastLen))
    var toast = new bootstrap.Toast(toastNode)
    toast.show()
  }else{
    $(tagMsg).prependTo(toastTag)
    $("."+toastLen).toast('show')
  }
}

```

<p data-height="512" data-theme-id="0" data-slug-hash="VwerdXR" data-default-tab="js,result" data-user="jacklow" data-embed-version="2" data-pen-title="VwerdXR" class="codepen">See the Pen <a href="https://codepen.io/jacklow/details/VwerdXR/">VwerdXR</a> by jacklow (<a href="https://codepen.io/jacklow">@jacklow</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

## 未来のじぶんへの解説

jQueryの`prependTo `に変わるコードを実装しました。
`insertAdjacentHTML`を`beforeend`することで指定タグに追加される。
イメージは、最初に追加されたのが下の方へ流れる感じです。

なおアラートは、5系の場合表示され続けるため、close処理をいれる必要がある。
そのほかにも書き方があるので追加表示ではなく、
静的なページの場合はそちらを選ぶといいと思う。

以上、また何かあれば更新しようと思う。

<!-- Links -->
[bs]:https://v5.getbootstrap.com/docs/versions/