Top-Bot
Top-Bot

Reputation: 892

Change Bootstrap Popover trigger on Click

I am trying to change the trigger of a Bootstrap popover using an html switch, I have some basic jQuery set up but each time I flip the switch each but popover responds differently.

I set up each popover, then put it into a function that I can call each time I change the trigger. I have the trigger set as a global variable that is changed by the function that runs on the html switch change.

Here is my jquery, the html is located at the codepen link.

jQuery(document).ready(function ($) {

  var click_funct = 'hover';
  $(".nrl-hint").contents().find(":checkbox").bind('change', function(){
    var check_checked = $('#nrl-hint').is(":checked");

    if (check_checked) {
      console.log("Check ran");
    click_funct = 'click';
    $("[data-toggle=popover]").popover('destroy');
    $("[data-toggle=popover_2]").popover('destroy');
    $("[data-toggle=popover_3]").popover('destroy');
    $("[data-toggle=popover_4]").popover('destroy');
    $("[data-toggle=popover_5]").popover('destroy');
    box_funct(click_funct);
    }
    else {
      console.log('Check ran x2');
      click_funct = 'hover';
      $("[data-toggle=popover]").popover('destroy');
      $("[data-toggle=popover_2]").popover('destroy');
      $("[data-toggle=popover_3]").popover('destroy');
      $("[data-toggle=popover_4]").popover('destroy');
      $("[data-toggle=popover_5]").popover('destroy');
    box_funct(click_funct);
    }
});
function box_funct(click_funct) {
  $(".ow-button-hover").attr("href", "javascript:void(0)");
  $('.ow-button-hover').popover({ 
      html : true, 
      trigger : 'click',
      placement: "top",
      content: function() {
        return $('#contact_form_nrl').html();
      },
      template: '<div class="popover nrl-popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
    });

  $('[data-toggle=popover]').popover({ 
      html : true, 
      trigger : click_funct,
      content: function() {
        return $('#popover_content_wrapper').html();
      },
      template: '<div class="popover nrl-popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
    });

    $('[data-toggle=popover_2]').popover({ 
      html : true,
      trigger : click_funct, 
      content: function() {
        return $('#popover_content_wrapper_2').html();
      },
      template: '<div class="popover nrl-popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
    });
    $('[data-toggle=popover_3]').popover({ 
      html : true,
      trigger : click_funct,
      placement : 'left', 
      content: function() {
        return $('#popover_content_wrapper_3').html();
      },
      template: '<div class="popover nrl-popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
    });
    $('[data-toggle=popover_4]').popover({ 
      html : true,
      trigger : click_funct,
      placement : 'right', 
      content: function() {
        return $('#popover_content_wrapper_4').html();
      },
      template: '<div class="popover nrl-popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
    });

    $('[data-toggle=popover_5]').popover({ 
      html : true,
      trigger : click_funct,
      placement : 'right', 
      content: function() {
        return $('#popover_content_wrapper_5').html();
      },
      template: '<div class="popover nrl-popover-2"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
    });
  }
  box_funct(click_funct);
});

Here is a codepen link to demonstrate. https://codepen.io/RobertCC/pen/Qqzwgd

I greatly appreciate any help! I know I am probably missing something.

Upvotes: 3

Views: 8175

Answers (1)

Robert
Robert

Reputation: 6967

Based on my understanding of what you're wanting to do I think we can reduce the amount of code you're using considerably. Bootstrap's Popover already supports triggers like click and hover so it's just a matter of re-initializing the Popover with the new trigger.

$("#pHover, #pClick").click(function() {
  var popTrigger = $(this).data("trigger");
  $('[data-toggle="popover"]').popover('dispose');
  $('[data-toggle="popover"]').popover({ trigger: popTrigger });
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js"></script>

<div class="btn-group">
  <button class="btn btn-info" id="pHover" data-trigger="hover">Hover</button>
  <button class="btn btn-danger" id="pClick" data-trigger="click">Click</button>
</div>

<hr />

<button type="button" class="btn btn-secondary" data-container="body" data-toggle="popover" data-placement="top" data-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">Popover on top</button>
<button type="button" class="btn btn-secondary" data-container="body" data-toggle="popover" data-placement="right" data-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">Popover on right</button>
<button type="button" class="btn btn-secondary" data-container="body" data-toggle="popover" data-placement="bottom" data-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">Popover on bottom</button>
<button type="button" class="btn btn-secondary" data-container="body" data-toggle="popover" data-placement="left" data-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">Popover on left</button>

Now for the purposes of this example you'll notice that the default state is that the Popover simply doesn't initialize. Clicking on "Hover" or "Click" applies the value of data-trigger to the popover initialization.

Note also that we have to destroy the popover before we re-initialize with the new trigger value (hence popover('dispose').

My example utilizes the latest version of Bootstrap (4.x) but this should work with version 3 as well, with some considerations for how popovers have migrated (3.x uses destroy and 4.x uses dispose).

One additional note worth considering; you can call a Popover using the data-trigger attribute alongside data-toggle="popover". It might be possible to figure out a way to change the value of data-trigger here and re-initialize the popover that way, too.

Edit: For Bootstrap 3.x users wrap the popover create function in a setTimeout(); function like this.

$("#pHover, #pClick").click(function() {
  var popTrigger = $(this).data("trigger");
  $('[data-toggle="popover"]').popover('dispose');
  setTimeout(function () {
  $('[data-toggle="popover"]').popover({ trigger: popTrigger });
    }, 200);
});

It turns out .popover('destroy') is asynchronous, and immediate initialization of another popover fails, while the previous one is being removed.

Upvotes: 2

Related Questions