PDA

View Full Version : Error with update



steffenk
21 Apr 2009, 8:40 AM
Hi,

while update a grid-app to Ext 3.0 i run in a problem, error-message is:
this.store.un is not a function

Any clue what might cause this error?

evant
21 Apr 2009, 8:41 AM
un() is a method on observable, which the store extends. Is it a custom store? Is the store null?

steffenk
21 Apr 2009, 8:46 AM
here it is:


var gridDs = new Ext.data.Store({
storeId: 'deletedRecordsStore',
reader: new Ext.data.JsonReader({
totalProperty: 'total',
root: 'rows'
}, [
{name: 'uid', type: 'int'},
{name: 'pid', type: 'int'},
{name: 'record', mapping: 'title'},
{name: 'crdate'},
{name: 'tstamp'},
{name: 'owner'},
{name: 'owner_uid'},
{name: 'tableTitle'},
{name: 'table'},
{name: 'path'}
]),
sortInfo: {
field: 'record',
direction: "ASC"
},
groupField: 'table',
url: Recycler.statics.ajaxController + '&depth=' + Recycler.statics.depthSelection + '&startUid=' + Recycler.statics.startUid + '&cmd=getDeletedRecords&pagingSizeDefault=' + Recycler.statics.pagingSize + '&table=' + Recycler.statics.tableSelection

});

but i don't think this one is the problem. When it's observable it may be a store bind to combo like this one:


store: new Ext.data.Store({
autoLoad: true,
url: Recycler.statics.ajaxController + '&startUid=' + Recycler.statics.startUid + '&cmd=getTables' + '&depth=' + Recycler.statics.depthSelection,
reader: new Ext.data.ArrayReader({}, [
{name: 'table', type: 'string'},
{name: 'records', type: 'int'},
{name: 'valueField', type: 'string'},
{name: 'tableTitle', type: 'string'}
]),
listeners: {
'load': {
fn: function(store, records) {
Ext.getCmp('tableSelector').setValue(Recycler.statics.tableSelection);
},
single: true
}
}
}),

difficult to say as the error ends up in ext-all.js

Animal
21 Apr 2009, 1:45 PM
Why are you not using ext-all-debug.js during development?

steffenk
23 Apr 2009, 2:17 AM
Hi Animal,

it's a large application, and i'm not the author. It's inside TYPO3 where all comes from community ;)

Running with ext-all-debug i get this stack:

this.store.un is not a function
bindStore()()ext-all-debug.js (Linie 24409)
constructor()()ext-all-debug.js (Linie 24239)
create()()ext-all-debug.js (Linie 7442)
add()()ext-all-debug.js (Linie 23871)
initComponent()()ext-all-debug.js (Linie 16467)
initComponent()()ext-all-debug.js (Linie 23828)
Component()(Object items=[1] layout=toolbar)ext-all-debug.js (Linie 14591)
F()()ext-base.js (Linie 14)
F()()ext-base.js (Linie 14)
Toolbar()(Object items=[1] layout=toolbar)ext-all-debug.js (Linie 23812)
onRender()(Object dom=div#ext-gen19.x-panel-body id=ext-gen19, null)ext-all-debug.js (Linie 18955)
onRender()(Object dom=div#ext-gen19.x-panel-body id=ext-gen19, null)ext-all-debug.js (Linie 34985)
render()(Object dom=div#ext-gen19.x-panel-body id=ext-gen19, undefined)ext-all-debug.js (Linie 14715)
render()()ext-all-debug.js (Linie 16494)
renderItem()(Object initialConfig=Object xtype=grid loadMask=true, 0, Object dom=div#ext-gen19.x-panel-body id=ext-gen19)ext-all-debug.js (Linie 16815)
renderAll()(Object initialConfig=Object id=delRecordId, Object dom=div#ext-gen19.x-panel-body id=ext-gen19)ext-all-debug.js (Linie 16807)
onLayout()(Object initialConfig=Object id=delRecordId, Object dom=div#ext-gen19.x-panel-body id=ext-gen19)ext-all-debug.js (Linie 16793)
layout()()ext-all-debug.js (Linie 16787)
doLayout()(undefined)ext-all-debug.js (Linie 16653)
doLayout()(undefined)ext-all-debug.js (Linie 16660)
setActiveItem()(Object initialConfig=Object id=delRecordId)ext-all-debug.js (Linie 16955)
setActiveTab()(Object initialConfig=Object id=delRecordId)ext-all-debug.js (Linie 22639)
afterRender()()ext-all-debug.js (Linie 22312)
render()("recyclerContent", undefined)ext-all-debug.js (Linie 14731)
render()()ext-all-debug.js (Linie 16494)
Component()(Object renderTo=recyclerContent layoutOnTabChange=true)ext-all-debug.js (Linie 14611)
F()()ext-base.js (Linie 14)
F()()ext-base.js (Linie 14)
F()()ext-base.js (Linie 14)
F()()ext-base.js (Linie 14)
init()()t3_recycler.js (Linie 511)
(?)()()t3_recycler.js (Linie 45)
wrapper()()prototype.js (Linie 3966)
[Break on this error] this.store.un("beforeload", this.beforeLoad, this);

Where is best place to look at?

Animal
23 Apr 2009, 3:13 AM
What is "this". What is "this.store"? Why are they the values they are?

steffenk
23 Apr 2009, 3:46 AM
good question. Stores are all in one object called recycler. There is no this.store, so i think it's inside core where the scope is changed to this.

Here is the complete object in code:



/***************************************************************
* Copyright notice
*
* (c) 2009 Julian Kleinhans <[email protected]>
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/

/**
* ExtJS for the 'recycler' extension.
* Contains the Recycler functions
*
* @author Julian Kleinhans <[email protected]>
* @author Erik Frister <[email protected]>
* @package TYPO3
* @subpackage tx_recycler
* @version $Id: t3_recycler.js 5194 2009-03-11 15:38:43Z ohader $
*/
Event.observe(window, 'load', function() {
//Quicktips initialisieren
Ext.QuickTips.init();

// @todo: description
// Ext.form.Field.prototype.msgTarget = 'side';

// disable loadindicator
Ext.UpdateManager.defaults.showLoadIndicator = false;

// fire recycler grid
new Recycler.grid.init();
});

Recycler.grid = {
/**
* Initializes the grid
*
* @return void
**/
init: function() {
/****************************************************
* row expander
****************************************************/

var expander = new Ext.grid.RowExpander({
tpl : new Ext.Template(
'<br/>' +
'<p style="margin-left:45px;"><b>' + Recycler.lang.table + ':</b> {table}</p>' +
'<p style="margin-left:45px;"><b>' + Recycler.lang.crdate + ':</b> {crdate}</p>' +
'<p style="margin-left:45px;"><b>' + Recycler.lang.tstamp + ':</b> {tstamp}</p>' +
'<p style="margin-left:45px;"><b>' + Recycler.lang.owner + ':</b> {owner} (UID: {owner_uid})</p>' +
'<p style="margin-left:45px;"><b>' + Recycler.lang.path + ':</b> {path}</p>' +
'<br/>'
)
});

/****************************************************
* pluggable renderer
****************************************************/

var renderTopic = function (value, p, record) {
return String.format('{0}', value, record.data.table, record.data.uid, record.data.pid);
};

/****************************************************
* row checkbox
****************************************************/

var sm = new Ext.grid.CheckboxSelectionModel({
singleSelect: false
});

/****************************************************
* filter grid
****************************************************/

var filterGrid = function(grid, cmp) {
var filterText = cmp.getValue();

addParameters('filterTxt', filterText);

// load the datastore
grid.getStore().load({
params: {
start: 0
}
});
};

/****************************************************
* grid datastore
****************************************************/
var gridDs = new Ext.data.Store({
storeId: 'deletedRecordsStore',
reader: new Ext.data.JsonReader({
totalProperty: 'total',
root: 'rows'
}, [
{name: 'uid', type: 'int'},
{name: 'pid', type: 'int'},
{name: 'record', mapping: 'title'},
{name: 'crdate'},
{name: 'tstamp'},
{name: 'owner'},
{name: 'owner_uid'},
{name: 'tableTitle'},
{name: 'table'},
{name: 'path'}
]),
sortInfo: {
field: 'record',
direction: "ASC"
},
groupField: 'table',
url: Recycler.statics.ajaxController + '&depth=' + Recycler.statics.depthSelection + '&startUid=' + Recycler.statics.startUid + '&cmd=getDeletedRecords&pagingSizeDefault=' + Recycler.statics.pagingSize + '&table=' + Recycler.statics.tableSelection

});

/****************************************************
* add param to grid store GET
****************************************************/
var addParameters = function(key, value) {
var grid = tabs.getComponent(0).getComponent(0);

var url = grid.getStore().proxy.conn.url;
var urlParts = url.split('?');

var params = urlParts[1].split('&');
var newParams = [];
var k = 0; // used to specify offset if we set a value

// add our new key / value to the new params if value is not ''
if ('' !== value) {
newParams[0] = key + '=' + value;
k = 1;
}

// find the key and remove it
var l = params.length;

for (var i = 0; i < l; i ++) {
if (params[i].indexOf(key + '=') != -1) {
k -= 1;
continue;
} else {
newParams[i + k] = params[i];
}
}

// make new url from http + params
url = urlParts[0] + '?' + newParams.join('&');


// set the new url for the store
grid.getStore().proxy.conn.url = url;
};

/****************************************************
* permanent deleting function
****************************************************/

var function_delete = function(ob) {
rowAction(ob, Recycler.lang.cmd_doDelete_confirmText, 'doDelete', Recycler.lang.title_delete, Recycler.lang.text_delete);
};

/****************************************************
* Undeleting function
****************************************************/

var function_undelete = function(ob) {
rowAction(ob, Recycler.lang.sure, 'doUndelete', Recycler.lang.title_undelete, Recycler.lang.text_undelete);
};

/****************************************************
* Row action function ( deleted or undeleted )
****************************************************/

var rowAction = function(ob, confirmQuestion, cmd, confirmTitle, confirmText) {
// get the 'undeleted records' grid object
var grid = tabs.getComponent(0).getComponent(0);
recArray = grid.getSelectionModel().getSelections();

if (recArray.length > 0) {

// check if a page is checked
var recursiveCheckbox = false;
var arePagesAffected = false;
var tables = [];
var hideRecursive = ('doDelete' == cmd);

for (iterator=0; iterator < recArray.length; iterator++) {
if (tables.indexOf(recArray[iterator].data.table) < 0) {
tables.push(recArray[iterator].data.table);
}
if (cmd == 'doUndelete' && recArray[iterator].data.table == 'pages' ) {
recursiveCheckbox = true;
arePagesAffected = true;
}
}

var frmConfirm = new Ext.Window({
xtype: 'form',
width: 300,
height: 200,
modal: true,
title: confirmTitle,
items: [
{
xtype: 'label',
text: confirmText + tables.join(', ')
},{
xtype: 'label',
text: confirmQuestion
},{
xtype: 'checkbox',
boxLabel: Recycler.lang.boxLabel_undelete_recursive,
name: 'recursiveCheckbox',
disabled: !recursiveCheckbox,
id: 'recursiveCheckbox',
hidden: hideRecursive // hide the checkbox when frm is used to permanently delete
}
],
buttons: [
{
text: Recycler.lang.yes,
handler: function(cmp, e) {
tcemainData = new Array();

for (iterator=0; iterator < recArray.length; iterator++) {
tcemainData[iterator] = [recArray[iterator].data.table, recArray[iterator].data.uid];
}

Ext.Ajax.request({
url: Recycler.statics.ajaxController + '&cmd=' + cmd,
callback: function(options, success, response) {
if (response.responseText === "1") {
// reload the records and the table selector
grid.getStore().reload();
Ext.getCmp('tableSelector').store.reload();
if (arePagesAffected) {
Recycler.utility.updatePageTree();
}
}else{
alert('ERROR: '+response.responseText);
}
},
params: {'data': Ext.encode(tcemainData), 'recursive':frmConfirm.getComponent('recursiveCheckbox').getValue() }
});

frmConfirm.destroy();
}
},{
text: Recycler.lang.no,
handler: function(cmp, e) {
frmConfirm.destroy();
}
}
]
});
frmConfirm.show();

} else {
// no row selected
Ext.MessageBox.show({
title: Recycler.lang.error_NoSelectedRows_title,
msg: Recycler.lang.error_NoSelectedRows_msg,
buttons: Ext.MessageBox.OK,
minWidth: 300,
minHeight: 200,
icon: Ext.MessageBox.INFO
});
}
};

/****************************************************
* tab container
****************************************************/

var tabs = new Ext.TabPanel({
renderTo: Recycler.statics.renderTo,
layoutOnTabChange: true,
activeTab: 0,
width: '99%',
height: 600,
frame: true,
border: false,
defaults: {autoScroll: true},
plain: true,
buttons: [{

/****************************************************
* Delete button
****************************************************/

id: 'deleteButton',
text: Recycler.lang.deleteButton_text,
tooltip: Recycler.lang.deleteButton_tooltip,
iconCls: 'delete',
disabled: Recycler.statics.deleteDisable,
handler: function_delete
},{

/****************************************************
* Undelete button
****************************************************/

id: 'undeleteButton',
text: Recycler.lang.undeleteButton_text,
tooltip: Recycler.lang.undeleteButton_tooltip,
iconCls: 'undelete',
handler: function_undelete
}
],
buttonAlign:'left',
items:[
{

/****************************************************
* Deleted records Tab
****************************************************/

id: 'delRecordId',
title: Recycler.lang.deletedTab,
items: [
{

/****************************************************
* Grid
****************************************************/

xtype: 'grid',
loadMask: true,
store: gridDs,
cm: new Ext.grid.ColumnModel([
sm,
expander,
{header: "UID", width: 10, sortable: true, dataIndex: 'uid'},
{header: "PID", width: 10, sortable: true, dataIndex: 'pid'},
{id:'record',header: "Records", width: 60, sortable: true, dataIndex: 'record', renderer: renderTopic},
{header: "Table", width: 20, sortable: true, dataIndex: 'tableTitle'}
]),

view: new Ext.grid.GridView({
forceFit:true
}),

bbar: [
{

/****************************************************
* Paging toolbar
****************************************************/
id: 'recordPaging',
xtype: 'paging',
store: 'deletedRecordsStore',
pageSize: Recycler.statics.pagingSize,
displayInfo: true,
displayMsg: Recycler.lang.pagingMessage,
emptyMsg: Recycler.lang.pagingEmpty
}
],

tbar: [
Recycler.lang.search, ' ',
new Ext.app.SearchField({
store: gridDs,
width: 200
}),
'->', {

/****************************************************
* Depth menu
****************************************************/

xtype: 'combo',
lazyRender: true,
valueField: 'depth',
displayField: 'label',
id: 'depthSelector',
mode: 'local',
emptyText: Recycler.lang.depth,
selectOnFocus: true,
readOnly: true,
triggerAction: 'all',
editable: false,
forceSelection: true,
hidden: Recycler.lang.showDepthMenu,
store: new Ext.data.SimpleStore({
autoLoad: true,
fields: ['depth','label'],
data : [
['0', Recycler.lang.depth_0],
['1', Recycler.lang.depth_1],
['2', Recycler.lang.depth_2],
['3', Recycler.lang.depth_3],
['4', Recycler.lang.depth_4],
['999', Recycler.lang.depth_infi]
]
}),
value: Recycler.statics.depthSelection,
listeners: {
'select': {
fn: function(cmp, rec, index) {
var store = tabs.getComponent(0).getComponent(0).getStore();
var depth = rec.get('depth');

addParameters('depth', depth);
store.load();

Ext.getCmp('tableSelector').store.load({
params: {
depth: depth
}
});
}
}
}
},'->',{

/****************************************************
* Table menu
****************************************************/

xtype: 'combo',
lazyRender: true,
valueField: 'valueField',
displayField: 'tableTitle',
id: 'tableSelector',
mode: 'local',
emptyText: Recycler.lang.tableMenu_emptyText,
selectOnFocus: true,
readOnly: true,
triggerAction: 'all',
editable: false,
forceSelection: true,

store: new Ext.data.Store({
autoLoad: true,
url: Recycler.statics.ajaxController + '&startUid=' + Recycler.statics.startUid + '&cmd=getTables' + '&depth=' + Recycler.statics.depthSelection,
reader: new Ext.data.ArrayReader({}, [
{name: 'table', type: 'string'},
{name: 'records', type: 'int'},
{name: 'valueField', type: 'string'},
{name: 'tableTitle', type: 'string'}
]),
listeners: {
'load': {
fn: function(store, records) {
Ext.getCmp('tableSelector').setValue(Recycler.statics.tableSelection);
},
single: true
}
}
}),
valueNotFoundText: String.format(Recycler.lang.noValueFound, Recycler.statics.tableSelection),
tpl: '<tpl for="."><tpl if="records &gt; 0"><div ext:qtip="{table} ({records})" class="x-combo-list-item">{tableTitle} ({records}) </div></tpl><tpl if="records &lt; 1"><div ext:qtip="{table} ({records})" class="x-combo-list-item x-item-disabled">{tableTitle} ({records}) </div></tpl></tpl>',
listeners: {
'select': {
fn: function(cmp, rec, index) {
var store = tabs.getComponent(0).getComponent(0).getStore();
var table = rec.get('valueField');

// do not reload if the table selected has no deleted records - hide all records
if (rec.get('records') <= 0) {
store.filter('uid', '-1'); // never true
return false;
}

addParameters('table', table);

store.load({
params: {
start: 0
}
});
}
}
}
}
],

sm: sm,
plugins: expander,
loadMask: true,
stripeRows: true,
width: '100%',
height: 530,
collapsible: false,
animCollapse: false,
frame: false,
border: false,
listeners: {
'render': {
fn: function(cmp) {
cmp.getStore().load();
},
single: true
}
}
}
]
}//,{

/****************************************************
* Lost and found Tab
****************************************************/
/*
id: 'lostAndFoundId',
title: Recycler.staticsRecycler.statics.lostFoundTab,
html:'Later'
} */
]
});
}
};


Recycler.utility = {
updatePageTree: function() {
if (top && top.content && top.content.nav_frame && top.content.nav_frame.Tree) {
top.content.nav_frame.Tree.refresh();
}
}
};

Animal
23 Apr 2009, 4:28 AM
There obviously is this.store, otherwise there would be a different error at that line.

You have to examine what it is, and see who passed it.

Animal
23 Apr 2009, 4:33 AM
store: 'deletedRecordsStore',


Shouldn't that be gridDs?

steffenk
23 Apr 2009, 8:11 AM
store: 'deletedRecordsStore',


Shouldn't that be gridDs?

it seems both works, object name and id, but you're right. Unfortunally this wasn't the error described here.

steffenk
23 Apr 2009, 8:14 AM
There obviously is this.store, otherwise there would be a different error at that line.

You have to examine what it is, and see who passed it.

i debugged several time - very difficult to find the place where it is, or i'm to clumsy in debugging. But i try to find the point where it crashes.

I have to say that the code works in 2.0 well without any error.

queej
27 Apr 2009, 1:20 PM
I am getting the same error with an upgrade to 3.0, in the same place (the PagingToolbar code).

I removed the paging toolbar from one grid and the problem cropped up in another grid, so I believe it may be a more general problem. I tried using both the component id and the variable name for the "ds" parameter, and both had the same behavior.



createObjectivesPanel: function() {
var objectivesRecord = new Ext.data.Record.create( [ { name: "id", type: "int" }, { name: "display_order" }, { name: "objective" } ] );
var objectivesStore = new Ext.data.JsonStore({
id: "des_objectives_store",
url: "ajaxFetch.php?m=obj",
baseParams: { method: "POST" },
sortInfo: { field: "display_order", direction: "ASC" },
fields: objectivesRecord,
totalProperty: "totalCount",
root: "data",
autoLoad: false
});
var objectivesGrid = new Ext.grid.EditorGridPanel({
id: "des_objectives_grid",
width: 420,
height: 200,
maxHeight: 400,
autoHeight: false,
stripeRows: true,
frame: false,
iconCls: "icon-grid",
clicksToEdit: 1,
sm: new Ext.grid.RowSelectionModel({ singleSelect: false }),
ds: objectivesStore,
cm: new Ext.grid.ColumnModel({
columns: [
{ id: "des_objective_id", header: "ID", width: 80, dataIndex: "id", sortable: true },
{ id: "des_objective_seq", header: "Sequence", width: 80, dataIndex: "display_order", sortable: true,
editor: ( lloom.Privileges.allow( "D_OBJECTIVES", "M" )? new Ext.grid.GridEditor( new Ext.form.TextField({}) ) : null ),
css: ( lloom.Privileges.allow( "D_OBJECTIVES", "M" )? lloom.FIELD_EDITABLE_STYLE : null )
},
{ id: "des_objective_text", header: "Objective", width: 400, height: 40, dataIndex: "objective",
editor: ( lloom.Privileges.allow( "D_OBJECTIVES", "M" )? new Ext.grid.GridEditor( new Ext.form.TextArea({}) ) : null ),
css: ( lloom.Privileges.allow( "D_OBJECTIVES", "M" )? lloom.FIELD_EDITABLE_STYLE : null )
}
]
}),
listeners: {
beforeremove: function() { lloom.Designer.changeMade( "grid remove" ); },
beforeadd: function() { lloom.Designer.changeMade( "grid add" ); },
afteredit: function() { lloom.Designer.changeMade( "grid edit" ); }
},
bbar: new Ext.PagingToolbar({
pageSize: 10,
store: "des_objectives_store",
displayInfo: true,
plugins: [new Ext.ux.Andrie.pPageSize()],
displayMsg: "Displaying records {0} - {1} of {2}",
emptyMsg: "No records to display.",
items: [
{
tooltip: "Click to add a record.",
iconCls: "add",
disabled: (!lloom.Privileges.allow( "D_OBJECTIVES", "A" )),
handler: function() {
var grid = Ext.getCmp( "des_objectives_grid" );
var newRecord = new objectivesRecord({ id: -1, objective: "-new objective-"});
grid.stopEditing();
objectivesStore.insert( 0, newRecord );
grid.startEditing( 0, 0 );
}
},
{
tooltip: "Click to Delete selected objectives(s)",
iconCls: "delete",
disabled: (!lloom.Privileges.allow( "D_OBJECTIVES", "D" )),
handler: function() {
var grid = Ext.getCmp( "des_objectives_grid" );
var sel = grid.getSelections();
var rootId = Ext.getCmp( "des_repo_root_id" ).getValue();
var blockId = Ext.getCmp( "des_repo_block_id" ).getValue();
if ( sel.length > 0 ) {
Ext.MessageBox.confirm( "Confirmation", "Are you sure you want to delete the selected objective(s)?",
function( btn ) {
if ( btn == "yes" ) {
var recList = [];
var records = grid.getSelectionModel().getSelections();
for ( var i=0; i<records.length; i++ ) {
objectivesStore.remove( records[i] );
var rec = records[i];
var id = rec.get( "id" );
if ( id != null && id > 0 ) {
recList.push( id );
}
}
if ( recList.length > 0 ) {
var params = { exec: "design::delete_block_objectives",
root_id: rootId,
block_id: blockId,
objective_ids: Ext.util.JSON.encode(recList)
};
lloom.execute( params,
function() {
grid.getEl().mask();
grid.getStore().commitChanges();
grid.getStore().load();
grid.getEl().unmask();
}
);
}
}
}
);
}
}
}
]
})
});
var llDesTabObjectives = new Ext.FormPanel({
title: "Objectives",
id: "des_objectives_panel",
disabled: (!lloom.Privileges.allow( "D_OBJECTIVES", "R" )),
hideLabels: true,
autoScroll: true,
waitMsgTarget: true,
layout: "fit",
bodyStyle: "padding: 10px;",
items: [ objectivesGrid ]
});

return llDesTabObjectives;
},

steffenk
3 Jun 2009, 3:12 PM
i could fix it.

reason was, that store in paging toolbar has to be defined as reference, not as string

- store: 'deletedRecordsStore',
+ store: gridDs,