Fullcalendar & Bootstrap:回调适用于 .modal(),但不适用于 .dropdown('toggle')



我正在构建一个日历应用程序,希望在用户拖动时间选择或单击一天中的某个时间时触发上下文菜单。(在绝对位于jsEvent.pageX,jsEvent.pageY的元素上使用Bootstrap的.dropdown())。

不幸的是,出现了一个问题-下拉菜单似乎没有正确触发。奇怪的是,.modal()的触发非常完美。

我的假设是,Fullcalendar用来监听和捕获事件以确认/呈现用户选择的代码会阻止Bootstrap正确触发,但为什么.modal()也会失败呢?

非常感谢您的帮助。

jsFiddle:http://jsfiddle.net/sqjz558x/

function eventCreate(start, end, jsEvent, view) {
  // Works 
  //$('.modal-new-event').modal(); 
  // Doesn't work, notice highlighting of button during drag
  $('.dropdown-toggle').dropdown('toggle'); 
  // Works but is unreliable (using unselect handler)
  //$('.dropdown-menu').toggle(); 
}
$(document).ready(function() {
    $('#calendar').fullCalendar({
        defaultView: 'agendaWeek',
        selectable: true,
        select: function (start, end, jsEvent, view) {
          return eventCreate(start, end, jsEvent, view); 
        },      
        dayClick: function (date, jsEvent, view) { 
          return eventCreate(date, null, jsEvent, view); 
        },
        unselect: function (view, jsEvent) { 
         // $('.dropdown-menu').toggle();
        }       
    })
});

只需停止日历中的事件传播:

document.getElementById("calendar").addEventListener("click", function (e) {
    e.stopPropagation();
});

参见工作JSFiddle

dropdown正由原始点击事件打开。然后事件传播,再次触发并关闭dropdowne.stopPropagation();将阻止这种行为。

问题是,fullcalendar在进行选择(或在日历内单击)后会触发documentclick事件,这是一个问题,因为引导程序下拉菜单的hide函数绑定到$(document).click()

这里实际发生的情况是显示了您的下拉菜单,但在那之后,由于点击document 的触发,它立即被隐藏

这不是一个好的解决方案(但它有效)-您可以取消文档上的点击绑定:

$(document).unbind('click');

真的不推荐,因为你真的不知道你会搞砸什么,但它有效(真的,检查一下!)

您可以看到,我还确保在unselect上切换下拉列表。


一个更好的解决方案是检查我们什么时候真正需要关闭下拉列表,如果下拉列表即将隐藏,但不应该阻止它被隐藏。为了做到这一点,我们需要一个新的变量来告诉我们是否需要打开下拉列表:

  • 当选择完成时,我们需要保持打开状态
  • 取消选择时-可以关闭它

这样,即使日历触发了$(document).click()事件,因为我们知道我们处于select状态,我们也不应该隐藏菜单:

var keepDropdownOpen = false;
$('#calendar').fullCalendar({
    defaultView: 'agendaWeek',
    selectable: true,
    select: function (start, end, jsEvent, view) {
        // On select - keep the dropdown open
        keepDropdownOpen = true;
        return eventCreate(start, end, jsEvent, view); 
    },      
    dayClick: function (date, jsEvent, view) { 
        //return eventCreate(date, null, jsEvent, view); 
    },
    unselect: function (view, jsEvent) { 
        // On unselect - no need to keep the dropdown open
        keepDropdownOpen = false;
        $('.dropdown-toggle').dropdown('toggle');
    }
});
$('.dropdown').on('hide.bs.dropdown', function (e) {
    // If we should keep the dropdown open - just return false
    if (keepDropdownOpen) {
        return false;
    }
    return true;
})

工作示例:https://jsfiddle.net/5yx4z534/

事实上,它被触发了两次:选择也会生成点击事件,因此eventCreate()被调用了两次,因此,下拉列表被切换两次,返回到其原始状态。

如果您在click事件中注释掉eventCreate()调用,那么click和selection都会像您所期望的那样工作(我认为),因为当您单击单个单元格时,实际上是在执行单个单元格长度的选择。参见jsfiddle:

dayClick: function (date, jsEvent, view) { 
    ////return eventCreate(date, null, jsEvent, view); 
},

我观察到的是,第二次点击再次触发相同的事件(在我看来是正确的),但第三次没有。但我认为这是关于fullCalendar插件内部。。。

另外,请注意,在下拉列表打开时单击不同的单元格会再次切换,导致其关闭而不是打开。所以你可能应该更好地使用一些("打开")功能(如果存在,我没有深入研究),或者在再次切换之前检查它的状态。

最新更新