-1

I have 2 websites:

  • A static website with Bootstrap 5.
  • A Drupal 8 site with Bootstrap 4.

My question relates to my previous question :

How does the text of the tooltip change when the button is clicked?

The answer works for Bootstrap 5 but I have an error in the console with Drupal 8 and Bootstrap 4.

I think the initialization of tooltip is not correct.

How can I correct this problem? Here is the code used with Bootstap 5 and an adaptation for Bootstrap 4.

I just changed data-bs-original-title to data-original-title

I also modified the code of the tooltip.js file

BOOTSTRAP 5

tooltip.js

var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
  return new bootstrap.Tooltip(tooltipTriggerEl)
})

btn-clipboard.js

(function (doc, clip, boot) {

  var tooltipShareButton = doc.getElementById('btn-clipboard-share');
  var tooltipShare = new boot.Tooltip(tooltipShareButton);
  var clipboardShare = new clip('#btn-clipboard-share', {
    container: doc.getElementById('modal-share')
  });

  clipboardShare.on('success', function(e) {      
    function restoreTitle(e) {
      tooltipShare.hide();
      tooltipShareButton.setAttribute('data-bs-original-title', 'Copier le lien');
      tooltipShareButton.removeEventListener('mouseleave', restoreTitle);
    }
    tooltipShareButton.setAttribute('data-bs-original-title', 'Lien copié');
    tooltipShare.update();
    tooltipShare.show();
    tooltipShareButton.addEventListener('mouseleave', restoreTitle);
  });

  clipboardShare.on('error', function(e) {
    tooltipShareButton.setAttribute('data-bs-original-title', 'Erreur');
    function restoreTitle(e) {
      tooltipShareButton.setAttribute('data-bs-original-title', 'Copier le lien');
      tooltipShareButton.removeEventListener('mouseleave', restoreTitle);
    }
    tooltipShare.update();
    tooltipShare.show();
    tooltipShareButton.addEventListener('mouseleave', restoreTitle);
  });

  var tooltipDonationButton = doc.getElementById('btn-clipboard-donation');
  var tooltipDonation = new boot.Tooltip(tooltipDonationButton);
  var clipboardDonation = new clip('#btn-clipboard-donation', {
    container: doc.getElementById('modal-donation')
  });

  clipboardDonation.on('success', function() {
    function restoreTitle() {
      tooltipDonation.hide();
      tooltipDonationButton.setAttribute('data-bs-original-title', "Copier ladresse");
      tooltipDonationButton.removeEventListener('mouseleave', restoreTitle);
    }
    tooltipDonationButton.setAttribute('data-bs-original-title', 'Adresse copiée');
    tooltipDonation.hide();
    tooltipDonation.update();
    tooltipDonation.show();
    tooltipDonationButton.addEventListener('mouseleave', restoreTitle);
  });

  clipboardDonation.on('error', function(e) {
    function restoreTitle(e) {
      tooltipDonation.hide();
      tooltipDonationButton.setAttribute('data-bs-original-title', 'Copier ladresse');
      tooltipDonationButton.removeEventListener('mouseleave', restoreTitle);
    }
    tooltipDonationButton.setAttribute('data-bs-original-title', 'Erreur');
    tooltipDonation.hide();
    tooltipShare.update();
    tooltipShare.show();
    tooltipDonationButton.addEventListener('mouseleave', restoreTitle);
  });

}(document, ClipboardJS, bootstrap));

BOOTSTRAP 4

enter image description here

tooltip.js

(function ($) {

  $(document).ready(function(){
    $('[data-toggle="tooltip"]').tooltip();
  });

})(jQuery);

btn-clipboard.js

(function (doc, clip, boot) {

  var tooltipShareButton = doc.getElementById('btn-clipboard-share');
  var tooltipShare = new boot.Tooltip(tooltipShareButton);
  var clipboardShare = new clip('#btn-clipboard-share', {
    container: doc.getElementById('modal-share')
  });

  clipboardShare.on('success', function(e) {      
    function restoreTitle(e) {
      tooltipShare.hide();
      tooltipShareButton.setAttribute('data-original-title', 'Copier le lien');
      tooltipShareButton.removeEventListener('mouseleave', restoreTitle);
    }
    tooltipShareButton.setAttribute('data-original-title', 'Lien copié');
    tooltipShare.update();
    tooltipShare.show();
    tooltipShareButton.addEventListener('mouseleave', restoreTitle);
  });

  clipboardShare.on('error', function(e) {
    tooltipShareButton.setAttribute('data-original-title', 'Erreur');
    function restoreTitle(e) {
      tooltipShareButton.setAttribute('data-original-title', 'Copier le lien');
      tooltipShareButton.removeEventListener('mouseleave', restoreTitle);
    }
    tooltipShare.update();
    tooltipShare.show();
    tooltipShareButton.addEventListener('mouseleave', restoreTitle);
  });

  var tooltipDonationButton = doc.getElementById('btn-clipboard-donation');
  var tooltipDonation = new boot.Tooltip(tooltipDonationButton);
  var clipboardDonation = new clip('#btn-clipboard-donation', {
    container: doc.getElementById('modal-donation')
  });

  clipboardDonation.on('success', function() {
    function restoreTitle() {
      tooltipDonation.hide();
      tooltipDonationButton.setAttribute('data-original-title', "Copier ladresse");
      tooltipDonationButton.removeEventListener('mouseleave', restoreTitle);
    }
    tooltipDonationButton.setAttribute('data-original-title', 'Adresse copiée');
    tooltipDonation.hide();
    tooltipDonation.update();
    tooltipDonation.show();
    tooltipDonationButton.addEventListener('mouseleave', restoreTitle);
  });

  clipboardDonation.on('error', function(e) {
    function restoreTitle(e) {
      tooltipDonation.hide();
      tooltipDonationButton.setAttribute('data-original-title', 'Copier ladresse');
      tooltipDonationButton.removeEventListener('mouseleave', restoreTitle);
    }
    tooltipDonationButton.setAttribute('data-original-title', 'Erreur');
    tooltipDonation.hide();
    tooltipShare.update();
    tooltipShare.show();
    tooltipDonationButton.addEventListener('mouseleave', restoreTitle);
  });

}(document, ClipboardJS, bootstrap));
1234ABC
  • 3
  • 2

1 Answers1

0

Following the way you’re using ClipboardJS to copy the content of the buttons on your modals using Bootstrap’s tooltips to show the copy-to-clipboard was successful on the Bootstrap 5 example you provided, I have duplicated the function for Bootstrap 4.

While Bootstrap 5 has the tooltip function as part of Bootstrap’s JavaScript, Bootstrap 4 extends jQuery to handle tooltip functions, so I replaced the Bootstrap 5 instances of the tooltip with jQuery functions.

(function ($, doc, clip) {
    var $shareBtn = $("#btn-clipboard-share");
    var $donateBtn = $("#btn-clipboard-donation");
    var clipboardShare;
    var clipboardDonation;

    // Initialize tooltips
    $shareBtn.tooltip();
    $donateBtn.tooltip();

    clipboardShare = new clip("#btn-clipboard-share", {
        container: doc.getElementById("modal-share")
    });

    clipboardShare.on("success", function () {

        function restoreTitle() {
            $shareBtn.tooltip("hide");
            $shareBtn.attr("data-original-title", "Copier l'adresse");
            $shareBtn.off("mouseleave.clipboard", restoreTitle);
        }

        $shareBtn.attr("data-original-title", "Lien copié");
        $shareBtn.tooltip("update");
        $shareBtn.tooltip("show");
        $shareBtn.on("mouseleave.clipboard", restoreTitle);
    });

    clipboardShare.on("error", function () {

        function restoreTitle() {
            $shareBtn.tooltip("hide");
            $shareBtn.attr("data-original-title", "Copier l'adresse");
            $shareBtn.off("mouseleave.clipboard", restoreTitle);
        }

        $shareBtn.attr("data-original-title", "Erreur");
        $shareBtn.tooltip("update");
        $shareBtn.tooltip("show");
        $shareBtn.on("mouseleave.clipboard", restoreTitle);
    });

    clipboardDonation = new clip("#btn-clipboard-donation", {
        container: doc.getElementById("modal-donation")
    });

    clipboardDonation.on("success", function () {

        function restoreTitle() {
            $donateBtn.tooltip("hide");
            $donateBtn.attr("data-original-title", "Copier l'adresse");
            $donateBtn.off("mouseleave.clipboard", restoreTitle);
        }

        $donateBtn.attr("data-original-title", "Adresse copiée");
        $donateBtn.tooltip("update");
        $donateBtn.tooltip("show");
        $donateBtn.on("mouseleave.clipboard", restoreTitle);
    });

    clipboardDonation.on("error", function () {

        function restoreTitle() {
            $donateBtn.tooltip("hide");
            $donateBtn.attr("data-original-title", "Copier l'adresse");
            $donateBtn.off("mouseleave.clipboard", restoreTitle);
        }

        $donateBtn.attr("data-original-title", "Erreur");
        $donateBtn.tooltip("update");
        $donateBtn.tooltip("show");
        $donateBtn.on("mouseleave.clipboard", restoreTitle);
    });
}(jQuery, document, ClipboardJS));
<link href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.8/dist/clipboard.min.js"></script>

<div class="container d-flex justify-content-center mt-5">
    <!-- Buttons triggering modals -->
    <button type="button" class="btn btn-outline-success mr-3" data-toggle="modal" data-target="#modal-share">
        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-share" viewBox="0 0 16 16">
            <path d="M13.5 1a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zM11 2.5a2.5 2.5 0 1 1 .603 1.628l-6.718 3.12a2.499 2.499 0 0 1 0 1.504l6.718 3.12a2.5 2.5 0 1 1-.488.876l-6.718-3.12a2.5 2.5 0 1 1 0-3.256l6.718-3.12A2.5 2.5 0 0 1 11 2.5zm-8.5 4a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zm11 5.5a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3z"></path>
        </svg> Partager
    </button>

    <button type="button" class="btn btn-outline-success ml-3" data-toggle="modal" data-target="#modal-donation">
        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-suit-heart-fill" viewBox="0 0 16 16">
            <path d="M4 1c2.21 0 4 1.755 4 3.92C8 2.755 9.79 1 12 1s4 1.755 4 3.92c0 3.263-3.234 4.414-7.608 9.608a.513.513 0 0 1-.784 0C3.234 9.334 0 8.183 0 4.92 0 2.755 1.79 1 4 1z"></path>
        </svg> Faire un don
    </button>

    <!-- Modals -->
    <div class="modal fade show" id="modal-share" tabindex="-1" aria-labelledby="partager" aria-hidden="true" aria-modal="true" role="dialog">
        <div class="modal-dialog modal-sm">
            <div class="modal-content">
                <div class="modal-header">
                    <h4 class="modal-title" id="partager">Partager cette page</h4>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    <p class="text-justify">Lorem ipsum dolor sit amet consectetur adipisicing elit. Numquam expedita consectetur laudantium iusto necessitatibus minima.</p>
                    <button id="btn-clipboard-share" class="btn btn-outline-dark btn-sm w-100" data-toggle="tooltip" data-placement="top" title="" data-clipboard-text="https://www.example.com/fr/groupe/le-blog" data-original-title="Copier l'adresse">
                        https://www.example.com/fr/groupe/le-blog
                        <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" class="bi bi-clipboard" viewBox="0 0 16 16">
                            <path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1h1a1 1 0 0 1 1 1V14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1h1v-1z"></path>
                            <path d="M9.5 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3zm-3-1A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3z"></path>
                        </svg>
                    </button>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div>

    <div class="modal fade show" id="modal-donation" tabindex="-1" aria-labelledby="donation" aria-hidden="true" aria-modal="true" role="dialog">
        <div class="modal-dialog modal-sm">
            <div class="modal-content">
                <div class="modal-header">
                    <h4 class="modal-title" id="donation">Faire un don</h4>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    <div class="message-donation">
                        <p class="text-justify">Si le contenu de ce groupe vous plaît, vous pouvez faire un don à son l'auteur en Bitcoin (BTC).</p>
                        <p class="mb-3"><a href="https://www.example.com/btc/address/1A5GqrNbpo7xwurpt1VQVvcA5yzoEcgaFvff" rel="nofollow" target="_blank">Voir les transactions sur la Blockchain</a></p>
                        <h5>Adresse BTC :</h5>
                        <p><img class="img-fluid" src="https://via.placeholder.com/300x300.png?text=QR%20Code" alt="Sample QR Code">
                        </p>
                        <button id="btn-clipboard-donation" class="btn btn-outline-dark btn-sm text-break" data-toggle="tooltip" data-placement="top" title="" data-clipboard-text="1A5GqrNbpo7xwurpt1VQVvcA5yzoEcgaFvff" data-original-title="Copier l'adresse">
                            1A5GqrNbpo7xwurpt1VQVvcA5yzoEcgaFvff
                            <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" class="bi bi-clipboard" viewBox="0 0 16 16">
                                <path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1h1a1 1 0 0 1 1 1V14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1h1v-1z"></path>
                                <path d="M9.5 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3zm-3-1A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3z"></path>
                            </svg>
                        </button>
                    </div>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div>
</div>

I did anonomize the code, using example.com in place of your URL, replaced the QR code with a gray image, and replaced the address hash.

Rich DeBourke
  • 2,873
  • 2
  • 15
  • 17
  • Yes – you can initialize tooltips individually (like I have in the snippet) *or* you can use a jQuery function `$(function () { $('[data-toggle="tooltip"]').tooltip() });` to initialize all of the tooltips on a page. – Rich DeBourke Apr 27 '21 at 13:51
  • If you're initializing *all* tooltips in your js file, then you can delete the lines to initialize the two individual tooltips. – Rich DeBourke Apr 27 '21 at 19:18
  • Without seeing your code in operation, it's not possible to figure out what the problem is. – Rich DeBourke Apr 28 '21 at 02:30
  • There is no mistake on this step but on all the other page of the site, I have an error with tooltip https://www.s1biose.com/fr/groupe/le-blog-de-mathieu https://www.s1biose.com/fr/article/6-remedes-naturels-contre-les-maux-de-lhiver The error-free page displays the 2 buttons (share and donation), the other pages display only 1 button (share). On this page the donation button (BTC) does not work https://www.s1biose.com/fr/soutenir-le-projet I have the feeling that it takes the presence of the 2 buttons on the page for it to work. – 1234ABC Apr 28 '21 at 13:11
  • The reason you’re getting an error is because the id in your html page is using an uppercase D ` – Rich DeBourke Apr 28 '21 at 14:37
  • I made the modification, but it is very weird, because this error only appears when I am logged in with my administrator account at Drupal 8. https://ibb.co/B3JT8Lp – 1234ABC Apr 28 '21 at 16:37
  • I can’t duplicate the problem you’re seeing with the error `Cannot convert undefined or null to object`. When accessing your two pages as a non-administrator, I’m able to open the modals and copy the address and code without any errors. You can click on the top line of the error message to see the line of code that’s generating the error, but you would need to use the browser’s developer tools to see what’s causing the error. If you’re only getting the error when in administrator mode, and it works for everybody else, you may want to just live with it. – Rich DeBourke Apr 29 '21 at 08:07