set the data to dojo data grid - javascript

I am working with Dojo, and I have a small requirement. I am using a store to create a Memory. I have a hardcoded list so that I can set this list to a Dojo data grid store and thereby perform some rowclick functions. My issue is that I am not able to set the store, and I am getting an error,
this.headerContentNode.firstChild is null. Please can anybody help me out?
the code snippet....
postCreate : function () {
//publist, sublist etc
this._handleLogDetails();
},
//methods...
_handleLogDetails : function(){
alert("hello...h..");
var theGreatestTeamOfAllTime = [ {
"jobName":"12",
"jobId":"Jim Kelly",
"status":"QB",
"timeStamp":"0"
},
{
"jobName":"1",
"jobId":" Kelly",
"status":"B",
"timeStamp":"10"
}
];
var clientJobStore = this.jobModel.getLogStore();
clientJobStore.setData(theGreatestTeamOfAllTime);
var thisData = new ObjectStore({objectStore: clientJobStore});
this.dapJobStatusGrid1.setStore(thisData); // attach point of dojo data grid, getting an error at this point...

Hard to say exactly what the issue is here without seeing how the grid is configured, but this is likely caused by one of the following:
You didn't call startup() on your grid.
When constructing your grid, you did not provide a DOM node for the grid.
For example, perhaps try something like the following, where the second argument is the DOM node the grid should be attached to.
var options = {// some options};
var foo = new DataGrid(options, someContainer.domNode);
foo.startup();

Related

crossfilter.js with dc.js update charts on callback group change

I have a factory for creating dc.js charts which uses crossfilters functions bound to $scope. Plnkr Example
$scope.updateMyPie = function(data) {
var cf = crossfilter(data)
$scope.mypie.dimension = cf.dimension(function(d) { return d.key })
$scope.mypie.group =
$scope.mypie.dimension.group().reduceSum(function(d){ return d.value });
}
chart factory takes all chart properties through the DOM via angular directive so the tags are like so
<mypie id="mypie" chart-dimesion="mypie.dimension" chart-group="mypie.group"...etc
this approach works fine for filtering, initial data loading, binding and chart rendering, etc....however this is one exception. If I have something like a button click event that fires a new data request, and then I use the above as the callback it takes and processes the data fine, but doesn't update the chart. Even if I include dc.redrawAll() or renderAll(), etc.
I have tried embedding redraw(), redrawAll(), verified the data is coming back correctly, destroying the tag entirely and re-creating and appending to DOM,etc. My assumption is there is an issue with my usage of this factory-style implementation of creating the DC/D3 charts, but I would assume that if I updated the group and/or dimenstion in the scope it should still work? It seems as though the chart objects don't pick up the changes to the dim/groups? I can verify that the cf group values referenced by the $scope.etc have changed by using the following in both the initial call and second call:
var print_filter = function(filter) {
var f = eval(filter);
if (typeof (f.top) != "undefined") {
f = f.top(Infinity);
}
if (typeof (f.dimension) != "undefined") {
f = f.dimension(function (d) {
return "";
}).top(Infinity);
}
console.log(filter + "(" + f.length + ") = " + JSON.stringify(f).replace("[", "[\n\t").replace(/}\,/g, "},\n\t").replace("]", "\n]"));
};
UPDATE: added plnkr, and attempt to better explain= so with the example I have sort of a "traditional" way to build the dc chart versus the service based approach I am trying to achieve using a directive and element. Everything works except what I have attempted to show in the plnkr...when I request new data (ajax) the first updates fine, with the directive based approach nothing seems to work. I have tried numerous ways but essentially updating the $scope dim/group should be working right? I believe it is two way binding therefore these "two scopes" should share a reference?? But even if I use scope.$parent.my.dimension, etc it doesn't affect it.
Your chart is still bound to your old crossfilter, dimension, and groups. Generally, when you load new data or replace data, don't throw away your crossfilter, dimension, or groups. Use the crossfilter.remove and crossfilter.add methods to add or remove data.
Here's how to modify your example:
Create your Crossfilter, dimensions, and groups up front when you create your controller, then don't create or destroy any more of them in the future:
myapp.controller('mycontroller', ['$scope', 'dataCaller', function($scope, dataCaller){
$scope.pageTitle = "Updating DC.js and Crossfilter";
$scope.currentData1 = "data1.json";
$scope.currentData2 = "data1.json";
$scope.my = {};
$scope.my.cf = crossfilter();
$scope.my.dimension = $scope.my.cf.dimension(function(d){ return d.key; })
$scope.my.group = $scope.my.dimension.group().reduceSum(function(d){ return d.value; })
Then change your update function to just switch out the data in the Crossfilter:
$scope.factoryBuildPieExample = function(data) {
$scope.my.cf.remove()
$scope.my.cf.add(data.response.data)
dc.redrawAll();
}
If you want to maintain your dc.js filters when you do this, this question/answer explains how: Updating dc.js data and reapplying original filters
Here is a working Plunker: http://plnkr.co/edit/UbfKsuhg9vH678MR6fQT?p=preview

SAPUI5 Table: unbindRows & destroyColumns cause error: Cannot read property 'shouldRender' of undefined

I am using the Table object from the SAPUI5's sap.ui.table namespace:
var oTableOverview = new sap.ui.table.Table();
On rowSelectionChange, when selecting one row I populate another table, let's call it oTableDetail, that is filled with some data.
When deselecting the row from the first table, I want to clear the content of the second, and for that I use:
oTableDetail.destroyColumns();
oTableDetail.unbindRows();
When deselecting the row I get the following error:
TableRenderer.js:6 Uncaught TypeError: Cannot read property 'shouldRender' of undefined
I found the method shouldRender of the sap.ui.table.Column class, but I am not sure why would the cells be rerendered in this case.
I also noticed that if I use either oTable.destroyColumns(), or oTable.unbindRows() separately, the error does not appear.
I am using the "1.38.11" version of SAPUI5.
Can you please help me identify why this happens?
EDIT 1: A possible workaround would be to use:
oTableDetail.setModel(new sap.ui.model.json.JSONModel({}));
oTableDetail.destroyColumns();
Although I still don't know why the code mentioned before is not working.
EDIT 2: A behavior that I find a bit weird:
trying to add a setTimeout like this works (the error is not happening):
oTable.destroyColumns();
setTimeout(function(){ oTable.unbindRows(); }, 50);
but this other way it doesn't work (the error still appears) even if the delay is longer:
oTable.unbindRows();
setTimeout(function(){ oTable.destroyColumns(); }, 50);
var oTableOverview = new sap.ui.table.Table();
//your model with new dynamic data
var oModel = new sap.ui.model.json.JSONModel(newData);
oTableDetail.setModel(oModel);
//use rerender method which tries to replace
//its DOM reference by re-rendering with new data.
oTableDetail.rerender();
You don't need to actually delete columns or unbind rows.
Rerender method will take care of new data.
So if you don't want to set a new model, then just try to clean oData of an existing model.
var oTable = this.byId("oTable")
//your model with new dynamic data
var oModel = oTable.getModel();
oModel.setData(null);
// then if its needed, use updateBindings method to refresh
oModel.updateBindings();

SAPUI5 bind model from core to list

I have 2 models in my application that I bind to sap.ui.core.
The following code is from my main view. Which is a split-app.
var checks = {
items: [
{
checklist: "ContainerCheck",
title:"Scan RFID container",
}
// etc...
]}
;
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData(checks);
sap.ui.getCore().setModel(oModel, "checks");
In another view I want to bind data to the masterpage
var oItemTemplate = new sap.m.ActionListItem({
title : "{title}",
icon : "sap-icon://activity-2",
activeIcon: "sap-icon://activity-2",
type : sap.m.ListType.Active,
});
this.oList = new sap.m.List({
itemPress: [oController.onListSelect, oController]
});
this.oList.bindItems("checks>/items",oItemTemplate);
However I'm not seeing any data in the list. I'm quite sure the sPath is correct checks>/items. Is it not possible to use this sPath because the model is bind to sap.ui.core. Or am I missing something else?
I'm pretty sure you have to prefix the propertyBinding with the models name:
var oItemTemplate = new sap.m.ActionListItem({
title : "{checks>title}",
...
});
This should work.
Try this this.oList.bindItems("{checks>/items}", oItemTemplete); instead of this.oList.bindItems("checks>/items",oItemTemplate);
I stumbled about the same problem and after a while I found this comment:
A control can only bind to one model, so if you have a container control with an assigned model, all controls contained in this container can only see the local model of the container and are no longer able to bind to the global model.
I assume that is the problem in your code. At least that's the one in mine :-)

Sencha Touch 2: How to FIlter on a Association's Store?

I have an issue trying to filter the results of an association. I have a list of categories with many subcategories. I'm using MVC architecture. So, here is an example what I'm trying to do:
var subcategories = category.subcategories();
subcategories.filter("title", "some text");
subcategories.each( function (item) { console.log(item.get('title')); } );
Some how the filter is not applying. It always return the original store, same amount of records, etc.
I'm also doing this:
var subcategories = category.subcategories();
subcategories.filterBy(function(item) {
console.log( item );
return (item.get('title') == 'some text');
});
But the console.log it's not running even once! The store is full of records, I've cehcked that
Any ideas? Am I doing something wrong?
Thanks
This may be a late answer, but it will help many people who are searching solution for the same problem.
The key is to calling setRemoteFilter(false) on Association's Store.
var products = user.products();
products.setRemoteFilter(false); // without this line, filter on Association's Store didn't work
var categorieFilter = new Ext.util.Filter({
property: 'categories',
value : 'Electronic'
});
products.setFilters(categorieFilter);
Couple questions:
What version of Sencha Touch are you using?
When using associations in Sencha Touch you still need to do a lot of work by yourself. It's not completely automatic. For example you need to add all subcatagories manually to each category object. Are you doing this?

How do I re-use components in ExtJS?

I have an ExtJS grid like so:
var grid = new Ext.grid.GridPanel({
...
});
I'd like to be able to re-use this grid so that I can have it multiple instances of it that all act independently. Is the only way to do this is by using Ext.extend, or is there another way? I don't really need to extend it, I just need to be able to create multiple instances of it.
If you really just need two grid instances, then create another one as Upper Stage said.
If you need to share a config among multiple grids, you could save the config as a separate JS object that you then pass into the grid constructor each time you create one.
var myCfg = { ... };
var grid1 = new Ext.GridPanel(Ext.apply(myCfg, { /* other options */ }));
var grid2 = new Ext.GridPanel(Ext.apply(myCfg, { /* other options */ }));
If you are going to reuse the grid with a particular configuration across your app or in multiple apps, then a subclass may be the best way to go.
This tutorial reviews several different methods for reusing functionality and would be a good starting point for you to decide what approach best suits your needs (if you need something beyond two basic instances).
Ext.Component#cloneConfig() perhaps?
Can you simply instantiate new objects?
var anotherGrid = new Ext.grid.GridPanel({
...
});
Ext has decent support for subclassing. This means you can extend the standard grid and instantiate that:
Foo = {};
Foo.BarGrid = function(config) {
Foo.BarGrid.superclass.constructor.call(this, config); //call the default grid constructor
}
Ext.extend(Foo.BarGrid, Ext.grid.GridPanel, {
//grid config
});
var grid = new Foo.BarGrid({/*minimal config*/});
You can even register your own xtype and use that instead of newing it:
Ext.reg('foobargrid', Foo.BarGrid);
var pane = new Ext.TabPanel({
items: [{xtype: 'foobargrid'}]
});
EDIT Misread the question. Since you obviously know about Ext.extend sharing the config, as suggested by bmoeskau, might just do the trick for you.

Categories

Resources