Related
When I create a new extjs panel with a Card layout inside an other panel I will got the following error:
"Uncaught TypeError: Cannot read property 'addClsOnOver' of null"
What is this error mean and how can I fix this?
Panel inside the: this is the page where I want to show a tabbed panel inside the item of this panel.
Ext.define('app.view.dashboard.DashboardLeft', {
extend: 'Ext.panel.Panel',
xtype: 'dashboardLeft',
requires: [
'Ext.layout.container.VBox',
'OPENhrm.view.dashboard.widget.*'
],
controller: 'dashboard-dashboardLeft',
viewModel: {
type: 'dashboard-dashboardLeft'
},
layout: {
type: 'vbox',
pack: 'start',
align: 'stretch'
},
defaults: {
frame: false
},
items: [{
flex: 1,
xtype: 'taskboard' // show tabbed panel
}]
});
The tabbed panel:
Ext.define("app.view.dashboard.widget.Taskboard", {
extend: 'Ext.tab.Panel',
requires: [
'Ext.layout.container.Card'
],
xtype: 'taskboard',
controller: 'taskboard',
viewModel: {
type: 'taskboard'
},
id: 'taskboard',
// tabs
items:[{
title: 'tab 1',
html: 'test 1'
}, {
title: 'tab 2',
html: 'test 2'
}, {
title: 'tab 3',
html: 'test 3'
}]
});
I'm trying to make a view with multiple formpanels (5) each with a fieldset inside however from what I've read, a view can only contain 1 formpanel, when i set 5 only the first one is shown.
Initially I was using a view with multiple fieldsets and got the look I wanted, however, this solution doesn't allow me to set store records to these fieldsets so i could manage multiple records in the same view so I had to try making these fieldsets have a parent formpanel and thus my problem started.
MyConfigView.js:
Ext.define('MyApp.view.MyConfigView',{
extend: 'Ext.Panel',
alias: 'widget.configview',
config:{
layout: {
type: 'card',
animation:{
type: 'slide',
direction: 'left',
duration: 8000
}
},
items:[
{
docked: 'top',
xtype: 'toolbar',
ui: 'light',
title: 'Yadayada',
itemId: 'toolbarMyConfigView',
items: [{
xtype: 'button',
ui: 'back',
text: 'Voltar',
action: 'voltarConfigView',
itemId: 'toolbarMyConfigViewVoltarBt'
}
]
},
{
xtype: 'formpanel',
items:[
{
xtype: 'fieldset',
title: 'Yada',
id: 'fieldSetAssalto',
model: 'Socorro.model.MyModel',
cls: 'x-floating',
items:[
{
xtype: 'textfield',
name: 'numeroTelefone',
label: 'Yada'
},
{
xtype: 'textfield',
name: 'mensagem',
label: 'Yada'
}
]
}
]
},
{
xtype: 'formpanel',
items:[
{
xtype: 'fieldset',
title: 'YADA',
itemId: 'fieldSetIncendio',
model: 'Socorro.model.MyModel',
cls: 'x-floating',
items:[
{
xtype: 'textfield',
name: 'numeroTelefone',
label: 'yadada'
},
{
xtype: 'textfield',
name: 'mensagem',
label: 'yaaada'
}
]
}
]
},
{
xtype: 'formpanel',
items:[
{
xtype: 'fieldset',
title: 'YADADA',
itemId: 'fieldSetSequestro',
model: 'Socorro.model.MyModel',
cls: 'x-floating',
items:[
{
xtype: 'textfield',
name: 'numeroTelefone',
label: 'Yadaaa'
},
{
xtype: 'textfield',
name: 'mensagem',
label: 'yadada'
}
]
}
]
},
{
xtype: 'formpanel',
items:[
{
xtype: 'fieldset',
title: 'YADA',
itemId: 'fieldSetEmedico',
model: 'Socorro.model.MyModel',
cls: 'x-floating',
items:[
{
xtype: 'textfield',
name: 'numeroTelefone',
label: 'YADAA'
},
{
xtype: 'textfield',
name: 'mensagem',
label: 'Yada'
}
]
}
]
},
{
xtype: 'formpanel',
items:[
{
xtype: 'fieldset',
title: 'Yada',
itemId: 'fieldSetAcidente',
model: 'Socorro.model.MyModel',
cls: 'x-floating',
items:[
{
xtype: 'textfield',
name: 'numeroTelefone',
label: 'Yada'
},
{
xtype: 'textfield',
name: 'mensagem',
label: 'Yada'
}
]
}
]
}
]
}
});
Any ideas on how can i get a view with multiple formpanels to work using Sencha Touch 2?
That is because your MyApp.view.MyConfigView view has a "card" layout applied, and this kind of layout allow you to display only a single sub view as active.
To display them all in the same view, I suggest you to set your view configuration as follows:
Ext.define('MyApp.view.MyConfigView',{
extend: 'Ext.Container',
alias: 'widget.configview',
config:{
layout: {
type: 'vbox',
align: 'stretch'
}
defaults: {
flex: 1
},
items: [
...
]
}
});
In this way you will dispose the formpanels vertically in your view, giving them the same height.
PS: Remove the 'x-floating' class from them.
However, if you want to use a Card layout (which seems to be the best solution), I suggest you to give all your formpanels a different "itemId" config param.
xtype: 'formpanel',
itemId: 'assalto',
items: [
...
]
and then, using the ST MVC architecture, get these forms one by one, and calling the function.
.setRecord(<YOUR_RECORD>);
Read more on ST Controllers on Sencha's docs.
http://docs.sencha.com/touch/2-1/#!/guide/controllers
I'm trying to have a subtabpanel in a tab panel. I did red some answers but not quite understood :(
Here for example, how can I heva tab 3, 4 and 5 appears with a back button on top when I click on tab 3 ? (everything I did : Tab 1, 2 and 3 stays there...)
Thanks :)
Main.js :
Ext.define('MyApp.view.MyNavigationView', {
extend: 'Ext.navigation.View',
config: {
ui: 'light',
items: [
{
xtype: 'tabpanel',
title: 'MyTabPanel1',
layout: {
animation: 'fade',
type: 'card'
},
items: [
{
xtype: 'container',
title: 'Tab 1',
iconCls: 'info'
},
{
xtype: 'container',
title: 'Tab 2',
iconCls: 'info'
},
{
xtype: 'container',
title: 'Tab 3',
iconCls: 'info'
}
],
tabBar: {
docked: 'bottom'
}
},
{
xtype: 'tabpanel',
title: 'MyTabPanel',
items: [
{
xtype: 'container',
title: 'Tab 3',
iconCls: 'info'
},
{
xtype: 'container',
title: 'Tab 4',
iconCls: 'info'
},
{
xtype: 'container',
title: 'Tab 5',
iconCls: 'info'
}
],
tabBar: {
docked: 'bottom'
}
}
]
}
});
In your case you push at once two tab panel into navigation view. But for first time you need only show first panel. For this you need add into navigation view only first panel. The second panel you need add to navigation view only when user choose third tab on first tabPanel. For this you should listen 'acitveitemchange' event and determine than 3 tab became active. Then push second tab pane.
Look this example
Ext.define('MyApp.view.MyNavigationView', {
extend: 'Ext.navigation.View',
config: {
ui: 'light',
autoDestroy: false
},
constructor : function(){
this.callParent(arguments);
this.firstTabPanel = Ext.create('Ext.tab.Panel',{
title: 'MyTabPanel1',
layout: {
animation: 'fade',
type: 'card'
},
items: [
{
xtype: 'container',
title: 'Tab 1',
iconCls: 'info',
html : 'TAB 1'
},
{
xtype: 'container',
title: 'Tab 2',
iconCls: 'info',
html : 'TAB 2'
},
{
xtype: 'container',
title: 'Tab 3',
iconCls: 'info',
html : 'TAB 3'
}
],
tabBar: {
docked: 'bottom'
}
});
this.secondTabPanel = Ext.create('Ext.tab.Panel',{
title: 'MyTabPanel',
items: [
{
xtype: 'container',
title: 'Tab 3',
iconCls: 'info',
html : 'TAB 3'
},
{
xtype: 'container',
title: 'Tab 4',
iconCls: 'info',
html : 'TAB 4'
},
{
xtype: 'container',
title: 'Tab 5',
iconCls: 'info',
html : 'TAB 5'
}
],
tabBar: {
docked: 'bottom'
}
});
this.firstTabPanel.on('activeitemchange', this.tabPanel1ActiveItemChange, this);
//show first tab panel
this.push(this.firstTabPanel);
},
tabPanel1ActiveItemChange : function(tabpanel, newtab){
//if newtab is third tab than show second tab panel
if(this.firstTabPanel.getInnerItems().indexOf(newtab)=== 2){
this.push(this.secondTabPanel);
}
}
});
I've tried to accomplish this a thousand different ways now, the Sencha Touch documentation is far from clear or helpful, and everyone seems to do it a different way...none of which have worked for me.
I've managed to get a List view working in the following way:
Ext.define("MyApp_eComm.view.Products", {
extend: 'Ext.navigation.View', //Needs to be navigation view to display the ProductList.js
xtype: 'products',
requires: [
'Ext.dataview.List',
'MyApp.view.ProductList',
'MyApp_eComm.view.ProductDetail'
],
config: {
title: sMY_CONST_TAB_BROWSE_TITLE,
iconCls: sMY_CONST_TAB_BROWSE_CLASS,
styleHtmlContent: true,
scrollable: true,
items: [
/*{
xtype: 'titlebar',
docked: 'top',
title: sMY_CONST_TAB_BROWSE_SUBTITLE
},*/
{
xtype: 'productlist',
title: sMY_CONST_TAB_BROWSE_SUBTITLE
}
]
}
})
This is my List view that goes inside the navigation view...inside the tab panel. the reason I've used a navigation view is so I can push a product details view on top from the disclosure component.
Ext.define("MyApp.view.ProductList", {
extend: 'Ext.List',
xtype: 'productlist',
requires: [
'MyApp.store.ProductStore'
],
config: {
itemTpl: '{text}',
store: 'ProductStore',
onItemDisclosure: true
}
});
Here is my model:
Ext.define('MyApp.model.ProductListModel', {
extend: 'Ext.data.Model',
config: {
fields: ['text']
}
});
And finally here is my store with test data in, not nested at the moment:
Ext.define('MyApp.store.ProductStore', {
extend: 'Ext.data.Store',
config: {
model: 'MyApp.model.ProductListModel',
sorters: 'text',
data: [
{
text: 'Burgers',
},
{
text: 'Pasta',
},
{
text: 'Sausages',
},
{
text: 'Cabbage',
},
{
text: 'Lettuce',
},
{
text: 'Marmalade',
},
{
text: 'Honey',
},
{
text: 'Yogurt',
},
{
text: 'Cheese',
},
{
text: 'Milk',
},
{
text: 'Bread',
},
{
text: 'Butter',
},
{
text: 'Goats Milk',
},
{
text: 'Apple',
},
{
text: 'Oranges',
},
{
text: 'Bananas',
},
{
text: 'Jelly',
},
{
text: 'Spagetti Hoops',
},
{
text: 'Ravioli',
},
{
text: 'Wheatabix',
},
{
text: 'Cornflakes',
},
]
}
});
try to add so
config: {
title: sMY_CONST_TAB_BROWSE_TITLE,
iconCls: sMY_CONST_TAB_BROWSE_CLASS,
styleHtmlContent: true,
scrollable: true,
items:
{
xtype: 'productlist',
title: sMY_CONST_TAB_BROWSE_SUBTITLE
}
}
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.