Angular2 : Drag Events Using Directives On Table Row Works Very Slow - drag-and-drop

I am implementing dragdrop functionality with the help of directives.
#Directive({
selector: '[Droppable]',
host:{
'(dragenter)':'onDragEnter($event)',
'(dragover)':'onDragOver($event)',
'(dragleave)':'onDragLeave($event)',
'(drop)':'onDrop($event)'
}
})
export class DragDropDirective {
#Input('Droppable') isDropable:boolean;
#Input() set doBoarderHighLight(decision:boolean) {
this._doBoarderHighLight = decision;
this._doBackgroundHighLight = !decision;
}
#Input() doBackgroundHighLight(decision:boolean) {
this._doBackgroundHighLight = decision;
this._doBoarderHighLight = !decision;
}
#Output() OnDrop = new EventEmitter(false);
_doBoarderHighLight:boolean = false;
_doBackgroundHighLight:boolean = true;
_isDropable:boolean = true;
el:ElementRef;
constructor(public _el:ElementRef) {
this.el = _el;
}
onDragOver(e:any) {
e.preventDefault();
}
onDragEnter(e:any) {
e.preventDefault();
e.stopPropagation();
if (this._doBoarderHighLight) {
this.el.nativeElement.addClass("drag-over");
this.el.nativeElement.addClass("highlight-border");
}
else {
this.el.nativeElement.addClass("drag-over");
this.el.nativeElement.addClass("highlight-background");
}
}
onDragLeave(e:any) {
e.preventDefault();
e.stopPropagation();
if (this._doBoarderHighLight) {
this.el.nativeElement.removeClass("drag-over");
this.el.nativeElement.removeClass("highlight-border");
}
else {
this.el.nativeElement.removeClass("drag-over");
this.el.nativeElement.removeClass("highlight-background");
}
}
onDrop(e:any) {
e.preventDefault();
e.stopPropagation();
Utils.nextEventIfExist(e, this.OnDrop);
if (this._doBoarderHighLight) {
this.el.nativeElement.removeClass("drag-over");
this.el.nativeElement.removeClass("highlight-border");
}
else {
this.el.nativeElement.removeClass("drag-over");
this.el.nativeElement.removeClass("highlight-background");
}
}
}
And I am using the directive on table rows,
<tbody *ngFor="let row of rows;#i = index">
<tr [Droppable]="isDropableRow" (OnDrop)="OnDropRow($event)" [ngClass]="{'row-data':true,'active':row.isSelected,'disabled-row':!isEnabled(row)}" (click)="onRowClick($event,row)">
The problem is that, the drag events fires very slowly, as you can see I've adding and removing classes to highlight the rows on dragEnter and DragLeave.
The thing I got is that the slowness is from angular2's zone js, may be the problem in my code or the problem in angular.

I think this is caused by https://github.com/angular/angular/issues/6311
There is already a PR https://github.com/angular/angular/pull/8761

Related

ionic 5 reorder scrolling issue

I have an issue with ion-reorder, i have implemented long press to start reorder and i have an issue when scrolling. i want to ignore the long press while scrolling and only address long press when scrolling has stopped.
my long press code is:
import {
Directive,
Output,
EventEmitter,
HostBinding,
HostListener
} from '#angular/core';
#Directive({
selector: '[appLongPress]'
})
export class LongPressDirective {
pressing: boolean;
longPressing: boolean;
timeout: any;
// interval: number;
interval: NodeJS.Timeout;
#Output()
onLongPress = new EventEmitter();
#Output()
onLongPressing = new EventEmitter();
#HostBinding('class.press')
get press() { return this.pressing; }
#HostBinding('class.longpress')
get longPress() { return this.longPressing; }
#HostListener('touchstart', ['$event'])
#HostListener('mousedown', ['$event'])
onMouseDown(event) {
this.pressing = true;
this.longPressing = false;
this.timeout = setTimeout(() => {
this.longPressing = true;
this.onLongPress.emit(event);
this.interval = setInterval(() => {
this.onLongPressing.emit(event);
}, 50);
}, 1500);
}
#HostListener('touchend')
#HostListener('mouseup')
#HostListener('mouseleave')
endPress() {
clearTimeout(this.timeout);
clearInterval(this.interval);
this.longPressing = false;
this.pressing = false;
}
}
thanks..

Change props value in vuejs2

I am new in vuejs2 development. I am working in a modal development. I kept the modal body code in a component and displaying that modal in another component. I have below code in modal body component.
<script>
import SemanticModal from 'vue-ya-semantic-modal'
export default {
components: { SemanticModal: SemanticModal() },
name: 'ModalBody',
props: ['active1',],
data() {
return {
visible: false
}
},
methods: {
close() {
this.$emit('sendValue', false); //this is working
this.visible = false
},
open () {
this.visible = true
},
},
watch: {
active1 () {
if (this.active1 && !this.visible) this.open()
else if (!this.active1 && this.visible) this.close()
},
},
directives: {
'click-outside': {
bind: function(el, binding, vNode) {
el.onclick = function(e) {
var modal = document.getElementsByClassName("modal");
el.addEventListener('click', function (event) {
if (!modal[0].contains(event.target)) {
vNode.context.$emit('sendValue', false); //this is not working
this.visible = false
}
})
}
}
}
}
}
I am calling that model (child) component in parent component like below
<modal-body :active1="active1" #sendValue="active1 = $event"></modal-body>
I need to change the below props active1 value to false from child to parent component.
You are handling click event by using directives.
According to your requirement , clickoutside directive should emit sendValue event from child to parent. But i feel like your code has some complications.
The proper code to accomplish your scenario is below
directives: {
'clickoutside': {
bind: function(el, binding, vNode) {
el.onclick = function(e) {
console.log("binding clicked");
vNode.context.$emit('sendValue', false);
}
}
}
}
if your objective is to use click event you can use #click binding to accomplish the same

How close popup by click on background

i have simple dropdown, and i need to hide (fadeout) it by clicking on the document
this is my jquery code:
var expandCheckbox = $('.filterShow'),
formCheckbox = $('.checkboxWrap');
expandCheckbox.click(function(e) {
e.preventDefault();
if ($(this).hasClass('active')) {
$(this).removeClass('active');
$(formCheckbox).fadeOut(200);
} else {
$(this).addClass('active');
$(formCheckbox).fadeIn(100);
}
});
$('body').not('.filterShow, .checkboxWrap').click(function() {
$(formCheckbox).fadeOut(100);
});
SEE JSFIDDLE
Remove "e.preventDefault" which has no use here, add "return false" to prevent event propagation to its parent, use "document" instead of "body" as the selector for fading the dropdownlist upon clicking anywhere on the document.
$(document).ready(function(){
expandCheckbox = $('.filterShow'),
formCheckbox = $('.checkboxWrap');
expandCheckbox.click(function (e) {
if ($(this).hasClass('active')) {
$(this).removeClass('active');
formCheckbox.fadeOut(200);
} else {
$(this).addClass('active');
formCheckbox.fadeIn(100);
}
return false;
});
$(document).click(function (e) {
if (expandCheckbox.hasClass('active')) {
expandCheckbox.removeClass('active');
formCheckbox.fadeOut(200);
}
return false;
});
formCheckbox.find('input:checkbox').click(function (e) {
e.stopPropagation();
});
});

Leaflet.js How to stop on map evnet

I am calling a function when the user has panned the map with:
$('#updateTheMap').click(function() {
if (document.getElementById('updateMap').checked) {
// stop the the dragend event...
}
else {
map.on('dragend', function() {
sortBinis(simpleFilterSql);
});
}
});
But I can not figure out how to end this event?
Use a variable:
var updateTheMap = true;
$('#updateTheMap').click(function() {
updateTheMap = document.getElementById('updateMap').checked;
});
map.on('dragend', function() {
if (updateTheMap) sortBinis(simpleFilterSql);
});
If by 'end this event' you mean 'remove the event listener' you can use map.off()
function onDragend(e) { sortBinis(simpleFilterSql); }
$('#updateTheMap').click(function() {
if (document.getElementById('updateMap').checked) {
map.off('dragend', onDragend);
}
else {
map.on('dragend', onDragend);
}
});

youtube iframe API does not work on ipad and iphone

I was trying to recreate the multiple iframes example detailed here for a slideshow. It works flawlessly in all browsers, including desktop safari, except on iphone and ipad.
http://codepen.io/lakshminp/pen/mepIB
Js:
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var players = {}
var YT_ready = (function() {
var onReady_funcs = [],
api_isReady = false;
return function(func, b_before) {
if (func === true) {
api_isReady = true;
for (var i = 0; i < onReady_funcs.length; i++) {
// Removes the first func from the array, and execute func
onReady_funcs.shift()();
}
}
else if (typeof func == "function") {
if (api_isReady) func();
else onReady_funcs[b_before ? "unshift" : "push"](func);
}
}
})();
function onYouTubeIframeAPIReady() {
jQuery(window).bind("load", function() {
YT_ready(true);
});
}
YT_ready(function() {
var identifier = "v9d09JLBVRc";
players[identifier] = new YT.Player(identifier, {
events: {
'onReady': onPlayerReady,
"onStateChange": createYTEvent(identifier)
}
});
});
function onPlayerReady(event) {
event.target.playVideo();
}
// Returns a function to enable multiple events
function createYTEvent(identifier) {
var player = players[identifier]; // Get cached player instance
return function (event) {
console.log(event.data);
}
}
HTML:
<div id="yt-container">
<iframe width="640" height="480" id="v9d09JLBVRc" class="media-youtube-player" src="//www.youtube.com/embed/v9d09JLBVRc?enablejsapi=1&autoplay=0" frameborder="0" allowfullscreen></iframe>
</div>
According to this
functions and parameters such as autoplay, playVideo(), loadVideoById() won't work in all mobile environments
and in your YTReady function, you load dynamically a video and for the moment that's not possible on iOS.
You can also try the YouTubeDemoPage and try to load another id and you will see that it can't be done.
You should also check this.