【问题标题】:Close knockout Popover from bootstrap 3.3.6 on click of outside Via knockout binding handler单击外部通过淘汰绑定处理程序从引导程序 3.3.6 关闭淘汰赛弹出窗口
【发布时间】:2016-03-11 17:26:44
【问题描述】:

我是淘汰赛的新手。我正在使用淘汰赛和引导程序 3.3.6(最新)。我需要通过敲除引导自定义绑定处理程序在点击外部时关闭引导弹出窗口。我有一些用于引导 3 自定义绑定处理程序的插件。但是我需要在点击正文时关闭弹出框。

这是我的sample Fiddle

    var guid = (function(s4) {
  return function() {
    return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
  };
})(function() {
  return Math.floor((1 + Math.random()) * 0x10000)
    .toString(16)
    .substring(1);
});

// Outer HTML
if (!$.fn.outerHtml) {
  $.fn.outerHtml = function () {
    if (this.length === 0) {
      return false;
    }
    var elem = this[0], name = elem.tagName.toLowerCase();
    if (elem.outerHTML) {
      return elem.outerHTML;
    }
    var attrs = $.map(elem.attributes, function (i) {
      return i.name + '="' + i.value + '"';
    });
    return "<" + name + (attrs.length > 0 ? " " + attrs.join(" ") : "") + ">" + elem.innerHTML + "</" + name + ">";
  };
}


// Bind Bootstrap Popover
ko.bindingHandlers.popover = {
  init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
    var $element = $(element);
    var popoverBindingValues = ko.utils.unwrapObservable(valueAccessor());
    var template = popoverBindingValues.template || false;
    var options = popoverBindingValues.options || {title: 'popover',placement:'bottom'};
    var data = popoverBindingValues.data || false;
    var controlDescendants = popoverBindingValues.controlDescendants;
    if (template !== false) {
      if (data) {
        options.content = "<!-- ko template: { name: template, if: data, data: data } --><!-- /ko -->";
      }
      else {
        options.content = $('#' + template).html();
      }
      options.html = true;
    }
    $element.on('shown.bs.popover', function(event) {

      var popoverData = $(event.target).data();
      var popoverEl = popoverData['bs.popover'].$tip;
      var options = popoverData['bs.popover'].options || {};
      var button = $(event.target);
      var buttonPosition = button.position();
      var buttonDimensions = {
        x: button.outerWidth(),
        y: button.outerHeight()
      };

      ko.cleanNode(popoverEl[0]);
      if (data) {
        ko.applyBindings({template: template, data: data}, popoverEl[0]);
      }
      else {
        ko.applyBindings(viewModel, popoverEl[0]);
      }

      var popoverDimensions = {
        x: popoverEl.outerWidth(),
        y: popoverEl.outerHeight()
      };

      popoverEl.find('button[data-dismiss="popover"]').click(function() {
        button.popover('hide');
      });

      switch (options.placement) {
        case 'right':
          popoverEl.css({
            left: buttonDimensions.x + buttonPosition.left,
            top: (buttonDimensions.y / 2 + buttonPosition.top) - popoverDimensions.y / 2
          });
          break;
        case 'left':
          popoverEl.css({
            left: buttonPosition.left - popoverDimensions.x,
            top: (buttonDimensions.y / 2 + buttonPosition.top) - popoverDimensions.y / 2
          });
          break;
        case 'top':
          popoverEl.css({
            left: buttonPosition.left + (buttonDimensions.x / 2 - popoverDimensions.x / 2),
            top: buttonPosition.top - popoverDimensions.y
          });
          break;
        case 'bottom':
          popoverEl.css({
            left: buttonPosition.left + (buttonDimensions.x / 2 - popoverDimensions.x / 2),
            top: buttonPosition.top + buttonDimensions.y
          });
          break;
      }
    });

    $element.popover(options);
    ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
      $element.popover('destroy');
    });

    return { controlsDescendantBindings: typeof controlDescendants == 'undefined' ? true : controlDescendants };

  }
};

var ViewModel = function() {
  this.exampleText = ko.observable(" I am trying to close popover on click of out side using knockout binding handler, Please let me know how to do this");
};

ko.applyBindings(new ViewModel());

<body>
       <div class="division">
       <button data-bind="popover:{template:'settingsPopover',trigger:'click',placement:'bottom'}">settings</button>
       </div>

        <script type="text/html" id="settingsPopover">
            <div data-bind="text: $data.exampleText" type="text"> </div>


        </script>
        </body>

请为 bootstrap 3.3.6 推荐最佳的淘汰赛捆绑处理程序,并帮助我通过淘汰赛处理程序关闭弹出窗口。

【问题讨论】:

    标签: javascript jquery knockout.js twitter-bootstrap-3


    【解决方案1】:

    这个插件的棘手之处在于它隐式附加到按钮的点击事件。它希望该按钮用于切换弹出框的可见性,并且不给您任何方法来覆盖它。

    控制可见性的一种更为淘汰的方法是(当然)使用可观察对象,当事物可见时为真,否则为假。你可能有:

    this.popoverIsOpen = ko.observable(false);
    

    然后在绑定处理程序的update 部分中类似于

    var openControl = ko.unwrap(valueAccessor());
    $element.popover(openControl ? 'show' : 'hide');
    

    我为您的小提琴所做的就是制作一个这样的控制器,并在 body 上放置一个始终将其设置为 false 的点击绑定:

    <body data-bind="click: popoverIsOpen.bind($data, false)">
    

    init 部分,我在显示时将值设置为true,并禁用了按钮,因为我要从正文向按钮发出我自己的点击事件。

    $element.on('shown.bs.popover', function(event) {
      $element.prop('disabled', true);
      openControl(true);
    

    我添加了一个订阅,如果新值为 false,则重新启用按钮并通过触发单击按钮关闭弹出框。

    openControl.subscribe(function (newValue) {
        if (!newValue) {
          $element.prop('disabled', false);
          $element.click();
        }
    });
    

    您可以在弹出框本身上放置一个点击绑定,以防止其中的点击关闭:

    click: function (d,e) {e.stopPropagation();}
    

    Updated fiddle.

    【讨论】:

    • 在弹出框之外单击工作正常,但在单击弹出框主体时弹出框不应关闭。你能更新一下吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多