Dropping onto an event (as opposed to the calendar) - how to identify event? - drag-and-drop

I have successfully implemented dragging of a jquery-ui element onto my fullCalendar. The problem is that what I want to drop onto is not the calendar itself but a specific event displayed on the calendar in order to add the dropped item to the event. The missing piece is how to identify the event that was under the mouse when I dropped.
drop: function (date, allDay, jsEvent, ui)
{
var event = ???;
event.description += ui.helper.data("filters").text;
$('#calendar').fullCalendar('updateEvent', event);
}

I've discovered the solution. Basically you have to add "droppable" to the event element. I do this by catching the "eventRender" (I assume this is a good spot)...
eventRender: function (event, element)
{
// store the ID for later...
$(element).data('id', event.id);
element.droppable({
drop: function (event, ui)
{
// get the ID I stored above...
var rowID = $(this).data('id');

I just implemented this - thankyou for your solution!
I'm using it in combination with drop - I need to be able to drop events either onto another event or onto a date.
In my case adding event.stopPropogation(); in element.droppable drop is necessary to stop the date drop function from also triggering.

Related

ag-grid programmatically selecting row does not highlight

Using Angular 4 (typescript), I have some code like below using ag-grid 12.0.2. All I'm trying to do is load my grid and automatically (programmatically) select the first row.
:
this.gridOptions = ....
suppressCellSelection = true;
rowSelection = 'single'
:
loadRowData() {
this.rowData = [];
// build the row data array...
this.gridOptions.api.setRowData(this.rowData);
let node = this.gridOptions.api.getRowNode(...);
// console logging here shows node holds the intended row
node.setSelected(true);
// console logging here shows node.selected == true
// None of these succeeded in highlighting the first row
this.gridOptions.api.redrawRows({ rowNodes: [node] });
this.gridOptions.api.redrawRows();
this.gridOptions.api.refreshCells({ rowNodes: [node], force: true });
First node is selected but the row refuses to highlight in the grid. Otherwise, row selection by mouse works just fine. This code pattern is identical to the sample code here: https://www.ag-grid.com/javascript-grid-refresh/#gsc.tab=0 but it does not work.
Sorry I am not allowed to post the actual code.
The onGridReady means the grid is ready but the data is not.
Use the onFirstDataRendered method:
<ag-grid-angular (firstDataRendered)="onFirstDataRendered($event)">
</ag-grid-angular>
onFirstDataRendered(params) {
this.gridApi.getDisplayedRowAtIndex(0).setSelected(true);
}
This will automatically select the top row in the grid.
I had a similar issue, and came to the conclusion that onGridReady() was called before the rows were loaded. Just because the grid is ready doesn't mean your rows are ready.(I'm using ag-grid community version 19) The solution is to setup your api event handlers after your data has loaded. For demonstration purposes, I'll use a simple setTimeout(), to ensure some duration of time has passed before I interact with the grid. In real life you'll want to use some callback that gets fired when your data is loaded.
My requirement was that the handler resizes the grid on window resize (not relevant to you), and that clicking or navigating to a cell highlights the entire row (relevant to you), and I also noticed that the row associated with the selected cell was not being highlighted.
setUpGridHandlers({api}){
setTimeout(()=>{
api.sizeColumnsToFit();
window.addEventListener("resize", function() {
setTimeout(function() {
api.sizeColumnsToFit();
});
});
api.addEventListener('cellFocused',({rowIndex})=>api.getDisplayedRowAtIndex(rowIndex).setSelected(true));
},5000);
}
Since you want to select the first row on page load, you can do onething in constructor. But your gridApi, should be initialized in OnGridReady($event) method
this.gridApi.forEachNode((node) => {
if (node.rowIndex === 0) {
node.setSelected(true);
}
It's setSelected(true) that does this.
We were using MasterDetail feature, its a nested grid and on expanding a row we needed to change the selection to expanded one.
Expanding a row was handled in
detailCellRendererParams: {
getDetailRowData: loadNestedData,
detailGridOptions: #nestedDetailGridOptionsFor('child'),
}
and withing loadNesteddata, we get params using we can select expanded row as
params.node.parent.setSelected(true)
Hope this helps.

How to observe added events in Meteor without firing on initialization?

There is a lot of information on this topic out there, but I can't seem to get it working for myself. I am using toastr to display notifications of events to the user in the top right hand corner of my app. I need to add an observer for the 'added' event to a collection, and create the toastr notification when an item is added. The problem is that the observer fires when the collection is initialized. I've tried about a half dozen different ways trying to check of the collection is ready() before I allow the observer code to continue through and show notifications, but I can't get it working consistently, especially when changing pages. Here is some sample code:
MainController = RouteController.extend({
before: [
function() {
deviceEventsInitializing = true;
var alerts = this.subscribe("alerts", Meteor.user()._id);
if (alerts.ready()) {
deviceEventsInitializing = false;
}
Alerts.find().observeChanges({
added: function(id, doc) {
if (deviceEventsInitializing || deviceEventsInitializing == undefined) {
return;
}
doToastrStuff();
}
});
this.next();
}
],
});
This is just my latest attempt. The flow goes like this:
1.) Subscription happens, all the items in the collection hit the observer but deviceEventsInitializing is true so it does nothing.
2.) alerts.ready() fires and deviceEventsInitilizing is set to false.
3.) The added trigger fires again for all the events in the collection, causing toastr to be called for every item.
All I'm interested in is the following:
1.) Some trigger or event where I can set a variable that says the subscription is reloading the collection.
2.) Some trigger or event that tells me that this reloading of the collection is complete so I can set a variable indicating that.
I think you're on the right track, but trying to manage reactivity like this using solely IronRouter can be a nightmare. I've tried and failed before.
Instead, leverage Mongo to limit your reactivity to only alerts you care about. Let's imagine your alerts database looks something like:
{
_id: 1,
hasNotified: false,
...
}
Now, Mongo is deciding what is new vs. not new instead of trying to determine state based on IronRouter timing. In fact, because in Meteor any alerts cursor is natively reactive, you don't even need to observeChanges:
MainController = RouteController.extend({
waitOn: function() {
return this.subscribe("alerts", Meteor.userId());
},
data: function() {
var newAlerts = Alerts.find({hasNotified: false}).forEach(function(doc) {
doToastrStuff();
Alerts.update({_id: doc._id}, {$set: {hasNotified: true}});
});
}
})
With this kind architecture, navigating to other routes, reloading the page, etc. will not re-fire any of your alerts because Mongo stores your alert state.

Controller lifecycle: when to call table.autoResizeColumn()

I'm currently using onAfterRendering() hook to auto adjust the layout of a table like this:
onAfterRendering: function() {
var table = this.getView().byId('table');
for (var i = 0; i < table.getColumns().length; i++) {
table.autoResizeColumn(i);
}
}
The result is not usable: all columns are sized 100% of the parent's width.
If I add a simple button to invoke the exact same logic the table gets drawn nicely. It looks like the complete table needs to be present in the DOM before autoResizeColumn() works properly.
My question: is there a suitable hook/event I can use to invoke the resizing once the table is in the document?
You can use the onAfterRendering of the table as suggested and add an if statement with bResized boolean or some kind of counter to prevent the endless loop.
As others have answered you can put add a function to oTable.onAfterRendering but the trick is if you do any rendering in that function it will trigger another rendering event that will again trigger onAfterRendering.
The problem here is where to hang the boolean switch that determine you have done the thing you have done.
One way to get around that is to add some customer data to the table with oTable.addCustomData.
The pattern becomes :
```
oTable.onAfterRendering = function () {
// check the prototype
// read the custom data
var customData = this.getCustomData();
// confirm *your* custom data is in the array (and not some other custom data)
// if not do your rendering operation and then
// set a switch to custom data
this.addCustomData(new sap.ui.core.CustomData({
key: "myRenderingCheck",
value: "true",
"writeToDom": true
}));

How to programmatically fire keydown event in ExtJS 4

In ExtJs 4 how can I programmatically fire 'keydown' (or 'keypress') event (on TAB key) ?
I should want to simulate a TAB key pression in response to another event.
I have tried with code (in this event handler) :
field.fireEvent('keydown', {keyCode: 9})
but it's not working...
You may have to spy your DOM a bit (to see what elements are there, like fileInputEl in the example below), but this works for me:
var uploadField = Ext.getCmp( 'uploadField' );
uploadField.fileInputEl.dom.click();
I am also looking for a solution .... I have a numberfield component and a pop-up keyboard... when I try to click on key ('.') on the keyboard-pop-up... I want to attach to numberfield (like when you press '.')... but nothing happens. I try this:
// Ext version 5.1
var field = Ext.getCmp('numberfield-test');
var event = Ext.create('Ext.event.Event', {
key: 110 // Want to emulate '.' key
});
// none of the following works
field.fireEvent('keydown', [ field, event ]);
field.fireEvent('keypress', [ field, event ]);
field.fireEvent('keyup', [ field, event ]);
// neither this ones
field.fireEvent('keydown', field, event);
field.fireEvent('keypress', field, event);
field.fireEvent('keyup', field, event);

Event after DOM manipulation in Sencha Touch

Is their an event available after DOM manipulation in Sencha Touch has succeeded?
I want to measure the time it takes to render a list with 1000 elements.
Therefor, a timer is started when the list is initialized and stoppend when the list is painted like so:
listeners: {
initialize: function () {
start = new Date();
var store = Ext.getStore('Songs');
for (var i = 1; i <= 1000; i++) {
store.add({id: i});
}
},
painted: function () {
stop = new Date();
Ext.Msg("Timer", stop - start);
}
}
The painted event is triggerd before DOM manipulation so the 1000 listitems are not visible when the rentertime pops up.
Is there an other event that is triggerd after DOM has been manipulated and the list is updated?
Or is there an alternative method to measure the time it takes to do this?
Greets,
Sander Van Loock
Unfortunately you are not answering, therefore I can only guess:
You are adding each item seperately to the store. In Sencha Touch this will eat up time. Better to create an array of items and add them at once.
If you are adding items and the update of the store takes too long, stop sorting of the store.
If you are interested in the list you better work with before and after events. Something like before updatedata and after updatadata. Or you could add start to the first itemTpl.
But again. Painting of a list which is infinite will not take any real time. So the DOM part really is not what you are looking for.
If you are using the dataview, this might be different.