Related
var radioGroup = {
xtype: 'radiogroup',
itemId: 'radioButton',
layout: 'hbox',
width: 700,
defaults: {
flex: 1
},
items: [{
boxLabel: option1
name: 'timeInterval',
inputValue:0
checked: true
}, {
boxLabel: option2
name: 'timeInterval',
inputValue:1,
checked: false
}, {
boxLabel: option1
name: 'timeInterval',
inputValue:2,
checked: false
}],
listeners: {
change: function (radio, newValue, oldValue) {
if (radio.getValue().timeInterval == 2) {
cardPanel.layout.setActiveItem(0);
//getting error cardPanel.layout.setActiveItem is not a function
} else if (radio.getValue().timeInterval == 0) {
cardPanel.layout.setActiveItem(1);
} else if (radio.getValue().timeInterval == O1) {
cardPanel.layout.setActiveItem(2);
}
}
}
};
var cardPanel = {
layout: 'card',
itemId: 'PanelID',
activeItem: 0,
items: [{
itemId: 'timeIntervalPanel',
name: 'timeInterval',
xtype: 'timeintervalpanel',
selection: this.defaultData,
dateFormat: this.dateFormat,
timeFormat: this.timeFormat
}, {
id: 'specificIntervalPanel',
name: 'timeInterval',
xtype: 'specificinterval',
selection: this.defaultData
}, {
itemId: 'emptyPanel',
name: 'emptyCard',
xtype: 'panel'
}]
};
You need to use following steps :-
First you need to get component which you have provided layout:"card" in change event of RadioGroup.
Now, you need to get getLayout() of your component.
Now need to use setActiveItem(newItem) method of card layout component.
In this FIDDLE, I have created a demo using your code and put some modification. I hope this will help you.
Code Snippet
//Timeinterval panel
Ext.define('Timeintervalpanel', {
extend: 'Ext.panel.Panel',
xtype: 'timeintervalpanel',
html: 'This is timeintervalpanel'
});
//Specific Interval panel
Ext.define('SpecificInterval', {
extend: 'Ext.panel.Panel',
xtype: 'specificinterval',
html: 'This is specificinterval'
});
//Empty Panel
Ext.define('EmptyPanel', {
extend: 'Ext.panel.Panel',
xtype: 'emptyPanel',
html: 'This is emptyPanel'
});
//Panel with radio button and card item.
Ext.create('Ext.panel.Panel', {
title: 'Card Layout Example with radio buttons',
renderTo: Ext.getBody(),
height: window.innerHeight,
layout: 'vbox',
tbar: [{
xtype: 'radiogroup',
itemId: 'radioButton',
layout: 'hbox',
defaults: {
flex: 1,
margin: 5,
name: 'timeInterval'
},
items: [{
boxLabel: 'Timeinterval panel',
inputValue: 0,
checked: true
}, {
boxLabel: 'Specific Interval',
inputValue: 1
}, {
boxLabel: 'Empty Panel',
inputValue: 2
}],
listeners: {
change: function (radio, newValue, oldValue) {
var cardPanel = radio.up('panel').down('#PanelID').getLayout();
cardPanel.setActiveItem(newValue.timeInterval);
//Only just for animation
//activeItem.getEl().slideIn('r');
}
}
}],
items: [{
//This panel have provided card layout.
xtype: 'panel',
flex: 1,
width: '100%',
layout: 'card',
itemId: 'PanelID',
defaults: {
bodyPadding: 20
},
items: [{
xtype: 'timeintervalpanel'
}, {
xtype: 'specificinterval'
}, {
xtype: 'emptyPanel'
}]
}]
});
Intro:
I need to call the backend controller to see if the user is admin. If the user is NOT admin, hide the toolbar in the application. Currently the var is successfully changing; However, it is changing after the view is already created causing the view to always have the toolbar visable.
Problem:
Need to check backend to see if user is in the admin group.
Need to return true if they are in admin group
MyCode:
var adminBool = false;
function CheckAdmin() {
debugger;
var a;
Direct.Report.IsAdmin(this.results, a);
debugger;
};
function results(result, constructor, c, d, e, f, g, h) {
debugger;
this.adminBool= result.adminUser; //returns bool
}
Ext.define('Ext.View.MyViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.AdministrationViewModel',
init: this.CheckAdmin(),
data: {
addNew: true,
update: true,
gridData: null,
isAdmin: this.adminBool
}
});
Synopsis:
Call the backend controller for admin status
Return bool
Update viewModel with bool respectively
ViewModel property,'isAdmin', will bind with hidden property to hide unwanted actions for non admins
UPDATE:
Basically I need a way to delay "isAdmin: this.adminBool" check to after the backend call is finished.
As you are using ViewModel.
So you can use set() method to update your viewmodel field.
I have created an sencha fiddle demo using viewmodel. You can check, how it is working in fiddle. In this fiddle I have not used any API, it just example regarding of ViewModel. Hope this will help you to solve your problem or achieve your requirement.
//ViewModel
Ext.define('MyViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.AdministrationViewModel',
data: {
isAdmin: true
}
});
//Panel
Ext.create('Ext.panel.Panel', {
title: 'ViewModel example',
width: '100%',
renderTo: Ext.getBody(),
viewModel: 'AdministrationViewModel',
layout: {
type: 'vbox', // Arrange child items vertically
align: 'stretch', // Each takes up full width
padding: 10
},
defaults: {
margin: 10
},
items: [{
xtype: 'combo',
height: 40,
fieldLabel: 'Choose Admin or user',
emptyText: 'Choose Admin or user',
labelAlign: 'top',
store: {
fields: ['name', 'value'],
data: [{
"value": true,
"name": "Admin"
}, {
"value": false,
"name": "User"
}]
},
queryMode: 'local',
displayField: 'name',
valueField: 'value',
listeners: {
select: function (combo, record) {
var viewModel = combo.up('panel').getViewModel(),
isAdmin = record.get('value');
//If selected value is {Admin} then we will show toolbar otherwise in case of {User} hide
viewModel.set('isAdmin', !isAdmin);
}
}
}, {
xtype: 'toolbar',
width: '100%',
height: 50,
padding: 10,
bind: {
hidden: '{isAdmin}'
},
items: [{
// xtype: 'button', // default for Toolbars
text: 'Admin',
}, {
xtype: 'splitbutton',
text: 'Split Button'
},
// begin using the right-justified button container
'->', // same as { xtype: 'tbfill' }
{
xtype: 'textfield',
name: 'field1',
emptyText: 'enter search term'
},
// add a vertical separator bar between toolbar items
'-', // same as {xtype: 'tbseparator'} to create Ext.toolbar.Separator
'text 1', // same as {xtype: 'tbtext', text: 'text1'} to create Ext.toolbar.TextItem
{
xtype: 'tbspacer'
}, // same as ' ' to create Ext.toolbar.Spacer
'text 2', {
xtype: 'tbspacer',
width: 50
}, // add a 50px space
'text 3'
]
}]
});
i got an ExtJS Grid in my view and now i do want to add some column filters...
i've already searched in the web, though i didnt succeed.
The problem is if i open the submenu of the column where i can sort etc. i do not see the option Filter.
the following code is a section of my view script:
Ext.define('Project.my.name.space.EventList', {
extend: 'Ext.form.Panel',
require: 'Ext.ux.grid.FiltersFeature',
bodyPadding: 10,
title: Lang.Main.EventsAndRegistration,
layout: {
align: 'stretch',
type: 'vbox'
},
initComponent: function () {
var me = this;
Ext.applyIf(me, {
items: [
...
{
xtype: 'gridpanel',
title: '',
store: { proxy: { type: 'direct' } },
flex: 1,
features: [filtersCfg],
columns: [
{
xtype: 'gridcolumn',
dataIndex: 'Title',
text: Lang.Main.CourseTitle,
flex: 1,
filterable: true
},
{
xtype: 'datecolumn',
dataIndex: 'StartDate',
text: Lang.Main.StartDate,
format: Lang.Main.DateFormatJS,
flex: 1,
filter: { type: 'date' }
},
{
xtype: 'datecolumn',
dataIndex: 'EndDate',
text: Lang.Main.EndDate,
format: Lang.Main.DateFormatJS,
flex: 1, // TODO: filter
},
{
xtype: 'gridcolumn',
dataIndex: 'Participants',
text: Lang.Main.Participants,
flex: 1
},
{
xtype: 'gridcolumn',
dataIndex: 'LocationName',
text: Lang.Main.Location,
flex: 1
},
{
xtype: 'gridcolumn',
dataIndex: 'Status',
text: Lang.Main.Status,
flex: 1, // TODO: filter
}],
dockedItems: [{
xtype: 'toolbar',
items: [{
icon: 'Design/icons/user_add.png',
text: Lang.Main.RegisterForEvent,
disabled: true
},
{
icon: 'Design/icons/user_delete.png',
text: Lang.Main.Unregister,
disabled: true
},
{
icon: 'Design/icons/application_view_list.png',
text: Lang.Main.Show,
disabled: true
},
{
icon: 'Design/icons/calendar_edit.png',
text: Lang.Main.EditButtonText,
hidden: true,
disabled: true
},
{
icon: 'Design/icons/calendar_add.png',
text: Lang.Main.PlanCourse,
hidden: true
}]
}]
}
]
});
me.callParent(arguments);
...
this.grid = this.query('gridpanel')[0];
this.grid.on('selectionchange', function (view, records) {
var selection = me.grid.getSelectionModel().getSelection();
var event = (selection.length == 1) ? selection[0] : null;
var registered = event != null && event.data.Registered;
me.registerButton.setDisabled(registered);
me.unregisterButton.setDisabled(!registered);
me.showButton.setDisabled(!records.length);
me.editButton.setDisabled(!records.length);
});
}
});
here is also a pastebin link of the code : http://pastebin.com/USivWX9S
UPDATE
just noticed while debugging that i get an JS error in the FiltersFeature.js file in this line:
createFilters: function() {
var me = this,
hadFilters = me.filters.getCount(),
grid = me.getGridPanel(),
filters = me.createFiltersCollection(),
model = grid.store.model,
fields = model.prototype.fields,
Uncaught TypeError: Cannot read property 'prototype' of undefined
field,
filter,
state;
please help me!
There are a couple of syntactic errors.
FiltersFeature is a grid feature and not a component.
You cannot extend an object literal (correct me if I'm wrong)
Use the filter like this:
var filtersCfg = {
ftype: 'filters',
local: true,
filters: [{
type: 'numeric',
dataIndex: 'id'
}]
};
var grid = Ext.create('Ext.grid.Panel', {
features: [filtersCfg]
});
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.
Here's my ExtJs component.
Everything works perfectly.... err well almost everything.
I just don't get why the this.on('load', function (form,action) {}) is not called whereas the same declaration for this.on('actioncomplete', function (form,action) {}); is called:
DossierPanel = Ext.extend(Ext.form.FormPanel, {
closable: true,
autoScroll:true,
initComponent : function(){
this.id = 'id_dossier_'+this.id_dossier;
this.bodyStyle = 'padding:15px';
this.labelWidth = 150;
this.items = [{
layout:'column',
border:false,
autoHeight: true,
items:[{
columnWidth:.5,
layout: 'form',
border:false,
items: [{
xtype:'textfield',
fieldLabel: 'Civilite ',
name: 'CIVILITE',
readOnly: true
}]
},{
columnWidth:.5,
layout: 'form',
border:false,
items: [{
xtype:'textfield',
fieldLabel: 'Email ',
name: 'EMAIL',
vtype:'email',
anchor:'95%'
}]
}]
},{
xtype:'tabpanel',
plain:true,
activeTab: 0,
deferredRender: false,
defaults:{bodyStyle:'padding:10px'},
items:[{
title:'Détails personnels',
layout:'form',
autoHeight: true,
defaults: {width: '99%'},
defaultType: 'textfield',
items: [{
xtype:'datefield',
fieldLabel: 'Date de naissance ',
name: 'NAISSANCEJMA',
format:'d/m/Y'
}]
},{
title:'Adresse',
layout:'form',
autoHeight: true,
defaults: {width: '95%'},
defaultType: 'textfield',
items: [{
fieldLabel: 'Adresse 1 ',
name: 'ADRESSE1'
}]
},{
title:'Téléphone(s)',
layout:'form',
autoHeight: true,
defaults: {width: 230},
defaultType: 'textfield',
items: [{
fieldLabel: 'DescTelephone1 ',
name: 'DESCTELEPHONE1',
readOnly: true
}]
},{
title:'Divers',
layout:'form',
autoHeight: true,
defaults: {width: 230},
defaultType: 'textfield',
items: [{
fieldLabel: 'ReferenceExterne ',
name: 'REFERENCEEXTERNE'
}]
}]
}];
this.buttonAlign = 'left';
this.buttons = [{
text: 'Recharger',
handler: function() {
this.getForm().load( {
url: '/w.php',
params: {
id_dossier: this.id_dossier
},
failure:function(form, action) {
handleAjaxError(action.response,'Refresh error');
}
});
},
scope: this
},{
text: 'Sauver',
handler: function() {
this.getForm().submit({
url: '/ws.php',
params: {
write: 1
},
waitTitle: 'Patientez',
waitMsg: 'Sauvegarde',
success: function (form, action) {
var b = Ext.util.JSON.decode(action.response.responseText);
if (b.success==true) {
if (b.msg) {
Ext.MessageBox.alert('Done!', b.msg);
}
else {
Ext.MessageBox.alert('Done!', 'Saved');
}
}
},
failure:function(form, action) {
handleAjaxError(action.response,'Refresh error');
}
});
},
scope: this
}];
//this.listeners = {
// actioncomplete: handleActionComplete,
// load: handleLoad
//};
this.on('load', function (a,b,c) {
console.log(a);
console.log(b);
console.log(c);
});
this.on('actioncomplete', function (form,action) {
if (action.type=='load') {
console.log('actioncomplete => action load');
}
});
this.on('load', function (form,action) {
if (action.type=='load') {
console.log('LOAAAAAD');
}
});
DossierPanel.superclass.initComponent.call(this);
console.log(this.events)
}
});
Watch carefully the this.on() code juste above: the console log shows only "'actioncomplete => action load'", not the 'LOAAAAAD'. From my pov this is not normal. Am I missing something?
Thank you very much
The Ext.form.FormPanel do not have a load event. So, even if you define a function for load event, the event is never fired and your function is never executed.
The actioncomplete event is an event of BasicForm and is fired when an action is completed.