How can I get list selected items in sencha touch 2.3.1 - sencha-touch

How can I get selected items of Ext.List on sench-touch 2.3.1?
Thank you.
[View]
{
xtype: 'list',
itemTpl: '{MATERIAL_ID} {TEXT}',
mode: 'MULTI'
}
[Controller]
'queryresult #queryButton': {
tap: function(){
var list = Ext.ComponentQuery.query('queryresult #list')[0];
//todo: get selected items
}
}

Strangely, I use list.getSelection(), return
"TypeError: 'undefined' is not a function (evaluating 'list.getSelectiion()')"
use list.selected.getRange() can get right result.....
But...document say
function getSelection(){ return list.selected.getRange(); }

var records = list.getSelection();
Check out this documentation page:
http://docs.sencha.com/touch/2.3.1/#!/api/Ext.dataview.List-method-getSelection

Related

Sencha Touch 2 - Pass value to view from controller is Error?

I want to use value from controller to filter store.I put this code:
My Controller:
showCatQuery: function(list,index,element,record){
var catid = record.get('id'); << Value to pass
this.getNavigation().push({
xtype: 'panel',
title: 'A',
scrollable: true,
styleHtmlContent: true,
catid: catid,
layout: {
type: 'fit'
},
items: [
{
xtype: 'showSearchCategory',
}
]
});
}
My view in initialize
this.callParent(arguments);
var sto = Ext.getStore('allapp');
sto.clearFilter();
sto.filter('categoryid', this.getCatid());
And this Error message:
Uncaught TypeError: Object [object Object] has no method 'getCatid'
Have you made sure, your View has a function called getCadid? This is what the error message is trying to tell you. You would have to make sure there is a method available while initializing.
Another, possible simpler approach is to filter the store in the controller - which would be the better approach from my perspective. The View would be able to just care about how anything is displayed and the controller cares about what data to display.
You can use references and controls to wait for the view to finish loading and then filter the store (or wait for the user to activate custom filters, etc.):
Ext.define('myApp.controller.aController', {
extend: 'Ext.app.Controller',
config: {
refs: {
justAName: 'ViewName'
}
control: {
justAName: {
activate: 'onActivateView'
}
}
}
onActivateView: function () {...}
});
This is the basic stub for a controller listening to the activation of a specific view. You can just get your store in this function and filter it by all data available in the controller. To get data from the View, create a reference to it, and access it in the controller via for example:
var data = this.getJustAnotherName().getValue();
//having a reference to a textfield for example called justAnotherName

Getting field values from Window

I have a window. and some fields in it (textfield and button). Now i want to submit these details.
I get this error:
TypeError: button.up("form").getValues is not a function
Button function
buClicked : function (button,record) {
var val= button.up('form').getValues();
console.log(val.textfieldValue);
}
My Widow Definition
Ext.define('MyApp.view.WindowForm', {
extend: 'Ext.window.Window',
alias: 'widget.winform',
id: 'winformid',
var val= button.up('form').getForm().getValues();
You are extending Window's class which is okay,but also add items config where ,you will include the xtype:form whose config has the the textfield and the buttons config something like this:
Ext.define('MyApp.view.WindowForm',
{
extend:'Ext.window.Window',
id:'myformvin',
items:[
{xtype:'form',items:[{xtype:'textfield',fieldLabel:'My name',name:'myname'}],
buttons:[{xtype:'button',text:'save',handler:function(btn){
var val = btn.up('form').getForm().getValues();
console.log(val); //to confirm that you have the values
}
}]
}
]
}
);

Add a custom button in column header dropdown menus {EXTJS 4}

I want a button in column header dropdown menu of grid in extjs4.
so that i can add or delete columns which are linked in database.
Any help will be appreciated...
Thankyou..:)
Couple of months ago I had the same problem. I've managed to solve it by extending Ext.grid.header.Container (I've overrided getMenuItems method). However, recently, I've found another solution which requires less coding: just add menu item manualy after grid widget is created.
I'll post the second solution here:
Ext.create('Ext.grid.Panel', {
// ...
listeners: {
afterrender: function() {
var menu = this.headerCt.getMenu();
menu.add([{
text: 'Custom Item',
handler: function() {
var columnDataIndex = menu.activeHeader.dataIndex;
alert('custom item for column "'+columnDataIndex+'" was pressed');
}
}]);
}
}
});
Here is demo.​
UPDATE
Here is demo for ExtJs4.1.
From what I have been seeing, you should avoid the afterrender event.
Context:
The application I am building uses a store with a dynamic model. I want my grid to have a customizable model that is fetched from the server (So I can have customizable columns for my customizable grid).
Since the header wasn't available to be modified (since the store gets reloaded and destroys the existing menu that I modified - using the example above). An alternate solution that has the same effect can be executed as such:
Ext.create('Ext.grid.Panel', {
// ...
initComponent: function () {
// renders the header and header menu
this.callParent(arguments);
// now you have access to the header - set an event on the header itself
this.headerCt.on('menucreate', function (cmp, menu, eOpts) {
this.createHeaderMenu(menu);
}, this);
},
createHeaderMenu: function (menu) {
menu.removeAll();
menu.add([
// { custom item here }
// { custom item here }
// { custom item here }
// { custom item here }
]);
}
});
For people who would like to have not just one "standard" column menu but have an individual columnwise like me, may use the following
initComponent: function ()
{
// renders the header and header menu
this.callParent(arguments);
// now you have access to the header - set an event on the header itself
this.headerCt.on('menucreate', function (cmp, menu, eOpts) {
menu.on('beforeshow', this.showHeaderMenu);
}, this);
},
showHeaderMenu: function (menu, eOpts)
{
//define array to store added compoents in
if(this.myAddedComponents === undefined)
{
this.myAddedComponents = new Array();
}
var columnDataIndex = menu.activeHeader.dataIndex,
customMenuComponents = this.myAddedComponents.length;
//remove components if any added
if(customMenuComponents > 0)
{
for(var i = 0; i < customMenuComponents; i++)
{
menu.remove(this.myAddedComponents[i][0].getItemId());
}
this.myAddedComponents.splice(0, customMenuComponents);
}
//add components by column index
switch(columnDataIndex)
{
case 'xyz': this.myAddedComponents.push(menu.add([{
text: 'Custom Item'}]));
break;
}
}
I took #nobbler's answer an created a plugin for this:
Ext.define('Ext.grid.CustomGridColumnMenu', {
extend: 'Ext.AbstractPlugin',
init: function (component) {
var me = this;
me.customMenuItemsCache = [];
component.headerCt.on('menucreate', function (cmp, menu) {
menu.on('beforeshow', me.showHeaderMenu, me);
}, me);
},
showHeaderMenu: function (menu) {
var me = this;
me.removeCustomMenuItems(menu);
me.addCustomMenuitems(menu);
},
removeCustomMenuItems: function (menu) {
var me = this,
menuItem;
while (menuItem = me.customMenuItemsCache.pop()) {
menu.remove(menuItem.getItemId(), false);
}
},
addCustomMenuitems: function (menu) {
var me = this,
renderedItems;
var menuItems = menu.activeHeader.customMenu || [];
if (menuItems.length > 0) {
if (menu.activeHeader.renderedCustomMenuItems === undefined) {
renderedItems = menu.add(menuItems);
menu.activeHeader.renderedCustomMenuItems = renderedItems;
} else {
renderedItems = menu.activeHeader.renderedCustomMenuItems;
menu.add(renderedItems);
}
Ext.each(renderedItems, function (renderedMenuItem) {
me.customMenuItemsCache.push(renderedMenuItem);
});
}
}
});
This is the way you use it (customMenu in the column config let you define your menu):
Ext.define('MyGrid', {
extend: 'Ext.grid.Panel',
plugins: ['Ext.grid.CustomGridColumnMenu'],
columns: [
{
dataIndex: 'name',
customMenu: [
{
text: 'My menu item',
menu: [
{
text: 'My submenu item'
}
]
}
]
}
]
});
The way this plugin works also solves an issue, that the other implementations ran into. Since the custom menu items are created only once for each column (caching of the already rendered version) it will not forget if it was checked before or not.

Sencha : can't call method "update" of undefined

Here, i'm registering my app:
App = new Ext.Application({
name: "App",
launch: function() {
this.views.viewport = new this.views.Viewport();
}
});
This is the way i register new panels and components. I put each of them into seperate js files.
App.views.Viewport = Ext.extend(Ext.TabPanel, {
fullscreen: true,
tabBar: {
dock: 'bottom',
layout: {
pack: 'center'
}
},
items: [
{
xtype: 'cPanel'
},
{
xtype: 'anotherPanel'
}
]
});
// register this new extended type
Ext.reg('App.views.viewport', App.views.Viewport);
I added the other components in the same manner.
In one my components which is a list view, I want to change the container panel's activeItem with another panel when tappen on an item, like this: ( Viewport contains this container panel)
App.views.ListApp = Ext.extend(Ext.List, {
store: App.store,
itemTpl: "...",
onItemDisclosure: function(record) {
App.detailPanel.update(record.data);
App.cPanel.setActiveItem("detailPanel");
},
listeners: {
itemtap: function(view, index, item, e) {
var rec = view.getStore().getAt(index);
App.views.detailPanel.update(rec.data);
App.views.cPanel.setActiveItem("detailPanel", {type:"slide", direction: "left"});
}
}
});
App.views.detailPanel.update(rec.data);
But it says: can't call method "update" of undefined
I tried different variations on that line, like:
App.detailPanel.update(rec.data);
and i tried to give detailPanel and cPanel ids, where they were added to their container panel, and tried to reach them with Ext.get(), but none of these worked.
What is the problem here?
And any other advices would be appreciated.
Thanks.
The lazy way: give the panels ids and use:
Ext.getCmp(id)
The recommended way: Assign itemId to your panel and use:
App.views.viewport.getComponent(itemId)
This will allow you to have more than one instance of the same component at aby given time, the first example is not valid cause you can only have a singular id in the DOM tree.
Also getComponent only works for components stored in the items collection.

Clearing ExtJS combobox input field

I have an Ext.form.ComboBox with the following properties:
fieldLabel: 'Regiune',
valueField: 'id',
displayField: 'reg',
id: 'cbRegR',
typeAhead: true,
store: new Ext.data.JsonStore({...}),
mode: 'local',
emptyText: '',
listeners:{...}
The problem is that I have to manually delete the combobox' input field after selecting a value from the dropdown list to view all the list items. The matter is the list displays only the items that begin with letters in input field.
How can I clear the input field on expanding dropdown list? I tried the following but it doesn't work:
listeners: { 'expand': function() { cbRegR.clearValue(); } }
Seems to be easy but it ain't so for me.. Any bright ideas? Thanks in advance.
Adding the config property to your combobox
triggerAction: 'all'
might do the trick, without the need to register an expand event handler or clearing the combobox's value
It is an intrinsic behaviour of Ext JS ComboBox-es to filter the list items based on the field value, as you already know.
You could perceivably override the expand() method, making additions to clear out the value before it renders the list. EG:
Ext.override(Ext.form.ComboBox, {
expand : function(){
if(this.isExpanded() || !this.hasFocus){
return;
}
//ADDITIONS HERE:
this.clearValue();
this.doQuery("", true);
//ADDITIONS END HERE
if(this.title || this.pageSize){
this.assetHeight = 0;
if(this.title){
this.assetHeight += this.header.getHeight();
}
if(this.pageSize){
this.assetHeight += this.footer.getHeight();
}
}
if(this.bufferSize){
this.doResize(this.bufferSize);
delete this.bufferSize;
}
this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
// zindex can change, re-check it and set it if necessary
this.list.setZIndex(this.getZIndex());
this.list.show();
if(Ext.isGecko2){
this.innerList.setOverflow('auto'); // necessary for FF 2.0/Mac
}
this.mon(Ext.getDoc(), {
scope: this,
mousewheel: this.collapseIf,
mousedown: this.collapseIf
});
this.fireEvent('expand', this);
}
});
The expand event is the good one but you have to be careful about the scope.
listeners: {
'expand': function() {
cbRegR.clearValue();
},
scope:this
}
Does setting the scope helps?
Using cbRegR won't work, because it's an undefined variable. Either use
listeners: { 'expand': function() { Ext.getCmp('cbRegR').clearValue(); } }
or, a more sophisticated approach:
listeners: { 'expand': function(self) { self.clearValue(); } }