Angular-calendar drag events across days - angular-calendar

I feel like this is a bit of a longshot but I'll ask anyway.
I have a component that displays the angular-calendar day-view-scheduler. I use this to display a view of any given day with the events that are scheduled on that particular day. One of the requirements I was given is to have this day-view-scheduler applied to a week view so it shows a higher level view of what is going on for the week. I modified a week-view to display a day-view-scheduler component instead of a singular column as it does normally.
I have this working as needed except for the ability to drag and drop events from one day to another. The events don't follow the cursor when I try to drag them across day boundaries, they are essentially stuck in the day column and that leaves me puzzled and out of luck.
Here is the html code associated with this week view component:
<div class="cal-week-view" role="grid">
<mwl-calendar-week-view-header
[days]="days"
[locale]="locale"
[customTemplate]="headerTemplate"
(dayHeaderClicked)="dayHeaderClicked.emit($event)"
(eventDropped)="eventDropped({ dropData: $event }, $event.newStart, true)"
(dragEnter)="dateDragEnter($event.date)">
</mwl-calendar-week-view-header>
<div class="cal-time-events" mwlDroppable (dragEnter)="dragEnter('time')" (dragLeave)="dragLeave('time')">
<div *ngIf="view.hourColumns.length > 0 && daysInWeek !== 1" class="cal-time-label-column">
<div *ngFor="let hour of view.hourColumns[0].hours; trackBy: trackByHour; let odd = odd" class="cal-hour" [class.cal-hour-odd]="odd">
<mwl-calendar-week-view-hour-segment
*ngFor="let segment of hour.segments; trackBy: trackByHourSegment"
[style.height.px]="hourSegmentHeight"
[segment]="segment"
[segmentHeight]="hourSegmentHeight"
[locale]="locale"
[customTemplate]="hourSegmentTemplate"
[isTimeLabel]="true"
[daysInWeek]="daysInWeek">
</mwl-calendar-week-view-hour-segment>
</div>
</div>
<div #dayColumns class="cal-day-columns" [class.cal-resize-active]="timeEventResizes.size > 0">
<div *ngFor="let column of view.hourColumns; trackBy: trackByHourColumn" class="cal-day-column">
<mwl-day-view-scheduler
[viewDate]="column.date"
[events]="events"
[users]="users"
[showHours]="false"
[dayStartHour]="8"
[dayEndHour]="17"
[hourSegments]="hourSegments"
[templateMode]="templateMode"
[eventTemplate]="customTemplate"
[hourSegmentHeight]="25"
(eventTimesChanged)="eventChanged($event)"
(userChanged)="resourceChanged($event)"
(clipboardEventDropped)="eventChanged($event)">
</mwl-day-view-scheduler>
</div>
</div>
<ng-template #customTemplate let-event="weekEvent">
<app-appointment-formatter [event]="event"></app-appointment-formatter>
</ng-template>
</div>
</div>
My guess is that there is some sort of limiter or boundary associated with the mwlDroppable, I'm just not sure how to remove it. Any input or insight would be greatly appreciated.

Related

mat-expansion-panel 'closed' event is called with random index instead of 'destroyed'

I am using mat-expansion-panel inside cdk-virtual-scroll.
I want to hit a function when the panel is destroyed after scrolling, but the (closed) event is called instead of the (destroyed) event, having a random index as a parameter.
<mat-accordion>
<cdk-virtual-scroll-viewport itemSize="50" [minBufferPx]="700" [maxBufferPx]="1000" scrollWindow>
<mat-expansion-panel *cdkVirtualFor="let item of items; let i = index;"
(opened)="panelOpened(i)"
(closed)="panelClosed(i)"
(destroyed)="panelDestroyed(item.status, i)"
[(expanded)]="item.status">
<mat-expansion-panel-header>
<mat-label>
<mat-label> {{item.id}} </mat-label>
<mat-label> isOpened: {{item.status}}</mat-label>
</mat-label>
</mat-expansion-panel-header>
<div>
<div>{{item.detail}}</div>
<div>
<button mat-raised-button color="accent">OK</button>
</div>
</div>
</mat-expansion-panel>
</cdk-virtual-scroll-viewport>
</mat-accordion>
You can test the scenario here
Steps to recreate the issue:
open console
open any expansion panel (let's say item5)
scroll down till opened panel is destroyed.
the console will show a Closed 'random index number' message instead of Destroyed 5.
I do not want to use templateCacheSize: 0, it causes slow item rendering on scrolling.

cdkDropListDropped event not emitted when item is dropped

I am trying to do drag and drop without deleting the item from the dragged list. I followed an example Working demo and tried to reproduce the same. Unfortunately it was not working and I found that the cdkDropListDropped event is emitted. You can find the issue in this link Problematic demo
I want to achieve like the Working demo
Please show me where I am wrong.
I found I had to move the directives cdkDropList and cdkDropListConnectedTo="drop-list" from the div with ID div1 to the parent div so the HTML becomes:
<div class="column left" cdkDropList cdkDropListConnectedTo="drop-list">
<div id="div1" cdkDrag *ngFor="let type of types" [cdkDragData]="type" (cdkDragMoved)="moved($event)" (cdkDropListDropped)="itemDropped($event)">
{{type.text}}
<div *cdkDragPlaceholder class="field-placeholder"></div>
</div>
</div>
At this point the cdkDropListDropped event fired and called the itemDropped function. The problem then was, there was a runtime error on the following line:
copyArrayItem(
event.previousContainer.data,
event.container.data,
event.previousIndex,
event.currentIndex
);
After copying the itemDropped method from your working demo StackBlitz, it then started work. Please see this StackBlitz for a demo.

What happened to w3-sidenav? Is it possible to use w3-sidebar instead without the drawbacks?

What happened to w3-sidenav? We now only seem to have w3-sidebar which is not as good as it always displays in large (laptop, desktop) machines.
Is it possible to use w3-sidebar, but avoid the always-on problem for large screens? I want it visible only when I say.
The w3 tutorials suggest that you use a class="w3-sidebar w3-bar-block" to build a side nav. You have different option of always display etc:
1) Always Display: Add Style="width=25%", and then to the adjacent div, add style="margin-left:25%"
2)Open over content:
a) add to sidebar style="display:none" id="mySideBar" <button onClick="we-close" class="w3-bar-iitem w3-large">Close × </button>
b) Add to content (Adjacent Div): <button class="w3-button w3-large" onClick="W3-open()">☰ </button>
c) Add script
function w3-open(){
document.getElementById("mySideBar").style.display="block";
}
function w3-close(){
document.getElementById("mySideBar").style.display="none";
}
Another option with this is to open the sidebar over the whole page, in which case you will use the same code as option 2 above, just add to the JS w3-open() function: document.getElementById("mySideBar").style.width="100%";
3) Collapsible & Responsive: (I think this is the one you will probably prefer):
a) Define sidebar div with
class="w3-sidebar w3-bar-block w3-collapse w3-card w3-animate-left" style="width: 200px" id="mySideBar">
<button class="w3-bar-item w3-button w3-large we-hide-large" onClick="w3-close()">close × </button>
b) Define the main wrapper div with
<div class="w3-main" style="margin-left:200px">
<div class="w3-blue">
<button class="w3-button …." onClick="w3-open()"> ☰ </button>
</div>
</div>
c) insert the javascript as per the above option 2, both w3-open() & w3-close()
Do not quote my code above, I just typed it freehand, so its probably riddled with errors.
Here is the w3school script for option 3
You can read more about sidebars here.

Meteor: In template rendered event selecting multiple elements to become draggable not working

Update 2: A The following repo on github shows the problem.
Update 1: Calling #firstNode in Template.editor.rendered returns <div class="editor"></div>.
I have the following template:
<template name="editor">
<div class="editor">
{{#each objects}}
<div class="object">{{content}}</div>
{{/each}}
</div>
</template>
The data is provided by iron-router in the data callback.
The coffeescript for my template:
Template.editor.rendered = ->
#findAll('.object').draggable()
When I go into my browser and try to drag one of the objects I get the text selection cursor and begin to select the text with the div instead of the object being dragged. So what is wrong and how can I get the drag and drop to work?
The drag and drop functionality is being provided by jquery-ui. Which is installed as a smart package.
Also feel free to edit the title of this post as I had a tough time coming up with one that made sense
The solution I found was to abstract <div class="object">{{content}}</div> into a seperate template like so:
<template name="object">
<div class="object">{{content}}</div>
</template>
Then change
Template.editor.rendered = ->
#findAll('.object').draggable()
to
Template.object.rendered = ->
#findAll('.object').draggable()
As stated in meteorpedia.

Displaying large tables of data with angular and MVC

We are trying to display large amounts of data on a webpage.
Data is cached, and is loaded via angular (to allow the actual page to load first and then fetch the data for the grid)
All working ok, however once the data has been received, the page freezes for 1 - 3 seconds,
which we assume is due to the table being rendered.
Size of table can vary, and range from 20 columns 10 rows to 100 columns 100 rows.
All data has to be loaded, as it is to display trends etc.
Below is the table:-
<table id="tbl" class="table table-striped table-bordered" ng-repeat="Grid in userresults.Trend">
<tr ng-repeat="item in Grid" ng-show="$first">
<th ng-repeat="somat in item | filter:{ColumnType :'!1'}">
{{somat.ColumnHeader}}
</th>
</tr>
<tr ng-repeat="item in Grid">
<td ng-repeat="somat in item | filter:{ColumnType : '!1'}" >
{{somat.ColumnValue}}
</td>
</tr>
</table>
Below is the angular:-
$scope.GetPatientResults = function () {
$("#ResultsLoader").show();
var url = "/user/11111/GetUserResults/";
$http.get(url)
.success(function (data) {
// if successful, bind success message to message
$scope.userresults = data;
$("#ResultsLoader").hide();
$('#ResultsSummary').show();
});
};
is there a way to actually only build part of the table that is displayed on screen to avoid this 1 - 3 second rendering / some kind of lazy loading for tables for rows and columns?
Any help / advise is greatly appreciated as this is currently impacting usability on our system.
One alternative may be to try to use ngGrid instead of a table. I believe that ngGrid will only render the items seen on screen, and not all grid items at once. If your problem is indeed the browser rendering, this approach should help.
The problem might be the <table> rendering type of the browsers.
All browsers render tables when all the columns and rows complete, so your data delay the rendering. There is an option to make the appropriate changes in order to render everything in div or try the following link which says that speeds up the table layout.
<div id="tbl" style="float:left;" ng-repeat="Grid in userresults.Trend">
<div style="float:left;" ng-repeat="item in Grid" ng-show="$first">
<div style="float:left;width:200px;" ng-repeat="somat in item | filter:{ColumnType :'!1'}">
{{somat.ColumnHeader}}
</div>
</div>
<div style="float:left;" ng-repeat="item in Grid">
<div style="float:left;width:200px;" ng-repeat="somat in item | filter:{ColumnType : '!1'}">
{{somat.ColumnValue}}
</div>
</div>
</div>

Resources