I'm trying to add a combobox to a floating (popup) form panel in ExtJS. But I'm getting a "Cannot set property 'component' of null" error and the window will not load.
I use the following code in a controller to create the window:
onTreeAddDocClick: function () {
var f = new Ext.form.Panel({
frame: false,
header: false,
floating: true,
closable: true,
items: [{
xtype: 'addDoc'
}]
});
f.show();
}
The code for the window itself is as follows:
Ext.define('OPENhrm.view.dossier.widget.popup.AddDoc', {
extend: 'Ext.form.Panel',
xtype: 'addDoc',
requires: [
'Ext.layout.container.VBox'
],
controller: "dossier-addDoc",
viewModel: {
type: "dossier-addDoc"
},
id: 'addDocForm',
frame: true,
title: 'Add document',
width: 400,
bodyPadding: '10 10 0',
layout: 'form',
closable: true,
defaults: {
anchor: '100%',
allowBlank: false,
msgTarget: 'side',
labelWidth: 50
},
items: [{
// item selector
xtype: 'filefield',
emptyText: 'Select Document',
fieldLabel: 'Document',
name: 'filePath',
id: 'filePath',
buttonText: 'upload document',
buttonConfig: {
icon : '/resources/images/icons/add.jpg'
}
}, {
xtype: 'combo',
fieldLabel: 'Test',
hiddenName: 'test',
store: new Ext.data.SimpleStore({
data: [
['Test1'],
['Test2']
],
id: 0,
fields: ['text']
}),
valueField: 'text',
displayField: 'text',
triggerAction: 'all',
editable: false
}],
// buttons
buttons: [{
text: 'Add',
handler: 'onAddDockClick'
}, {
text: 'Reset',
handler: function () {
this.up('form').getForm().reset();
}
}]
});
If I remove the combobox, the window works just fine. If I place the combobox in a form somewhere else in my application (e.g. on a page with 2 panels; a searchfilter/form and a grid with search results), it works just fine. That other page however, is not a floating/popup window.
I got it to work by defining the whole page in the controller, but as I'm using a MVC structure, that doesn't seem like the way to go. Does anyone know how to get the combobox to work in a floating window, without putting the whole code for that window in the controller?
Related
I have a form defined that I use to submit to a PHP script that will create an Excel Spreadsheet using PHPExcel.
Ext.define('Admin.view.main.LedgerParams',{
extend: 'Ext.window.Window',
xtype: 'ledgerparams',
title: 'Generate Account Ledger',
defaultFocus: '[name=period]',
layout: 'fit',
closable: false,
resizable: false,
modal : true,
standardSubmit: true,
items: [{
xtype: 'form',
layout: 'fit',
fieldDefaults: {labelWidth: 80,labelAlign: 'right'},
padding: 10,
items: [{
xtype: 'fieldset',
padding: 10,
title: '<b>Account Ledger Parameters</b>',
defaultType: 'numberfield',
defaults: {enforceMaxLength: true},
items:[{
name: 'period',
flex : 1,
fieldLabel: 'Fiscal Period',
selectOnFocus: true,
value: new Date().getFullYear(),
minValue: 1980
}]
}]
}],
buttons:[{
text: 'Generate',
handler: 'onClick_btnLedgerPrint'
},{
text: 'Cancel',
handler: function(){this.up('window').destroy();}
}]
});
The onClick_BtnLedgerPrint method in the main controller calls the form submit:
onClick_btnLedgerPrint: function(btn){
btn.up('window').down('form').submit({
url: 'app/data/Reports.php',
params: {action:'print',reportname:'generate_ledger'}
});
}
however it appears that a JSON response is required by the form from the server instead of initiating the download. Is the standardSubmit broken in ExtJS5? Any help would be appreciated!
JavaScript cannot initiate the download, same as Ext JS. Only browser does this.
var formValues = btn.up('window').down('form').getForm().getValues();
var params = { action: 'print', reportname: 'generate_ledger' };
var requestParams = Ext.merge(formValues, params);
var url = 'app/data/Reports.php?' + Ext.Object.toQueryString(requestParams);
document.location = url;
Or you can try to use method with iframe described here
This seems like a trivial issue, but... I have a list of addresses in a panel to which I wish to add geolocation coordinates (and to display them on a map) that is rendered in a form panel, so that when I click on the address of interest in the panel an onTap is fired to do execute the onSelectGeolocation given below to open the form panel rendered in the ViewPort and to add any existing records to the associated form elements:
onSelectGeolocation: function(view, index, target, record, event) {
console.log('Selected a Geolocation from the list');
var geolocationForm = Ext.Viewport.down('geolocationEdit');
if(!geolocationForm){
geolocationForm = Ext.widget('geolocationEdit');
}
geolocationForm.setRecord(record);
geolocationForm.showBy(target);
}
The line that uses the setRecord method to write any existing records in my store to the form elements, however, is preventing the default values in my form panel below from getting written to the desired form elements. When I comment this out, all is good. Problem is that I need to grab those records that exist in my store, e.g., address, to display in my form. How can I do this AND write default values to my textfield elements in my form?
My form panel that is rendered as a ViewPort via the onTap is:
Ext.define('EvaluateIt.view.GeolocationEdit', {
extend: 'Ext.form.Panel',
alias : 'widget.geolocationEdit',
requires: [
'Ext.form.Panel',
'Ext.form.FieldSet',
'Ext.field.Number',
'Ext.field.DatePicker',
'Ext.field.Select',
'Ext.field.Hidden'
],
config: {
// We give it a left and top property to make it floating by default
left: 0,
top: 0,
// Make it modal so you can click the mask to hide the overlay
modal: true,
hideOnMaskTap: true,
// Set the width and height of the panel
width: 400,
height: 330,
scrollable: true,
layout: {
type: 'vbox'
},
defaults: {
margin: '0 0 5 0',
labelWidth: '40%',
labelWrap: true
},
items: [
{
xtype: 'datepickerfield',
destroyPickerOnHide: true,
name : 'datOfEvaluatione',
label: 'Date of evaluation',
value: new Date(),
picker: {
yearFrom: 1990
}
},
{
xtype: 'textfield',
name: 'address',
label: 'Address',
itemId: 'address'
},
{
xtype: 'textfield',
name: 'latitude',
label: 'Latitude',
itemId: 'latitude',
value: sessionStorage.latitude,
},
/* {
xtype: 'textfield',
name: 'longitude',
label: 'Longitude',
itemId: 'longitude',
value: sessionStorage.longitude
},
{
xtype: 'textfield',
name: 'accuracy',
label: 'Accuracy',
itemId: 'accuracy',
value: sessionStorage.accuracy
},*/
{
xtype: 'button',
itemId: 'save',
text: 'Save'
}
]
}
});
Behavior is as expected. I will use Ext.getCmp on the id's for each item instead.
i have a form panel and a tree panel
the form is used to add new users, the tree is used to show the list of users
what i want is to right click a node in my tree ,click edit (already can do that) then i have my data in the add form panel and be able to modify there and update my user
so basically use the same form for adding and updating
this is how im trying to do up to know
but its not working at all
i added a model to my tree,i used loadRecord(rec), but i dont know how to bind my tree data with the form fields!
tried adding displayfield with same name from my tree model!!
my tree model and store:
Ext.define('TreeModel', {
extend: 'Ext.data.Model',
fields: [
{ name: 'text' },
{ name: 'id' }
]
});
window.ATreeStore = Ext.create('Ext.data.TreeStore', {
model: 'TreeModel',
root: Ext.decode(objt.TreeToJson()),
proxy: {
type: 'ajax'
},
sorters: [{
property: 'leaf',
direction: 'ASC'
}, {
property: 'text',
direction: 'ASC'
}]
});
my tree menu:
var myContextMenu = new Ext.menu.Menu({
items: [{
text: 'Edit',
handler: function () {
Ext.getCmp('addaform').getForm().loadRecord(rec);
}
}
}]
my form:
Ext.define("Ext.app.Adduser", {
extend: "Ext.form.Panel",
title: 'Add user',
id : 'addform',
closable: true,
collapsible: true,
animCollapse: true,
draggable: true,
resizable: true,
margin: '5 5 5 5',
height: 400,
frame: true,
fieldDefaults: {
labelAlign: 'top',
msgTarget: 'side'
},
defaults: {
anchor: '100%'
},
items: [{
layout: 'column',
border: false,
items: [{
padding: '5',
columnWidth: .5,
border: false,
layout: 'anchor',
defaultType: 'textfield',
items: [{
fieldLabel: ' Name',
name: 'name',
allowBlank: false,
displayfield:'id',//
anchor: '95%'
}]
}, {
padding: '5',
columnWidth: .5,
border: false,
layout: 'anchor',
defaultType: 'textfield',
items: [{
fieldLabel: 'First name',
name: 'fname',
allowBlank: false,
anchor: '95%'
}, {
xtype: 'textarea',
fieldLabel: 'Profile',
name: 'prof',
anchor: '95%'
}]
}],
buttons: [{
text: 'Save',
handler: function () {
this.up('form').getForm().submit
({
url: 'AddData.ashx',
params: { action: 'add' },
success: function (form, action)
{
Ext.MessageBox.show({ title: 'Success !',
msg: 'User added successfully<br />',
icon: Ext.MessageBox.INFO,
buttons: Ext.MessageBox.OK
}) }
}) }]
thank you
If your TreePanel uses a TreeStore which in turn has a Ext.data.Model, then when you right click on a node (say nodeA), you should be just able to do form.loadRecord(nodeA), the API for loadRecord is here
If it's still not clear, I think this blog post could help, it talks about loading a grid record into a form. I know it's not ExtJS 4, but the key functions are the same.
Ok, let me show this with a super simple example, hope it will help.
First we create the form that we want to display stuff in, note that the renderTo property is bound to a div inside my HTML, so you might need to change that. Also note that the name property of the textarea and textfield, they are the key for the loadRecord to work, they have to match the fields defined in the model later.
var form = Ext.create('Ext.form.Panel',{
renderTo : 'form-div',
items : [{
xtype : 'textarea',
fieldLabel : 'label 1',
name : 'name'
},{
xtype : 'textfield',
fieldLabel : 'label 2',
name : 'age'
}]
});
Next, we create the tree to display our data, we start by creating a simple model :
Ext.define('Person',{
extend : 'Ext.data.Model',
fields : [{
name : 'name',
type : 'string'
},{
name : 'age',
type : 'int'
}]
});
Then we create a TreeStore that uses that model and initialize it with some inline data:
var store = Ext.create('Ext.data.TreeStore',{
model : 'Person',
root : {
expanded : true,
children : [{
name : 'John',
age : 10,
leaf : true
},{
name : 'Joe',
age : 100,
leaf : true
}]
}
});
Then we create the tree to display the data in the store. (Note that the nodes will show up as "undefined" because we are not using the default "text" property of a Node)
var tree = Ext.create('Ext.tree.Panel',{
height : 300,
width : 300,
store : store,
rootVisible : false,
renderTo : 'tree-div',
listeners : {
itemclick : function(view, record){
form.loadRecord(record);
}
}
});
Now, you should see a tree with two nodes both displayed as "undefined" on your page, as well as a Form with a textarea and a textfield. If you click on a node inside the tree, the form will display the name and age of the selected node.
I'm having a problem where I would like to remove a FormPanel from a Window.
Here is my Form which is being loaded in a Window:
myForm = new Ext.FormPanel({
frame: true,
width: '100%',
id: 'myform',
layout: 'form',
autoHeight: true,
autoDestroy: false,
region: 'center',
monitorValid: true,
items: [{
xtype: 'textfield',
id: 'mytextfield',
fieldLabel: 'My Label',
}]
});
MyWindow = new Ext.Window({
title: 'MyWindow',
layout: 'auto',
resizable: false,
width: 717,
autoheight:true,
id:'mywindow',
closeAction:'hide',
closable: true,
items:[Ext.getCmp("myform")]
});
Now I want to remove this form and have to show another form, and I'm doing like this somewhere else:
MyWindow.removeAll();
MyWindow.add(Ext.getCmp("myAnotherForm"));
But this gives me error "Uncaught TypeError: Cannot read property 'events' of undefined" in ext-all-debug.js.
Is there anything, I'm missing here ?
Thanks.
You can remove the form and add another form by using the following code:
Ext.onReady(function() {
var btn = new Ext.Button({
id : 'button',
width : 100,
height : 30,
text : 'click me',
listeners : {
click : function(){
var myanother = myAnotherForm;
var anotherbtn = btn1;
Mywindow.removeAll();
Mywindow.add(myanother);
Mywindow.add(anotherbtn);
Mywindow.doLayout();
}
}
});
var btn1 = new Ext.Button({
id : 'button1',
width : 100,
height : 30,
text : 'Another button'
});
myAnotherForm = new Ext.FormPanel({
frame: true,
width: '100%',
id: 'myanotherform',
layout: 'form',
autoHeight: true,
autoDestroy: false,
region: 'center',
monitorValid: true,
items: [{
xtype: 'textfield',
id: 'mytextfield',
fieldLabel: 'My Another Label',
}]
});
myForm = new Ext.FormPanel({
frame: true,
width: '100%',
id: 'myform',
layout: 'form',
autoHeight: true,
autoDestroy: false,
region: 'center',
monitorValid: true,
items: [{
xtype: 'textfield',
id: 'mytextfield',
fieldLabel: 'My Label',
}]
});
var Mywindow = new Ext.Window({
title: 'MyWindow',
layout: 'auto',
resizable: false,
width: 317,
autoheight:true,
id:'mywindow',
closeAction:'hide',
closable: true,
items : [myForm,btn]
});
Mywindow.show();
});
The working sample for the above is follows:
http://jsfiddle.net/kesamkiran/MVewR/1/
* Click on 'click me' button then you will get the another form with another button.If you want to change only form,then you can remove the button.
thats weired - it worked and suddenly (changed nothing but adding code to other panels...) it's not working any more:
I used to enable/disable a form with a button inside a docked toolbar. within the handler ofthe button the disable/enable is triggered with a simple
formBase.enable();
but this is throwing the error
TypeError: Result of expression 'formBase.enable' [undefined] is not a
function.
now.
I don't get it....
any help would be great!
thx!
You probabilly have a scope issue, so you can't get your formBase variable from the button handler.
I post you a full working example I've done to let you understand how it is possible to enable / disable your form.
Ext.setup({
onReady: function() {
var form = new Ext.form.FormPanel({
scroll: 'vertical',
fullscreen: true,
url : 'postUser.php',
standardSubmit : false,
dockedItems: [{
xtype: 'toolbar',
title: 'Example',
items: [{
xtype: 'button',
text: 'Disable',
handler: function(){
form.disable();
}
},{
xtype: 'spacer'
},{
xtype: 'button',
text: 'Enable',
handler: function(){
form.enable();
}
}]
}],
items: [{
xtype: 'fieldset',
title: 'Personal Info',
instructions: 'Please enter the information above.',
defaults: {
required: true,
labelAlign: 'left',
labelWidth: '40%'
},
items: [
{
xtype: 'textfield',
name : 'name',
label: 'Name',
useClearIcon: true,
autoCapitalize : false
}, {
xtype: 'passwordfield',
name : 'password',
label: 'Password',
useClearIcon: false
}]
}]
});
form.show();
}
});
Hope This helps.