I have a problem creating ng-grids dynamically:
The next function loops through each element of $scope.dataSparqlResponses (each element is an array of data) and put the value of the iteration in $scope.dataSparqlAux. And $scope.dataSparqlAux is the variable used in the grids (data input). The problem is that in each iteration this variable ($scope.dataSparqlAux) is reassigned, so in the template I can only see the last grid with data.
**controller.js**
$scope.crearGrids = function() {
angular.forEach($scope.dataSparqlResponses, function(elem) {
$scope.dataSparqlAux = elem.data;
$scope.dataGrids.push({grid: {
data: 'dataSparqlAux',
enablePinning: false,
showFooter: true,
selectedItems: [],
i18n: 'es',
showSelectionCheckbox: true,
afterSelectionChange: function() {
console.log(this);
},
columnDefs: [{field: elem.nombre + '.value', displayName: elem.nombre, cellTemplate: templateWithTooltip}]
}});
console.log($scope.dataGrids);
});
};
**template.html**
<div data-get-width data-num-elementos="{{dataGrids.length}}" >
<div ng-repeat="dataGrid in dataGrids">
<div class="tabla_det" ng-grid="dataGrid.grid"></div>
</div>
</div>
is possible to do something like this?
$scope.dataGrids.push({grid: {
**data: 'dataSparqlResponses[cont]',**
enablePinning: false,
showFooter: true,
selectedItems: [],
i18n: 'es',
showSelectionCheckbox: true,
afterSelectionChange: function() {
console.log(this);
},
columnDefs: [{field: elem.nombre + '.value', displayName: elem.nombre, cellTemplate: templateWithTooltip}]
}});
console.log($scope.dataGrids);
How can I fix this to create grids and display information dynamically?
Regards and thanks for your time.
EDIT: here a plunker with the problem http://plnkr.co/edit/zYtuMW4TKW053YoDY0kg?p=preview
I've shared an answer on github about your issue.
Basically, data is referencing a variable, you're not storing it.
What you can do is reference a new variable on every loop, as shown in the jsbin.
Declare an index :
var index = 0;
You declare your string with the index of the sub-document :
var dirtyConcat = 'dataSparqlResponses['+index+'].data';
Don't forget to increment the index :
++index;
Then, you reference it.
data: dirtyConcat,
Related
I have a web application with multiple Selectize objects initialized on the page. I'm trying to have each instance load a default value based on the query string when the page loads, where ?<obj.name>=<KeywordID>. All URL parameters have already been serialized are are a dictionary call that.urlParams.
I know there are other ways to initializing Selectize with a default value I could try; but, I'm curious why calling setValue inside onInitialize isn't working for me because I'm getting any error messages when I run this code.
I'm bundling all this JavaScript with Browserify, but I don't think that's contributing to this problem.
In terms of debugging, I've tried logging this to the console inside onInititalize and found that setValue is up one level in the Function.prototype property, the options property is full of data from load, the key for those objects inside options corresponds to the KeywordID. But when I log getValue(val) to the console, I get an empty string. Is there a way to make this work or am I ignoring something about Selectize or JavaScript?
module.exports = function() {
var that = this;
...
this.selectize = $(this).container.selectize({
valueField: 'KeywordID', // an integer value
create: false,
labelField: 'Name',
searchField: 'Name',
preload: true,
allowEmptyOptions: true,
closeAfterSelect: true,
maxItems: 1,
render: {
option: function(item) {
return that.template(item);
},
},
onInitialize: function() {
var val = parseInt(that.urlParams[that.name], 10); // e.g. 5
this.setValue(val);
},
load: function(query, callback) {
$.ajax({
url: that.url,
type: 'GET',
error: callback,
success: callback
})
}
});
};
...
After sprinkling in some console.logs into Selectize.js, I found that the ajax data hadn't been imported, when the initialize event was triggered. I ended up finding a solution using jQuery.when() to make setValue fire after the data had been loaded, but I still wish I could find a one-function-does-one-thing solution.
module.exports = function() {
var that = this;
...
this.selectize = $(this).container.selectize({
valueField: 'KeywordID', // an integer value
create: false,
labelField: 'Name',
searchField: 'Name',
preload: true,
allowEmptyOptions: true,
closeAfterSelect: true,
maxItems: 1,
render: {
option: function(item) {
return that.template(item);
},
},
load: function(query, callback) {
var self = this;
$.when( $.ajax({
url: that.url,
type: 'GET',
error: callback,
success: callback
}) ).then(function() {
var val = parseInt(that.urlParams[that.name], 10); // e.g. 5
self.setValue(val);
});
}
});
};
...
You just need to add the option before setting it as the value, as this line in addItem will be checking for it:
if (!self.options.hasOwnProperty(value)) return;
inside onInitialize you would do:
var val = that.urlParams[that.name]; //It might work with parseInt, I haven't used integers in selectize options though, only strings.
var opt = {id:val, text:val};
self.addOption(opt);
self.setValue(opt.id);
Instead of using onInitialize you could add a load trigger to the selectize. This will fire after the load has finished and will execute setValue() as expected.
var $select = $(this).container.selectize({
// ...
load: function(query, callback) {
// ...
}
});
var selectize = $select[0].selectize;
selectize.on('load', function(options) {
// ...
selectize.setValue(val);
});
Note that for this you first have to get the selectize instanze ($select[0].selectize).
in my case it need refresh i just added another command beside it
$select[0].selectize.setValue(opt);
i added this
$select[0].selectize.options[opt].selected = true;
and changes applied
but i dont know why?
You can initialize each selectize' selected value by setting the items property. Fetch the value from your querystring then add it as an item of the items property value:
const selectedValue = getQueryStringValue('name') //set your query string value here
$('#sel').selectize({
valueField: 'id',
labelField: 'title',
preload: true,
options: [
{ id: 0, title: 'Item 1' },
{ id: 1, title: 'Item 2' },
],
items: [ selectedValue ],
});
Since it accepts array, you can set multiple selected items
Hello i am receiving an error from the code below, and not sure why because i thought i was defining it. I want to make sure my code is working properly before i add complexity to the report.
launch: function() {
this._createGrid();
},
_createGrid: function() {
Ext.create('Rally.data.wsapi.TreeStoreBuilder').build({
models: ['PortfolioItem/Initiative'],
autoLoad: true,
enableHierarchy: true
}).then({
success: function(store) {
var myGrid = Ext.create('Ext.Container', {
items: [{
xtype: 'rallytreegrid',
columnCfgs: ['Name', 'Owner'],
store: store
}],
renderTo: Ext.getBody()
});
}
});
this.add(myGrid);
},
});
"Error: success callback for Deferred transformed result of Deferred transformed result of Deferred threw: ReferenceError: myGrid is not defined"
I am new to this so any help would be greatly appreciated!
You issue you're running into is probably due to some confusion in how components and containers behave in ExtJS combined with the this scoping issue mentioned in the answer above.
Here's how I would write it:
_createGrid: function() {
Ext.create('Rally.data.wsapi.TreeStoreBuilder').build({
models: ['PortfolioItem/Initiative'],
autoLoad: true,
enableHierarchy: true
}).then({
success: function(store) {
//The app class is already a container, so you can just
//directly add the grid to it
this.add({
xtype: 'rallytreegrid',
itemId: 'myGrid',
columnCfgs: ['Name', 'Owner'],
store: store
});
},
scope: this //make sure the success handler executes in correct scope
});
}
You also don't need to feel like you need to keep a myGrid reference around since you can always find it using the built-in component querying feature of ExtJS:
var myGrid = this.down('#myGrid');
You're defining myGrid inside of the success function scope, then trying to use it at the end of the _createGrid function, where it is undefined. I assume you're trying to do it that way because this is not bound correctly inside the success function. Try this instead:
_createGrid: function() {
var self = this;
Ext.create('Rally.data.wsapi.TreeStoreBuilder').build({
models: ['PortfolioItem/Initiative'],
autoLoad: true,
enableHierarchy: true
}).then({
success: function(store) {
var myGrid = Ext.create('Ext.Container', {
items: [{
xtype: 'rallytreegrid',
columnCfgs: ['Name', 'Owner'],
store: store
}],
renderTo: Ext.getBody()
});
self.add(myGrid);
}
});
},
I have two grids that have rows I can select. I want to be able to get the data in the selected rows into another data object so that I can pass it to a backend service. Here is the relevant code:
angular.module('gridPanel',['ui.bootstrap','ui.grid', 'ui.grid.edit', 'ui.grid.rowEdit', 'ui.grid.cellNav', 'ui.grid.selection'])
.controller('GridPanelController', function($scope, $log, referenceDataService){
$scope.nameGrid = {
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: true,
onRegisterApi: function(gridApi) {
$scope.gridApiNames= gridApi;
},
columnDefs: [
{name: 'Name', field: 'name'}
{name: 'Description', field: 'description'}
],
data:[]
};
$scope.regionsGrid = {
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: true,
onRegisterApi: function(gridApi) {
$scope.gridApiRegions = gridApi;
},
columnDefs: [
{name: 'Region', field: 'region'}
],
data:[]
};
referenceDataService.getAllNames().then(function (data){
$scope.nameGrid.data = data;
});
referenceDataService.getRegions().then(function (data){
$scope.regionsGrid.data = data;
});
$scope.debug = function(obj) {
var dataObj = {
names: [],
regions: []
};
dataObj.regions = $scope.gridApiRegions.selection.getSelectedRows();
dataObj.names= $scope.gridApiNames.selection.getSelectedRows();
$log.log(JSON.stringify(dataObj, null, 4));
};
});
However, when I check to see what the log says in console, it shows me that dataObj.regions and dataObj.names are both blank arrays. The data shows up fine in the actual tables, and nothing goes wrong when I click on them - I can select multiple rows without issue. The problem only comes when I click on the submit button, which for now directs to $scope.debug so that I can look at the objects in console. I have other fields in the form, mostly text fields, that also display fine when I click on debug in the console log, so the only place with an issue is getting selected rows. Thanks in advance!
edit: also, when I try to log just the 'getSelectedRows' part, it returns a blank array.
Found the problem. It's because I was using the same grids elsewhere on the webpage (within a modal) to display the same information. Once I made two sets of grids, the problem was fixed. Still seems kind of inefficient to have two sets of the same grids that serve the same purpose, but I guess maybe that's just how it is or something?
I have a property grid :
periods.each(function(record){
var tempPropGrid = me.getView().add(
{
xtype:'propertygrid',
width: 80,
header: false,
title: 'prop grid',
//for some reason the headers are not hiding, we may need to deal with this using CSS
//hideHeaders: true,
enableColumnResize: false,
sortableColumns: false,
nameColumnWidth: 1,
source: record.data,
sourceConfig: {
periodScrumMaster: {
editor: Ext.create('Ext.form.ComboBox', {
tdCls: 'red',
store: team,
queryMode: 'local',
displayField: 'personName',
valueField: 'personName',
listeners: {
'expand' : function(combo) {
var gridvalues = this.up('propertygrid').getSource();
combo.getStore().clearFilter(true);
combo.getStore().addFilter({property: 'teamName', value: teamName});
combo.getStore().addFilter({property: 'periodName', value: gridvalues.periodName});
var totalFTE = team.count();
console.log(totalFTE);
var teamStore = Ext.getStore('personPeriods');
console.log('store');
console.log(teamStore);
},
}}),
displayName: 'Scrum Master'
},
},
That has a render listener:
beforerender: function(){
debugger;
var gridValues = this.getSource();
// console.log(record);
//debugger;
// filter periods for this period only
periods.filterBy(function(record,id){
if(record.get("periodName") === gridValues.periodName){
return true;
}});
// filter teamMembers for this period and team
var view = this.up();
var vm = view.getViewModel();
var store = vm.getStore('teamMembers');
store.filterBy(function(record,id){
if(record.get("periodName") === gridValues.periodName) {
return true;
}});
//store.clearFilter(true);
store.addFilter({property: 'teamName', value: teamName});
// get FTEs assigned to this team in this period by counting records
var resourcedFtes = store.count();
// Here I check the record in the periods store to make sure the data matches up with how many resourcedFte there is an update it if required
// This is super bad and will need to refactor
periods.each(function(record,idx){
var value = record.get('resourcedFte');
if(value != resourcedFtes){
record.set('resourcedFte',resourcedFtes);
record.commit();
vm.data.parentController.saveParent();
}});
// Need to call save parent so that the record is updated when we update it above
//Clear everything so that we can start fresh next period
store.clearFilter(true);
//periods.clearFilter(true);
Basically there is some logic to check if the data is correct/up to date and if its not it updates it. This works fine, but the data is not then loaded into the grid. I have to refresh after rendering the grid for it to load correctly.
Is there a way I can call a refresh or reload method on the property grid to load the data again inside an if statement?
If I understand your question, I would suggest you to programm the store proxy so that it returns the whole changed record.
Is your store parametered with autoLoad enabled?
(sorry I can't (yet) comment)
I am using dgrid and i am attempting to set the dataStore externally. When the page loads i call aliasTicket.load() to create the grid. At the time the grid is loading the datasource is null. When a query is executed the setAliasSource(aliasData); is set.
There are no errors however the grid is still empty. The aliasStore is being updated with data however it isn't being reflected on the grid even after the grid is refreshed. How can i get the data reflected in the grid after the query?
Javascript Object
var aliasTicket = (function (){
var aliasData = [];
require([ "dojo/store/Observable", "dojo/store/Memory"]);
var aliasStore = new dojo.store.Observable(new dojo.store.Memory({
data: aliasData,
idProperty: "id"
}));
return{
load:function(){
require([
........
], function(declare, Memory, OnDemandGrid, ColumnSet, Selection,
selector, Keyboard, DijitRegistry, editor, ColumnHider,
registry, Observable,lang) {
aliasData = this.aliasData;
var Store = this.aliasStore = new dojo.store.Observable(new dojo.store.Memory({
data: aliasData,
idProperty: "id"
}));
console.log(Store);
var CustomAliasNameGrid = declare([OnDemandGrid, selector, Selection, Keyboard, editor, DijitRegistry, ColumnHider]);
var aliasNameGrid = new CustomAliasNameGrid({
store: Store,
columns: {
id: {
label: "Id",
field: "id",
hidden: true,
autoSizeColumn: true
},
employeeTicketId: {
label: "Employee Ticket Id",
field: "employeeTicketId",
hidden: true,
autoSizeColumn: true
},
chkBox: selector({}),
aliasName: {
label: "Alias Names",
field: "aliasTicketName",
autoSizeColumn: true,
formatter: function(str) {
return str.replace(/\w\S*/g, function(txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
});
}
}
},
selectionMode: "none",
loadingMessage: "Loading data...",
noDataMessage: "No results found....",
allowSelectAll: true
}, "aliasNameGrid");
aliasNameGrid.refresh()
});
},
setAliasSource: function (data){
console.log(data);
this.aliasSource = data;
},
setAliasData: function (data){
this.aliasData = data;
},
getAliasSource: function (){
return this.aliasSource;
}
};
})();
Setting Data Store Data
aliasData = [{.....},
{.....},
{......];
require(["dijit/dijit"]);
aliasTicket.setAliasSource(aliasData);
dijit.byId('aliasNameGrid').refresh();
You are setting 'this.Store' to an object array, not a real 'dojo store' object. Following your code I can not see where you actually use 'this.Store'. Inside the grid code I do see a local variable named 'Store'.
So I'm not sure if I'm following your code example here but, you should 'set' the store of the grid and then refresh it. Something like this.
setAliasSource: function (data){
console.log(data);
this.Store = data;
dijit.byId('aliasNameGrid').set("store",new dojo.store.Observable(new dojo.store.Memory({ data: data,idProperty: "id"}));
dijit.byId('aliasNameGrid').refresh();
},