Proper way of adding stuff to senchas carousell in runtime - javascript

So how can I add stuff to carousell in sencha touch 2.x?
var c = Ext.create('Ext.Carousel', {
fullscreen: true,
defaults: {
styleHtmlContent: true
},
items: [
{
html : 'Item 1'
}]
});
If I want to, for example, push a form f to the carousell how can I do that?
I have already tried c.push(f) and c.add(f) but I can't see my form being added there.

The proper way of adding stuff into a container like Ext.Carousel is using the add() function. You can also define your carousel like this, if you want to just add all your stuff to it in runtime:
var c = Ext.create('Ext.Carousel', {
fullscreen: true,
defaults: {
styleHtmlContent: true
}
});
Now you can use the c.add(f) function. Also to remove the object f from the carousel or other container c use c.remove(f)

Related

Dragging windows

I did some research on this and still can't find a good solution for it. I wrote my app in ExtJS 4.1 and when I run it on an iPod the dragging functionality is disabled by default (which is what I want), but if I write the same app in ExtJS 6.2 all windows can be draggable which causes issues of visibility of the app. With that being said, Does anyone know how to disable window dragging when using Tablets (iPod, iPad, etc.)? I'm using ExtJS 6.2
Here's my working code that works great for a single window, but I want a general solution that will stop ALL windows from being dragged.
var win = Ext.create('Ext.Window', {
title: "My Window",
width: 500,
modal: true,
layout: 'fit',
items: form,
buttons: [{
text: 'Close',
handler: function() {
win.hide();
}
}]
});
win.show();
if(Ext.os.deviceType === 'Tablet') {
win.dd.disable();
}
A "global solution" sounds like you want to use an override to apply one of the other answers globally to your application:
Ext.define('MyAppName.override.Window', {
override: 'Ext.window.Window',
initComponent: function() {
this.callParent(arguments);
if(Ext.os.deviceType === 'Tablet') {
this.dd.disable();
}
}
})
or
Ext.define('MyAppName.override.Window', {
override: 'Ext.window.Window',
initComponent: function() {
if(Ext.os.deviceType === 'Tablet') {
this.draggable = false;
}
this.callParent(arguments);
}
})
To make the override work, put it into the file app/override/Window.js and add a reference to your requires array in Application.js:
requires: [
'MyAppName.override.Window'
],
You are looking for Ext.os class.
More precisely Ext.os.is method, according to the docs it has all the values you would need.
I am not sure why you want to block only iPads and not tables in general. If you wan tablets than you can use if(Ext.os.deviceType === 'Tablet') {...}
Otherwise if(Ext.os.is.iPad) {...}.
UPDATE Solution:
If you want to force anything across all classes in the ExtJS you would use Ext.override.
So the solution would be to put at the beginning of the app this code:
if (Ext.os.deviceType === 'Tablet') {
Ext.override('Ext.Window', {
privates: {
initDraggable: function(){}
}
})
}
FYI You can check the Ext.Window source code. I had to override this method, the default value draggable: false doesn't work.
https://fiddle.sencha.com/#view/editor&fiddle/2iqi
To test it, just press F12 switch to table mode.
But this solution has 1 drawback:
If the target is a class declared using Ext.define, the override
method of that class is called
Which means this solution don't work when you use Ext.create('Ext.Window',{})
Solution for that would be to define our own Ext.Window class and than inside the app when you are using Ext.create('Ext.Window' you would use Ext.create('Fiddle.view.MyWindow', and when we have our own function already we don't need to use override but can put if directly into the class definition like this:
Ext.define('Fiddle.view.MyWindow', {
extend: 'Ext.Window',
alias: 'widget.mywindow',
draggable: (function(){
if (Ext.os.deviceType === 'Tablet') {
return false;
} else {
return true;
}
})()
});
https://fiddle.sencha.com/#view/editor&fiddle/2iqj
I don't know how to override it for Ext.create('Ext.Window' if you still insists on using it. One solution would be to re-write Ext.create or simply edit the framework source itself but I highly discourage from that.
Why you are not using draggable: false in window config
Here is some code in FIDDLE
var win = Ext.create('Fiddle.view.MyWindow', {
title: "My Window",
width: 500,
draggable: false,
modal: true,
layout: 'fit',
buttons: [{
text: 'Close',
handler: function() {
win.hide();
}
}]
});
win.show();

Show/hide subpanels dynamically in Ext JS

I have created a view (a panel) with 3 subpanels ...
When the view loads , I want a function to run in viewController and based on its outcome , I want subpanel 1 to be visible(subpanel2 to be invisible) or subpanel2 to be visible(subpanel1 to be invisible)
How can I accomplish this ?
You are looking for card layout. It is already implemented. So you don't have to implement again. Just tell it witch panel gonna be active it will do all layout things itself. Checkout this api doc.
May be the Accordion layout can help you:
This is a layout that manages multiple Panels in an expandable accordion style such that by default only one Panel can be expanded at any given time
Here's a full example, it's quite straight forward:
Fiddle
Ext.define('FooController', {
extend: 'Ext.app.ViewController',
alias: 'controller.foo',
init: function(view) {
var child = Math.random() < 0.5 ? 'p1' : 'p2';
view.setActiveItem(this.lookupReference(child));
}
})
Ext.define('Foo', {
extend: 'Ext.container.Container',
layout: 'card',
controller: 'foo',
items: [{
title: 'P1',
reference: 'p1'
}, {
title: 'P2',
reference: 'p2'
}]
});
Ext.onReady(function() {
new Foo({
renderTo: document.body,
width: 200,
height: 200
});
});
Give itemId to all three panel and then fireEvent.
Listener of view
listeners:{
show: function(){
me.fireEvent('showHidePanel');
}
}
define showHidePanel method in Controller and in that method get panel by using down() with item id and hide/show panel by using hide()/show() method.

Ext JS 4: Grid List Filter is NOT updated

I am running a weird problem when I try to set Grid Filter list dynamically.
Let me explain by my code snippets
I have a column with filter list is defined as
{
text : 'Client',
dataIndex : 'topAccount',
itemId : 'exTopAccount',
filter: {
type: 'list',
options:[]
}
}
I initialize list from store in 'viewready'
viewready: function(cmp,eOpts){
cmp.getHeaderCt().child('#exTopAccount').initialConfig.filter.options = clientsStore.collect('topAccount');
}
===> WORKS GOOD
Now, I have to build the new client store based on the records when user moves to next page. Therefore I build the store in the 'change' event of paging
listeners: {
'change' :function( toolbar, pageData, eOpts ) {
var store = Ext.StoreManager.get('ExceptionRecords');
clientsStore.removeAll(true);
store.each(function(record){
if(clientsStore.findRecord('topAccount',record.data.topAccount.trim()) == null ) {
clientsStore.add({topAccount: record.data.topAccount.trim()})
}
})
Ext.getCmp('exceptionGridContainer').view.refresh;
Ext.getCmp('exceptionGridContainer').view.getHeaderCt().doLayout;
console.log(clientsStore);
Ext.getCmp('exceptionGridContainer').view.getHeaderCt().child('#exTopAccount').initialConfig.filter.options = clientsStore.collect('topAccount');
}
}
I can now see the new data in clientsStore . But Grid filter list is not updated. still showing old data. I tried refresh,layout etc. Nothing helps
Any help will be appreciated
Thanks
Tharahan
Just changing the value of a property does not affect the component rendered or computed state. The menu is created when the list is first initialized. The first time you do that, it works because that's before the initialization, but the second time, that's too late.
If you can grab a reference to the instantiated ListFilter, I think you could force the recreation of the menu this way:
listFilter.menu = listFilter.createMenu({
options: [ ... ] // new options
// rest of the filter config
});
So, supposing you have a reference to your target grid, you could change the options for the column with dataIndex of "topAccount" by a call similar to this:
var listFilter = grid
.findFeature('filters') // access filters feature of the grid
.get('topAccount'); // access the filter for column
listFilter.menu = listFilter.createMenu({
options: [ ... ] // new options
// rest of the filter config
});
--- Edit ---
OK, complete example. Tested, working.
Ext.widget('grid', {
renderTo: Ext.getBody()
,height: 400
,features: [{
ftype: 'filters'
,local: true
}]
,columns: [{
dataIndex: 'a'
,text: 'Column A'
,filter: {
type: 'list'
,options: ['Foo', 'Bar']
}
},{
dataIndex: 'b'
,text: 'Column B'
},{
dataIndex: 'c'
,text: 'Column C'
}]
,store: {
fields: ['a', 'b', 'c']
,autoLoad: true
,proxy: {
type: 'memory'
,reader: 'array'
,data: [
['Foo', 1, 'Bar']
,['Bar', 2, 'Baz']
,['Baz', 1, 'Bar']
,['Bat', 2, 'Baz']
]
}
}
,tbar: [{
text: 'Change list options'
,handler: function() {
var grid = this.up('grid'),
// forget about getFeature, I read the doc and found something!
filterFeature = grid.filters,
colAFilter = filterFeature.getFilter('a');
// If the filter has never been used, it won't be available
if (!colAFilter) {
// someone commented that this is the way to initialize filter
filterFeature.view.headerCt.getMenu();
colAFilter = filterFeature.getFilter('a');
}
// ok, we've got the ref, now let's try to recreate the menu
colAFilter.menu = colAFilter.createMenu({
options: ['Baz', 'Bat']
});
}
}]
});
I was solving similar problem and answers to this question helped me a lot. Local List filter menu is in fact lazy loaded (only created when clicked) and I needed to set filter menu to be reloaded if the grid store has been reloaded with different data. Solved it by destroying of menu after each reload, so on next click menu is recreated:
var on_load = function() {
var grid_header = me.gridPanel.filters.view.headerCt
if (grid_header.menu) {
grid_header.menu.destroy();
grid_header.menu = null;
}
}

get checkbox value without using Ext.getCmp

I am trying to get value of this checkbox
Ext.define('myRoot.myExtApp.myForm', {
extend: 'Ext.form.Panel',
layout: {
type: 'vbox',
align: 'stretch'
},
scope: this,
constructor: function() {
this.callParent(arguments);
this.myFieldSet = Ext.create('Ext.form.FieldSet', {
scope: this,
columnWidth: 0.5,
collapsible: false,
defaultType: 'textfield',
layout: {
type: 'hbox', align: 'stretch'
}
});
this.mySecondForm = Ext.create('myRoot.myExtApp.myForm2', {
scope: this,
listener: this,
margin: '1 3 0 0'
});
this.myCheckBox = Ext.create('Ext.form.Checkbox', {
scope: this,
//id: 'myCheckBox',
boxLabel: 'Active',
name: 'Active',
checked: true,
horizontal: true
});
this.myFieldSet.add(this.mySecondForm);
this.myFieldSet.add(this.myCheckBox);
this.add(this.myFieldSet);
}
});
As you can see I have another form
Ext.define('myRoot.myExtApp.myForm2', {
where I have a handler, that should get the value of the checkbox from "myForm"
How can I get the value of my checkbox from Form2 without using Ext.getCmp? I know I can get the value of the checkbox if I do
Ext.getCmp('myCheckBox').getValue();
but using
this.myCheckBox.getValue();
gives me undefined error.
UPDATE - with Wared suggestion I tried this inside myForm2
this.temp=Ext.create('myRoot.myExtApp.myForm'), {});
var tempV = this.temp.myCheckBox.getValue();
I was able to get the value but I get the same true value even if I uncheck the box
I assume you worry about performance loss due to excessive use of component queries. A nice trick to minimize component queries could be to define a new method inside a closure in order to cache the result of the first getCmp call. Wrapping the definition of the method inside a closure allows to avoid using global scope or a useless class property.
getMyCmp: function (cmp) {
// "cmp" does not exist outside this function
return function () {
return cmp = cmp || Ext.getCmp('#myCmp');
};
}()
One solution could be :
myRoot.myExtApp.myForm.myCheckBox.getValue();
Beware, wrong answer. See comments below for a valid solution.

Sencha Touch 2 - TabPanel does not work in MVC designed App

simple question for you today...
This works:
var carousel = Ext.create('Ext.Carousel', {
fullscreen: 'true',
//load in views view clean instantiation using
// the widget.alias's defined in each view... yea
// For some reason, putting flex on these components... oh...
// Have to call directly in by just the xtype since these are just
// references..
items: [
{
xtype: 'Main'
},
{
xtype: 'CommentList'
}
]
This does NOT work:
var tabpanel = Ext.create('Ext.TabPanel', {
fullscreen: 'true',
tabBarPosition: 'bottom',
defaults: {
styleHtmlContent: true
},
//load in views view clean instantiation using
// the widget.alias's defined in each view... yea
// For some reason, putting flex on these components... oh...
// Have to call directly in by just the xtype since these are just
// references..
items: [
{
xtype: 'Main',
title: 'The Main',
iconCls: 'user'
},
{
xtype: 'CommentList',
title: 'Comments',
iconCls: 'user'
}
]
});
As you can see, they are pretty much the same except one is a TapPanel (with the required default configs added) and the other is a carousel.
Everything else is exactly the same.... This is in the app.js of my Sencha Touch 2.0 app designed following the MVC architecture.
The result of the not-working TabPanel is that I only see the first view (Main) and no tab-bar appears in the bottom of the screen.
Any ideas what my problem might be?
I am not sure if this is an issue but in my code the line is:
Ext.create("Ext.tab.Panel", {
Not:
Ext.create('Ext.TabPanel', {
Fullscreen should be fullscreen: true instead of fullscreen: 'true'. You could also add this code to make them switch:
cardSwitchAnimation: {type: "fade", duration: 1000},
layout: "card",
Didn't test it, but it worked for me (got it from a snippet of my own code)

Categories