Meteor.js event on client data redrawn/update - javascript

Is there a way to know on the client side when the data has been re-rendered?
I am using aldeed:tabular package and the problem I'm having is that when the data changes, I loose my selected highlighted row because the table is completely redrawn.
So, I need to catch this re-rendering event in order to re-highlight my selected row.

When you create your data table options, add a callback function for the drawCallback property, documented here
Like so:
TabularTables.MyTable = new Tabular.Table({
// other DT properties...
drawCallback: function( settings ) {
// do your magic here
}
});

Related

ag-Grid RowClassRule not updating after using updateRowData

I'm trying to update an ag-Grid row data the following way:
this.table.api.updateRowData({
update: [response.data]
})
The updating works fine, the cells get the updated values. However, Ag Grid is not re-evaluating the class of the row. Additionally, I get an error message:
ag-Grid: could not find data item as object was not found
Here is my rowClassRule:
rowClassRules: {
"row-disabled": function(params) {
if (params.data.status != 1) {
return true
}
}
}
What am I doing wrong here and how can I get ag Grid to update the class as well? I have tried using: rowNode.setData() which was working perfectly (updating the cell value + class) - but I can't use it because it's not refreshing the filters, unfortunately.
After setting the new row data, since you are using rowClass feature you have to use api.redrawRows()
rowNode.setData() being an api method is closely tied with ag-grid change detection mechanism and would automatically trigger api.refreshCells() for you. But if you are manually updating the data set, you need to invoke api.redrawRows() for styles to change.
As per docs -
Use redraw row if you want to create the row again from scratch. This
is useful when you have changed a property that only gets used when
the row is created for the first time such as:
Whether the row is fullWidth or not.
The cellRenderer used for any cell (as this is specified once when the cell is created).
You want to specify different styles for the row via the callbacks getRowStyle() or getRowClass().
Example here - redraw nodes

Kendo datasource requestEnd event parameter has no type

I have a kendo grid where I want to execute some code after the datasource syncs. In my datasource, I have the requestEnd event defined as:
requestEnd: function(e) {
console.log(e);
// More code...
}
On initial page load, the event fires after read and I see the logged object as:
However, later on when I call a create / update via grid.dataSource.sync() the event object is logged, but is missing the type property:
Why does the event parameter in requestEnd look good in read operations, but is missing data in create / update operations? I've also tried using the sync event, but when I include that in my datasource, it doesn't seem to ever get hit at all.

How to unsubscribe from the collection?

My publications:
Meteor.publish('items', function() {
return Items.find({}, {skip: randomNumber, limit: 100});
});
My subscription code happening when a button is clicked (in templates.event)
Meteor.subscribe('items');
Items.find().fetch();
However, the problem is that items isn't refreshed with the new data, but new data is appended to the old list instead. What can I do to unsubscribe the old data?
When you call Meteor.subscribe it will return a subscription handle.
You call stop on the handle to cancel it.
eg, in your event helper
if (SomeGlobalVar){
SomeGlobalVar.stop();
}
SomeGlobalVar = Meteor.subscribe('items');
The other way is to run the subscription inside Deps.autorun; it will automatically clean up old subscriptions.
eg, in you event handler
Session.set('subscribe', true);
Elsewhere in your code:
Deps.autorun(function(){
if (Session.get('subscribe')){
Meteor.subscribe('items');
}
});
If you call Session.set('subsribe', false); Meteor will automatically cancel/clean-up that subscription to items.
Seems to me like there is a bit of a confusion here, when you are connecting to a reactive data source you are not subscribing to specific data, so when new records are added ofcourse they are appended to your data through that connection.
If I understood your question and you want the new data to completely replace the old data I advise you not to build your template around the Collection but rather build it around a cached version of the data (which will kept in an object and made reactive using Deps), that way you will have total control over the data displayed.

Prevent Kendo grid data bind events when updating multiple model properties

I'm updating multiple properties on a Kendo datasource row model (using model.set javascript), and I want the grid to update only after the last change is made.
Another issue is that i don't know (without many if statements) whether any of the properties actually changed.
This is the answer I pulled off the Kendo Forum:
var grid = $("#grid").data("kendoGrid");
grid.bind("dataBinding", function(e) { e.preventDefault(); });
//begin modifying the data
//.....
//finish modifying the data
grid.unbind("dataBinding");
grid.refresh();

Edit List using Backbone.js/Marionette

I'll start off with I'm new to these two frameworks but I'm really excited with what I've learned so far with them. Big improvement with the way I've been doing things.
I want to display a collection of items (trip itineraries) in say a table. I only want to display a couple of the itinerary fields in the table because there are many fields. When you edit/add an item, I would like to display a form to edit all the fields in a different region or in a modal and obviously when you save the list/table is updated. I'm unsure of the best way to structure this and am hoping someone could point me in the right direction or even better an example of something similar. My searches so far have came up short. It seems I should use a composite view for the list but how to best pass the selected item off to be edited is where I'm kinda stuck at. Any pointers would be much appreciated.
I'd use a CompositeView for the table, and an ItemView for the form. Clearly this is incomplete, but it should get you started. Actually... I kind of got carried away.
What follows are some ideas for the basic structure & flow. The implementation details, including templates, I'll leave to you.
The table/row views:
// each row in the table
var RowView = Backbone.Marionette.ItemView.extend({
tagName: "tr"
});
// This could be a table tag itself, or a container which holds the table.
// You want to use a CompositeView rather than a CollectionView so you can
// render the containing template (the table tag, headers), and also, it works
// if you have an actual collection model (ItineraryList, etc).
var TableView = Backbone.Marionette.CompositeView.extend({
itemView: RowView,
collectionEvents: {
"change": "render"
}
});
The form view:
// This would be a simple form wrapper that pulls default values from
// its model. There are some plugins in this space to help with
// forms in backbone (e.g. backbone-forms), but they may or may not
// be worth the bloat, or might be tricky to work with Marionette.
var FormView = Backbone.Marionette.ItemView.extend({
events: {
"submit form": "onFormSubmit"
},
data: function () {
// here you'd need to extract your form data, using `serializeArray`
// or some such, or look into a form plugin.
return {};
},
// Clearly this is incomplete. You'd need to handle errors,
// perhaps validation, etc. You probably also want to bind to
// collection:change or something to close the formview on success.
//
// Re-rendering the table should be handled by the collection change
// event handler on the table view
onFormSubmit: function (e) {
e.preventDefault();
if (this.model.isNew()) {
this.collection.create(this.data());
} else {
this.model.save(this.data());
}
}
});
Somewhere in your load process you'd instantiate a collection and show it:
// first off, somewhere on page load you'd instantiate and probably fetch
// a collection, and kick off the tableview
var itineraries = new Itineraries();
itineraries.fetch();
// For simplicity I'm assuming your app has two regions, form and table,
// you'll probably want to change this.
app.table.show(new TableView({collection: itineraries}));
Making routes for the edit and new itinerary links makes sense, but if your form is in a modal you might want to bind to button clicks instead. Either way, you'd open the form something like this:
// in the router (/itineraries/edit/:id) or a click handler...
function editItinerary(id) {
var itinerary = itineraries.get(id);
// then show a view, however you do that. If you're using a typical
// marionette region pattern it might look like
app.form.show(new FormView({
collection: itineraries,
model: itinerary
});
}
// once again, a route (/itineraries/new), or a click handler...
function newItinerary() {
app.form.show(new FormView({
collection: itineraries,
model: new Itinerary()
}));
}

Categories