Adding Drop down menu in the window heder using extjs4? - javascript

I need to add drop down menu when I click the top right icon on the window header display it like Google Chrome browser menu. Adding Drop down menu in the window header using extjs4.
Here is the code, but cannot able to see the menu.
code here:
Hi I need this looks like google chrome browser menu. i cannot see when i click the menu on window.
Ext.require([
'Ext.form.*'
]);
Ext.onReady(function() {
var win;
var options = [
{"name":"AAdvantage ",},
{"name":"PNR",},
{"name":"Bag File",}
];
Ext.regModel('Options', {
fields: [
{type: 'string', name: 'name'}
]
});
var store = Ext.create('Ext.data.Store', {
model: 'Options',
data: options
});
var menu = Ext.create('Ext.menu.Menu', {
id: 'mainMenu',
items: [
{
text: 'Search Customer',
checked: true
}, '-',
{
text: 'Customer Information',
checked: true
}, '-', {
text: 'Travel History',
checked: true
}, '-', {
text: 'Resolution'
}, '-', {
text: 'Future OD'
}, '-', {
text: 'History OD'
},'-', {
text: 'Help',
checked: true
}, '-', {
text: 'Upload Document',
checked: true
}
]
});
function showContactForm() {
if (!win) {
var form = Ext.widget('form', {
layout: {
type: 'vbox',
align: 'stretch'
},
border: false,
bodyPadding: 10,
fieldDefaults: {
labelSeparator: "",
labelAlign: 'top',
labelWidth: 100,
labelStyle: 'font-weight:bold'
},
defaults: {
margins: '0 0 10 0'
},
items: [{
xtype: 'fieldcontainer',
fieldLabel: 'Search Customer',
labelStyle: 'font-weight:bold;padding:0',
layout: 'hbox',
defaultType: 'textfield',
fieldDefaults: {
labelAlign: 'top'
},
},
{
xtype: 'combobox',
fieldLabel: 'Select Option',
name: 'suit_options_id',
id: 'ComboboxSuitOptions',
typeAhead:false,
labelAlign:'top',
labelSeparator: "",
store: store,
editable: false,
displayField: 'name',
hiddenName: 'id',
valueField: 'id',
queryMode: 'local',
listeners: {
change: function(combo) {
console.log(combo.getValue());
}
}
},
{
xtype: 'textfield',
fieldLabel: 'AAdvantage Number',
allowBlank: false
},
{
xtype: 'button',
text : 'Search',
handler: function() {
}
}]
});
win = Ext.widget('window', {
title: '<center>FCR</center>',
closeAction: 'hide',
width: 200,
height: 300,
minHeight: 300,
layout: 'fit',
closable: false,
tools: [
{ type:'left',
menu: menu
}
],
resizable: true,
modal: true,
items: form
});
}
win.show();
}
showContactForm();
});

The code does what it means:
tools: [
{ type:'left',
menu: menu
}
],
This code generates your left icon in the top window see the doc, but ool`has no property menu, so your code cannot work.
Define a handler function that shows your menu (this code works, but there is some tuning necessary to align the menu on the button) :
tools: [
{ type:'left',
handler: function(){menu.show()}
}
],
There are also some other problems with your code.
I get an warning Ext.regModel has been deprecated. Models can now be created by extending Ext.data.Model: Ext.define("MyModel", {extend: "Ext.data.Model", fields: []});.
Also, you should prefer use the launch method of Ext.app.Application to start rather than Ext.onReady which is ExtJS version 3

Related

How to hide choose file button in extJs

We're using an old version of extJS (2.3.0) I'm experiencing some headache with choose file button / Here is my code
var uploadBtn = new Ext.Panel({
tbar : [
{text: 'Upload CSV file', id: 'upload-btnn', handler: uploadHandler} // tbbutton is the default xtype if not specified
]
});
var fileField = new Ext.ux.form.FileUploadField({
fieldLabel: 'File name',
id: 'form-file',
emptyText: 'Select a Document',
name: 'file',
hideButton: true
//buttonText: 'Оберіть файл'
});
var fileUploader = new Ext.FormPanel({
id:'upload-form',
fileUpload: true,
header: false,
hidden: true,
labelWidth: 75,
frame:true,
bodyStyle:'padding:5px 5px 0',
autoWidth: true,
//defaultType: 'textfield',
items: [
fileField
],
buttons: [{
text:'upload',
handler: submitIt
},{
text: 'cancel',
handler: function(){
fileUploader.getForm().reset();
fileUploader.hide();
//$('upload-btnn').show();
//uploadBtn.show();
}
}],
border:false,
scope: this
});
function submitIt(){
fileUploader.getForm().isValid();
fileUploader.getForm().submit({
url: 'links_generation/file_upload',
clientValidation: false,
waitMsg: 'Uploading your Document...',
success: function(fp, o){
//msg('Success', 'Processed file "'+o.result.file+'" on the server');
fileUploader.getForm().reset();
//fileUploadWin.hide();
},
failure: function(a,b) {
fileUploader.getForm().reset();
//fileUploadWin.hide();
}
});
}
function uploadHandler(){
this.hide();
fileUploader.show();
}
It appears two button. I need to influence a choose file button (to style it properly) or to hide Browse button at least. Would be grateful for any advise
I don't see you are using customized 'filefield', so its is better to use it as a self initialized item.
Try this
items: [
{
xtype:'filefield', //change the xtype as per doc
fieldLabel: 'File name',
id: 'form-file',
emptyText: 'Select a Document',
name: 'file',
hideButton: true
}
]
Try this ..
items: [{
xtype: 'filefield',
name: 'photo',
fieldLabel: 'Upload a file',
emptyText: 'Click here to browse files...',
labelWidth: 100,
msgTarget: 'side',
allowBlank: false,
anchor: '100%',
buttonText: '',
buttonConfig: {
cls: 'browseBtnCls'
}
}]
and add following class in css
.browseBtnCls {padding: 0px !important;background-color: transparent !important; border-color: transparent; width: 0px}
Check this working fiddle.

How to POST a grid within a form in ExtJS

I have a form that has comboboxes, tagfields, date pickers, etc., and a grid. Each of these elements has a different store. The user is going to make selections from the comboboxes, etc,. and enter values into the grid. Then the values from the grid and other form elements are all sent on a POST to the server. I know how to POST the data from the comboboxes, tagfields, and date pickers. However, I don't know how to send the data in the grid with the form. Here is the form view:
Ext.define('ExtTestApp.view.main.List', {
extend: 'Ext.form.Panel',
xtype: 'cell-editing',
frame: true,
autoScroll: true,
title: 'Record Event',
bodyPadding: 5,
requires: [
'Ext.selection.CellModel',
'ExtTestApp.store.Personnel'
],
layout: 'column',
initComponent: function(){
this.cellEditing = new Ext.grid.plugin.CellEditing({
clicksToEdit: 1
});
Ext.apply(this, {
//width: 550,
fieldDefaults: {
labelAlign: 'left',
labelWidth: 90,
anchor: '100%',
msgTarget: 'side'
},
items: [{
xtype: 'fieldset',
//width: 400,
title: 'Event Information',
//height: 460,
//defaultType: 'textfield',
layout: 'anchor',
defaults: {
anchor: '100%'
},
items: [{
xtype: 'fieldcontainer',
fieldLabel: 'Event',
layout: 'hbox',
defaults: {
hideLabel: 'true'
},
items: [{
xtype: 'combobox',
name: 'eventTypeId',
width: 300,
//flex: 1,
store: {
type: 'events'
},
valueField: 'eventTypeId',
// Template for the dropdown menu.
// Note the use of the "x-list-plain" and "x-boundlist-item" class,
// this is required to make the items selectable.
allowBlank: false
}
]
},
{
xtype: 'container',
layout: 'hbox',
margin: '0 0 5 0',
items: [
{
xtype: 'datefield',
fieldLabel: 'Date',
format: 'Y-m-d',
name: 'startDate',
//msgTarget: 'under', //location of error message, default is tooltip
invalidText: '"{0}" is not a valid date. "{1}" would be a valid date.',
//flex: 1,
emptyText: 'Start',
allowBlank: false
},
{
xtype: 'datefield',
format: 'Y-m-d',
name: 'endDate',
//msgTarget: 'under', //location of error message
invalidText: '"{0}" is not a valid date. "{1}" would be a valid date.',
//flex: 1,
margin: '0 0 0 6',
emptyText: 'End',
allowBlank: false
}
]
}]
},
{
xtype: 'fieldset',
//height: 460,
title: 'Platform Information',
//defaultType: 'textfield',
layout: 'anchor',
defaults: {
anchor: '100%'
},
items: [
{
xtype: 'fieldcontainer',
layout: 'hbox',
fieldLabel: 'Platform',
//combineErrors: true,
defaults: {
hideLabel: 'true'
},
items: [
{
xtype: 'combobox',
name: 'platformId',
store: {
type: 'platforms'
},
valueField: 'platformId',
allowBlank: false
}
]
}
]
},
{
xtype: 'fieldcontainer',
layout: 'hbox',
fieldLabel: 'Software Type(s)',
//combineErrors: true,
defaults: {
hideLabel: 'true'
},
items: [
{
xtype: 'tagfield',
width: 400,
//height: 50,
fieldLabel: 'Software Type(s)',
name: 'softwareTypeIds',
store: {
type: 'softwareTypes'
},
labelTpl: '{softwareName} - {manufacturer}',
valueField: 'softwareTypeId',
allowBlank: false
}
]
},
{
xtype: 'gridpanel',
layout: 'anchor',
defaults: {
anchor: '100%'
},
width: 1300,
//columnWidth: 0.78,
//title: 'Metrics',
plugins: [this.cellEditing],
title: 'Personnel',
store: {
type: 'personnel'
},
columns: [
{ text: 'Name', dataIndex: 'name', editor: 'textfield' },
{ text: 'Email', dataIndex: 'email', flex: 1 },
{ text: 'Phone', dataIndex: 'phone', flex: 1 }
]
}
],
buttons: [
{
text: 'Save Event',
handler: function() {
var form = this.up('form'); // get the form panel
// if (form.isValid()) { // make sure the form contains valid data before submitting
Ext.Ajax.request({
url: 'api/events/create',
method:'POST',
headers: { 'Content-Type': 'application/json' },
params : Ext.JSON.encode(form.getValues()),
success: function(form, action) {
Ext.Msg.alert('Success', action.result);
},
failure: function(form, action) {
//console.log(form.getForm().getValues());
Ext.Msg.alert('Submission failed', 'Please make sure you selected an item for each required field.', action.result);
}
});
// } else { // display error alert if the data is invalid
// Ext.Msg.alert('Submit Failed', 'Please make sure you have made selections for each required field.')
// }
}
}
]
});
this.callParent();
}
});
var grid = Ext.ComponentQuery.query('grid')[0];
Here is the store for the grid:
Ext.define('ExtTestApp.store.Personnel', {
extend: 'Ext.data.Store',
alias: 'store.personnel',
fields: [
'name', 'email', 'phone'
],
data: { items: [
{ name: 'Jean Luc', email: "jeanluc.picard#enterprise.com", phone: "555-111-1111" },
{ name: 'Worf', email: "worf.moghsson#enterprise.com", phone: "555-222-2222" },
{ name: 'Deanna', email: "deanna.troi#enterprise.com", phone: "555-333-3333" },
{ name: 'Data', email: "mr.data#enterprise.com", phone: "555-444-4444" }
]},
autoLoad: true,
proxy: {
type: 'memory',
api: {
update: 'api/update'
},
reader: {
type: 'json',
rootProperty: 'items'
},
writer: {
type: 'json',
writeAllFields: true,
rootProperty: 'items'
}
}
});
Ideally, you would need to create a custom "grid field" so that the grid data is picked up on form submit like any other field.
You can also use this workaround: in the "Save Event" button handler, dig out the grid store and fish data out of it:
var gridData = [];
form.down('gridpanel').store.each(function(r) {
gridData.push(r.getData());
});
Then get the rest of the form data and put the grid data into it:
var formData = form.getValues();
formData.gridData = gridData;
Finally, include it all in your AJAX call:
params: Ext.JSON.encode(formData)

ExtJS 3.4: Render buttons in hidden tabpanel

In ExtJs 3.4 I have a TabPanel with two tabs, the second tab contains a FormPanel, what contains a ButtonGroup. If the second tab is active, when I load the page, then everything is good, but when the first tab is active and I switch to the second, then there is no button in the button group, just the label. Here is the code:
var tabs = new Ext.TabPanel({
renderTo: 'tabs',
width:500,
forceLayout: true,
activeTab: 0,
deferredRender: false,
defaults:{autoHeight: true},
items:[
{contentEl:'tab1', title: 'Tab1'},
{contentEl:'tab2', title: 'Tab2'}
]
});
var form = new Ext.form.FormPanel({
width : 400,
autoHeight: true,
renderTo: 'form',
bodyStyle: 'padding: 5px',
items: [
{
xtype: 'buttongroup',
fieldLabel: 'Label',
items:
[
{
xtype: 'button',
text: 'Find By User',
width: 100,
scope: this,
handler: this.handleFind
},
{
xtype: 'button',
text: 'Find All',
width: 100,
scope: this,
handler: this.handleFindAll
}
]
}
]
});
I set the deferredRender: false and forceLayout: true, also tried the hideMode: 'offsets', but these didn't help.
Well, I add the hideMode: 'offsets' to the defaults of the TabPanel and it works fine. I did the same a few years ago without significant result.
Remove renderTo: 'form' and look at the working code here:
var form = new Ext.form.FormPanel({
width: 400,
autoHeight: true,
//renderTo: 'form',
bodyStyle: 'padding: 5px',
items: [{
xtype: 'buttongroup',
fieldLabel: 'Label',
items: [{
xtype: 'button',
text: 'Find By User',
width: 100,
scope: this,
handler: this.handleFind
}, {
xtype: 'button',
text: 'Find All',
width: 100,
scope: this,
handler: this.handleFindAll
}]
}]
});
var tabs = new Ext.TabPanel({
renderTo: 'tabs',
width: 500,
forceLayout: true,
activeTab: 0,
//deferredRender: false,
height: 300,
defaults: {
autoHeight: true
},
items: [{
contentEl: 'tab1',
title: 'Tab1'
}, {
//contentEl: 'tab2',
title: 'Tab2',
items: [form]
}]
});

Sencha Touch2 - Panels with Card layout not working

I have tabpanel, which contains a few tabs. I will be concentrating on the 6th tab here - navigatingPanels.js file. In this file, I have a card layout, so that the user can fill form1 & move to form2 on submission (slide to form2). I also have a docked toolbar, with a back button, so that the user can move back to form1 (if needed). It gives an error -
Uncaught Error: [ERROR][Ext.Base#callParent] Invalid item given: undefined, must be either the config object to factory a new item, or an existing component instance.
The app can be seen here - http://maalguru.in/touch/Raxa-70/MyApp/
Update - If I add one extra card to the concerned panel, & remove the form1 & form2 (required panels/cards), then it works fine. In this case I have to setActiveItem to the desired cards (form1 & form2). Changed Viewport - http://pastebin.com/P4k04dBQ
Is there any solution to achieve with only 2 panels/cards ?
Viewport.js
Ext.define('MyApp.view.Viewport', {
extend: 'Ext.TabPanel',
xtype: 'my-viewport',
config: {
fullscreen: true,
tabBarPosition: 'bottom',
items: [{
xclass: 'MyApp.view.navigatingPanels'
}]
}
});
NavigatingPanels.js
Ext.define('MyApp.view.navigatingPanels', {
extend: 'Ext.Panel',
id: 'navigatingPanels',
xtype: 'navigatingPanels',
config: {
iconCls: 'user',
title: 'Navigating Panels',
layout: 'card',
animation: {
type: 'slide',
direction: 'left'
},
defaults: {
styleHtmlContent: 'true'
},
items: [{
docked: 'top',
xtype: 'toolbar',
title: 'Registeration Form',
items: [{
text: 'Back',
ui: 'back',
align: 'centre',
//back button to take the user back from form2 to form1
handler: function() {
Ext.getCmp('navigatingPanels').setActiveItem(form1);
}
}]
},
form1,
form2
]
}
});
var form1 = new Ext.Panel({
scrollable: 'vertical',
items: [{
xtype: 'fieldset',
title: 'Form 1',
items: [{
xtype: 'textfield',
label: 'Name',
name: 'name',
},
{
xtype: 'button',
text: 'Save Data & move to form2',
ui: 'confirm',
//TODO add some action: to store data
//save data & move to form2
handler: function() {
Ext.getCmp('navigatingPanels').setActiveItem(form2, {
type: 'slide',
direction: 'right'
});
console.log("Form1");
}
}
]
}]
});
var form2 = new Ext.Panel({
scrollable: 'vertical',
items: [{
xtype: 'fieldset',
title: 'Form 2',
items: [{
xtype: 'textareafield',
label: 'Message',
name: 'message'
},
{
xtype: 'button',
text: 'Submit Data',
ui: 'confirm',
//TODO add some action: to store data
//action: 'Submit Data'
}
]
}]
});
App.js
Ext.Loader.setConfig({
enabled: true
});
Ext.application({
name: 'MyApp',
controllers: ['Main'],
launch: function() {
Ext.create('MyApp.view.Viewport', {
fullscreen: true
});
}
});
Finally I got the answer. The component instances should not be given as items in Ext.define, instead their config should be given. The setActiveItem can be called the the normal way -
Ext.getCmp('navigatingPanels').setActiveItem(0);
CODE SNIPPET
Ext.define('MyApp.view.navigatingPanels', {
extend: 'Ext.Panel',
id: 'navigatingPanels',
xtype: 'navigatingPanels',
config: {
iconCls: 'user',
title: 'Navigating Panels',
layout: 'card',
animation: {
type: 'slide',
direction: 'left',
duration: 300
},
defaults: {
styleHtmlContent: 'true'
},
items: [{
docked: 'top',
xtype: 'toolbar',
title: 'Registeration Form',
items: [{
text: 'Back',
ui: 'back',
align: 'centre',
//back button to take the user back from form2 to form1
handler: function() {
Ext.getCmp('navigatingPanels').setActiveItem(0, {
type: 'slide',
reverse: 'true',
duration: '300'
});
console.log(Ext.getCmp('navigatingPanels'));
}
}]
},
{
xtype: 'fieldset',
title: 'Form 1',
scrollable: 'vertical',
items: [{
xtype: 'textfield',
label: 'Name',
name: 'name',
},
{
xtype: 'button',
text: 'Save Data & move to form2',
ui: 'confirm',
//TODO add some action: to store data
//save data & move to form2
handler: function() {
Ext.getCmp('navigatingPanels').setActiveItem(1, {
type: 'slide',
direction: 'right'
});
console.log("Form1");
}
}
]
},
{
scrollable: 'vertical',
items: [{
xtype: 'fieldset',
title: 'Form 2',
items: [{
xtype: 'textareafield',
label: 'Message',
name: 'message'
},
{
xtype: 'button',
text: 'Submit Data',
ui: 'confirm',
//TODO add some action: to store data
//action: 'Submit Data'
}
]
}]
}
]
}
});
Try this...
myNavigationPanel = Ext.create('MyApp.view.navigatingPanels');
myNavigationPanel.setActiveItem(0);
Ext.define('MyApp.view.Viewport', {
extend: 'Ext.TabPanel',
xtype: 'my-viewport',
config: {
fullscreen: true,
tabBarPosition: 'bottom',
items: [{
xclass: 'MyApp.view.Home'
},
{
xclass: 'MyApp.view.Contact'
},
{
xclass: 'MyApp.view.Products'
},
{
xclass: 'MyApp.view.Forms'
},
{
xclass: 'MyApp.view.NestedTabPanels'
},
myNavigationPanel
]
}
});

ExtJs 4 MVC Nested Layouts

I'm trying to implement a simple framework for an app. The idea is to create a background viewport type 'layout' with a north region containing the page header and an interchangeable center region.
When my app starts, a Login form is shown. If the user/password is ok, the form is destroyed and the main layout should appear. The main layout should insert a nested layout in its center region.
This is my background layout code:
Ext.define('DEMO.view.BackgroundLayout', {
extend: 'Ext.container.Viewport',
alias: 'widget.background',
requires: [
'DEMO.view.Main'
],
layout: {
type: 'border'
},
initComponent: function() {
var me = this;
Ext.applyIf(me, {
items: [
{
region: 'north',
html: '<h1 class="x-panel-header">Page Title</h1>'
},
{
xtype: 'mainview',
region: 'center',
forceFit: false,
height: 400
}
]
});
me.callParent(arguments);
}
});
The main layout is this:
Ext.define('DEMO.view.Main', {
extend: 'Ext.container.Viewport',
alias: 'widget.mainview',
requires: [
'DEMO.view.MyGridPanel'
],
layout: {
type: 'border'
},
initComponent: function() {
var me = this;
console.log('bb');
Ext.applyIf(me, {
items: [
{
xtype: 'mygridpanel',
region: 'center',
forceFit: false
},
{
xtype: 'container',
height: 38,
forceFit: false,
region: 'north',
items: [
{
xtype: 'button',
height: 34,
id: 'btnLogout',
action: 'logout',
text: 'Logout'
}
]
}
]
});
me.callParent(arguments);
}
});
As you can see, the center region needs an xtype named "mygridpanel". This is the code for it:
Ext.define('DEMO.view.ui.MyGridPanel', {
extend: 'Ext.grid.Panel',
border: '',
height: 106,
title: 'My Grid Panel',
store: 'MyJsonStore',
initComponent: function() {
var me = this;
Ext.applyIf(me, {
viewConfig: {
},
columns: [
{
xtype: 'gridcolumn',
dataIndex: 'Id',
text: 'Id'
},
{
xtype: 'gridcolumn',
dataIndex: 'Name',
text: 'Name'
},
{
xtype: 'gridcolumn',
dataIndex: 'Sales',
text: 'Sales'
}
],
dockedItems: [
{
xtype: 'toolbar',
dock: 'top',
items: [
{
xtype: 'button',
disabled: true,
id: 'btnDelete',
allowDepress: false,
text: 'Delete'
},
{
xtype: 'button',
disabled: true,
id: 'btnEdit',
allowDepress: false,
text: 'Edit'
}
]
}
]
});
me.callParent(arguments);
}
});
My problem is that when I call Ext.create('DEMO.view.BackgroundLayout', {}); it only shows the nested layout, and the background layout is hidden, also I get this error in Chrome's console:
Uncaught Error: HIERARCHY_REQUEST_ERR: DOM Exception 3
What I'm doing wrong?.
Thanks in advance,
Leonardo.

Categories