Click one Panel, Hide other Panels - Ext JS - extjs

I have three separate buttons with controllers. When one of the buttons is clicked, a panel is created and displayed (with animation). Here's what one of my controllers looks like:
Ext.define('AM.controller.Prod_Select', {
extend: 'Ext.app.Controller',
init: function() {
this.control({
'#prod_select': {
click: this.prodSelect
}
});
},
prodSelect: function() {
var subPanel = Ext.create('Ext.panel.Panel', {
width: 200,
height: 160,
html: '<center><p class="sub_panel_text "> Link <br /> Link <br /> Link </p> </center>',
bodyStyle: 'background:#010a4d',
border:false,
floating: true,
shadow: false,
style: 'opacity: 0;',
x: 770,
y: 75,
cls: 'sub_panel'
});
subPanel.show();
subPanel.animate({
duration: 1000,
to: {
opacity: .6,
x: 800,
y: 75
}
});
console.log('Clicked Prod');
}
});
This works just fine, but currently I can click one button x amount of times, and it will create x amount of panels. What I want out of this controller, however, is to create only a single panel from a click AND hide any other panel (with fade out) that may displayed already out of the three.
Is there any way to accomplish this? Thanks for reading!

You could add a property to the subPanel so it can be easily selected using ComponentQuery, then iterate through the query's results and hide the other panels.
var subPanel = Ext.create('Ext.panel.Panel', {
someCustomProperty: 'someCustomValue',
...
});
var allPanels = Ext.ComponentQuery.query('panel[someCustomProperty="someCustomValue"]');
Ext.Array.each(allPanels, function(panel) {
if (panel === subPanel) {
//show it
} else {
//hide it
}
});

Related

Couple of questions about fotorama

I found your Fotorama gallery script v4.6.4 and it is exactly what I was looking for.
I do have a couple of questions:
How can I move the Caption down so that it is not overlaying the bottom of an image?
I would like it to be completely separate i.e.
Main Image
Caption
Thumbs
Here is an image that shows how the caption is currently obscuring the lower part of the main image, seems worse the smaller the viewport:
Caption Overlaying Image
Currently the caption shows the image title & a download link for the displayed image.
I would like the link to point to the Flickr image page instead of the ability to download it.
My JS script is currently:
<script type="text/javascript">
$(function() {
var AddPhotosToCarousel = function(data) {
var imgs = [];
$.each(data.photoset.photo, function(index, photo) {
// TODO: use flickr.photos.getSizes
caption = photo['title'] +
' <small>(Download)</small>'
imgs.unshift({img: photo['url_m'],
thumb: photo['url_s'],
caption: caption});
});
$('.fotorama').fotorama({
data: imgs,
width: '100%',
maxwidth: '960',
maxheight: '100%',
ratio: '4/3',
nav: 'thumbs',
autoplay: 8000,
keyboard: 'true',
arrows: 'true',
transition: 'crossfade'
});
};
$.getJSON('https://api.flickr.com/services/rest/?method=flickr.photosets.getPhotos&api_key=[API KEY]&photoset_id=[PHOTOSET ID]&format=json&extras=url_s,url_m,url_o&jsoncallback=?', AddPhotosToCarousel);
});
</script>
this forms a URL in the format:
https://farm2.staticflickr.com/1566/[IMAGE ID][SECRET]_o.jpg
but I would like it to form a URL in format:
https://www.flickr.com/photos/[USER]/[PHOTO ID]/in/dateposted-public/
Any help would be appreciated.
Kind regards..,
OK, I found this page:
Jquery JSON Flickr API Returning Photos in a Set
& altered my script to:
<script type="text/javascript">
$(function() {
var AddPhotosToCarousel = function(data) {
var imgs = [];
$.each(data.photoset.photo, function(index, photo) {
var a_href = "http://www.flickr.com/photos/" + data.photoset.owner + "/" + photo.id + "/";
// TODO: use flickr.photos.getSizes
caption = photo['title'] +
' (Open)'
imgs.unshift({img: photo['url_m'],
thumb: photo['url_s'],
caption: caption});
});
$('.fotorama').fotorama({
data: imgs,
width: '100%',
maxwidth: '960',
maxheight: '100%',
ratio: '4/3',
nav: 'thumbs',
autoplay: 8000,
keyboard: 'true',
arrows: 'true',
transition: 'crossfade',
click: 'false'
});
};
$.getJSON('https://api.flickr.com/services/rest/?format=json&method=flickr.photosets.getPhotos&photoset_id=72157664523293315&api_key=449126625d797cace5a6d5a90532b741&extras=url_s,url_m&jsoncallback=?', AddPhotosToCarousel);
});
</script>
While this does build the direct image link, clicking on this link only advances the slideshow instead of opening the link.
You can see that I also included the click: 'false' option but this has not stopped the issue.
How do I stop the slideshow advancing when clicking the link?
Regards..,
Right, got question 2 sorted, seemed to be an issue with Chrome caching the page.
Script is now:
<script type="text/javascript">
$(function() {
var AddPhotosToCarousel = function(data) {
var imgs = [];
$.each(data.photoset.photo, function(index, photo) {
var a_href = "http://www.flickr.com/photos/1cm69/" + photo.id + "/";
// TODO: use flickr.photos.getSizes
caption = ' <small><a href="' + a_href + '" target=_blank>' + photo['title'] + '</a></small>'
imgs.unshift({img: photo['url_m'],
thumb: photo['url_s'],
caption: caption});
});
$('.fotorama').fotorama({
data: imgs,
width: '100%',
maxwidth: '960',
maxheight: '100%',
ratio: '4/3',
nav: 'thumbs',
autoplay: 8000,
keyboard: 'true',
arrows: 'true',
transition: 'crossfade'
});
};
$.getJSON('https://api.flickr.com/services/rest/?format=json&method=flickr.photosets.getPhotos&photoset_id=72157664523293315&api_key=449126625d797cace5a6d5a90532b741&extras=url_s,url_m&jsoncallback=?', AddPhotosToCarousel);
});
</script>
& working.
So only one question left, that of the Caption overlaying the bottom of the image.
Regards..,

ExtJS TabItem Click Event

Good Morning All,
I have an ExtJS 5 tabpanel. When the tabpanel first appears there is a single tab inside with a star for the title. What I need is when the user clicks the star for it to create a new tabItem. I have tried the activate event but that only works with more than one tab present. I have also tried binding to the a click event and nothing happens for that. Here is the code I have now:
{
xtype:'tabpanel',
itemId:'tabCtr1',
width:785,
items:[
{ iconCls: 'btn-NewTab', html : 'A simple tab' }
]
}
function assetDetailsDialog_AfterRender(sender, eOpts)
{
parent.down('tabpanel').items.getAt(0).on('click', function(){
alert('Hello World');
});
}
Thanks everyone
Follow On Issue:
I am having one more issue with setting the active tab. When the button is click it creates the new tab not issue, but when I call setActiveTab it appears to do nothing. When I stepped through it in Chrome I can see it is actually changing the tab to the specified one but then switching it back to the original. Any help would be great. Any idea's?
I have created a fiddle which demonstrates how to add tabs dynamically on click, the code is also listed below in case the link breaks. In the code below, the significant thing is adding the listener to the tabConfig
Ext.application({
name: 'Fiddle',
launch: function() {
var tabPanel = Ext.create('Ext.tab.Panel', {
width: 800,
height: 400,
renderTo: document.body,
items: [{
title: 'Click me to add another tab',
tabConfig: {
listeners: {
click: function(tab) {
alert("Adding another tab");
var newTab = tabPanel.add({
// we use the tabs.items property to get the length of current items/tabs
title: 'Tab ' + (tabPanel.items.length + 1),
html: 'Another one'
});
}
}
}
}, {
title: 'Bar',
tabConfig: {
title: 'Custom Title',
tooltip: 'A button tooltip'
}
}]
});
}
});
Most of this code was taken from the documentation here

It's possible to know the field that holds the focus before button click?

In a form, that have a couple of text items and a button, it's possible to know in which item the focus was before the click in the button?
I want to open another form, in a button click, and this form have a "context" that depends in the focus of the previous form.
Any thoughts?
EDIT
I tried to hold the last focused element in the controller, binding the blur event of all fields, but it seems that this event is not synchronized in IE (always he), Chrome and FF seems ok with that.
Ext.define('MyApp.controller.MyController', {
extend: 'Ext.app.Controller',
id: 'MyController',
views: [
'MyView'
],
init : function(application){
var me = this;
me.lastFocus = null;
me.control({
'.field' : {
blur: me.fieldBlur,
scope: me
}
});
},
fieldBlur: function(field, event, opts) {
this.lastFocus = field;
//console.log('lastFocus: ' + field);
}
});
I never tried it myself but Ext.FocusManager.focusedCmp looks promising. Note that you will need to activate it before you can use it by calling Ext.FocusManager.enable()
Edit
I thought it would be more stable by now. I am sorry to hear that it seams not to help you but I can not understand why the focusedCmp should be undefined on time you are clicking the button it should be the button. And with that I come to my error you need to access previousFocusedCmp.
But it should work cause what it does it no magic...
A little example JSFiddle:
Ext.FocusManager.enable();
Ext.create('Ext.form.Panel', {
title: 'Simple Form',
bodyPadding: 5,
width: 350,
// The form will submit an AJAX request to this URL when submitted
url: 'save-form.php',
// Fields will be arranged vertically, stretched to full width
layout: 'anchor',
defaults: {
anchor: '100%'
},
// The fields
defaultType: 'textfield',
items: [{
fieldLabel: 'First Name',
name: 'first',
allowBlank: false
},{
fieldLabel: 'Last Name',
name: 'last',
allowBlank: false
}],
// Reset and Submit buttons
buttons: [{
text: 'Reset',
handler: function() {
console.log('Most likely the button you clicked: ', Ext.FocusManager.focusedCmp, 'The Component that was focused before: ',Ext.FocusManager.previousFocusedCmp );
this.up('form').getForm().reset();
}
}, {
text: 'Submit',
formBind: true, //only enabled once the form is valid
disabled: true,
handler: function() {
var form = this.up('form').getForm();
if (form.isValid()) {
form.submit({
success: function(form, action) {
Ext.Msg.alert('Success', action.result.msg);
},
failure: function(form, action) {
Ext.Msg.alert('Failed', action.result.msg);
}
});
}
}
}],
renderTo: Ext.getBody()
});
How does the FocusManger do it in one sentence (we spare the keynav):
Well as soon as he get's enabled he queries the whole DOM for all
focusable components and tell each of them to inform him about focus and blur
changes.
From the persective of a user this sounds a bit shady, but whatever here you go:
use jQuery mouseover on each of the forms and where it sets some global variable to itself or a respective string, when the button is called the variable contains the last active field.
something like
var last_active = 0;
function set_last_active(e, ui){
last_active = $(this);
}
$('.tracked_form').mouseover(set_last_active);
should do the trick, also see if you can use event bubbling.
The proposal of using blur event in the form fields works in the button if you delay the access to my lastFocus attribute.
onButtonClick : function(button, e, eOpts) {
var me = this;
setTimeout(function(){
alert(me.lastFocus.getItemId());
}, 250);
}

Using more than one controller with ExtJS 4 MVC

Let's say I have a main controller, then my application has a controller for each "module". This main controller contains the viewport, then a header (with a menu) + a "centered" container, which is empty at the beginning.
A click in the menu will change the current module/controller and the adhoc view (which belongs to this controller) will be displayed in the centered container.
I think it's a very simple scenario, but strangely I didn't find the proper way to do it. Any ideas? Thanks a lot!
Here is what I do: I have a toolbar on top, a left navigation and the center location is work area (basically a tab panel) like you mentioned. Lets take each part fo the application and explain.First, here is how my viewport look like:
Ext.define('App.view.Viewport',{
extend: 'Ext.container.Viewport',
layout: 'border',
requires: [
'App.view.menu.NavigationPane',
'App.view.CenterPane',
'App.view.menu.Toolbar'
],
initComponent: function() {
Ext.apply(this, {
items: [{
region: 'north',
xtype: 'panel',
height: 24,
tbar: Ext.create('App.view.menu.Toolbar')
},{
title: 'Navigation Pane',
region: 'west',
width: 200,
layout: 'fit',
collapsible: true,
collapsed: true,
items: Ext.create('App.view.menu.NavigationPane')
},{
region: 'center',
xtype: 'centerpane'
}]
});
this.callParent(arguments);
}
});
You can see that I have a toolbar (App.view.menu.Toolbar) with menu and left navigation (App.view.menu.NavigationPane). These two, components make up my main menu or gateway to other modules. Users select the menu item and appropriate module views (like form, grid, charts etc) get loaded into the 'centerpane'. The centerpane is nothing but a derived class of Ext.tab.Panel.
Like you said, I have a main controller that handles all the requests from the toolbar and navigation pane. It handled only the toolbar and navigation pane's click actions. Here is my AppController:
Ext.define('CRM.controller.AppController',{
extend: 'Ext.app.Controller',
init: function() {
this.control({
'apptoolbar button[action="actionA"]' : {
click : function(butt,evt) {
this.application.getController('Controller1').displayList();
}
},
.
. // Add all your toolbar actions & navigation pane's actions...
.
'apptoolbar button[action="actionB"]' : {
click : function(butt,evt) {
this.application.getController('Controller2').NewRequest();
}
}
});
}
});
Look at one of my button's handler. I get hold of the controller through the 'application' property:
this.application.getController('Controller2').NewRequest();
With the help of getController method, I get the instance of the controller and then call any method inside my controller. Now lets have a look at the skeleton of my module's controller:
Ext.define('CRM.controller.Controller2',{
extend: 'Ext.app.Controller',
refs: [
{ref:'cp',selector: 'centerpane'}, // reference to the center pane
// other references for the controller
],
views: ['c2.CreateForm','c2.EditForm','c2.SearchForm','c2.SearchForm'],
init: function() {
this.control({
'newform button[action="save"]' : {
// Do save action for new item
},
'editform button[action="save"]' : {
// update the record...
},
'c2gridx click' : {
// oh! an item was click in grid view
}
});
},
NewRequest: function() {
var view = Ext.widget('newform');
var cp = this.getCp(); // Get hold of the center pane...
cp.add(view);
cp.setActiveTab(view);
},
displayList: function() {
// Create grid view and display...
}
});
My module's controller have only the actions related to that module (a module's grid, forms etc). This should help you get started with rolling in right direction.
In main controller add child controller in the click event handler of menu
Ext.define('MyAPP.controller.MainController',{
...
init:function()
{
this.control({
'menulink':
{
click:this.populateCenterPanel
}
});
},
populateCenterPanel:function()
{
this.getController('ChildController');
}
});
In launch function add listener to controller add event like this -
Ext.application({
...
launch:function(){
this.controllers.addListener('add',this.newControllerAdded,this);
},
newControllerAdded:function(idx, ctrlr, token){
ctrlr.init();
}
});
Now put code for dynamically embedding views in the viewport in init method of ChildController.
Ext.define('MyAPP.controller.ChildController',{
...
refs: [
{ref:'displayPanel',selector:'panel[itemId=EmbedHere]'}
]
init:function(){
var panel=this.getDisplayPanel();
panel.removeAll();
panel.add({
xtype:'mycustomview',
flex:1,
autoHeight:true,
...
});
}
});
HTH :)

extjs adding icons to the titlebar of an extended window widget (two levels of extension)

I am new to extjs....
I am trying to add icons to the title bar of a window.
I am not able to figure out the error in my code
i tried using tools config for the window
Here is my code:
**Ext.ns('DEV');
DEV.ChartWindow = Ext.extend(Ext.ux.DEV.SampleDesktopWidget, {
width:740,
height:480,
iconCls: 'icon-grid',
shim:false,
animCollapse:false,
constrainHeader:true,
layout: 'fit',
initComponent : function() {
this.items = [
new Ext.Panel({
border:true,
html : '<iframe src="" width="100%" height="100%" ></iframe>'
})
];
DEV.ChartWindow.superclass.initComponent.apply(this, arguments);
},
getConfig : function() {
var x = DEV.ChartWindow.superclass.getConfig.apply(this, arguments);
x.xtype = 'DEV Sample Window';
return x;
},
tools: [{
id:'help',
type:'help',
handler: function(){},
qtip:'Help tool'
}]
});
Ext.reg('DEV Sample Window', DEV.ChartWindow);**
SampleDesktopWidget is an extension of Window
Can somebody help me with this
Thanks in advance
I believe title is part of the header. I dont think you can do this with initialConfig programmatically but you can either override part of component lifecycle or hook in with an event. E.g. add this to config. You might (probably) be able to hook in at any early stage after init maybe, but thats an experiment for you.
listeners: {
render: {
fn: function() {
this.header.insert(0,{
xtype: 'panel',
html: '<img src="/img/titleIcon1.gif"/>'
});
}
}
}
However for this particular scenario I would use iconCls
iconCls: 'myCssStyle'
Then include a CSS file with:
.myCssStyle {
padding-left: 25px;
background: url('/ima/titleIcon.gif') no-repeat;
}
This is a good example that might help, using extjs 3.2.1.
Adding tools dynamically

Resources