I'm trying to drag events from the external events box to the fullcalendar.
I recreated the issue that I face in the following CodePen:
at the first time, Dragging an external event from the list into the calendar works fine. However, when I apply the filter on a book in the search input text filter books I have the following issue.
Here are the steps to reproduce :
1- look for 111 in the search input that will filter to the only resulting 111 event book.
2- As you could observe that dragging this resulting event from the filter into the calendar could work fine : but Here we are mainly interested on the case we decide to filter but to do not drag anything into calendar.
3- so for now clear the 111 filter as text from the search input, the
external events box would back all the defaults events but this time trying
to drag one of them into the calendar freezes. It's no more working.
It freezes on all the external events except for the last found
by the filter means the 111 event (look at the last row on the events )
that onlty one that could be dragged.
and no more able to drag others events into the calendar.
4- and even If I dragged 111 into the calendar, and after that if I try to drag anothor one It will freeze.
HTML
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<script data-require="angular.js@1.0.x" src="https://code.angularjs.org/1.3.15/angular.min.js" data-semver="1.0.7"></script>
<script type="text/javascript" src="https://github.com/kamilkp/angular-vs-repeat/blob/master/dist/angular-vs-repeat.js"></script>
<script src="https://code.angularjs.org/1.3.15/angular-animate.min.js"></script>
</head>
<body ng-controller="MainCtrl">
<div id="first">
<input type="search" id="myInput" ng-model="searchText" placeholder="filter books..." title="filter books"/>
<div style="width:200px;display:inline-block;vertical-align:top;color: gray;">
<input type='checkbox' id='drop-remove' checked='checked'/>
<label for='drop-remove'> Remove after a drag </label>
</div>
<div id='external-events'>
<ul vs-repeat="60" class="repeater-container" title="Books darggable({{books.length}})" data- drag="true" data-jqyoui-options="{revert: 'invalid'}">
<li class="animate-repeat fc-event item-element" ng-repeat="book in books | orderBy : sort : false | filter:searchText as results track by book.contents.name" id="{{book.id}}">
<div class="circle">{{book.contents['date']}}</div>
<div class="left content" ng-bind-html="trustAsHtml(book.contents['name'])" id="book_{{book.id}}"></div>
<div class="left rating">2/10</div>
<div class="clear"></div>
</li>
<li class="animate-repeat" ng-if="results.length === 0">
<strong>No results found...</strong>
</li>
</ul>
</div>
</div>
<div id="second">
<div id='calendar-container'>
<div id='calendar'></div>
</div>
</div>
</body>
</html>
js
var app = angular.module("app", ['ngAnimate']);
(function(angular) {
'use strict';
app.controller("MainCtrl", ['$scope', '$sce', function($scope, $sce){
$scope.books = [
{
id: 'id1',
contents: {
name: '<span>1Alain du sceau france</span><br><span> Canada Madagascar philipine</span>',
price: 'price1',
date: '111'
}
},
{
id: 'id2',
contents: {
name: '<span>2Name zu Long zu Schreiben Bis Here ist Ein Beispiel</span><br><span>Maneschester Canada Madagascar philipine</span>',
price: 'price2',
date: '22'
}
},
{
id: 'id3',
contents: {
name: '<span>3name Aleatoire Schwer und zu Leicht Zu Schreiben</span><br><span>Mexico Canada USA France Uk Deutschland Schweiz Madagascar philipine</span>',
price: 'price3',
date: '23'
}
},
{
id: '4',
contents: {
name: '<span>4name Aleatoire Schwer und zu Leicht Zu Schreiben</span><br><span>Mexico Canada USA France Uk Deutschland Schweiz Madagascar philipine</span>',
price: 'price4',
date: '4'
}
},
{
id: 'id5',
contents: {
name: '<span>5name Aleatoire Schwer und zu Leicht Zu Schreiben</span><br><span>Mexico Canada USA France Uk Deutschland Schweiz Madagascar philipine</span>',
price: 'price5',
date: '5'
}
},
{
id: 'id6',
contents: {
name: '<span>6name Aleatoire Schwer und zu Leicht Zu Schreiben</span><br><span>Mexico Canada USA France Uk Deutschland Schweiz Madagascar philipine</span>',
price: 'price6',
date: '6'
}
},
{
id: 'id7',
contents: {
name: '<span>7name Aleatoire Schwer und zu Leicht Zu Schreiben</span><br><span>Mexico Canada USA France Uk Deutschland Schweiz Madagascar philipine</span>',
price: 'price7',
date: '7'
}
},
{
id: 'id8',
contents: {
name: '<span>8name Aleatoire Schwer und zu Leicht Zu Schreiben</span><br><span>Mexico Canada USA France Uk Deutschland Schweiz Madagascar philipine</span>',
price: 'price8',
date: '8'
}
},
{
id: 'id9',
contents: {
name: '<span>9name Aleatoire Schwer und zu Leicht Zu Schreiben</span><br><span>Mexico Canada USA France Uk Deutschland Schweiz Madagascar philipine</span>',
price: 'price9',
date: '9'
}
},
{
id: 'id10',
contents: {
name: '<span>10Alain du sceau france</span><br><span> Canada Madagascar philipine</span>',
price: 'price10',
date: '10'
}
},
{
id: 'id11',
contents: {
name: '<span>11Name zu Long zu Schreiben Bis Here ist Ein Beispiel</span><br><span>Maneschester Canada Madagascar philipine</span>',
price: 'price11',
date: '11'
}
},
{
id: 'id12',
contents: {
name: '<span>12name Aleatoire Schwer und zu Leicht Zu Schreiben</span><br><span>Mexico Canada USA France Uk Deutschland Schweiz Madagascar philipine</span>',
price: 'price12',
date: '12'
}
},
{
id: 'id13',
contents: {
name: '<span>13name Aleatoire Schwer und zu Leicht Zu Schreiben</span><br><span>Mexico Canada USA France Uk Deutschland Schweiz Madagascar philipine</span>',
price: 'price13',
date: '13'
}
},
{
id: 'id14',
contents: {
name: '<span>14name Aleatoire Schwer und zu Leicht Zu Schreiben</span><br><span>Mexico Canada USA France Uk Deutschland Schweiz Madagascar philipine</span>',
price: 'price14',
date: '14'
}
},
{
id: 'id15',
contents: {
name: '<span>15name Aleatoire Schwer und zu Leicht Zu Schreiben</span><br><span>Mexico Canada USA France Uk Deutschland Schweiz Madagascar philipine</span>',
price: 'price15',
date: '15'
}
},
{
id: 'id16',
contents: {
name: '<span>16name Aleatoire Schwer und zu Leicht Zu Schreiben</span><br><span>Mexico Canada USA France Uk Deutschland Schweiz Madagascar philipine</span>',
price: 'price16',
date: '16'
}
},
{
id: 'id17',
contents: {
name: '<span>17name Aleatoire Schwer und zu Leicht Zu Schreiben</span><br><span>Mexico Canada USA France Uk Deutschland Schweiz Madagascar philipine</span>',
price: 'price17',
date: '17'
}
},
{
id: 'id18',
contents: {
name: '<span>18name Aleatoire Schwer und zu Leicht Zu Schreiben</span><br><span>Mexico Canada USA France Uk Deutschland Schweiz Madagascar philipine</span>',
price: 'price18',
date: '18'
}
},
{
id: 'id19',
contents: {
name: '<span>19name Aleatoire Schwer und zu Leicht Zu Schreiben</span><br><span>Mexico Canada USA France Uk Deutschland Schweiz Madagascar philipine</span>',
price: 'price19',
date: '19'
}
},
{
id: 'id20',
contents: {
name: '<span>20name Aleatoire Schwer und zu Leicht Zu Schreiben</span><br><span>Mexico Canada USA France Uk Deutschland Schweiz Madagascar philipine</span>',
price: 'price20',
date: '20'
}
}
];
/*$scope.books.forEach(function(book) {
book.contents.name = $sce.trustAsHtml(book.contents.name);
})*/
$scope.trustAsHtml = $sce.trustAsHtml;
$scope.h = function(html) {
return $sce.trustAsHtml(html);
};
$scope.sort = function(num) {
var newNum = parseInt(num.contents.date);
console.log("$$newnum",newNum);
return newNum;
};
$(document).ready( function(){
//Initialise external events
initialise_external_event('.fc-event');
initialise_calendar();
});
// initialize the external events
// -----------------------------------------------------------------
function initialise_external_event(selector){
/* initialize the external events
-----------------------------------------------------------------*/
$('#external-events .fc-event').each(function() {
// store data so the calendar knows to render an event upon drop
$(this).data('event', {
title: $.trim($(this).text()), // use the element's text as the event title
stick: true // maintain when user navigates (see docs on the renderEvent method)
});
// make the event draggable using jQuery UI
$(this).draggable({
zIndex: 999,
revert: true, // will cause the event to go back to its
revertDuration: 0 // original position after the drag
});
});
}
function initialise_calendar(){
/* initialize the calendar
-----------------------------------------------------------------*/
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
editable: true,
droppable: true, // this allows things to be dropped onto the calendar
dragRevertDuration: 0,
drop: function() {
// is the "remove after drop" checkbox checked?
if ($('#drop-remove').is(':checked')) {
// if so, remove the element from the "Draggable Events" list
$(this).remove();
}
},
eventDragStop: function( event, jsEvent, ui, view ) {
if(isEventOverDiv(jsEvent.clientX, jsEvent.clientY)) {
$('#calendar').fullCalendar('removeEvents', event._id);
var el = $( "<div class='fc-event'>" ).appendTo( '#external-events-listing' ).text( event.title );
el.draggable({
zIndex: 999,
revert: true,
revertDuration: 0
});
el.data('event', { title: event.title, id :event.id, stick: true });
}
}
});
var isEventOverDiv = function(x, y) {
var external_events = $( '#external-events' );
var offset = external_events.offset();
offset.right = external_events.width() + offset.left;
offset.bottom = external_events.height() + offset.top;
// Compare
if (x >= offset.left
&& y >= offset.top
&& x <= offset.right
&& y <= offset .bottom) { return true; }
return false;
}
}
}]);
})(window.angular);
css
ul[title]::before {
content: attr(title);
/* then add some nice styling as needed, eg: */
font: italic 11px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
color: gray;
}
/*ul {
list-style-type: none;
}*/
#myInput {
/*background-image: url('/css/searchicon.png');*/
background-position: 10px 12px;
background-repeat: no-repeat;
width: 77%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 12px;
}
/*ul>li {
display:block;
padding-right: 0cm;
margin-left: 0px;
}*/
#calendar{
padding: 0 10px;
width: 650px;
float: right;
margin: 0px 0px 10px 55px;
}
#external-events {
width: 500px;
padding: 0 0px;
border: 0px solid #ccc;/* gray moyen*/
background: #eee;/* #5D6D7E;(Blue mat) */ /* #eee color gray*/
text-align: left;
}
#external-events .fc-event {
cursor: pointer;
z-index: 9999;
background: #eee;
border: solid 1px black;
border-radius: 2px;
margin-bottom:5px;
}
.content span
{
color: gray;
}
.fc-event span:first-child
{
font-size: 25px;
font-weight: bold italic;
}
.content
{
float:left;
max-width:75%;
}
.clear
{
clear:both;
}
.circle {
float:left;
width: 10%;
height: 25%;
padding: 0 10px;
border-radius: 360px;
/* Just making it pretty */
@shadow: rgba(0, 0, 0, .1);
@shadow-length: 4px;
-webkit-box-shadow: 0 @shadow-length 0 0 @shadow;
box-shadow: 0 @shadow-length 0 0 @shadow;
text-shadow: 0 @shadow-length 0 @shadow;
background: #FFFFFF;/*color white*/
color: #f05907;/* color red*/
font-family: Helvetica, Arial Black, sans;
font-size: 10;
text-align: center;
}
.rating
{
float:right;
background: #FFFFFF;/*color white*/
color: #f05907;/* color red*/
font-family: Helvetica, Arial Black, sans;
font-size: 10;
text-align: center;
border-radius: 360px;
}
.animate-repeat {
line-height:30px;
list-style:none;
box-sizing:border-box;
}
.animate-repeat.ng-move,
.animate-repeat.ng-enter,
.animate-repeat.ng-leave {
transition:all linear 0.5s;
}
.animate-repeat.ng-leave.ng-leave-active,
.animate-repeat.ng-move,
.animate-repeat.ng-enter {
opacity:0;
max-height:0;
}
.animate-repeat.ng-leave,
.animate-repeat.ng-move.ng-move-active,
.animate-repeat.ng-enter.ng-enter-active {
opacity:1;
max-height:30px;
}
#first {
width: 650px;
float: left
}
#second {
width: 650px;
float: left;
}
.repeater-container{
height: 445px;
overflow: auto;
box-shadow: 0 0 10px;
border-radius: 5px;
list-style: none;
margin: 0;
padding: 0;
-webkit-overflow-scrolling: touch;
}
.repeater-container .item-element {
margin: 0 !important;
width: 100%;
height: 140px;
border: 1px solid green;
box-sizing: border-box;
-moz-box-sizing: border-box;
}