0

I'm trying to drag events from the external events box to a list which has a z-index.

I recreated the issue that I face in the following CodePen:

Dragging an external event from the list into the calendar works fine. However, while dragging it from external event box into the calendar(or from the calendar back to the list), the event disappears behind the Virtual Scroll Repeat (until released into the callendar it shows up in the calendar). Note that I set the z-index of the external events list on purpose.

However, I wonder how I can influence the overflow:auto of repeater-container css class necessary for the scroll that holds the external events. How to make events show up over the virtual scroll during their trips into the fullcalendar? The same thing should be apply in the case I want to dragg back an event from the calendar back to the external event list.

N.B: to see clearly the problem that I'm describing here. Here are the steps to reproduce : 1) comment the overflow: auto; line 147 in the css file on the
class="repeater-container" on the codepen. 2) scroll down to one event

  3) drag it into the calendar
     so you can see from steps 1-2-3 the drag into the calendar works fine .

  Now uncomment the overflow: auto;  line 147 in the css file on the 
  class="repeater-container"

  repeat the steps 2-3 like described before 
  so from steps 1-2-3(with overflow: auto;) the drag into the calendar 
  works also well but during the trip(from external events box to calendar) 
  the  event disappear under the virtual scroll until it reaches the 
  calendar and it shows up into the calendar.

Any help would be greatly appreciated.

Best regards,

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;
}
Schwertfisch
  • 133
  • 3
  • 16

1 Answers1

0

Here is a workaround that I implemented for that case.

It's not a perfect solution:

mainly (if we stop during our trip into the calendar) by avoiding a drop into the calendar, The external event should revert back to the external event Box. but for now it's still isolated out of the box.

The workaround: added a call on the triggered events: ondragstart,ondragend and make a call to ctrlstartDragging and ctrlendDragging on the controller namely this should be done in from outside the control of angularjs which means $scope object will not available in "Outside angular context". Whenever you want to access angular scope in JavaScript (Outside angular world) then you need to get the scope of by getting the DOM of that element & then access the scope of it like angular.element(this).scope()....

ondragstart="angular.element(this).scope().ctrlstartDragging(id)" 
ondragend="angular.element(this).scope().ctrlendDragging(id)" 

and hence html div become like that one

<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}}"
ondragstart="angular.element(this).scope().ctrlstartDragging(id)" ondragend="angular.element(this).scope().ctrlendDragging(id)">

and add on the controller ctrlstartDragging(id) and ctrlendDragging(id)

app.controller("MainCtrl", ['$scope', '$sce', function($scope, $sce){

    $scope.ctrlstartDragging = function(id) {


        var book = document.getElementById(id);
        var domRect = book.getBoundingClientRect();
            book.style.position = 'fixed';
            book.style.top = domRect.top + 'px';
            book.style.left = domRect.left + 'px';
            book.style.width=domRect.width + 'px';

    };
    $scope.ctrlendDragging = function(id) {

       var book = document.getElementById(id);
            book.style.position = 'relative';
            book.style.top = 'unset';
            book.style.left = 'unset';
            book.style.width='unset';
    };

workingPen

Hope it may help someone ;).

Schwertfisch
  • 133
  • 3
  • 16