Drag and drop within in a list (Cypress) - drag-and-drop

I have been trying to perform drag and drop within the list of elements.I was able to perform drag and drag of the element with the below code
const dragElementCss = `[data-test-subj='${dragElement}']`;
const dropElementCss = `[data-test-subj='${dropElement}']`;
cy.get(dragElementCss).move({ deltaX: 400, deltaY: 0, force: true })
.move({ deltaX: 1, deltaY: 0, force: true })
.drag(dropElementCss, { force: true });
return this;
}
but the placement of the drag element is not consistent, sometimes above target and sometimes below.
I would like to have consistent placement. Please let me know if there are any better solutions.
Note: cy.get().trigger('') methods is not performing any actions either

Related

Custom Control: "Lifecycle-Method" when aggregation is updated

I am creating a simple custom control:
sap.ui.define([
"sap/ui/core/Control"
], function(Control) {
"use strict";
return Control.extend("my.control.SvgVisualizer", {
metadata: {
properties: {
width: {
type: "sap.ui.core.CSSSize",
defaultValue: "100%"
},
height: {
type: "sap.ui.core.CSSSize",
defaultValue: "100%"
}
},
aggregations: {
elements: {
type: "my.control.Element",
multiple: true,
singularName: "element"
}
}
},
renderer: {
apiVersion: 2,
render: function(oRm, oControl) {
oRm.openStart("svg", oControl.getId())
.attr("viewBox", oControl._sViewBox)
.attr("width", oControl.getWidth())
.attr("height", oControl.getHeight())
.openEnd();
oRm.close("svg");
}
}
});
});
Basically, it can be used to implement svg stuff with aggregations into SAPUI5.
When creating the svg (html)-element in the renderer function I need a viewBox.
I would like to calculate the value for the viewBox based on the properties of the controls in the aggregation elements. The calculation could be pretty heavy if there are loads of elements.
My question is where I should calculate the viewBox property. It needs to be recalculated when the aggregation elements changes (so init isn't enough) but it does not need to be recalculated every time the renderer function is called.
Is attaching a handler to the aggregation-binding in the constructor the best way: this.getBinding("elements").attachChange(...)
It is possible to override all the aggregation modifiers like addElement, removeElement, ...etc and recalculate there.
But I would suggest to implement some kind of change detection for the elements aggregation in the onBeforeRendering hook and perform calculations only if the aggregation has changed. This way you don't need to worry if you have overridden all the modifiers correctly and you have the implementation on a single place. For example:
onBeforeRendering: function () {
var currElements = this.getElements();
var recalculate = false;
if (!this._oldElements) {
recalculate = true;
} else if (this._oldElements.length !== currElements.length) {
recalculate = true;
} else if (... another condition that should trigger recalculation) {
recalculate = true;
}
if (recalculate) {
this._sViewBox = ...;
this._oldElements = currElements;
}
}

Trigger event on multiple features when hovering over any of those in leaflet

I have a layer with two polylines and polylineDecorators. I would like to highlight both polylines and polylineDecorators when I hover on any of these. Right now I'm able to highlight only one at the time when hovering on it.
Here is my code:
var layer_migration = L.layerGroup({
layerName: 'layer_migration',
pane: 'linesPane',
});
function onEachFeature_migration (feature, layer) {
var polyline = L.polyline(layer.getLatLngs(),{
color: "#8B0000",weight: 5,opacity: 0.4,dashArray: '8,8',
dashOffset: 0
}).addTo(layer_migration);
var PLdecorator1 = L.polylineDecorator(polyline, {
patterns: [{
offset: '104%',
repeat: 100,
symbol: L.Symbol.arrowHead({pixelSize: 16,
pathOptions: {color: "#8B0000",fillOpacity: 0.6,weight: 0
}
})
}]
}).addTo(layer_migration)
var myfeatures = L.featureGroup([polyline,PLdecorator1]).addTo(layer_migration);
myfeatures.on('mouseover', function(e) {
var layer = e.target;
layer.setStyle({color: '#8B0000',opacity: 1,fillOpacity:1
});
});
}
Any help super appreciated.
Thanks,
P
In your mouseover callback, I think that e.target will just refer to the individual layer (polyline or decorator) that triggered the event, not the collection of layers that make up the feature group. I've not tested it, but according to the docs, you ought to be able to get the effect you want by calling .setLayer() on the feature group itself:
myfeatures.on('mouseover', function(e) {
myfeatures.setStyle({color: '#8B0000',opacity: 1,fillOpacity:1});
});
Also, if the two polylines are created by two separate calls to onEachFeature_migration(), then they will end up as two separate feature groups. To get around this, you might need to assign an empty featureGroup to myfeatures outside the function, then add the new polylines to it inside the function using myfeatures.addLayer().

Open Layer: Problem with persistent select interaction feature

In my app I had to develop a system that allows the user, with a double click, to zoom in to a cluster.
Everything work, but the problem is that the double click add a feature on the map (a point) and it is persistent (it also replace the feature I selected in case I select not the cluster but the single element, even if I have specified that features.length>=2, so the double click should work only if the user doubles click on the cluster, but it is not like that ).
I would like the select interaction perform only the zoom into the cluster and not that the event adds also a feature on the map. How could I solve this?
var selectDoubleClick = new ol.interaction.Select({
multi: true,
condition: ol.events.condition.doubleClick,
layer: this.clusterLayer,
style: this.selectedClusterStyle
});
selectDoubleClick.on('select',function(event) {
var eventFeature = event.selected[0];
var features = eventFeature.get('features');
if (features.length>=2){
var extent = ol.extent.createEmpty();
features.forEach(function(feature) {
ol.extent.extend(extent, feature.getGeometry().getExtent());
});
this.getMap().getView().fit(extent, {padding: [150, 150, 150, 150]})
}
});
this.map.addInteraction(selectDoubleClick);
I also tried to set selectDoubleClick style:null but it doesn't solve my problem
Follow this discussion, I finally found a solution:
Openlayers 4 - Make layer invisible on feature click
In particular:
The ol.interaction.Select selected features are added to an internal
unmanaged layer.
This is why the selected feature is visible even if the underlying
layer is not.
You could unselect the selected features while you zoom on it using
select_interaction.getFeatures().clear() (just like clicking away).
So I edited my code like that:
selectDoubleClick.on('select',function(event) {
var eventFeature = event.selected[0];
var features = eventFeature.get('features');
if (features.length>1){
var extent = ol.extent.createEmpty();
features.forEach(function(feature) {
ol.extent.extend(extent, feature.getGeometry().getExtent());
});
this.getMap().getView().fit(extent, {padding: [150, 150, 150, 150]})
}else{
selectDoubleClick.getFeatures().clear()
}
});
this.map.addInteraction(selectDoubleClick);

Vizframe Datalabel show for one Line

I'm using Vizframe component where there is two lines, when I try to show the Datalabel, the modifications is applied to both lines, I want to apply it just to one of them (A line with Datalabel set to True and a line with DataLabel set to False.)
Here's how it looks
This is how I change DataLabel property:
plotArea: {
dataLabel: {
visible: false
},
},
Well I know that this question might be older, but I had a similar issue recently. You can use the renderer function to customize the data labels to your needs.
For me, it worked, when I checked the context data for the correct measure and decide then, if I return nothing, which shows the label normally or return an empty DOM node.
dataLabel: {
visible: true,
style: {
color: "#000"
},
renderer: function (ctx) {
var node = document.createElement("text");
if (ctx.ctx.measureNames === "Optimum") {
var text = document.createTextNode("");
node.appendChild(text);
return node;
}
}
},
As you can see in the picture below, the label for the orange line (Optimum) is gone.
You can hide the values when they are overlapped using this:
plotArea: {
dataLabel: {
visible: true,
hideWhenOverlap: true
}
}
Julian's answer is useful yet in order for the change to take effect on the document we need to attach the returned node to the parent data point node.
The renderer function does not provide data regarding the graph itself but only the selected label, which leaves us clueless on how to render the node effectively.
Something like this would make me happier:
renderer: function(...) {
var parent = document.getElementById(some_given_data_point_id);
parent.appendChild(text_node);
return parent;
}

Restrict drag and drop in ExtJs tree panel

I developed two tree panels in ExtJs (Tree-1 and Tree-2). These trees are working with drag and drop in between two of them in all the cases. I want drag and drop in the following cases
(From Tree-1 to Tree-2), (From Tree-1 to Tree-1) and (From Tree-2 to Tree-2) only. That is want to restrict drag and drop from Tree-2 to Tree-1. The following is my source code.
/*Tree1*/
Ext.create('Ext.tree.Panel', {
title: 'From Agent:',
collapsible: true,
collapseDirection: Ext.Component.DIRECTION_TOP,
frame:true,
width: 310,
minHeight: 50,
margin: '0 0 0 0',
store: store1,
listeners:{
checkchange:function( node, checked, eOpts){
node.cascadeBy(function(n){n.set('checked', checked);} );
}
},
rootVisible: false,
viewConfig: {
plugins: {
ptype: 'treeviewdragdrop',
sortOnDrop: true,
containerScroll: true
}
},
sorters: [{
property: 'text',
direction: 'ASC'
}]
}),
/*Tree2*/
Ext.create('Ext.tree.Panel', {
title: 'To Agent:',
frame: true,
collapsible: true,
collapseDirection: Ext.Component.DIRECTION_TOP,
width: 310,
margin: '0 0 0 20',
minHeight: 50,
store: store2,
listeners:{
checkchange:function( node, checked, eOpts){
node.cascadeBy(function(n){n.set('checked', checked);} );
}
},
rootVisible: false,
viewConfig: {
plugins: {
ptype: 'treeviewdragdrop',
sortOnDrop: true,
containerScroll: true
}
},
sorters: [{
property: 'text',
direction: 'ASC'
}]
}),
These codes are working as cut and paste while drag and drop. I want to make these code as copy and paste while drag and drop. Please, help me.
Thanks in advance.
Take a look at this example from the docs:
http://docs.sencha.com/extjs/4.2.2/extjs-build/examples/tree/custom-drop-logic.html
Basically it uses nodedragover event to control when one can drop or not.
Return false when you don't want to allow the drop.
As far as making it copy instead of cutting, the documentation mentions the following (although I've never tried it myself):
This plugin provides drag and/or drop functionality for a TreeView.
It creates a specialized instance of DragZone which knows how to drag
out of a TreeView and loads the data object which is passed to a
cooperating DragZone's methods with the following properties:
copy : Boolean
The value of the TreeView's copy property, or true if the TreeView was
configured with allowCopy: true and the control key was pressed when
the drag operation was begun.
Try setting copy: true to the two views.