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

时间:2016-07-24 15:08:17

标签: jquery twitter-bootstrap fullcalendar

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

不幸的是,这是一个问题 - 下拉菜单似乎没有被正确触发。奇怪的是.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();
        }       
    })
});

3 个答案:

答案 0 :(得分:2)

您遇到的问题是,在选择(或者您的日历内的任何点击)之后,fullcalendar会为click触发document事件,这是一个问题因为引导程序&#39 ; s下拉的hide函数绑定到$(document).click()

这里实际发生的是您的下拉菜单,但在此之后,由于点击document

的触发,它会被隐藏
  

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

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

真的不推荐,因为你真的不知道你会弄得什么,but it works(真的,检查一下!)

您可以看到我确保切换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/

答案 1 :(得分:2)

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

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

见工作JSFiddle

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

答案 2 :(得分:0)

实际上它被触发两次:Selection也会生成click事件,因此eventCreate()被调用两次,因此,下拉菜单会切换两次,返回其原始状态。

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

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

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

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