Javascript primefaces日历关闭覆盖面板

Javascript primefaces日历关闭覆盖面板,javascript,jsf,primefaces,Javascript,Jsf,Primefaces,我有一个覆盖面板,这个面板有一个日历 <p:overlayPanel hideEffect="fade" showCloseIcon="true" dismissable="true" > <h:form> <p:panelGrid columns="1" styleClass="dateRangeFilterClass"> <p:calendar value="#{cc.attr

我有一个覆盖面板,这个面板有一个日历

 <p:overlayPanel hideEffect="fade" showCloseIcon="true" dismissable="true" >
        <h:form>
            <p:panelGrid columns="1" styleClass="dateRangeFilterClass">
                <p:calendar value="#{cc.attrs.value.from}" showOn="button" pattern="#{dateFormat.onlyDateFormat}"
                            mask="true"  >
                    <p:ajax event="dateSelect" global="false"/>
                </p:calendar>
 </p:panelGrid>
        </h:form>
    </p:overlayPanel>

因此,当用户选择一天时,OverlyPanel关闭。这是我的问题。 我需要使用dismissable=“true”,因为我需要错误单击“关闭”

有没有解决这个日历覆盖面板错误的方法

我尝试用JS处理这个问题,但失败了

谢谢

最好的选择是打开一个,这样他们就能解决问题

解决您的特定问题的另一种方法是重写OverlyPanel原型的定义,其中实现了可撤销逻辑。在那里,您可以检查单击是否在日期选择器上,并防止覆盖面板关闭。此解决方案如下所示(使用PrimeFaces 6.1测试)

创建一个文件overlypanelfix.js

(function() {
  PrimeFaces.widget.OverlayPanel.prototype.bindCommonEvents = function(dir) {
    var $this = this;

    if (this.cfg.showCloseIcon) {
      this.closerIcon.on('mouseover.ui-overlaypanel', function() {
        $(this).addClass('ui-state-hover');
      }).on('mouseout.ui-overlaypanel', function() {
        $(this).removeClass('ui-state-hover');
      }).on('click.ui-overlaypanel', function(e) {
        $this.hide();
        e.preventDefault();
      }).on('focus.ui-overlaypanel', function() {
        $(this).addClass('ui-state-focus');
      }).on('blur.ui-overlaypanel', function() {
        $(this).removeClass('ui-state-focus');
      });
    }

    // hide overlay when mousedown is at outside of overlay
    if (this.cfg.dismissable && !this.cfg.modal) {
      var hideNS = 'mousedown.' + this.id;
      $(document.body).off(hideNS).on(
          hideNS,
          function(e) {
            if ($this.jq.hasClass('ui-overlay-hidden')) {
              return;
            }

            // do nothing on target mousedown
            if ($this.target) {
              var target = $(e.target);
              if ($this.target.is(target) || $this.target.has(target).length > 0) {
                return;
              }
            }

            // NEW PART: do nothing on datepicker mousedown
            var target = $(e.target);
            if(target.hasClass('ui-datepicker') || target.parents('.ui-datepicker').length) {
              return;
            }
            // NEW PART END

            // hide overlay if mousedown is on outside
            var offset = $this.jq.offset();
            if (e.pageX < offset.left || e.pageX > offset.left + $this.jq.outerWidth() || e.pageY < offset.top
                || e.pageY > offset.top + $this.jq.outerHeight()) {

              $this.hide();
            }
          });
    }

    // Hide overlay on resize
    var resizeNS = 'resize.' + this.id;
    $(window).off(resizeNS).on(resizeNS, function() {
      if ($this.jq.hasClass('ui-overlay-visible')) {
        $this.align();
      }
    });
  }
})();
<h:outputScript name="js/overlayPanelFix.js" />
(函数(){
PrimeFaces.widget.OverlyPanel.prototype.bindCommonEvents=函数(dir){
var$this=这个;
if(this.cfg.showCloseIcon){
this.closerIcon.on('mouseover.ui overlypanel',function(){
$(this.addClass('ui-state-hover');
}).on('mouseout.ui overlypanel',function(){
$(this.removeClass('ui-state-hover');
}).on('click.ui overlypanel',函数(e){
$this.hide();
e、 预防默认值();
}).on('focus.ui overlypanel',function(){
$(this.addClass('ui-state-focus');
}).on('blur.ui overlypanel',function(){
$(this.removeClass('ui-state-focus');
});
}
//当mousedown位于覆盖层外侧时隐藏覆盖层
if(this.cfg.dismissable&&!this.cfg.modal){
var hideNS='mousedown.+this.id;
$(document.body).关闭(隐藏).打开(
隐藏,
职能(e){
if($this.jq.hasClass('ui-overlay-hidden')){
返回;
}
//在目标上不执行任何操作鼠标向下
如果($this.target){
var目标=$(e.target);
if($this.target.is(target)|$this.target.has(target.length>0){
返回;
}
}
//新部分:在datepicker mousedown上不执行任何操作
var目标=$(e.target);
if(target.hasClass('ui-datepicker')| | target.parents('.ui-datepicker').length){
返回;
}
//新零件端
//如果鼠标向下位于外侧,则隐藏覆盖
var offset=$this.jq.offset();
如果(e.pageXoffset.left+$this.jq.outerWidth()| e.pageYoffset.top+$this.jq.outerHeight()){
$this.hide();
}
});
}
//在调整大小时隐藏覆盖
var resizeNS='resize.+this.id;
$(窗口).off(resizeNS.on(resizeNS,function()){
if($this.jq.hasClass('ui-overlay-visible')){
$this.align();
}
});
}
})();
它是原始函数的副本,带有附加的“新部分”(参见函数中的注释)

将脚本集成到您的facelet中:

(function() {
  PrimeFaces.widget.OverlayPanel.prototype.bindCommonEvents = function(dir) {
    var $this = this;

    if (this.cfg.showCloseIcon) {
      this.closerIcon.on('mouseover.ui-overlaypanel', function() {
        $(this).addClass('ui-state-hover');
      }).on('mouseout.ui-overlaypanel', function() {
        $(this).removeClass('ui-state-hover');
      }).on('click.ui-overlaypanel', function(e) {
        $this.hide();
        e.preventDefault();
      }).on('focus.ui-overlaypanel', function() {
        $(this).addClass('ui-state-focus');
      }).on('blur.ui-overlaypanel', function() {
        $(this).removeClass('ui-state-focus');
      });
    }

    // hide overlay when mousedown is at outside of overlay
    if (this.cfg.dismissable && !this.cfg.modal) {
      var hideNS = 'mousedown.' + this.id;
      $(document.body).off(hideNS).on(
          hideNS,
          function(e) {
            if ($this.jq.hasClass('ui-overlay-hidden')) {
              return;
            }

            // do nothing on target mousedown
            if ($this.target) {
              var target = $(e.target);
              if ($this.target.is(target) || $this.target.has(target).length > 0) {
                return;
              }
            }

            // NEW PART: do nothing on datepicker mousedown
            var target = $(e.target);
            if(target.hasClass('ui-datepicker') || target.parents('.ui-datepicker').length) {
              return;
            }
            // NEW PART END

            // hide overlay if mousedown is on outside
            var offset = $this.jq.offset();
            if (e.pageX < offset.left || e.pageX > offset.left + $this.jq.outerWidth() || e.pageY < offset.top
                || e.pageY > offset.top + $this.jq.outerHeight()) {

              $this.hide();
            }
          });
    }

    // Hide overlay on resize
    var resizeNS = 'resize.' + this.id;
    $(window).off(resizeNS).on(resizeNS, function() {
      if ($this.jq.hasClass('ui-overlay-visible')) {
        $this.align();
      }
    });
  }
})();
<h:outputScript name="js/overlayPanelFix.js" />


在更新到较新的PrimeFaces版本时,请小心覆盖类似的内容。您必须始终检查是否一切正常。

“解决您的特定问题的一种黑客方法是覆盖”,这不是真正的黑客方法,而是在创建真正的补丁和/或在上游“修复”之前更改/调整内容的常用方法。源代码是开放的,因此这是完全可行的,并且maintainable@AlexFire让我一天都很愉快谢谢老兄,完美的解决方案!