Techioz Blog

Rails 6 Bootstrap v3.4.1、jQuery 1.12.4 のポップオーバー関数では、タイトルは表示されますが、本文は表示されません。

概要

私は FILTERtrak というアプリケーションを書き直していますが、今のところ順調に進んでいます。私はこれにサブスクリプション モデルを追加し、あらゆる方法で強化し、Ruby と Rails がとても好きになりました。元々は Ruby 2.2.2 と Rails 4.2 で書かれていました。 (最近) Ruby 2.7.2 と Rails 6.1.5 にアップグレードしました。 Bootstrap v3.4.1 と jQuery 1.12.4 で実行しているアプリの両方のバージョン

私が遭遇し、解決した問題のうち、はるかに複雑なものは、あまりにもばかげているように思え、なぜそれが起こっているのか理解できないようです。

FILTERtrak の古いバージョンは依然として Heroku 上で稼働しています。まだアップグレード中のため、アプリをまだ新しいバージョンに切り替えていません。

古いバージョンのアプリでこのフィルター条件ガイド ボタンにカーソルを置くと、ポップオーバーが正常に表示されます。このアプリの新しいバージョンでは、何らかの理由でまったく同じコードが表示され、タイトルだけが表示されますが、本文は表示されません??私にとって本当に混乱するのはどれですか?

つまり、Rails が動作し、JavaScript が動作し、jQuery が動作し、ブートストラップが動作していることがわかります。そうでない場合、ポップオーバー タイトルは表示されません。コードが変更されていないのに、なぜタイトルでは機能し、本文では機能しないのでしょうか?!?

今日思いつく限りのことを試し、約1000回検索しました。ばかげているようですが、この小さな問題を解決できないようですが、アプリ内の他の場所でより多くのポップオーバーを使用する必要があるため、これを理解する必要があります。

APP の別の領域に別のポップオーバーを書き込もうとしましたが、正常に動作しました。したがって、Ruby on Rails の新しいバージョンが原因でボディ部分が表示されないのか、それともそれが何なのかはわかりません。

私はフロントエンドに関してはまだあまり得意ではありません。 HAML に少し慣れ始めたところです。切り替えを処理する HAML 行は、私には非常に複雑に思えます (.btn.btn-xs で始まります)。何が起こっているのかをよく確認するために、いくつかのオンラインコンバーターを使用してその1行をHAMLからHTMLに変更しようとしましたが、どのコンバーターも正常に変換できませんでした。だからそれは運が悪いです。この行を自分で HTML に書き直しましたが、まったく同じ結果でした。そのため、それが .btn.btn-xs で始まる HAML 行と関係があるかどうかはわかりません。それが書かれた方法でそのhaml行でまだ動作しているので、それが問題ではないと思いますが、試せることが長い間不足しています。

これはボタンのある HAML ビューです。 (ビューの関連部分と他のコードを含めているだけです。詳細を確認する必要がある場合は、お知らせください)。

.text-center
  .btn.btn-xs.btn-block.btn-primary{data: { popover: { content: "#condition-popover" }, placement: "top", toggle: "popover", trigger: "hover click"}, tabindex: "0" } Filter Condition Guide
        #condition-popover.hidden
          .popover-heading
            What do the conditions mean?
          .popover-content
            %dl
              %dt Operational
              %dd
                %ul
                  %li No soot on outlet/bypass
                  %li No cracks
                  %li Wire test passes
              %dt Potentially Compromised
              %dd
                %ul
                  %li 0-20% soot on outlet/bypass
                  %li No cracks
                  %li Dents or impact damage
              %dt Compromised
              %dd
                %ul
                  %li 20%+ soot on outlet/bypass
                  %li Any cracks observed
                  %li Wire test fails

ここにJavaScript/jQueryファイルがあります

(function() {
  var ready;

  ready = function() {
    $('[data-toggle=popover]').popover({
      container: 'body',
      html: true,
      content: function() {
        var content;
        content = $(this).attr('data-popover-content');
        return $(content).children('.popover-content').html();
      },
      title: function() {
        var title;
        title = $(this).attr('data-popover-content');
        return $(title).children('.popover-heading').html();
      }
    });
    return $('#service_filter_condition').on('change', function() {
      var selection;
      selection = $(this).val();
      switch (selection) {
        case 'operational':
          $('#customer_notified_container').fadeOut();
          break;
        case 'potentially_compromised':
          $('#customer_notified_container').fadeIn();
          break;
        case 'compromised':
          $('#customer_notified_container').fadeIn();
          break;
        default:
          $('#customer_notified_container').fadeOut();
      }
    });
  };

  $(document).ready(ready);

  $(document).on('turbolinks:load', ready);

}).call(this);

こちらが現在予定されているものの写真です。見出しが表示され、タイトル セクションの正しいスタイルも設定されています。

以下は、古いバージョンのアプリで動作しているまったく同じコードの図です。

さらに不思議なのは、HTML ページを調べてみると、データがすべてそこにあるということです。ボディセクションが切り替わらないだけで、なぜなのか理解できません。ボディが時々表示されない問題を解決できることがわかったので、さまざまな場所にcontainer: ’body’を追加してみました。私が見つけることができた他の例はすべて、私のものと似ていませんでした。

他に何か見たい人がいたら教えてください。 この軽度の刺激物が発生する原因について、あらゆるご意見をいただければ幸いです。 いくつかの DB クエリを書き直すのにかかる時間が短縮され、この小さな問題が修正され、気が狂いそうになりました。

ありがとう、 スコット

更新: 現在動作しているコードは次のとおりです。

JS

(function() {
  var ready;

  ready = function() {
    $('[data-toggle=popover]').popover({
      html: true,
      trigger: 'hover click',
      placement: 'top',
      title: 'What do the conditions mean?',
      content: function() {
        return $('#popover-body').html();
        }
    });
    return $('#service_filter_condition').on('change', function() {
      var selection;
      selection = $(this).val();
      switch (selection) {
        case 'operational':
          $('#customer_notified_container').fadeOut();
          break;
        case 'potentially_compromised':
          $('#customer_notified_container').fadeIn();
          break;
        case 'compromised':
          $('#customer_notified_container').fadeIn();
          break;
        default:
          $('#customer_notified_container').fadeOut();
      }
    });
  };

ハムル:

 .btn.btn-xs.btn-block.btn-primary{"data-toggle": "popover", "tabindex": "0", "html": "true" } Filter Condition Guide
          #popover-body.hidden{"data-toggle": "popover", "html": "true"}
            = render 'filter_conditions_popover'

正しく動作するようになりました。情報を部分的に、よりクリーンにしたいので、最終的にレンダリング ラインを保持することにしました。また、読みやすいと思うので、書き直した Javascript も保存しておきます。

解決策

バージョン 3.4 以降のブートストラップでは、ポップオーバーまたはツールチップ コンテンツに表示される前に HTML タグと属性がサニタイズされます。したがって、デフォルトのホワイトリストにタグと属性が存在しない場合は、必ずホワイトリストにタグと属性を追加してください。

デフォルトのホワイトリストはここにリストされています: https://getbootstrap.com/docs/3.4/javascript/#js-sanitizer

ホワイトリストへの新しいタグは以下に追加できます。

// ポップオーバー本文にタグを表示できるようにするには、デフォルトのホワイトリストに存在しないタグをホワイトリストに登録する必要があります。 // 現在、テーブルとその子はデフォルトではホワイトリストに登録されていません // したがって、他の必要なタグとともにテーブルタグを追加します

var myDefaultWhiteList = $.fn.popover.Constructor.DEFAULTS.whiteList
myDefaultWhiteList.table = []
myDefaultWhiteList.tbody = []
myDefaultWhiteList.tr = []
myDefaultWhiteList.td = []
myDefaultWhiteList.th = []

// タグ属性を許可するには、次のように追加できます myDefaultWhiteList.td = [‘データオプション’]

タグを追加して、ポップオーバー本文に HTML コンテンツを表示することもできます。