PDA

View Full Version : ed is undefined



nithiz
15 Feb 2010, 2:20 PM
Hi,

First of all, sorry for my bad english and thanks for the awesome work and support on ExtJs. :D
I'm working on a application using ExtJs, so far everything i've seem to figure out by searching the forums for solutions and my application is almost finished. Though i have came across one thing that i can't figure out.

It probably has to do something with the fact that i want a grid which has both DND and editor functions in it.

I get the error when clicking on a row in the grid which i want to edit.

The error:
ed is undefined - roweditor.js (line 265)

The code:

Ext.onReady(function(){

Ext.BLANK_IMAGE_UR = 'images/sgif';
Ext.QuickTips.init();

// use RowEditor for editing
var editor = new Ext.ux.grid.RowEditor({
saveText: 'Update'
});

function title_text(store){
return '<div style="padding:0px 20px">'+'<b style="font-size: 13px;">'+store.data.name+'</b><br>'+'<i> '+store.data.type+'</i></div>';
}

var taskStore = new Ext.data.SimpleStore({
fields:
[
"name",
"type"
],
data : [
[
"Titel",
"textrow"
],
[
"Tekst",
"textarea"
]
]
});

var grid = new Ext.grid.GridPanel({
renderTo: 'pagefieldblock',
frame:true,
title: 'Pagina velden',
height:200,
width:600,
selModel: new Ext.grid.RowSelectionModel({
singleSelect:true,
listeners: {
beforerowselect: function(sm,i,ke,row){
grid.ddText = title_text(row);
}
}
}),
store: taskStore,
plugins: [editor],
enableDragDrop : true,
ddGroup : 'mygrid-dd',
ddText : 'Hier plaatsen',
columns: [
{header: "Naam", id:'name', dataIndex: 'name', sortable: true, editor: {xtype: 'textfield',allowBlank: false}},
{header: "Type", id:'type', dataIndex: 'type', sortable: true}
],
tbar: [{
text: 'Toevoegen',
icon: 'resources/img/icons/add.png',
handler: onAdd
}, '-', {
text: 'Verwijderen',
icon: 'resources/img/icons/cross.png',
handler: onDelete
}],
listeners: {
render: {
fn: function (grid) {
this.view.dragZone = new Ext.dd.SortableDragZone(grid.getView().mainBody, { ddGroup: grid.ddGroup });
}
}
}
});

function onAdd(btn, ev) {
var u = new grid.store.recordType({
name: '',
type : ''
});
editor.stopEditing();
grid.store.insert(0, u);
editor.startEditing(0);
}

function onDelete() {
var rec = grid.getSelectionModel().getSelected();
if (!rec) {
return false;
}
grid.store.remove(rec);
}

var dropTarget = new Ext.dd.DropTarget(grid.getView().mainBody, {
ddGroup : 'mygrid-dd',
notifyDrop : function(dd, e, data){
var sm = grid.getSelectionModel();
var rows = sm.getSelections();
var cindex = dd.getDragData(e).rowIndex;
if (sm.hasSelection()) {
for (i = 0; i < rows.length; i++) {
taskStore.remove(taskStore.getById(rows[i].id));
taskStore.insert(cindex,rows[i]);
}
sm.selectRecords(rows);
}
}
});


});

nithiz
16 Feb 2010, 12:04 PM
Still no solutions? :(

realjax
16 Feb 2010, 2:30 PM
Still no solutions? :(

Hold your horses, kaaskop. :D

Few questions:

- have you *tried* debugging roweditor.js in firebug?
- got the same error when you disable DND ?

If you want answers it is best to include all info, including the offending lines ( at least) that throw the error. Now you are expecting people to first go and find the source files themselves. Most will not even bother.

ps. I bet your problem is in the beforerowselect listener...

nithiz
17 Feb 2010, 2:08 AM
Hey man :) thanks for your reply.

The error i get in firebug with Extdebugger is :

ed is undefined
Line 265

If i completely disable all DnD functions i still get the error, and removing the lines below doenst make a difference either:


listeners: {
beforerowselect: function(sm,i,ke,row){
grid.ddText = title_text(row);
}
}


Roweditor.js:


/*!
* Ext JS Library 3.1.1
* Copyright(c) 2006-2010 Ext JS, LLC
* [email protected]
* http://www.extjs.com/license
*/
Ext.ns('Ext.ux.grid');

/**
* @class Ext.ux.grid.RowEditor
* @extends Ext.Panel
* Plugin (ptype = 'roweditor') that adds the ability to rapidly edit full rows in a grid.
* A validation mode may be enabled which uses AnchorTips to notify the user of all
* validation errors at once.
*
* @ptype roweditor
*/
Ext.ux.grid.RowEditor = Ext.extend(Ext.Panel, {
floating: true,
shadow: false,
layout: 'hbox',
cls: 'x-small-editor',
buttonAlign: 'center',
baseCls: 'x-row-editor',
elements: 'header,footer,body',
frameWidth: 5,
buttonPad: 3,
clicksToEdit: 'auto',
monitorValid: true,
focusDelay: 250,
errorSummary: true,

saveText: 'Save',
cancelText: 'Cancel',
commitChangesText: 'You need to commit or cancel your changes',
errorText: 'Errors',

defaults: {
normalWidth: true
},

initComponent: function(){
Ext.ux.grid.RowEditor.superclass.initComponent.call(this);
this.addEvents(
/**
* @event beforeedit
* Fired before the row editor is activated.
* If the listener returns <tt>false</tt> the editor will not be activated.
* @param {Ext.ux.grid.RowEditor} roweditor This object
* @param {Number} rowIndex The rowIndex of the row just edited
*/
'beforeedit',
/**
* @event canceledit
* Fired when the editor is cancelled.
* @param {Ext.ux.grid.RowEditor} roweditor This object
* @param {Boolean} forced True if the cancel button is pressed, false is the editor was invalid.
*/
'canceledit',
/**
* @event validateedit
* Fired after a row is edited and passes validation.
* If the listener returns <tt>false</tt> changes to the record will not be set.
* @param {Ext.ux.grid.RowEditor} roweditor This object
* @param {Object} changes Object with changes made to the record.
* @param {Ext.data.Record} r The Record that was edited.
* @param {Number} rowIndex The rowIndex of the row just edited
*/
'validateedit',
/**
* @event afteredit
* Fired after a row is edited and passes validation. This event is fired
* after the store's update event is fired with this edit.
* @param {Ext.ux.grid.RowEditor} roweditor This object
* @param {Object} changes Object with changes made to the record.
* @param {Ext.data.Record} r The Record that was edited.
* @param {Number} rowIndex The rowIndex of the row just edited
*/
'afteredit'
);
},

init: function(grid){
this.grid = grid;
this.ownerCt = grid;
if(this.clicksToEdit === 2){
grid.on('rowdblclick', this.onRowDblClick, this);
}else{
grid.on('rowclick', this.onRowClick, this);
if(Ext.isIE){
grid.on('rowdblclick', this.onRowDblClick, this);
}
}

// stopEditing without saving when a record is removed from Store.
grid.getStore().on('remove', function() {
this.stopEditing(false);
},this);

grid.on({
scope: this,
keydown: this.onGridKey,
columnresize: this.verifyLayout,
columnmove: this.refreshFields,
reconfigure: this.refreshFields,
beforedestroy : this.beforedestroy,
destroy : this.destroy,
bodyscroll: {
buffer: 250,
fn: this.positionButtons
}
});
grid.getColumnModel().on('hiddenchange', this.verifyLayout, this, {delay:1});
grid.getView().on('refresh', this.stopEditing.createDelegate(this, []));
},

beforedestroy: function() {
this.grid.getStore().un('remove', this.onStoreRemove, this);
this.stopEditing(false);
Ext.destroy(this.btns);
},

refreshFields: function(){
this.initFields();
this.verifyLayout();
},

isDirty: function(){
var dirty;
this.items.each(function(f){
if(String(this.values[f.id]) !== String(f.getValue())){
dirty = true;
return false;
}
}, this);
return dirty;
},

startEditing: function(rowIndex, doFocus){
if(this.editing && this.isDirty()){
this.showTooltip(this.commitChangesText);
return;
}
if(Ext.isObject(rowIndex)){
rowIndex = this.grid.getStore().indexOf(rowIndex);
}
if(this.fireEvent('beforeedit', this, rowIndex) !== false){
this.editing = true;
var g = this.grid, view = g.getView(),
row = view.getRow(rowIndex),
record = g.store.getAt(rowIndex);

this.record = record;
this.rowIndex = rowIndex;
this.values = {};
if(!this.rendered){
this.render(view.getEditorParent());
}
var w = Ext.fly(row).getWidth();
this.setSize(w);
if(!this.initialized){
this.initFields();
}
var cm = g.getColumnModel(), fields = this.items.items, f, val;
for(var i = 0, len = cm.getColumnCount(); i < len; i++){
val = this.preEditValue(record, cm.getDataIndex(i));
f = fields[i];
f.setValue(val);
this.values[f.id] = Ext.isEmpty(val) ? '' : val;
}
this.verifyLayout(true);
if(!this.isVisible()){
this.setPagePosition(Ext.fly(row).getXY());
} else{
this.el.setXY(Ext.fly(row).getXY(), {duration:0.15});
}
if(!this.isVisible()){
this.show().doLayout();
}
if(doFocus !== false){
this.doFocus.defer(this.focusDelay, this);
}
}
},

stopEditing : function(saveChanges){
this.editing = false;
if(!this.isVisible()){
return;
}
if(saveChanges === false || !this.isValid()){
this.hide();
this.fireEvent('canceledit', this, saveChanges === false);
return;
}
var changes = {},
r = this.record,
hasChange = false,
cm = this.grid.colModel,
fields = this.items.items;
for(var i = 0, len = cm.getColumnCount(); i < len; i++){
if(!cm.isHidden(i)){
var dindex = cm.getDataIndex(i);
if(!Ext.isEmpty(dindex)){
var oldValue = r.data[dindex],
value = this.postEditValue(fields[i].getValue(), oldValue, r, dindex);
if(String(oldValue) !== String(value)){
changes[dindex] = value;
hasChange = true;
}
}
}
}
if(hasChange && this.fireEvent('validateedit', this, changes, r, this.rowIndex) !== false){
r.beginEdit();
Ext.iterate(changes, function(name, value){
r.set(name, value);
});
r.endEdit();
this.fireEvent('afteredit', this, changes, r, this.rowIndex);
}
this.hide();
},

verifyLayout: function(force){
if(this.el && (this.isVisible() || force === true)){
var row = this.grid.getView().getRow(this.rowIndex);
this.setSize(Ext.fly(row).getWidth(), Ext.isIE ? Ext.fly(row).getHeight() + 9 : undefined);
var cm = this.grid.colModel, fields = this.items.items;
for(var i = 0, len = cm.getColumnCount(); i < len; i++){
if(!cm.isHidden(i)){
var adjust = 0;
if(i === (len - 1)){
adjust += 3; // outer padding
} else{
adjust += 1;
}
fields[i].show();
fields[i].setWidth(cm.getColumnWidth(i) - adjust);
} else{
fields[i].hide();
}
}
this.doLayout();
this.positionButtons();
}
},

slideHide : function(){
this.hide();
},

initFields: function(){
var cm = this.grid.getColumnModel(), pm = Ext.layout.ContainerLayout.prototype.parseMargins;
this.removeAll(false);
for(var i = 0, len = cm.getColumnCount(); i < len; i++){
var c = cm.getColumnAt(i),
ed = c.getEditor();
if(!ed){
ed = c.displayEditor || new Ext.form.DisplayField();
}else{
ed = ed.field;
}
if(i == 0){
ed.margins = pm('0 1 2 1');
} else if(i == len - 1){
ed.margins = pm('0 0 2 1');
} else{
ed.margins = pm('0 1 2');
}
ed.setWidth(cm.getColumnWidth(i));
ed.column = c;
if(ed.ownerCt !== this){
ed.on('focus', this.ensureVisible, this);
ed.on('specialkey', this.onKey, this);
}
this.insert(i, ed);
}
this.initialized = true;
},

onKey: function(f, e){
if(e.getKey() === e.ENTER){
this.stopEditing(true);
e.stopPropagation();
}
},

onGridKey: function(e){
if(e.getKey() === e.ENTER && !this.isVisible()){
var r = this.grid.getSelectionModel().getSelected();
if(r){
var index = this.grid.store.indexOf(r);
this.startEditing(index);
e.stopPropagation();
}
}
},

ensureVisible: function(editor){
if(this.isVisible()){
this.grid.getView().ensureVisible(this.rowIndex, this.grid.colModel.getIndexById(editor.column.id), true);
}
},

onRowClick: function(g, rowIndex, e){
if(this.clicksToEdit == 'auto'){
var li = this.lastClickIndex;
this.lastClickIndex = rowIndex;
if(li != rowIndex && !this.isVisible()){
return;
}
}
this.startEditing(rowIndex, false);
this.doFocus.defer(this.focusDelay, this, [e.getPoint()]);
},

onRowDblClick: function(g, rowIndex, e){
this.startEditing(rowIndex, false);
this.doFocus.defer(this.focusDelay, this, [e.getPoint()]);
},

onRender: function(){
Ext.ux.grid.RowEditor.superclass.onRender.apply(this, arguments);
this.el.swallowEvent(['keydown', 'keyup', 'keypress']);
this.btns = new Ext.Panel({
baseCls: 'x-plain',
cls: 'x-btns',
elements:'body',
layout: 'table',
width: (this.minButtonWidth * 2) + (this.frameWidth * 2) + (this.buttonPad * 4), // width must be specified for IE
items: [{
ref: 'saveBtn',
itemId: 'saveBtn',
xtype: 'button',
text: this.saveText,
width: this.minButtonWidth,
handler: this.stopEditing.createDelegate(this, [true])
}, {
xtype: 'button',
text: this.cancelText,
width: this.minButtonWidth,
handler: this.stopEditing.createDelegate(this, [false])
}]
});
this.btns.render(this.bwrap);
},

afterRender: function(){
Ext.ux.grid.RowEditor.superclass.afterRender.apply(this, arguments);
this.positionButtons();
if(this.monitorValid){
this.startMonitoring();
}
},

onShow: function(){
if(this.monitorValid){
this.startMonitoring();
}
Ext.ux.grid.RowEditor.superclass.onShow.apply(this, arguments);
},

onHide: function(){
Ext.ux.grid.RowEditor.superclass.onHide.apply(this, arguments);
this.stopMonitoring();
this.grid.getView().focusRow(this.rowIndex);
},

positionButtons: function(){
if(this.btns){
var g = this.grid,
h = this.el.dom.clientHeight,
view = g.getView(),
scroll = view.scroller.dom.scrollLeft,
bw = this.btns.getWidth(),
width = Math.min(g.getWidth(), g.getColumnModel().getTotalWidth());

this.btns.el.shift({left: (width/2)-(bw/2)+scroll, top: h - 2, stopFx: true, duration:0.2});
}
},

// private
preEditValue : function(r, field){
var value = r.data[field];
return this.autoEncode && typeof value === 'string' ? Ext.util.Format.htmlDecode(value) : value;
},

// private
postEditValue : function(value, originalValue, r, field){
return this.autoEncode && typeof value == 'string' ? Ext.util.Format.htmlEncode(value) : value;
},

doFocus: function(pt){
if(this.isVisible()){
var index = 0,
cm = this.grid.getColumnModel(),
c,
ed;
if(pt){
index = this.getTargetColumnIndex(pt);
}
for(var i = index||0, len = cm.getColumnCount(); i < len; i++){
c = cm.getColumnAt(i);
ed = c.getEditor();
if(!c.hidden && ed){
ed.field.focus();
break;
}
}
}
},

getTargetColumnIndex: function(pt){
var grid = this.grid,
v = grid.view,
x = pt.left,
cms = grid.colModel.config,
i = 0,
match = false;
for(var len = cms.length, c; c = cms[i]; i++){
if(!c.hidden){
if(Ext.fly(v.getHeaderCell(i)).getRegion().right >= x){
match = i;
break;
}
}
}
return match;
},

startMonitoring : function(){
if(!this.bound && this.monitorValid){
this.bound = true;
Ext.TaskMgr.start({
run : this.bindHandler,
interval : this.monitorPoll || 200,
scope: this
});
}
},

stopMonitoring : function(){
this.bound = false;
if(this.tooltip){
this.tooltip.hide();
}
},

isValid: function(){
var valid = true;
this.items.each(function(f){
if(!f.isValid(true)){
valid = false;
return false;
}
});
return valid;
},

// private
bindHandler : function(){
if(!this.bound){
return false; // stops binding
}
var valid = this.isValid();
if(!valid && this.errorSummary){
this.showTooltip(this.getErrorText().join(''));
}
this.btns.saveBtn.setDisabled(!valid);
this.fireEvent('validation', this, valid);
},

showTooltip: function(msg){
var t = this.tooltip;
if(!t){
t = this.tooltip = new Ext.ToolTip({
maxWidth: 600,
cls: 'errorTip',
width: 300,
title: this.errorText,
autoHide: false,
anchor: 'left',
anchorToTarget: true,
mouseOffset: [40,0]
});
}
var v = this.grid.getView(),
top = parseInt(this.el.dom.style.top, 10),
scroll = v.scroller.dom.scrollTop,
h = this.el.getHeight();

if(top + h >= scroll){
t.initTarget(this.items.last().getEl());
if(!t.rendered){
t.show();
t.hide();
}
t.body.update(msg);
t.doAutoWidth(20);
t.show();
}else if(t.rendered){
t.hide();
}
},

getErrorText: function(){
var data = ['<ul>'];
this.items.each(function(f){
if(!f.isValid(true)){
data.push('<li>', f.getActiveError(), '</li>');
}
});
data.push('</ul>');
return data;
}
});
Ext.preg('roweditor', Ext.ux.grid.RowEditor);


Thanks for the help :)

realjax
17 Feb 2010, 2:37 AM
Here's how to go about:

This works:



var editor = new Ext.ux.grid.RowEditor({
saveText: 'Update'
});


var taskStore = new Ext.data.SimpleStore({
fields:
[
"name",
"type"
],
data : [
[
"Titel",
"textrow"
],
[
"Tekst",
"textarea"
]
]
});

var grid = new Ext.grid.GridPanel({

frame:true,
title: 'Pagina velden',
height:200,
width:600,

store: taskStore,
plugins: [editor],
columns: [
{header: "Naam", id:'name', dataIndex: 'name', sortable: true, editor: {xtype: 'textfield',allowBlank: false}},
{header: "Type", id:'type', dataIndex: 'type', sortable: true}
],
tbar: [{
text: 'Toevoegen',
icon: 'resources/img/icons/add.png'
}, '-', {
text: 'Verwijderen',
icon: 'resources/img/icons/cross.png'
}]

});

new Ext.Window({items:grid}).show();


I stripped out a number of items, now you find out which one is the problem maker..

nithiz
17 Feb 2010, 2:51 AM
It's not working here,

when i remove this line:

editor: {xtype: 'textfield',allowBlank: false}

I get the following, which ofcourse does not have the TextField =P~:

http://img64.imageshack.us/img64/2707/editor.jpg

It simply can not find the editor somehow..

realjax
17 Feb 2010, 4:31 AM
looks more like as if you forgot to include the roweditor css sheet

nithiz
17 Feb 2010, 4:39 AM
Nah, i did include the css file. And a problem with a css file would not throw a JS error if im right.


<link href="uploader/css/uploadify.css" rel="stylesheet" type="text/css" />
<link href="system/application/views/extjs/editorgrid/roweditor.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="system/application/views/extjs/editorgrid/roweditor.js"></script>
<script type="text/javascript" src="system/application/views/extjs/editwebsite.js"></script>
<script type="text/javascript" src="system/application/views/extjs/pagefieldgrid.js"></script>

Editwebsite.js renders a different Extjs form.
Pagefieldgrid.js has the Extjs grid buildup i shown u before.

Thanks for your help though, much apreciated :)

realjax
17 Feb 2010, 4:48 AM
well, something in your pages is amiss. I tested the source I posted in firebugs console against the roweditor sample page and it worked fine.

>And a problem with a css file would not throw a JS error if im right.
Sure it can. But your post #6 does not mention any error..

nithiz
17 Feb 2010, 6:05 AM
Thanks alot.

It's working now. The problem was the fact that i was using EXT 3.1.0 and not 3.1.1 .
Stupid mistake on my side /:)
Thanks for the effort :)

Mike Robinson
17 Feb 2010, 7:10 AM
"For the benefit of the Peanut Gallery ..."

(1) Many things don't exist until the object is "rendered." There are no DOM objects until that happens, and any properties that refer to DOM objects are undefined. ExtJS is "lazy" about everything it can afford to be "lazy" about, and that's a good thing.

(2) It's a good idea to use a slight 'delay' when responding to the "render" event (and it can be marked 'single' as well). Sometimes the event happens a few milliseconds before the browser (e.g. in a separate thread?) has actually finished doing the work, and it's not repeatable.

(3) A hash with an 'xtype' property is, of course, not an object: it's a hash. A JavaScript object is made from that hash, and frequently replaces the hash.

(4) ExtJS typically has no "pretty error-traps" to tell you what went wrong: those take up space. FireBug is your best friend. Use it well. So is the Eclipse editor with the Aptana plugins and "JSLint syntax checking" turned-on. ~o)

realjax
17 Feb 2010, 1:08 PM
Thanks alot.

You're welcome.

Brett889
18 Feb 2010, 4:27 PM
Thanks a lot. I had the same issue, and upgrading to 3.1.1 solved the issue.