ui-router ui-grid Typeerror undefined - angular-ui-router

I use ui-router and ui-grid in a project.
I receive a TypeError when I switch the state to a different view which contains a ui-grid.
I did not had this issue without the ui-router. I've experimented with a single html-page that contained a ui-grid. No problems there. When I implemented the ui-router the TypeError occured.
I've added a demo on plunkr. http://plnkr.co/edit/FzsxLDNGRWQrpGUKNHBa?p=preview
As you can see in the following piece of code in my app.js, my module gets populated with dependencies for ui-router and ui-grid.
var app = angular.module('app', [
'ui.router',
'ui.grid'
]);
If you switch to the second view in this demo, you will see an empty ui-grid. Chrome developper tools report the TypeError.

You are referring the View2Controller as vm in your template but the gridOptions is add in the $scope, just change the $scope.gridOptions to vm.gridOptions and it will work.
vm.gridOptions = {
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
},
data: 'vm.customers',
columnDefs: [
{
field: 'status', name: '', width: 50, sort: {
direction: uiGridConstants.DESC,
priority: 0
}
},
{
field: 'member', name: 'M', width: 50, type: 'boolean',
cellTemplate: '<input type="checkbox" ng-model="row.entity.lid" >'
},
{
field: 'company', name: 'Company', width: 200, minWidth: 200, maxWidth: 600
},
{ field: 'creationDate', name: 'Date', width: 120, cellClass: 'right-align', type: 'date' },
]
};
http://plnkr.co/edit/mpRYJZKEnwPIRefPQc9J?p=preview

Related

Error dom is null in Ext.grid.Panel after cell click only when grid is sorted

I've error on grid, when try to click on disabled cell. Here is the code:
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.create('Ext.data.Store', {
storeId: 'simpsonsStore',
fields: ['name', 'email', 'phone'],
data: [{
name: 'Lisa',
email: 'lisa#simpsons.com',
phone: '555-111-1224'
}, {
name: 'Bart',
email: 'bart#simpsons.com',
phone: '555-222-1234'
}]
});
Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
store: Ext.data.StoreManager.lookup('simpsonsStore'),
plugins: {
ptype: 'cellediting',
clicksToEdit: 1
},
columns: [{
text: 'Name',
dataIndex: 'name',
editor: {
xtype: 'textfield',
disabled: true
}
}, {
text: 'Email',
dataIndex: 'email',
flex: 1
}],
height: 100,
width: 400,
renderTo: Ext.getBody()
});
}});
How to reproduce:
Click on cell "Lisa"
Sort by "Name" column
Wait 30 sec
Click on cell "Lisa" cell again
This error occurs:
Uncaught TypeError: Cannot read properties of null (reading 'value')
Reproduced on ExtJs "7.5.0" and older.

How to Change Row Location in jqgrid?

I am using jqgrid with MVC and for now, I want change Row location when click on ^ to get one line up and inverse.
actually I want to set 'up' and 'down' signs to every row for change one level row locations
any body can help me?!
There are a lot of possible solution. One of them is to use custom formtter to define the buttons and then bind event on loadComplete to move the rows using the jquery. Below the code:
$("#jqGrid").jqGrid({
datatype: "local",
data: mydata,
height: 250,
width: 780,
colModel: [
{ label :'move', formatter : myformatter, width:95},
{ label: 'Inv No', name: 'id', width: 75, key:true },
{ label: 'Date', name: 'invdate', width: 90 },
{ label: 'Client', name: 'name', width: 100 },
{ label: 'Amount', name: 'amount', width: 80 },
{ label: 'Tax', name: 'tax', width: 80 },
{ label: 'Total', name: 'total', width: 80 },
{ label: 'Notes', name: 'note', width: 150 }
],
viewrecords: true, // show the current page, data rang and total records on the toolbar
caption: "Load jqGrid through Javascript Array",
loadComplete : function() {
$(".up,.down").on('click', function () {
var row = $(this).closest("tr.jqgrow");
if($(this).is('.up')){
row.insertBefore(row.prev());
} else {
row.insertAfter(row.next());
}
});
}
});
function myformatter() {
return '<button class="up" >Up</button>' + '<button class="down">Down</button>';
}
Demo here

Get a field placed in the header of a grid column. Extjs 6

I'm working on a grid with a remote filter. So, i set a field in a grid column header.
My question is,
How can i get the field value without field-id ??
See the example below
Thank You
You might be able to bind the value config of your textfield (the textfield in your items of the column header) to an attribute in a view model.
Something like :
var vm = Ext.create('Ext.app.ViewModel', {
data: [{
test : ''
}],
alias: 'viewmodel.myviewmodel',
stores: {
simpsonsStore: Ext.create('Ext.data.Store', {
fields:['name', 'email', 'phone'],
data:[
{'name': 'Lisa', "email":"lisa#simpsons.com", "phone":"555-111-1224"},
{'name': 'Bart', "email":"bart#simpsons.com", "phone":"555-222-1234"},
{'name': 'Homer', "email":"homer#simpsons.com", "phone":"555-222-1244"},
{'name': 'Marge', "email":"marge#simpsons.com", "phone":"555-222-1254"}
]
})
}
});
var grid = Ext.create('Ext.panel.Panel', {
height: 400,
width: 400,
renderTo: Ext.getBody(),
viewModel: vm,
layout: 'hbox',
items:[{
xtype: 'button',
bind: {
text: '{test}'
}
},{
xtype: 'grid',
flex: 1,
bind: '{simpsonsStore}',
columns: [{
text: 'Name',
dataIndex: 'name',
items: [{
xtype: 'textfield',
bind: {
value: '{test}'
}
}]
}, {
text: 'Email',
dataIndex: 'email',
flex: 1
}, {
text: 'Phone',
dataIndex: 'phone'
}]
}]
});
PS : here is the fiddle ;) https://fiddle.sencha.com/#fiddle/15j6 you can type in your header filed, the button text will updated automatically :)

Appending to list not updating on pull to refresh

I am still new to ST so I am probably doing several things wrong here but I can't figure out where the problems are.
Problem 1
when I use the pull to refresh plug-in, I get double the data instead of it just refreshing the data. I have seen to use a propertyId and so I did to no avail. This should be simple so probably something silly I'm doing wrong.
Problem 2
I am trying to figure out the most efficient way to use the MVC architecture and I have read through the documentation and many examples. So, I don't know if I am just not understanding clearly or need a better example. I am trying to create a simple app for now with a list that I can tap on an item and get a detailed view of that item. I will later evolve it into a more robust monster but for now I am trying to understand the basics. I finally got my close button to close the detail view when I click a list item but then I can no longer get a detail view when tapping another item. I have read that this is due to 'autoDestroy: off' not being present but I tried that, also with no luck. I want to be able to create certain buttons like 'close' that I can put in multiple views and just have to have the logic in the controllers.
Main View
Ext.define('SenchaFirstApp.view.DistributorView', {
// extend: 'Ext.form.Panel',
extend: 'Ext.Container',
requires: ['SenchaFirstApp.store.DistributorStore', 'Ext.dataview.List', 'Ext.Toolbar', 'Ext.form.Panel'],
model: 'SenchaFirstApp.model.Distributors',
alias: 'widget.mainlist',
xtype: 'mainlist',
config:
{
layout: 'fit',
border: 5,
title: 'Distributors',
html: 'My datalist',
autoDestroy: false,
items:[{
xtype: 'toolbar',
docked: 'top',
title: 'Distributor List',
height: 40,
centered: true,
items: [
{
xtype: 'button',
text: 'Close',
width: 100,
height: 20,
name: 'close',
// iconCls: 'delete',
}]
},
{
autoLoad: true,
html: ['<div class="distr"><table><tr><th>Type</th><th>Distributor</th><th>Site</th><th>Status</th><th>Active</th><th>Assigned</th><th>State </th><th>Schedule</th><th>Finished</th></tr></table></div>'],
itemTpl: [ '<div class="distr"><table><tr><td>{t}</td><td>{distr}</td><td colspan="2">{site}</td><td>{status}</td> <td>{active}</td><td>{assigned}</td> <td>{state}</td><td>{schedule}</td><td>{finished}</td></tr></table></div>' ],
xtype: 'list',
store: 'DistrID',
plugins: [
{
xclass: 'Ext.plugin.PullRefresh',
pullRefreshText: 'Pull down to refresh Distributor List'
}],
ui: 'showDetails',
id: 'mainlist',
autoDestroy: false,
}
]
},
});
Detailed View
Ext.define('SenchaFirstApp.view.DetailView',{
extend: 'Ext.Panel',
requires: ['Ext.Toolbar'],
model: 'SenchaFirstApp.model.Distributors',
alias: 'widget.detailview',
xtype: 'detailview',
name: 'detail',
config:{
html: 'This will contain detailed information',
xtype: 'panel',
// fullscreen: false,
centered: true,
modal: false,
scrollable: true,
width: 300,
height: 200,
},
});
Store
Ext.define('SenchaFirstApp.store.DistributorStore', {
extend: 'Ext.data.Store',
requires: ['SenchaFirstApp.model.Distributors'],
config: {
// xtype: 'distrlist',
storeId: 'DistrID',
model: 'SenchaFirstApp.model.Distributors',
autoLoad: true,
proxy: {
type: 'jsonp',
url:'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://gdata.youtube.com/feeds/api/users/hobbitin5/uploads&num=4',
reader: {
type: 'json',
rootProperty: 'responseData.feed.entries'
}
}
}
Controller to get detailed view
Ext.define('SenchaFirstApp.controller.DistributorsController',{
extend: 'Ext.app.Controller',
config:
{
refs:
{
mainlist: '#mainlist',
},
control:
{
mainlist: {
itemtap: 'dispDetail'
},
},
//when item is tapped
listeners: {
itemtap: function(list, index, items, record)
{
console.log('An item was tapped and the listener heard it');
}
}
},
dispDetail: function(view, record) {
console.log('Item was tapped on the Data View');
var oldView = this.getMainlist();
var curRecord = oldView.getStore(record);
var newView = Ext.create('SenchaFirstApp.view.DetailView');
console.log(curRecord);
curRecord += 'other stuff';
newView.setHtml(curRecord);
newView.add(
{
xtype: 'toolbar',
docked: 'top',
title: 'Details',
height: 40,
items: [
{
xtype: 'button',
text: 'Close',
width: 100,
height: 20,
name: 'close',
}]
}
)
oldView.add(newView);
// Ext.Viewport.add(newView)
// Ext.Viewport.setActiveItem(newView)
}
});
Controller for buttons (just close for now)
Ext.define('SenchaFirstApp.controller.NavController', {
extend: 'Ext.app.Controller',
config:
{
refs:
{
mainlist: 'mainlist',
main: '#mainlist',
closeBtn: 'button[name=close]',
detaillist: {
selector: 'panel panel[name=detail] deetaillist',
xtype: 'detailview',
}
},
control:
{
closeBtn: {
tap: 'closeView',
},
mainlist: {
tap: 'closeView',
},
detaillist: {
tap: 'closeView',
}
}
},
closeView: function(){
var newView = this.getMainlist();
// var child = Ext.Viewport.getActiveItem();
var child = this.getDetaillist();
var instance = Ext.getCmp('mainlist');
var activeIndex = instance.indexOf(instance.getActiveItem());
var curIndex = activeIndex+1;
var closeView = this.getDetaillist();
console.log('Close btn clicked' + ' child: ' + this.child + ' activeIndex: ' + activeIndex);
// Ext.Viewport.destroy(closeView); //(child);
newView.remove(child);
newView.destroy();
Ext.Viewport.add(Ext.create('SenchaFirstApp.view.DistributorView'));
` }
})`;
Model
Ext.define('SenchaFirstApp.model.Distributors', {
extend: 'Ext.data.Model',
config: {
idProperty: 'DistrID',
fields: [
{name: 'DistrID'},
{name: 't', type: 'string'},
{name: 'distr', type: 'string'},
{name: 'group', type: 'string'},
{name: 'site', type: 'string'},
{name: 'status', type: 'string'},
{name: 'active', type: 'string'},
{name: 'assigned', type: 'string'},
{name: 'state', type: 'string'},
{name: 'schedule', type: 'string'},
{name: 'finished', type: 'string'},
//{mapping: 't',
// name: 'DistrID'}
],
}
});
I understand that is a lot but any help is appreciated...even a nudge in the right direction. Thanks in advance! Also, I'm sure there is stuff in there that doesn't need to be as I've had trouble locating good examples for what I am trying to accomplish so I have pieces here and there from different examples that I've tried to get to play nice together :(
I solved the refresh issue by changing the idProperty to 'id' and put that in my model field list. I'm still not sure why the 'DistrID wasn't working but I had an 'id' field in my script that held the server response that I didn't know about as I didn't write that part. So, I would have to guess that is why it wasn't working.
I had read that 'autoDestroy: false' is what was needed to allow clicking a second time but that was wrong. When I took that property out it allowed me to continue to open and close details of list items.
Now I just have to work on passing id's of list items clicked to get a detailed view of that particular item. If anyone can help with that it would be great or I will post a new question. Thanks!
I figured out how to get the list item id in case it can help anyone...
Iny my DistributorController I simply get the store and the record id
var store = Ext.getStore('NodeStore');
var id = record.get('id');
Then set the params and load the store
store.getProxy().setExtraParams({id: id});
store.load();
I did also find that you can't reference your store through the controller with refs. Instead get the store as I did above with var store = Ext.getStore('StoreName');
This is all pretty simple stuff but I'm still very knew so maybe it can help out another n00b

Unable to sort data in ExtJS DataGrid when grouped

I'm using ExtJS 3.3.0 with a datagrid that consumes a JSON data store (Ext.data.GroupingStore).
When I'm not grouping by a column, I can sort just fine, however when grouping by a column, the sort algorithm seems to fall apart.
I have another data grid that does server side sorting (and grouping and paging) and this works just fine. Comparing the the code between the two has left me stumped for the difference that's making one work and the other not work.
Many thanks in advance.
CW.App.FileGrid = {
store : null,
initComponent: function(){
this.store = new Ext.data.GroupingStore({
autoLoad:true,
url:'/sites/files.js',
groupField:'modified',
// Sort by whatever field was just grouped by. This makes the data
// make more sense to the user.
groupOnSort:true,
remoteSort:false,
remoteGroup:false,
sortInfo:{
field:'modified',
direction:'DESC'
},
reader: new Ext.data.JsonReader({
idProperty:'filename',
root:'data',
fields: [
'iconCls',
{
name: 'modified',
type: 'date',
dateFormat:'timestamp'
},
'description', 'folder', 'filename',
'filesize', 'ext', 'dateGroup']
})
});
// this.store.setDefaultSort('modified', 'DESC');
Ext.apply(this, {
store: this.store,
loadMask:true,
columns: [
{
xtype:'actioncolumn',
items:[{
getClass:function(v,meta,rec){
return rec.get('iconCls');
}
}],
width:25
},{
id:'filename',
header: "Filename",
sortable: true,
dataIndex: 'filename'
},{
id:'ibmu',
header: "iBMU",
width:50,
sortable:true,
dataIndex: 'folder'
},{
id:'date',
header: "Date",
width: 65,
sortable: true,
dataIndex: 'modified',
renderer: Ext.util.Format.dateRenderer('Y-m-d h:i'),
groupRenderer:function(v,unused,r,rowIdx,colIdx,ds){
return r.data['dateGroup'];
}
},{
id:'type',
header: "Type",
width: 70,
sortable: true,
dataIndex: 'description'
},{
id:'size',
header: "Size",
width: 50,
sortable: true,
dataIndex: 'filesize',
renderer: Ext.util.Format.fileSize
},{
xtype:'actioncolumn',
items:[{
icon: '/img/fam/drive_disk.png',
tooltip: 'Download file',
handler: function(grid, rowIndex, colIndex){
var rec = store.getAt(rowIndex);
location.href = Ext.urlAppend('/ibmus/download/', Ext.urlEncode({
folder: rec.get('folder'),
filename: rec.get('filename')
}));
}
}]
}
],
autoExpandColumn:'filename',
view: new Ext.grid.GroupingView({
emptyText: 'No files found. Please wait up to 24 hours after activating your account for files to appear.',
forceFit:true,
groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Files" : "File"]})'
}),
frame:false,
width: '100%',
height: 250,
collapsible: false,
animCollapse: false
});
CW.App.AlarmGrid.superclass.initComponent.call(this);
}
};

Resources