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

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.

Related

Sencha Ext JS - how to refresh the Tabs after date picking?

I have MVC app, it's a Tab Panel containing few Tabs with a chart on each, there is also a Date Picker with Refresh button, and a Combo box to choose which data source is being used for the 'Date Range'.
The app currently loads the charts with all available data but the purpose is to select 1 of 3 available data sources, select a date range and refresh every chart tab by clicking a button, how do I do it?
Fiddle sample
Something like this:
Ext.create('Ext.panel.Panel', {
renderTo: Ext.getBody(),
height: 800,
width: 800,
layout: 'border',
defaults: {
collapsible: false,
split: true,
},
items: [{
title: 'PanelCenter',
xtype: 'tabpanel',
region: 'center',
itemId: 'centerPanel',
bodyPadding: 10,
activeTab: 0,
items: [{
title: "Tab1",
items: {
xtype: 'cartesian',
width: 655,
height: 400,
store: {
fields: ['name', 'value'],
data: [{
name: 'metric one',
value: 10,
}, {
name: 'metric two',
value: 7,
}, {
name: 'metric three',
value: 5,
}]
},
axes: [{
type: 'numeric',
position: 'left',
title: {
text: 'Sample Values',
fontSize: 15
},
}, {
type: 'category',
position: 'bottom',
title: {
text: 'Sample Values',
fontSize: 15
},
fields: 'name',
}],
series: [{
type: 'bar',
xField: 'name',
yField: 'value'
}
]
}
}, {
title: "Tab2",
items: {
xtype: 'cartesian',
width: 655,
height: 400,
store: {
fields: ['name', 'value'],
data: [{
name: 'metric one',
value: 3,
}, {
name: 'metric two',
value: 5,
}, {
name: 'metric three',
value: 10,
}]
},
axes: [{
type: 'numeric',
position: 'left',
title: {
text: 'Sample Values',
fontSize: 15
},
}, {
type: 'category',
position: 'bottom',
title: {
text: 'Sample Values',
fontSize: 15
},
fields: 'name',
}],
series: [{
type: 'bar',
xField: 'name',
yField: 'value'
}
]
}
}, {
title: "Tab3",
items: {
xtype: 'cartesian',
width: 655,
height: 400,
store: {
fields: ['name', 'value'],
data: [{
name: 'metric one',
value: 10,
}, {
name: 'metric two',
value: 3,
}, {
name: 'metric three',
value: 9,
}]
},
axes: [{
type: 'numeric',
position: 'left',
title: {
text: 'Sample Values',
fontSize: 15
},
}, {
type: 'category',
position: 'bottom',
title: {
text: 'Sample Values',
fontSize: 15
},
fields: 'name',
}],
series: [{
type: 'bar',
xField: 'name',
yField: 'value'
}
]
}
}]
}, {
xtype: 'form',
title: 'PanelTop',
layout: {
type: 'hbox',
},
region: 'north',
border: false,
bodyPadding: 10,
height: '100',
width: '100%',
margin: '0 0 5 0',
region: 'north',
items: [{
xtype: 'combo',
name: 'data_type',
itemId: 'dataTypeSelect',
emptyText: 'Select date type',
displayField: 'source',
store: {
fields: ['code', 'source'],
data: [{
code: 'created',
source: 'Sales date'
}, {
code: 'invoice',
source: 'Invoice date'
}, {
code: 'bookIn',
source: 'Order date'
}]
},
allowBlank: false,
}, {
xtype: 'datefield',
itemId: 'dateFromSearchField',
fieldLabel: 'From',
labelAlign: 'right',
name: 'from_date',
format: 'd/m/Y',
maxValue: new Date(),
allowBlank: false,
}, {
xtype: 'datefield',
itemId: 'dateToSearchField',
fieldLabel: 'To',
labelAlign: 'right',
name: 'to_date',
format: 'd/m/Y',
maxValue: new Date(),
value: new Date(),
padding: '0 30 0 0',
allowBlank: false
}, {
xtype: 'button',
itemId: 'refreshButton',
region: 'center',
text: 'Refresh',
formBind: true,
handler: function () {
const formData = this.up('panel').getValues();
if (
formData.data_type && formData.from_date && formData.to_date
) {
const tabPanel = Ext.ComponentQuery.query('tabpanel#centerPanel')[0];
const cartesianCharts = tabPanel.query('cartesian');
Ext.Array.each(cartesianCharts, function (cartesianChart) {
cartesianChart.getStore().load({
params: formData,
callback: function (records, operation, success) {
},
scope: this
});;
}, this);
}
}
}],
}]
});

Extjs on resize column width textfield Ui get destroyed

Basically, the problem that I have is the following:
When I resize the column in my GridPanel the textbox UI near Name get destroyed: the line on the right disappear. It should instead resize according to the width. How could I fix it?
This is my code:
...
columns: {
defaults: {
flex: 1,
},
layout:'auto',
items: [{
text: Strings.sharedName,
flex: 1,
minWidth: Traccar.Style.columnWidthNormal,
dataIndex: 'name',
//style: 'text-align:right;!important',
filter: 'string',
defaults: {
margin: '-28 30 -5 50'
},
items: [{
xtype: 'container',
layout: {
type: 'vbox',
align: 'right'
},
flex: 2,
items: [{
xtype: 'textfield',
id: 'nameFilter',
listeners: {
change: function(field, value) {
filterGrid('name', value);
}
}
}]
}]
}
...
Here a reproducible example:
https://fiddle.sencha.com/#view/editor&fiddle/3a41

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 :)

Sencha Touch 2 "view is not defined" console error

Trying to have a button push to a different view 'new profile' and 'profile page' (second view) Of course I would have authentication, however just trying to get the views correct before implement the controllers and server side.
Having the following errors:
Uncaught ReferenceError: view is not defined Main.js:116
Uncaught ReferenceError: view is not defined Main.js:126
Google only brings back "ext is not defined" responses.
Forgive the shocking coding as this is my first app for my school assignment (please give feedback how to improve this if possible) I understand that the view needs to be defined, however in the Sencha Touch's API is where I got the information.
Thanks for your time.
var pageFilterGame = {
xtype: 'panel',
title: 'Filter Games',
items: [
{
xtype: 'fieldset',
title: 'Filter games to find the perfect one',
instructions: 'Please fill in atleast one field to start.',
items: [
{
xtype: 'selectfield',
label: 'What enviroment will this game be played in',
options: [
{ text: 'Outside on Grass', value: 'grass' },
{ text: 'Outside on Concrete', value: 'concrete' },
{ text: 'Inside', value: 'inside' }
]
},
{
xtype: 'selectfield',
name: 'equipment',
label: 'What equipment do you have',
options: [{text: 'DB form'}]
},
{
xtype: 'numberfield',
name : 'Player Numbers',
label: 'How many players do you have',
minValue: 2,
maxValue: 50
},
{
xtype: 'numberfield',
name: 'avgname',
label: 'Average age of players',
minValue: 2,
maxValue: 99
},
{
xtype: 'selectfield',
label: 'Sort result by:',
options: [
{ text: 'Highest Rated', value: 'rated' },
{ text: 'Equipment', value: 'equipment' },
{ text: 'Alphabetically', value: 'alpha' }
]
},
],
},
{
xtype: 'button',
ui: 'action',
text: 'Filter Games',
action: '',
maxWidth: '150px'
}
]
};
var pageSearch = {
xtype: 'panel',
title: 'Search',
items: [
{
xtype: 'fieldset',
title: 'Search',
items: [
{
xtype: 'searchfield',
label: 'Search',
name: 'search'
}
]
},
{
xtype: 'button',
ui: 'action',
text: 'Search',
action: '',
maxWidth: '100px'
}
]
};
var pageProfileLogin = {
xtype: 'panel',
title: 'My Profile',
items: [
{
xtype: 'fieldset',
title: 'Please login to access your profile',
items: [
{
xtype: 'textfield',
name : 'username',
label: 'Username'
},
{
xtype: 'passwordfield',
name: 'password',
label: 'Password',
clearIcon: false
}
]
},
{
xtype: 'toolbar',
docked: 'bottom',
items: [
{
text: 'Login',
ui: 'confirm',
handler: function() {
view.push({
title: 'Second View',
padding: 10,
})},
},
{
xtype: 'button',
ui: 'action',
text: 'Create New',
handler: function() {
view.push({
title: 'New Profile',
items: [
{
xtype: 'fieldset',
title: 'Please fill in the form to create your profile',
items: [
{
xtype: 'textfield',
name : 'username',
label: 'Username'
},
{
xtype: 'passwordfield',
name: 'password',
label: 'Password',
clearIcon: false
},
{
xtype: 'textfield',
name : 'name',
label: 'Name'
},
],
},
{
xtype: 'toolbar',
docked: 'bottom',
items: [
{
text: 'Login',
ui: 'confirm',
},
]
}
]
});
}
},
]
},
]}
var viewTabConfig = {
xtype: 'tabpanel',
styleHtmlContent: true,
title: 'Get Creative!',
items: [pageFilterGame, pageSearch, pageProfileLogin]
};
var viewDef = {
//
// Another new UI element introduced. This UI element allows one to add multiple panels in a 'stacked' like operation. A
// new panel when pushed into the NavigationView will be displayed along with a back button. When the back button is tapped,
// the visible view is 'popped' and the parent view gets displayed again. See demo in the lecture recording.
//
extend: 'Ext.NavigationView',
id: 'navView',
requires: [
'Ext.TitleBar',
'Ext.Video',
'Ext.field.Password',
'Ext.field.Select',
'Ext.field.Number',
'Ext.field.Search',
'Ext.form.FieldSet',
'Ext.tab.Panel',
'Ext.data.Store',
'Ext.data.reader.Xml'
],
config: {
fullscreen: true,
items: [viewTabConfig]
}
};
Ext.define("a2.view.Main", viewDef);
I had to add extra models and view to the app.js file and it worked fine.

How to sync combobox and textfield value. i.e how to load different values from store on textfield,while I am changing values on combobox

I am new to EXTjs(and to Stackoverflow as well). I was struggling with this issue and at last decided to ask for help.My question is " How to sync combobox and textfield values. i.e how to load different values from 'store' on textfield,while I am changing values on combobox? " My problem is that while I load values on combobox and I select them my textfield stays empty all the time. I tried "Ext.getCmp().setValue();" it works fine with this ,but I think it is not the best option if I'd have 100 textfields. I want combobox and textfield to be synched with store somehow. Any help is appreciated. Situation in pictures are in links below :
pic one
pic two
And my code :
My app.js :
Ext.Loader.setConfig({
enabled: true
});
Ext.application({
name: 'work',
appFolder: 'app',
controllers: ['Work'],
launch: function() {
Ext.create('Ext.container.Viewport', {
//layout: 'fit',
items: [{
xtype: 'rightpanel' // gets it from view class
}
]
});
}
});
My view RightPanel :
Ext.define('work.view.works.RightPanel', {
extend: 'Ext.panel.Panel',
ALIAS: 'widget.rightpanel',
width: 300,
title: 'Building navigation',
animCollapse: true,
collapsible: true,
split: true,
minSize: 400,
maxSize: 400,
margins: '0 5 0 0',
//activeTab:1, tabPosition:'bottom',
initComponent: function() {
this.items = [{
xtype: 'form',
items: [{
xtype: 'combobox',
fieldLabel: 'BuildingID',
queryMode: 'local',
name: 'Bid',
displayField: 'Bid',
valueField: 'Bid',
id: 'Bid',
MODE: 'remote',
store: 'Work'
}, {
xtype: 'textfield',
fieldLabel: 'Address',
name: 'Address',
displayField: 'Address',
valueField: 'Address',
id: 'Address',
store: 'Work'
}]
}];
this.columns = [{
header: 'ID',
dataIndex: 'Bid',
flex: 1
}, {
header: 'Texts',
dataIndex: 'Address',
flex: 1
}];
this.callParent(arguments);
}
});
My store :
Ext.define('work.store.Work', {
extend: 'Ext.data.Store',
model: 'work.model.Work',
storeId: 'workstore',
id: 'workstore',
autoLoad: true,
proxy: {
type: 'ajax',
limitParam: undefined,
startParam: undefined,
paramName: undefined,
pageParam: undefined,
noCache: false,
api: {
read: 'data/showWork.php' // just a .php file that reads values from database and shows them on combobox
},
reader: {
type: 'json',
root: 'data',
successProperty: 'success'
},
writer: {
type: 'json',
root: 'data',
encode: true
}
}
});
My Model class :
Ext.define('work.model.Work', {
extend: 'Ext.data.Model',
//idProperty: 'WorkID',
fields: [{
name: 'Bid',
type: 'int'
}, 'Address']
});
My Controller :
Ext.define('work.controller.Work', {
extend: 'Ext.app.Controller',
stores: ['Work'],
models: ['Work'],
views: [
'works.RightPanel' // name comes from view class
],
init: function() {
console.log('Done');
this.control({
'viewport > rightpanel': {
render: this.test
},
'rightpanel combobox[id=Bid]': {
select: this.change
}
});
},
change: function(buttons) {
var values = this.getStore('Work').collect('Address', 'Address', false);
var win = buttons.up('rightpanel'); // gets the needed widget
var form = win.down('combobox'); // gets the needed form
var value = form.getValue(); // gets the value
console.log("value " + value);
}
});
You want to watch for a change on the combobox, and then action a change based off its new value.
this.items = [{
xtype: 'form',
items: [{
xtype: 'combobox',
fieldLabel: 'BuildingID',
queryMode: 'local',
name: 'Bid',
displayField: 'Bid',
valueField: 'Bid',
id: 'Bid',
mode: 'remote',
store: 'Work'
listeners::{
change:function(cbx, newVal,oldVal,e){
var record = cbx.getStore().find("Bid",newVal); // theres prolly a better way to find this, such as to find the active record of the cbx
Ext.getCmp('Address').setValue(record.getValue("Address"))
}
}
},{
xtype: 'textfield',
fieldLabel: 'Address',
name: 'Address',
displayField: 'Address',
valueField: 'Address',
id: 'Address',
store: 'Work'
}]

Resources