Sencha Touch 2 - Position a floating panel next to source button - sencha-touch-2

I have this code which creates a floating panel centered to the screen:
Ext.define('myapp.view.ButtonNav', {
extend: 'Ext.Container',
xtype: 'myapp_buttonnav',
config: {
fullscreen: false,
layout: 'hbox',
items: [
{
xtype: 'button',
text: 'Button 1',
listeners: {
tap: function () {
var panel = Ext.Viewport.add({
xtype: 'panel',
defaultType: 'button',
baseCls: 'btn1_cont',
centered: true,
layout: {
type: 'vbox',
align: 'center',
pack: 'center'
},
items: [
{
baseCls: 'btn1',
text: 'HOME PAGE',
handler: function() {
Ext.Viewport.setActiveItem({
xtype: 'myapp_homepage'
});
panel.destroy();
}
}
],
top: // SET TOP TO SOURCE BUTTON
left: // SET LEFT TO SOURCE BUTTON
});
}
}
},
]
}
});
As you can see, it is a container, with a button which when clicked shows a floating panel.
How do i position the floating panel centered to the button that triggered the floating panel?

If I understand correctly, you need to use the showBy function like so :
myPanel.showBy(myButton);
It will show the panel next to the button and you can choose the alignment as well.
You can take a look at the documentation
How to get the button
If you take a look at the tap listener signature : http://docs.sencha.com/touch/2-0/#!/api/Ext.Button-event-tap
You can see that the first parameter is the button itself so :
listeners: {
tap: function (myButton, myEvent) {
... // create your panel
myPanel.showBy(myButton);
}
}
Hope this helps

Related

Sencha Touch: Accessing the controls in view and calling their functions via their refrences in controller

[Sencha Touch 2.4.0]
I have a problem where .setHtml and .setValue function called against the refrences of labels and textfields are not doing anything ie the change is not showcasing in UI as desired but after the line of code is executed If I run .getHtml or .getValue in the console of the browser the change is visible in the output of the console but nothing changes in the UI.
My scenario in this Test Application is I have 3 labels [lbl1,lbl2 and lbl3] and 3 textfields [txt1,txt2 and txt3] I access the lbl1,lbl3,txt1,txt3 via their refrences in the controller. I desire to change the content of the lbl1 and txt1 if user clicks the button in the same panel. I have another form [initial view] with only button. what It does is opens the panel with 3 labels, 3 textfields and a button as I have described above but before pushing this Panel I want to set lbl3 and txt3. In all the cases .setValue and .setHtml is not updating the UI. Can anyone help me what am I doing wrong in here? I have also attached the sencha architecture project in zip.
MainViewr (initial view)
Ext.define('MyApp.view.mainView', {
extend: 'Ext.navigation.View',
requires: [
'Ext.form.Panel',
'Ext.Button'
],
config: {
itemId: 'mynavigationview',
items: [
{
xtype: 'formpanel',
items: [
{
xtype: 'button',
itemId: 'mybutton1',
text: 'MyButton1'
}
]
}
]
}
});
2nd Panel
Ext.define('MyApp.view.MyFormPanel1', {
extend: 'Ext.form.Panel',
alias: 'widget.myformpanel1',
requires: [
'Ext.Panel',
'Ext.Button',
'Ext.field.Text',
'Ext.Label'
],
config: {
itemId: 'myformpanel1',
scrollable: true,
items: [
{
xtype: 'panel',
docked: 'top',
height: '100%',
scrollable: true,
items: [
{
xtype: 'button',
itemId: 'mybutton',
text: 'MyButton'
},
{
xtype: 'textfield',
itemId: 'txt3',
label: 'Field'
},
{
xtype: 'textfield',
id: 'txt2',
itemId: 'txt2',
label: 'Field',
name: 'txt2'
},
{
xtype: 'textfield',
itemId: 'txt1',
label: 'Field'
},
{
xtype: 'label',
html: 'Name 3',
itemId: 'lbl3'
},
{
xtype: 'label',
html: 'Name 2',
id: 'lbl2',
itemId: 'lbl2'
},
{
xtype: 'label',
html: 'Name1',
itemId: 'lbl1'
}
]
}
]
}
});
Controller for the 1st View. Here I want to change the content of the label and textfield (lbl3 and txt3 which is on the 2nd view via thier refs) but setValue and setHtml or even calling other functions against their refs like hide() or setHidden(true) does not show on the UI but if I do getValue(), getHtml, getHidden in the browser's console thier hidden property and content is changed but it is not reflected on UI.
Ext.define('MyApp.controller.MyController', {
extend: 'Ext.app.Controller',
config: {
refs: {
mainView: 'navigationview#mynavigationview',
lbl3: 'label#lbl3',
txt3: 'textfield#txt3',
myFormPanel1: 'formpanel#myformpanel1'
},
control: {
"button#mybutton1": {
tap: 'btnlogin_click'
}
}
},
btnlogin_click: function(button, e, eOpts) {
var myformpanel1 = Ext.create('widget.myformpanel1');
lbl3 = this.getLbl3();
txt3=this.getTxt3();
mainView = this.getMainView();
txt3.setValue('Hello');
lbl3.setHtml('Hello');
mainView.push({
xtype: "myformpanel1",
title: "Dashboard"
});
}
});
Controller for 2nd View. As you can see I have tried to change the content of lbl1,lbl2,txt1 and txt2 in the button click but the content of only lbl2 and txt2 are changing because I have accessed them via their ID and not via reference.
Ext.define('MyApp.controller.MyController1', {
extend: 'Ext.app.Controller',
config: {
refs: {
lbl1: 'label#lbl1',
txt1: 'textfield#txt1'
},
control: {
"button#mybutton": {
tap: 'setText_Click'
}
}
},
setText_Click: function(button, e, eOpts) {
lbl1 = this.getLbl1();
txt1 = this.getTxt1();
Ext.getCmp('txt2').setValue("Hello");
Ext.getCmp('lbl2').setHtml("Hello");
txt1.setValue("Hello");
lbl1.setHtml("Hello");
}
});
Is accessing controls via their IDs is the only way? because I have read somewhere that accessing the controls via ID is not very good thing to do in Sencha Touch. What am I doing wrong in here so that my code changes the content and properties of the controls internally but not reflected on UI as desired.
I checked your code and found out that this problem is causing because of the navigation view. I don't know the reason for this weird problem but changing the navigation view to Container solved the problem.
Main View :-
Ext.define('MyApp.view.MainView', {
extend: 'Ext.Container',
xtype: 'main',
requires: [
'Ext.form.Panel',
'Ext.Button'
],
config: {
itemId: 'mynavigationview',
items: [
{
xtype: 'button',
itemId: 'mybutton1',
text: 'MyButton1'
}
]
}
});
Set the form view on btnlogin_click like this:-
Ext.Viewport.setActiveItem(myformpanel1);

Button Event not getting fired when put inside Tab Panel in Sencha Touch 2

I have put two buttons inside a tab Panel in Sencha Touch 2 application. The code is given below:
var btnAttendance = Ext.create('Ext.Button', {
text: 'Take Attendance',
padding: 10,
width: 200,
handler: function () {
alert('a');
}
});
var btnAddUser = Ext.create('Ext.Button', {
text: 'Add User',
padding: 10,
width: 200,
handler: function () {
alert('a');
}
});
var buttonContainer = Ext.create('Ext.Panel', {
fullscreen: true,
title: 'Home',
defaults: {
margin: 5
},
layout: {
type: 'vbox',
align: 'center'
},
padding: 10,
items: [
btnAttendance,
btnAddUser
]
});
Ext.application({
requires: [
'Ext.tab.Panel'
],
launch: function () {
Ext.Viewport.add({
xtype: 'tabpanel',
items: [
buttonContainer,
{
title: 'Present',
items: {
html: '2',
centered: true
},
cls: 'present'
},
{
title: 'Absent',
items: {
html: '3',
centered: true
},
cls: 'absent'
}
]
});
}
});
I have tried modifying the handler function as:
handler: function (button, event)
But this also doesn't work.
Thanks,
Nitin
You need to put all your code inside Ext.application... and launch:function(){...}.... Your code is working fine. See demonstration here.
But then again, buttonContainer is not really being added to any tab panel. If you change the tab, you can see buttonContainer is gone once to change the tabs. If you want to add it inside any tab do this-
First -
Set fullscreen:false to you buttonContainer panel.
var buttonContainer = Ext.create('Ext.Panel', {
fullscreen: false,
....... //rest of the code.
And suppose you want to add those buttons in Present tab. You can do this with following--
Ext.Viewport.add({
xtype: 'tabpanel',
items: [
{
title: 'Present',
cls: 'present',
items: [
{
html: '2',
centered: true
},
buttonContainer
]
},
{
title: 'Absent',
items: {
html: '3',
centered: true
},
cls: 'absent'
}
]
});
Here, buttonContainer is added as an item inside present tab only. You can switch the tabs and can see buttons there with correct event handler.
See this demo here
If you follow MVC architecture, your job becomes much easier writing application having multiple views and user interactions. ST is all about MVC and it's good practice to follow it.

Listener to Tab Item Click in Sencha

In my application, I'm using a tab panel with 5 items in it. Each item holds around 6 panels added in card layout. When I'm at the last panel inside a tab item, I need to get back to the initial panel by clicking on the bottom tab panel (somewhat similar to a normal tab view controller in iOS). I have came across some solutions I found here, but it seems to work only when I switch between the tabs. In fact I want to listen to the click event on the same tab icon. How can I do this?
I have worked on your problem. I think this is exactly what you want. Hope this helps. If not so, please leave a comment.
1). View (MyTabPanel1.js)
Ext.define('MyApp.view.MyTabPanel1', {
extend: 'Ext.tab.Panel',
config: {
scrollable: 'vertical',
items:
[
{
xtype: 'panel',
id:'cardpanel1',
title: 'Tab1',
layout: 'card',
items: [
{
html: "First Item",
items:
[
{
xtype: 'button',
text: 'Forward',
handler: function() {
Ext.getCmp('cardpanel1').setActiveItem(1);
console.log('Going to Second Item');
}
}
]
},
{
html: "Second Item",
items:
[
{
xtype: 'button',
ui: 'confirm',
text: 'Go back',
handler: function() {
Ext.getCmp('cardpanel1').setActiveItem(0);
console.log('Going to First Item');
}
}
]
}
]
},
{
xtype: 'panel',
title: 'Tab2',
scrollable: true,
items: [
{
xtype: 'button',
margin: 10,
ui: 'action',
text: 'Tab2'
}
]
},
{
xtype: 'panel',
title: 'Tab3',
scrollable: true,
items: [
{
xtype: 'button',
margin: 10,
ui: 'action',
text: 'Tab3'
}
]
}
]
}
});
2). Controller (MainController.js)
Ext.define('MyApp.controller.MainController', {
extend: 'Ext.app.Controller',
config: {
control: {
"tabpanel #ext-tab-1":{ //ext-tab-1 is the id for the 1st tab generated by Sencha
tap: 'ontap'
}
}
},
ontap: function (){
console.log('inside controller');
Ext.getCmp('cardpanel1').setActiveItem(0);
}
});
I would give a much simpler solution
This is my view called Viewport which is a TabPanel:
Ext.define('Sencha.view.iphone.Viewport',{
extend: 'Ext.TabPanel',
xtype: 'newviewport',
alias: 'widget.newTabPanel',
Now in my controller file:
Ext.define('Sencha.controller.iphone.main', {
extend: 'Ext.app.Controller',
config:
{
refs: {
theMainTabPanelTabbarTab: 'newTabPanel > tabbar > tab', //this the tab of the tabpanel, if we listen to it that way we will know of tab panel tap.
},
control: {
theMainTabPanelTabbarTab:{
tap: 'onTapMainTabPanel'
}
}
This is a working code and works fine. Hopefully this will help you.

Activate the 2nd tab of the tab panel

I have a tabpanel, and a button on the 1st tab. When i click on that button, i need to setfocus to the 2nd tab and activate it (as in show content that belongs to that tab). My code is as follows, and i unable to setFocus or activate that tab from the Button click event.
Ext.define('MyApp.view.MyTabPanel', {
extend: 'Ext.tab.Panel',
height: 250,
width: 400,
activeTab: 0,
initComponent: function () {
var me = this;
Ext.applyIf(me, {
items: [{
xtype: 'panel',
title: 'Tab 1',
items: [{
xtype: 'button',
text: 'MyButton',
listeners: {
click: {
fn: me.onButtonClick,
scope: me
}
}
}]
}, {
xtype: 'panel',
title: 'Tab 2'
}, {
xtype: 'panel',
title: 'Tab 3'
}]
});
me.callParent(arguments);
},
onButtonClick: function (button, e, options) {
// Set Focus, and activate the 2nd tab
}
});
Find the container of the tab panel. to get the container you can use Ext.getCmp
Ext.getCmp('center-region').setActiveTab('your-tab-name');
http://docs.sencha.com/ext-js/4-1/#!/api/Ext.tab.Panel-method-setActiveTab
There are also several examples of setting the active tab at the class level documentation.

Sencha Touch TabBar + page navigation. Why it's breaking?

I'm a newbie to SenchaTouch. I have started working on an App and the results are this until now: http://mobz.com.br:86. (based on the Sencha-Touch-tabs-and-toolbars-demo)
Now I started playing with it and I have difficulties to set things strait in my head.
I have lot of JQuery experience, but regarding the design of this library, the coin haven't dropped yet.
I got a TabPanel with 5 sections. I will focus only in one section cause there where my problem is.
The Problem
As you can see in my app, when one clicks an item of ingressos (tickets in English), the app loads the second panel, but load it with bugs.
It loads it without the title bar, without the Back button, and also add an empty sixth button on the right.
But if I load the second panel first, when the page loads, it loads without any UI issues.
My Code
First I declare my ViewPort
Mobz.views.Viewport = Ext.extend(Ext.TabPanel, {
fullscreen: true,
initComponent: function() {
Ext.apply(this, {
tabBar: {
dock: 'bottom',
layout: {
pack: 'center'
}
},
items: [
{ xtype: 'destaques', id: 'home' },
{ xtype: 'ingressos' },
{ xtype: 'mobilizacoes' },
{ xtype: 'locais' },
{ xtype: 'minhaconta' }
]
});
Mobz.views.Viewport.superclass.initComponent.apply(this, arguments);
}
});
Than after, at the ingressos.js file, I define the tab.
First I got the panel that will load the items into it.
Mobz.views.Ingressos = Ext.extend(Ext.Panel, {
id: "ingressos",
title: "Ingressos", //title of the page
iconCls: "arrow_right", // icon of the tab at the bottom
styleHtmlContent: true,
fullscreen: true,
layout: 'card',
initComponent: function () {
Ext.apply(this, {
dockedItems: [{
xtype: "toolbar",
title: "Ingressos"
}],
items: [Mobz.views.IngressosList]
});
Mobz.views.Ingressos.superclass.initComponent.apply(this, arguments);
}
});
Ext.reg('ingressos', Mobz.views.Ingressos);
This is the initial item that load into the panel.
Mobz.views.IngressosList = new Ext.List({
id: 'ingressoslist',
itemTpl: IngressosList_Template,
store: Mobz.stores.IngressosStore,
onItemTap: function (subIdx) {
//Mobz.views.IngressoCinemaList.update(subIdx);
Mobz.views.viewport.setActiveItem(Mobz.views.IngressoCinemaList, { type: 'slide', direction: 'left' });
}
});
And that's the second panel.
The panel where the first panel goes to.
Mobz.views.IngressoTitle = new Ext.Panel({
id: 'ingressotitle',
tpl: IngressoTitle_Template,
data: Mobz.stores.IngressoTitle_Store
});
Mobz.views.IngressoCinemaList = new Ext.List({
id: 'ingressocinemalist',
itemTpl: IngressoCinemaList_Template,
store: Mobz.stores.IngressoCinemaListStore,
flex: 1, grouped: true,
dockedItems: [{
xtype: 'toolbar',
items: [{
text: 'Back',
ui: 'back',
handler: function () {
Mobz.views.viewport.setActiveItem(Mobz.ingressos, { type: 'slide', direction: 'right' });
}
}]
}
],
onItemDisclosure: function () {
app.views.viewport.setActiveItem(Mobz.views.IngressosHorario, { type: 'slide', direction: 'left' });
}
});
Mobz.views.Ingresso = new Ext.Panel({
id: 'ingresso',
layout: {
type: 'vbox',
align: 'fit'
},
items: [Mobz.views.IngressoHorario_IngressoECinemaTitles, Mobz.views.IngressoCinemaList]
});
That's it.
I hope some of you guys will have the patient to read all my code examples. I'll appreciate any help.
Shlomi.
First, you must understand the logic about the panels.
You have an TabPanel and you have 5 panel in it. If you run your code when you click a ticket as you described in problem, your code added a new pane to TabPanel. But you need to set active item of Ingression panel(second panel which is in tabPanel).
Now start the solution;
The second tab has a panel(I will say senchaTabItem) whose layout is card layout. And this panel has a panel in it with list of Ingressos. We want to remove this panel and replace the new panel so we should not call the tabPanel's method, we must call to senchaTabItem's method.
So if you replace below code
Mobz.views.viewport.setActiveItem(Mobz.views.IngressoCinemaList, { type: 'slide', direction: 'left' });
with working code(below code).
Mobz.views.viewport.getActiveItem().setActiveItem(Mobz.views.IngressoCinemaList, { type: 'slide', direction: 'left' });
In your site; it is at line 170 in ingressos.js
I tried and it works, I hope it helps