Using PanZoom JS, I am trying to handle a simple click event for any SVG that was clicked. According to docs, it should be as simple as this:
$panzoom.on('panzoomend', function(e, panzoom, matrix, changed) {
if (changed) {
// deal with drags or touch moves
} else {
// deal with clicks or taps
}
});
This never fires and it never hits the if test.
First you have to create the $panzoom variable and call the panzoom.
You can enter something like this
var $panzoom = $('.panzoom').panzoom({
contain: 'invert',
minScale: 0.5,
increment: 0.5,
});
after you can enter your code
$panzoom.on('panzoomend', function(e, panzoom, matrix, changed) {
if (changed) {
// deal with drags or touch moves
alert("changed");
} else {
// deal with clicks or taps
alert("not changed");
}
});
Related
I'm using ag-grid (javascript) to display a large amount of rows (about 3,000 or more) and allow the user to enter values and it should auto-save them as the user goes along. My current strategy is after detecting that a user makes a change to save the data for that row.
The problem I'm running into is detecting and getting the correct values after the user enters a value. The onCellKeyPress event doesn't get fired for Backaspace or Paste. However if I attach events directly to DOM fields to catch key presses, I don't know how to know what data the value is associated with. Can I use getDisplayedRowAtIndex or such to be able to reliably do this reliably? What is a good way to implement this?
EDIT: Additional detail
My current approach is to capture onCellEditingStopped and then getting the data from the event using event.data[event.column.colId]. Since I only get this event when the user moves to a different cell and not just if they finish typing I also handle the onCellKeyPress and get the data from event.event.target (since there is no event.data when handling this event). Here is where I run into a hard-to-reproduce problem that event.event.target is sometimes undefined.
I also looked at using forEachLeafNode method but it returns an error saying it isn't supported when using infinite row model. If I don't use infinite mode the load time is slow.
It looks like you can bind to the onCellKeyDown event. This is sometimes undefined because on first keydown the edit of agGrid will switch from the cell content to the cell editor. You can wrap this around to check if there is a cell value or cell textContent.
function onCellKeyDown(e) {
console.log('onCellKeyDown', e);
if(e.event.target.value) console.log(e.event.target.value)
else console.log(e.event.target.textContent)
}
See https://plnkr.co/edit/XhpVlMl7Jrr7QT4ftTAi?p=preview
As been pointed out in comments, onCellValueChanged might work, however
After a cell has been changed with default editing (i.e. not your own custom cell renderer), the cellValueChanged event is fired.
var gridOptions = {
rowData: null,
columnDefs: columnDefs,
defaultColDef: {
editable: true, // using default editor
width: 100
},
onCellEditingStarted: function(event) {
console.log('cellEditingStarted', event);
},
onCellEditingStopped: function(event) {
console.log('cellEditingStopped', event);
},
onCellValueChanged: function(event) {
console.log('cellValueChanged', event);
}
};
another option could be to craft your own editor and inject it into cells:
function MyCellEditor () {}
// gets called once before the renderer is used
MyCellEditor.prototype.init = function(params) {
this.eInput = document.createElement('input');
this.eInput.value = params.value;
console.log(params.charPress); // the string that started the edit, eg 'a' if letter a was pressed, or 'A' if shift + letter a
this.eInput.onkeypress = (e) => {console.log(e);} // check your keypress here
};
// gets called once when grid ready to insert the element
MyCellEditor.prototype.getGui = function() {
return this.eInput;
};
// focus and select can be done after the gui is attached
MyCellEditor.prototype.afterGuiAttached = function() {
this.eInput.focus();
this.eInput.select();
};
MyCellEditor.prototype.onKeyDown = (e) => console.log(e);
// returns the new value after editing
MyCellEditor.prototype.getValue = function() {
return this.eInput.value;
};
//// then, register it with your grid:
var gridOptions = {
rowData: null,
columnDefs: columnDefs,
components: {
myEditor: MyCellEditor,
},
defaultColDef: {
editable: true,
cellEditor: 'myEditor',
width: 100
},
onCellEditingStarted: function(event) {
console.log('cellEditingStarted', event);
},
onCellEditingStopped: function(event) {
console.log('cellEditingStopped', event);
}
};
I have two series of points on a Highcharts scatter plot. One of the series is draggable. The other has a click event:
events: {
click: function(e) {
if (e.point.v != 0) {
if (e.point.options.p != 0) {
location.href = 'newPage.php?pID=' + e.point.options.p;
}
}
}
},
When I drag a point from the first series and leave it (mouse-up) over a point from the second series, the click event fires and the page is redirected.
I don't want that click event to occur when dragging a point over it.
You can try using the custom events plugin for this, so that for the second series the event is 'mousedown' and not click. That should solve the problem.
plotOptions: {
series: {
point: {
events: {
mousedown: function () {
alert(this.y);
}
}
}
}
}
A working example.
NOTE: You need to be running the latest version of Highcharts for this to work, which 3.0.7
In OpenLayers 2 one can specify a pixelTolerance setting in the Click handler. If the map is moved by less than or equal to this number of pixels a click event is also fired.
OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, {
defaultHandlerOptions: {
'pixelTolerance': 20,
...
},
...
}
Question: Is there anything similar in OpenLayers 3?
You can achieve this listening if map is dragging:
map.on('pointermove', function(evt) {
if (evt.dragging) {
console.info('dragging');
}
});
// another option
map.on('pointerdrag', function(evt) {
console.info('pointerdrag');
console.info(evt);
});
Scenario: user can drag an item on the web page, and drop on other item(s). When user drags item onto another object, live feedback is shown to the user about what will happen if he drops item X on item Y.
When user start to drag data must be fetched from backend for current item and this might take 1-2 seconds.
So basically while this happens, we must show to the user some kind of loader, and wait before giving feedback, even though he already may have dragged item X onto item Y.
I'm using dragula library which has the following signature:
dragula(dragulaConfig)
.on('drag', function(el, source ) { /* do on drag */ })
.on('cancel', function(el, container, source ) { /* do on cancel */ })
.on('drop', function(el, target, source ) { /* do on drop */ })
.on('over', function(el, container, source ) { /* do on over */ })
.on('out', function(el, container, source ) { /* do on out */ });
So basically it does not care if i have the data or not, it just fires the events.
What i'm thinking is to use Rx to limit events to over and out events until i have data for given draggable item.
My attempt at this:
var instance = dragula(dragulaConfig);
var pauser = new Rx.Subject();
var rxo = Rx.Observable;
var transform = function(el, target, source) {
return {
el: el,
target: target,
source: source
};
};
var pause = function() {
pauser.onNext(false);
};
//subscribe to drag event, and release pause once we have the data./
rxo
.fromEvent(instance, 'drag', transform)
.subscribe(function(event) {
thisReturnsAPromise(event).then(function() {
pauser.onNext(true);
});
});
// subscribe to 'over' event that will not be fired until we have our item data
rxo
.fromEvent(instance, 'over', transform)
.pausable(pauser)
.subscribe(function() { /* show feedback to the user */});
// subscribe to 'out' event that will not be fired until we have our item data
rxo
.fromEvent(instance, 'out', transform)
.pausable(pauser)
.subscribe(function() { /* remove feedback to the user */});
// subscribe to 'cancel' event - this will put pause to over/out events
var cancel = rxo
.fromEvent(instance, 'cancel', transform);
cancel.subscribe(pause);
cancel.subscribe(function() { /* show feedback to the user if he cancels */});
// subscribe to 'drop' event - this will put pause to over/out events
var drop = rxo
.fromEvent(instance, 'drop', transform);
drop.subscribe(pause);
drop.subscribe(function() { /* add dropped item */});
Which works, but it just does not feel right (and I'm newbie to RxJS) - too much boilerplate.
How could I improve this?
Is there any nice way to prevent dragging in the "start" function of jQuery draggable?
Such that the actual "drag" callback isn't called at all.
$("#item" + i).draggable({
...
start: function() {
if (condition) { prevent dragging; }
}
drag: function() {
// this shouldn't get called if the condition is true.
console.log("obama loves syria");
}
}
Calling $(document).trigger("mouseup") doesn't work very well since, if the mouseman is fast enough, the element still succeeds to move a bit.
Try with
return false;
to exit the start method and prevent movement