I'd be grateful for any help please. I've just started to build my first ever sencha app and am pleased with the results so far, but am now stuck on one thing. I've built a search form and want to be able to display the results on the same page, but this is where I'm stuck. The form works and sends the results using GET, but it doesn't send it to the correct place. I want to show it on the same page (I've built a php file called search.php to handle the results), but it reloads the whole app with the variables in the url.
I've tested all of the code away from the app and it works perfectly so I know the problem isn't with the code, but more with my lack of understanding of Sencha so would be extremely grateful for any help.
Code:
searchForms = new Ext.TabPanel({
fullscreen: true,
title: 'Search',
displayField: 'text',
store: searchForm,
iconCls: 'search',
items: [{
id: 'searchSubmit',
xtype: 'form',
standardSubmit : true,
scroll: 'vertical',
items: [{
xtype: 'fieldset',
title: 'Keywords',
defaults: {
// labelAlign: 'right'
labelWidth: '35%'
},
items: [{
xtype: 'textfield',
name: 'keywords',
id: 'keywords',
placeHolder: 'EG: Music, TV',
autoCapitalize : true,
required: true,
useClearIcon: true
}]
}, {
xtype: 'fieldset',
title: 'Advanced Search',
items: [{
xtype: 'selectfield',
name: 'genre',
id: 'genre',
label: 'Genre',
options: [{
text: 'All',
value: ' '
text: 'Country',
value: '1'
text: 'Sci-Fi',
value: '2'
text: 'Western',
value: '3'
}]
}, {
xtype: 'selectfield',
name: 'media',
id: 'media',
label: 'Media',
options: [{
text: 'All',
value: ' '
text: 'Music',
value: '1'
text: 'TV',
value: '2'
text: 'Movie',
value: '3'
}]
}]
}, {
layout: 'vbox',
defaults: {xtype: 'button', flex: 1, style: 'margin: .5em;'},
items: [{
text: 'Search',
ui: 'confirm',
scope: this,
hasDisabled: false,
handler: function(){
searchForms.submit({
url: 'search.php'
});
}
}, {
text: 'Reset',
ui: 'decline',
handler: function(){
searchForms.reset();
}
}]
}]
}]
});
I've then tried to use this to display the results on the same page, but as I say this just doesn't work. It doesn't call the search.php page at all.
I've made sure all of the files (except the index.js file which is in a js folder) are in the same directory as the index.html file.
I've also tried to load the file in the app seperately by using:
Ext.regModel('mobile', {
fields: [
{name: 'text', type: 'string'}
]
});
var searchForm = new Ext.data.TreeStore({
model: 'mobile',
proxy: {
type: 'ajax',
url: 'search.php?keywords=test',
reader: {
type: 'tree',
root: 'items'
}
}
});
and that works perfectly so I know that all of the php stuff is working and does work with Sencha Touch, but I'm just not sure how to get it to only work when somebody clicks 'search'
I'd be grateful for any help with this as I've spent days searching the web to get this fix, but nothing seems to be working :(
I don't know if this is of help, but the main javascript file is:
var tabPanel;
var homePanel = new Ext.Panel({
title: 'Home',
iconCls: 'home',
fullscreen: true,
scroll:{direction:'vertical',threshold:7},
items: [{
html: '<center><p>Home</p></center>'
}]
});
var servicePanel = new Ext.Panel({
title: 'Services',
iconCls: 'team',
fullscreen: true,
items: [{
html: '<center>Please choose a service</center>'
}]
});
var searchPanel = new Ext.Panel({
title: 'Search',
iconCls: 'search',
fullscreen: true,
items: [{
html: '<center>Search</center>'
}]
});
var feedtabpanel = new Ext.Carousel({
title: 'More',
iconCls: 'more',
fullscreen: true,
sortable : true,
xtype:'panel',
scroll:{direction:'vertical',threshold:7},
items: [
{
title: 'Contact',
html : '<center><h1>Contact Us</h1></center>',
},
{
title: 'Feedback',
html : '<center><h1>Let us know what you think<h1></center>',
},
{
title: 'Tell a friend',
html : '<center><h1>Tell your friends how much you love this app</h1></center>',
}
]
});
searchForms = new Ext.TabPanel({
fullscreen: true,
title: 'Search',
displayField: 'text',
store: searchForm,
iconCls: 'search',
items: [{
id: 'searchSubmit',
xtype: 'form',
standardSubmit : true,
scroll: 'vertical',
items: [{
xtype: 'fieldset',
title: 'Keywords',
defaults: {
// labelAlign: 'right'
labelWidth: '35%'
},
items: [{
xtype: 'textfield',
name: 'keywords',
id: 'keywords',
placeHolder: 'EG: Music, TV',
autoCapitalize : true,
required: true,
useClearIcon: true
}]
}, {
xtype: 'fieldset',
title: 'Advanced Search',
items: [{
xtype: 'selectfield',
name: 'genre',
id: 'genre',
label: 'Genre',
options: [{
text: 'All',
value: ' '
text: 'Country',
value: '1'
text: 'Sci-Fi',
value: '2'
text: 'Western',
value: '3'
}]
}, {
xtype: 'selectfield',
name: 'media',
id: 'media',
label: 'Media',
options: [{
text: 'All',
value: ' '
text: 'Music',
value: '1'
text: 'TV',
value: '2'
text: 'Movie',
value: '3'
}]
}]
}, {
layout: 'vbox',
defaults: {xtype: 'button', flex: 1, style: 'margin: .5em;'},
items: [{
text: 'Search',
ui: 'confirm',
scope: this,
hasDisabled: false,
handler: function(){
searchForms.submit({
url: 'search.php'
});
}
}, {
text: 'Reset',
ui: 'decline',
handler: function(){
searchForms.reset();
}
}]
}]
}]
});
Ext.regModel('mobile', {
fields: [
{name: 'text', type: 'string'}
]
});
var searchForm = new Ext.data.TreeStore({
model: 'mobile',
proxy: {
type: 'ajax',
url: 'search.php',
reader: {
type: 'tree',
root: 'items'
}
}
});
var store = new Ext.data.TreeStore({
model: 'mobile',
proxy: {
type: 'ajax',
url: 'areas.php',
reader: {
type: 'tree',
root: 'items'
}
}
});
var nestedList = new Ext.NestedList({
fullscreen: true,
title: 'Location',
displayField: 'text',
store: store,
iconCls: 'locate',
});
nestedList.on('leafitemtap', function(subList, subIdx, el, e) {
var store = subList.getStore(),
record = store.getAt(subIdx),
recordNode = record.node,
title = nestedList.renderTitleText(recordNode),
card, preventHide, anim;
if (record) {
card = record.get('card');
anim = record.get('animation');
preventHide = record.get('preventHide');
}
if (card) {
tabPanel.setCard(card, anim || 'slide');
tabPanel.currentCard = card;
}
});
var services = new Ext.data.TreeStore({
model: 'mobile',
proxy: {
type: 'ajax',
url: 'subcats.php',
reader: {
type: 'tree',
root: 'items'
}
}
});
var servicesList = new Ext.NestedList({
fullscreen: true,
title: 'Services',
displayField: 'text',
store: services,
iconCls: 'team',
});
servicesList.on('leafitemtap', function(subList, subIdx, el, e) {
var store = subList.getStore(),
record = store.getAt(subIdx),
recordNode = record.node,
title = servicesList.renderTitleText(recordNode),
card, preventHide, anim;
if (record) {
card = record.get('card');
anim = record.get('animation');
preventHide = record.get('preventHide');
}
if (card) {
tabPanel.setCard(card, anim || 'slide');
tabPanel.currentCard = card;
}
});
Ext.setup({
icon: 'icon.png',
glossOnIcon: false,
tabletStartupScreen: 'tablet_startup.png',
phoneStartupScreen: 'phone_startup.png',
onReady: function() {
tabPanel = new Ext.TabPanel({
tabBar: {
dock: 'bottom',
layout: {
pack: 'center'
}
},
fullscreen: true,
ui: 'dark',
animation: {
type: 'cardslide',
cover: true
},
items: [
homePanel,
nestedList,
servicesList,
searchForms,
feedtabpanel
]
});
}
})
Just update your store with the filter() function. First you have to add the correct filterParam to your store configuration. After this, you can call the filter() function in your search button handler. E.g.
searchForm.filter('keywordParam', searchfield.getValue());
After this, your store will get updated without the page refreshing. You could then use a DataView to show your search results.
Related
I have 4 forms, which called to the main view by buttons through controller.
How I must to link fields of forms with Django database, through REST api?
For example I have form:
Ext.define('Foresto.view.forms.RenterData', {
extend: 'Ext.form.Panel',
title: 'Renter',
header: {
cls: 'header-cls'
},
xtype: 'foresto-renterdata',
layout: 'fit',
scrollable: true,
tools: [{
type: 'minimize',
handler: function() {
this.up("panel").hide();
}
}, {
type: 'save'
}, {
type: 'close',
handler: function() {
this.up("panel").close();
}
}],
requires: ['Foresto.view.forms.RenterType'],
url: 'save-form.php',
defaults: {
xtype: 'textfield',
labelWrap: true,
required: true,
afterLabelTextTpl: [
'<span style="color:red;font-weight:normal" data-qtip="Required">*</span>'
]
},
items: [{
xtype: 'foresto-rentertype',
label: 'Type',
name: 'rentertype'
}, {
xtype: 'selectfield',
label: 'Document',
name: 'document',
}, {
label: 'Document number',
name: 'document_num'
}, {
label: 'NAME',
name: 'name_represent'
}, {
label: 'Position',
name: 'position_represent'
}]
});
And values of
name: 'document'
From Django:
{"license","rent agreement","order", "ticket"}
Where I can to add api url? I have to create proxy store or I can add api into form?
Please help! thanks!
I'm creating an app that simply shows customers information on a table, and if a user is being clicked then a pop-up window shows up showing user's information in a form (name and email). Within this PopUp I want to be able to update customers name and email and then when clicking on Update button I want the new information to show up on the table right away. As of right now I'm able to populate the table with customers' information as well as binding their information with the Pop-up window. But since I'm still kind of new to ExtJS I'm not really sure how to make the update to show right away on the table after clicking on update button. I would really appreciate any help!. Thanks a lot.
Here's my code that works just fine.
index.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css"
href="https://cdnjs.cat.net/ajax/libs/extjs/6.0.0/classic/theme-triton/resources/theme-triton-all-debug_1.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/extjs/6.0.0/ext-all.js"></script>
<script type="text/javascript">
Ext.define('UserModal', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'},
{name: 'email', type: 'string'}
]
});
Ext.onReady(function () {
// Ajax call
var usersFromAJAX = Ext.create('Ext.data.Store', {
storeId: 'user',
model: 'UserModal',
autoLoad: 'true',
proxy: {
type: 'ajax',
url: 'example.json',
reader: {
type: 'json',
root: 'customers'
}
}
});
// Setting up the Grid
Ext.create('Ext.grid.Panel', {
store: usersFromAJAX,
id: 'user',
title: 'Employees',
iconCls: 'x-fa fa-users',
listeners: {
itemclick: function (view, index, item, record) {
var window = Ext.create('Ext.window.Window', {
xtype: 'formpanel',
title: 'Update Record',
width: 300,
height: 200,
floating: true,
centered: true,
modal: true,
record: record,
viewModel: {
data: {
employee: index.data// employee's name
}
},
items: [{
xtype: 'textfield',
id: 'firstname',
name: 'firstname',
fieldLabel: 'First Name',
bind: '{employee.name}' // biding employee's name
},
{
xtype: 'textfield',
name: 'firstname',
fieldLabel: 'Email',
bind: '{employee.email}' // biding employee's name
},
{
xtype: 'toolbar',
docked: 'bottom',
style:{
background: "#ACCCE8",
padding:'20px'
},
items: ['->', {
xtype: 'button',
text: 'Update',
iconCls: 'x-fa fa-check',
handler: function () {
console.log("Updating name...");
// Need to add something in here
this.up('window').close();
}
}, {
xtype: 'button',
text: 'Cancel',
iconCls: 'x-fa fa-close',
handler: function () {
// this.up('formpanel').destroy();
this.up('window').close();
//this.up('window').destroy();
}
}]
}]
})
window.show();
}
},
columns: [{
header: 'ID',
dataIndex: 'id',
sortable: false,
hideable: true
}, {
header: 'NAME',
dataIndex: 'name',
}, {
header: 'Email',
dataIndex: 'email',
flex: 1 // will take the whole table
}],
height: 300,
width: 400,
renderTo: Ext.getElementById("myTable")
});
});
</script>
</head>
<body>
<div id="myTable"></div>
</body>
</html>
Here's the JSON that populates my table.
{
"customers": [{
"id": 1,
"name": "Henry Watson",
"email": "henry#email.com"
},
{
"id": 2,
"name": "Lucy",
"email": "lucy#email.com"
},
{
"id": 3,
"name": "Mike Brow",
"email": "Mike#email.com"
},
{
"id": 4,
"name": "Mary Tempa",
"email": "mary#email.com"
},
{
"id": 5,
"name": "Beto Carlx",
"email": "beto#email.com"
}
]
}
Binding is for "live" data, so that means it will update the grid as you type. If you want to defer the changes until you hit a button, you can use methods on the form to do so:
Fiddle
Ext.define('UserModal', {
extend: 'Ext.data.Model',
fields: ['id', 'name', 'email']
});
Ext.onReady(function () {
// Setting up the Grid
Ext.create('Ext.grid.Panel', {
store: {
model: 'UserModal',
autoLoad: 'true',
proxy: {
type: 'ajax',
url: 'data1.json',
reader: {
type: 'json',
rootProperty: 'customers'
}
}
},
listeners: {
itemclick: function (view, record) {
var f = Ext.create('Ext.form.Panel', {
xtype: 'formpanel',
title: 'Update Record',
width: 300,
height: 200,
floating: true,
centered: true,
modal: true,
buttons: [{
text: 'Update',
iconCls: 'x-fa fa-check',
handler: function () {
f.updateRecord(record);
f.close();
}
}, {
text: 'Cancel',
iconCls: 'x-fa fa-close',
handler: function () {
f.close();
}
}],
items: [{
xtype: 'textfield',
id: 'firstname',
name: 'name',
fieldLabel: 'First Name'
}, {
xtype: 'textfield',
name: 'email',
fieldLabel: 'Email'
}]
})
f.show();
f.loadRecord(record);
}
},
columns: [{
header: 'ID',
dataIndex: 'id',
sortable: false,
hideable: true
}, {
header: 'NAME',
dataIndex: 'name',
}, {
header: 'Email',
dataIndex: 'email',
flex: 1 // will take the whole table
}],
height: 300,
width: 400,
renderTo: document.body
});
});
I have an app that uses a Tab layout with the same grid panel shared as an xtype widget between each form panel bound to each tab.
My Main tab layout is as follows:
Ext.define('cardioCatalogQT.view.main.Main', {
extend: 'Ext.tab.Panel',
xtype: 'main-view',
controller: 'main-view',
requires: [
'cardioCatalogQT.view.main.MainController',
'cardioCatalogQT.view.main.MainModel',
'Ext.ux.form.ItemSelector',
'Ext.tip.QuickTipManager',
'Ext.layout.container.Card'
],
style: 'background-color:#dfe8f5;',
width: '100%',
height: 400,
layout: 'vbox',
defaults: {
bodyPadding: 5
},
items: [{
title:'Main',
region: 'south',
xtype: 'form',
itemId: 'Ajax',
flex: 1,
styleHtmlContent: true,
items:[{
xtype: 'image',
src: 'resources/images/R3D3.png',
height: 50,
width: 280
},{
title: 'Ad Hoc Sandbox for Cohort Discovery'
}] ,
lbar:[{
text: 'Initiate advanced request',
xtype: 'button',
handler: function(button){
var url = 'https://url_here';
//cardioCatalogQT.service.UtilityService.http_auth(button);
window.open(url);
}
}]
},
/*{
xtype: 'resultsGrid'
//disabled: true
},*/
/*{
xtype: 'searchGrid'
//disabled: true
},*/
{
xtype: 'demographicGrid'
//disabled: true
},
{
xtype: 'vitalGrid'
//disabled: true
},
{
xtype: 'labGrid'
//disabled: true
},
{
xtype: 'diagnosisGrid'
//disabled: true
},
{
xtype: 'medicationGrid'
//disabled: true
},
{
xtype: 'procedureGrid'
//disabled: true
},
{
xtype: 'queryGrid'
//disabled: true
}
]
});
The individual tabs that share the same grid widget (specifically, demographicGrid, vitalGrid, labGrid, diagnosisGrid, procedureGrid and medicationGrid, each referenced by xtype in the main view) look like:
/**
* Widget with template to render to Main view
*/
Ext.define('cardioCatalogQT.view.grid.DemographicGrid', {
extend: 'Ext.form.Panel',
alias: 'widget.demographicGrid',
itemId: 'demographicGrid',
store: 'Payload',
requires: [
'cardioCatalogQT.view.main.MainController'
],
config: {
variableHeights: false,
title: 'Demographics',
xtype: 'form',
width: 200,
bodyPadding: 10,
defaults: {
anchor: '100%',
labelWidth: 100
},
// inline buttons
dockedItems: [ {
xtype: 'toolbar',
height: 100,
items: [{
xtype: 'button',
text: 'Constrain sex',
itemId: 'showSex',
hidden: false,
listeners: {
click: function (button) {
button.up('grid').down('#sexValue').show();
button.up('grid').down('#hideSex').show();
button.up('grid').down('#showSex').hide();
}
}
}, {
xtype: 'button',
text: 'Hide sex constraint',
itemId: 'hideSex',
hidden: true,
listeners: {
click: function (button) {
button.up('grid').down('#sexValue').hide();
button.up('grid').down('#sexValue').setValue('');
button.up('grid').down('#hideSex').hide();
button.up('grid').down('#showSex').show();
}
}
},{ // Sex
xtype: 'combo',
itemId: 'sexValue',
queryMode: 'local',
editable: false,
value: 'eq',
triggerAction: 'all',
forceSelection: true,
fieldLabel: 'Select sex',
displayField: 'name',
valueField: 'value',
hidden: true,
store: {
fields: ['name', 'value'],
data: [
{name: 'female', value: 'f'},
{name: 'male', value: 'm'}
]
}
}, {
xtype: 'button',
text: 'Constrain age',
itemId: 'showAge',
hidden: false,
listeners: {
click: function (button) {
button.up('grid').down('#ageComparator').show();
button.up('grid').down('#ageValue').show();
button.up('grid').down('#hideAge').show();
button.up('grid').down('#showAge').hide();
}
}
}, {
xtype: 'button',
text: 'Hide age',
itemId: 'hideAge',
hidden: true,
listeners: {
click: function (button) {
button.up('grid').down('#ageComparator').hide();
button.up('grid').down('#ageValue').hide();
button.up('grid').down('#upperAgeValue').hide();
button.up('grid').down('#ageComparator').setValue('');
button.up('grid').down('#ageValue').setValue('');
button.up('grid').down('#upperAgeValue').setValue('');
button.up('grid').down('#hideAge').hide();
button.up('grid').down('#showAge').show();
}
}
}, { // Age
xtype: 'combo',
itemId: 'ageComparator',
queryMode: 'local',
editable: false,
value: '',
triggerAction: 'all',
forceSelection: true,
fieldLabel: 'Select age that is',
displayField: 'name',
valueField: 'value',
hidden: true,
store: {
fields: ['name', 'value'],
data: [
{name: '=', value: 'eq'},
{name: '<', value: 'lt'},
{name: '<=', value: 'le'},
{name: '>', value: 'gt'},
{name: '>=', value: 'ge'},
{name: 'between', value: 'bt'}
]
},
listeners: {
change: function(combo, value) {
// use component query to toggle the hidden state of upper value
if (value === 'bt') {
combo.up('grid').down('#upperAgeValue').show();
} else {
combo.up('grid').down('#upperAgeValue').hide();
}
}
}
},{
xtype: 'numberfield',
itemId: 'ageValue',
fieldLabel: 'value of',
value: '',
hidden: true
},{
xtype: 'numberfield',
itemId: 'upperAgeValue',
fieldLabel: 'and',
hidden: true
},{
xtype: 'button',
text: 'Constrain race/ethnicity',
itemId: 'showRace',
hidden: false,
listeners: {
click: function (button) {
button.up('grid').down('#raceValue').show();
button.up('grid').down('#hideRace').show();
button.up('grid').down('#showRace').hide();
}
}
}, {
xtype: 'button',
text: 'Hide race/ethnicity constraint',
itemId: 'hideRace',
hidden: true,
listeners: {
click: function (button) {
button.up('grid').down('#raceValue').hide();
button.up('grid').down('#raceValue').setValue('');
button.up('grid').down('#hideRace').hide();
button.up('grid').down('#showRace').show();
}
}
},{ // Race
xtype: 'combo',
itemId: 'raceValue',
queryMode: 'local',
editable: false,
value: 'eq',
triggerAction: 'all',
forceSelection: true,
fieldLabel: 'Select race',
displayField: 'name',
valueField: 'value',
hidden: true,
store: {
fields: ['name', 'value'],
data: [
{name: 'female', value: 'f'},
{name: 'male', value: 'm'}
]
}
},{
//minWidth: 80,
text: 'Add to search',
xtype: 'button',
itemId: 'searchClick',
handler: 'onSubmitDemographics'
}]
},
{
xtype:'searchGrid'
}
]
}
});
The only difference between each of the form panels in the tabs are the item components. Each of these form panels references an xtype of 'searchGrid' and renders it like in the attached image:
The problem is that I have 6-instances of this same grid. This works for the most part, but it is causing some issues related to getting control of the checkboxes in my grid along with some bizarre grid store load behaviors, and honestly, keeping track of components using this anti-pattern is a PITA.
I would like to somehow have a single instance of my searchGrid in a lower vertical panel, while an upper vertical panel has the item components I need to change according to the requirements for each tab. An example of how the item controls vary is
My desired behavior is that when I click on a tab, the upper item components would take me to a different form panel, while the lower panel stay fixed on the search grid.
However, I currently have the searchGrid bound to each tab's form panel, since that is the only way I could get this to work.
The searchGrid grid panel looks like:
Ext.define('cardioCatalogQT.view.grid.Search', {
extend: 'Ext.grid.Panel',
xtype: 'framing-buttons',
store: 'Payload',
itemId: 'searchGrid',
requires: [
'cardioCatalogQT.view.main.MainController'
],
columns: [
{text: "ID", width: 50, sortable: true, dataIndex: 'id'},
{text: "Type", width: 120, sortable: true, dataIndex: 'type'},
{text: "Key", flex: 1, sortable: true, dataIndex: 'key'},
{text: "Criteria", flex: 1, sortable: true, dataIndex: 'criteria'},
{text: "DateOperator", flex: 1, sortable: true, dataIndex: 'dateComparatorSymbol'},
{text: "When", flex: 1, sortable: true, dataIndex: 'dateValue'},
{text: "Count", flex: 1, sortable: true, dataIndex: 'n'}
],
columnLines: true,
selModel: {
type: 'checkboxmodel',
listeners: {
selectionchange: 'onSelectionChange'
}
},
// When true, this view acts as the default listener scope for listeners declared within it.
// For example the selectionModel's selectionchange listener resolves to this.
defaultListenerScope: false,
// This view acts as a reference holder for all components below it which have a reference config
// For example the onSelectionChange listener accesses a button using its reference
//referenceHolder: true,
// inline buttons
dockedItems: [{
xtype: 'toolbar',
dock: 'bottom',
ui: 'footer',
layout: {
pack: 'center'
}
}, {
xtype: 'toolbar',
items: [{
//reference: 'andButton',
text: 'AND',
itemId: 'andButton',
tooltip: 'Add the selected criteria as AND',
iconCls: 'and',
disabled: true,
handler: 'onCriterionAnd'
},'-',{
//reference: 'orButton',
text: 'OR',
itemId: 'orButton',
tooltip: 'Add the selected criteria as OR',
iconCls: 'or',
disabled: true,
handler: 'onCriterionOr'
},'-',{
//reference: 'notButton',
text: 'NOT',
itemId: 'notButton',
tooltip: 'Add the selected criteria as NOT',
iconCls: 'not',
disabled: true,
handler: 'onCriterionNot'
},'-',{
//reference: 'removeButton', // The referenceHolder can access this button by this name
text: 'Remove',
itemId: 'removeButton',
tooltip: 'Remove the selected item',
iconCls: 'remove',
disabled: true,
handler: 'onCriterionRemove'
},'-', { // SaveQuery
//reference: 'SaveQuery',
text: 'Save',
itemId: 'saveQuery',
tooltip: 'save the current filter',
iconCls: 'save',
disabled: true,
handler: 'onFilterSave'
}]
}],
height: 1000,
frame: true,
iconCls: 'icon-grid',
alias: 'widget.searchGrid',
title: 'Search',
initComponent: function() {
this.width = 750;
this.callParent();
}
});
I messed around with using a Vbox layout to get my desired behavior, but was rather unsuccessful. This does not seem like that uncommon of a use case to have an upper Vbox panel change to different form panels based on a Tab click, while the lower Vbox panel remains fixed. Any insight would be most welcome.
If I understand correctly, this small test of mine should do exactly what you want, using a border layout with regions north and center.
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="ext-theme-gray.css">
<title>Test app</title>
<script type="text/javascript" src="ext-all-dev.js"></script>
<script>
Ext.onReady(function() {
var Viewport = Ext.create('Ext.container.Viewport',{
layout:'border',
items:[{
xtype:'tabpanel',
region:'north',
items:[{
xtype:'panel',
title:'A',
items:[{xtype:'button',text:'Clickme'}]
},{
xtype:'panel',
title:'B',
items:[{xtype:'textfield'}]
}]
},{
xtype:'gridpanel',
title:'center',
region:'center',
columns:[{
dataIndex:'A',
text:'A'
},{
dataIndex:'B',
text:'B'
}]
}]
})
Ext.create('Ext.app.Application',{
name:'TestApp',
autoCreateViewport: true,
views:[
Viewport
]
});
});
</script>
</head>
<body>
</body>
</html>
PS: I used ExtJS 4.2.2, but it should work in other Ext versions as well.
I am trying to make one form in "extjs" in which i want to use "vbox layout" so that i can place textfield and a button in the same line but unable to do that please help me as early as possible please ???
This is the following code which i am using to create a form:
[{ formitems :{[xtype:'dsqfieldcontainer'
layout: {
type: 'vbox'
},
items:[{mapping:'ChannelURL',
name:'ChannelURL',
fieldLabel:'Channel URL',
xtype:'dsqtextfield'
},
{mapping:'Look_Up_ChannelID',
name:'Look_Up_ChannelID',
fieldLabel:'Look_Up_ChannelID',
xtype:dsqbutton
}
]
] },
{
mapping:'CHANNELNAME',
name:'CHANNELNAME',
fieldLabel:'Channel Name',
xtype:'dsqtextfield'
},
{
mapping:'CHANNELID',
name:'CHANNELID',
fieldLabel:'Channel ID',
xtype:'dsqtextfield'
},
{
mapping:'REFRESHTOKEN',
name:'REFRESHTOKEN',
fieldLabel:'Refresh Token',
xtype:'dsqtextfield'
}
}]
Just check below code and you will get your mistake. In my code, textbox and button are showing in one line by hbox layout. Just check it and let me know if you get any issue. My fiddler account is not working. That's why i can't give you link.
My example -
Ext.create('Ext.window.Window', {
height: 400,
width: 400,
items: [
{
xtype:'fieldcontainer',
layout: {
type: 'hbox'
},
items:[{
mapping:'ChannelURL',
name:'ChannelURL',
fieldLabel:'Channel URL',
xtype:'textfield'
},
{
mapping:'Look_Up_ChannelID',
name:'Look_Up_ChannelID',
xtype:'button',
text: 'Button Name'
}]
}]
}).show();
Changes in your example -
items:[
{
xtype: 'fieldcontainer',
layout: {
type: 'hbox'
},
items: [{
mapping: 'ChannelURL',
name: 'ChannelURL',
fieldLabel: 'Channel URL',
xtype: 'textfield'
}, {
mapping: 'Look_Up_ChannelID',
name: 'Look_Up_ChannelID',
xtype: 'button',
text: 'Button Name'
}]
},
{
mapping: 'CHANNELNAME',
name: 'CHANNELNAME',
fieldLabel: 'Channel Name',
xtype: 'textfield'
}, {
mapping: 'CHANNELID',
name: 'CHANNELID',
fieldLabel: 'Channel ID',
xtype: 'textfield'
}, {
mapping: 'REFRESHTOKEN',
name: 'REFRESHTOKEN',
fieldLabel: 'Refresh Token',
xtype: 'textfield'
}
]
Try with:
layout: {
type: 'table'
}
I have a JSFiddle Demo which creates a Grid with editing enabled. The problem I am facing is that the textfields that are displayed when editing a row are too narrow. They are about half the column width.
// Data to be bound to the grid.
var albums = [{
title: 'Frampton Comes Alive!',
artist: 'Peter Frampton',
genre: 'Rock',
year: '01/06/1976'
}, {
title: 'Led Zeppelin II',
artist: 'Led Zeppelin',
genre: 'Rock',
year: '10/22/1969'
}, {
title: 'Queen',
artist: 'Queen',
genre: 'Rock',
year: '07/13/1973'
}];
// Imports
Ext.require([
'Ext.grid.*',
'Ext.data.*'
]);
// Models
Ext.define('AlbumManager.model.Album', {
extend: 'Ext.data.Model',
fields: [{
name: 'title',
type: 'string'
}, {
name: 'artist',
type: 'string'
}, {
name: 'genre',
type: 'string'
}, {
name: 'year',
type: 'date',
dateFormat: 'm/d/Y'
}]
});
// Stores
Ext.define('AlbumManager.store.AlbumStore', {
extend: 'Ext.data.JsonStore',
storeId: 'albumStore',
model: 'AlbumManager.model.Album',
data: albums,
autoLoad: 'true'
});
// Plugins
Ext.define('AlbumManager.plugin.AlbumEdit', {
extend: 'Ext.grid.plugin.RowEditing',
clicksToMoveEditor: 1,
autoCancel: false
});
// Create view DOM onReady.
Ext.onReady(function () {
// Store
var albumStore = Ext.create('AlbumManager.store.AlbumStore');
var rowEditing = Ext.create('AlbumManager.plugin.AlbumEdit');
var grid = Ext.create('Ext.grid.GridPanel', {
id: 'gridPanel',
title: 'Albums',
width: 400,
height: 200,
renderTo: 'grid-example',
store: albumStore,
columns: [{
header: 'Album Title',
dataIndex: 'title',
flex: 1,
editor: {
width: 300,
allowBlank: false
}
}, {
header: 'Artist',
dataIndex: 'artist',
flex: 1,
editor: {
allowBlank: false
}
}, {
header: 'Genre',
dataIndex: 'genre',
width: 60,
editor: {
allowBlank: true
}
}, {
header: 'Year',
dataIndex: 'year',
width: 60,
editor: {
xtype: 'datefield',
allowBlank: true
},
renderer: Ext.util.Format.dateRenderer('M Y')
}],
plugins: [rowEditing],
dockedItems: [{
xtype: 'toolbar',
dock: 'top',
items: [{
xtype: 'button',
text: 'Add New Album',
handler: function () {
// Create a model instance
var r = Ext.create('AlbumManager.model.Album', {
title: 'New Album',
artist: 'New Artist'
});
albumStore.insert(0, r);
rowEditing.startEdit(0, 0);
},
disabled: false
}, {
xtype: 'button',
text: 'Delete Album',
handler: function () {
Ext.MessageBox.confirm('Delete', 'Are you sure ?', function (btn) {
if (btn === 'yes') {
var sm = grid.getSelectionModel();
rowEditing.cancelEdit();
albumStore.remove(sm.getSelection());
if (albumStore.getCount() > 0) {
sm.select(0);
}
}
});
},
disabled: false
}]
}]
});
});
In your fiddle you use javascript from Ext JS 4.2.0 version but CSS from Ext JS 4.0.2a version.
You always should use javascript files and CSS from same version of Ext JS framework. Otherwise you can get unexpected results as you can see in your fiddle.
When I setup your fiddle with javascript and CSS from Ext JS 4.2.1 version, everything works without problems: https://fiddle.sencha.com/#fiddle/3ft