I create a webpage which has some elements of ext js embedded in it. I am having a problem displaying a loading mask especially when there is so much data to load. In this example, I am using color box to create a popup window. Inside the popup window, I want to display ext js data grid where a user can select items. The problem is in the speed in which the grid loads. It takes a while before it fully loads.
The page is : http://ictpunt.be, click on the 'add offer' button to see the popup.
I would like to display a loading mask while it is loading. I have tried doing it on the viewport, but it only shows when the data is about to load. So a user has to look at the blank screen for close to 10 seconds before the loadmask msg appears! Here is a piece of my code
Ext.create('Ext.Viewport', {
items: [ contentPanel ],
renderTo: 'content',
loadMask: true,
viewConfig: {
loadingText: "Loading, please wait..."
},
....
});
You want the setLoading method on the instance of the Viewport that you are creating:
myViewport = Ext.create('Ext.Viewport', {
renderTo: 'body'
});
myViewport.setLoading('Loading, please wait...');
setTimeout(function () { myViewport.setLoading(false); }, 2000);
Related
I have a dynamic form and i want to add a listener when change a field value, but i couldnt achive to do that. I added a click listener but when i change it to the change it doesnt work.
thanks in advance.
here is the code below :
panel = Ext.define('MyApp.view.dynamicform.Form', {
extend: 'Ext.form.Panel',
alias: 'widget.dynamicformform',
title: title,
id: 'dynamicform.Form',
bodyPadding: 5,
autoScroll: true,
layout: 'auto',
defaults: {
anchor: '100%'
},
dockedItems: [],
items : genItems(storeData),
listeners: {
afterrender: function (comp) {
var element = comp.getEl();
element.on('change', function(e,el) {
alert('blabla')
});
}
},
initComponent : function() {
this.callParent(arguments);
}
});
when i write click instead of change it works perfectly. I dont get what iam doing wrong.
The afterrender event you have added the listener for is purely for the panel component alone. Therefore trying to attach a change event wont work, since you are trying to do this on the panel:
afterrender: function (comp) {
var element = comp.getEl();
//element is the panel here, not child items such as spinners...
element.on('change', function(e,el) {
alert('blabla')
});
}
You say the click is working, but I think that's just because you are clicking anywhere on the panel including on the child items you are rendering. Instead, the child items coming back in the genItems() need to contain change event listener configs.
EDIT
You could loop through the child items on comp in your afterrender event and for any that are spinners, etc, add the change events that way.
Is there a way to display a thumbnail of a youtube video in a BackboneJS view, then after clicking the thumbnail a lightbox opens and plays the video and at the same time the URL changes, so that you actually can send the URL-link?
I have a Backbone App where I list multiple Artists and when you click on one of those you get to an artist specific page where the user among other things can watch videos. So lets say you are on Lady Gaga's page and i click on a video, the Magnific Popup-opens with the video. But what I want to achieve i that the URL changes as well. something like ladygaga/videos/titleofvideo(or youtubelink):
Right now, in my Backbone View I have:
events: {
'click .video' : 'popUp'
},
popUp: function (e) {
e.preventDefault();
$('.video').magnificPopup({
disableOn: 700,
type: 'iframe',
mainClass: 'mfp-fade',
removalDelay: 160,
preloader: false,
fixedContentPos: false
});
}
The popup works fine, I just need the URL to change... Does anyone have an idea how to add this here if it is possible?
Thanks in advance...
Please, help me. I am creating a TabPanel using the MVC. At the time of rendering panel add tab. Here is the code of the two views and controller. The result is a distorted picture.
The title of the tab is drawn twice: at the top and bottom (stretched to full screen). When I change in the controller function addNewTab() the line "tp.add({xtype: 'mytab'}).show();"
to the other "tp.add({title: 'new Tab', html: 'MVC New Tab Example'}).show();", then everything is rendered properly. I will be grateful for the help.
Views:
Ext.define('MY.view.Tab', {
extend: 'Ext.tab.Tab',
alias: 'widget.mytab',
initComponent: function() {
this.title = 'new Tab';
this.html = 'MVC New Tab Example';
this.callParent(arguments);
}
});
Ext.define('MY.view.TabPanel', {
extend: 'Ext.tab.Panel',
alias: 'widget.mytabpanel',
initComponent: function() {
this.id = 'MYTabPanel';
this.callParent(arguments);
}
});
Controller:
Ext.define('MY.controller.TabPanel', {
extend: 'Ext.app.Controller',
requires: ['MY.view.Tab'],
init: function() {
this.control({
'#MYTabPanel': {
render: this.addNewTab
}
});
},
addNewTab: function(tp) {
tp.add({xtype: 'mytab'}).show(); //it work bad
//tp.add({title: 'new Tab', html: 'MVC New Tab Example'}).show(); //it work good
}
});
Your mytab class extends Ext.tab.Tab. That means that this code tp.add({xtype: 'mytab'});
is adding a Tab as a main view for the TabPanel. A tab is created automatically for every panel or container you add to the tab panel and consists of just the button-like component at the top of the view.
That means that when you call the code above, a Tab is created and pushed into the TabPanel as a view, then the TabPanel creates another another Tab using the same title and attaches it to the top of the Tab you just added.
This code tp.add({title: 'new Tab', html: 'MVC New Tab Example'})' works because you are actually adding a panel (The default xtype used by Ext is panel) and the TabPanel is creating the tab for you using the title you've provided.
To fix: make MY.view.Tab extend Panel instead of Tab. If you're trying to customize just the tab for a particular view, dig into the source for Ext.tab.Panel and check out the undocumented tagConfig property that you can add to TabPanel items.
I have a Tab Panel as my initial item inside a Navigation View. When I change tab, I'm updating the Title in the Navigation Bar via:
activeitemchange: function(container){
var navigationView = container.up('navigationview'),
navigationBar = navigationView.getNavigationBar(),
newTabTitle = value.tab._title;
navigationBar.setTitle(newTabTitle);
}
The problem is that when I push a new view onto the Navigation View, the Text for the Back Button uses the old/original Title, and not the updated Title. Clicking the Back Button also sets the Navigation View Title to the old/original Title.
The closest I got to finding a solution was this:
http://www.sencha.com/forum/showthread.php?189284-Navigation-View-Title-(IPad-App)
But I get an 'undefined' error on the navigationBar.refreshProxy() call, so I'm assuming that only works for an older version of ST.
Any help would be great,
Thanks.
I don't know if you found any answer for this question or solved it by your own since question is quite old. But I tried what you wanted to do and I managed to get the result successfully. So here's the code. I'm following MVC strictly so posting necessary files that need this to work. Basically, views and controllers.
Main.js containing TabPanel
Ext.define('SO.view.Main', {
extend: 'Ext.tab.Panel',
xtype: 'main',
requires: [
'Ext.TitleBar',
'Ext.Video'
],
config: {
tabBarPosition: 'bottom',
items: [
{
title: 'Welcome',
iconCls: 'home',
styleHtmlContent: true,
scrollable: true,
html: [
"You've just generated a new Sencha Touch 2 project. What you're looking at right now is the ",
].join("")
},
{
title: 'Get Started',
iconCls: 'action',
items: [
{
xtype: 'button',
text: 'Push a new view!',
action:'push_new_view'
}
]
}
]
}
});
Nav.js having navigation view and default item as above tab panel
Ext.define('SO.view.Nav', {
extend: 'Ext.NavigationView',
xtype: 'nav',
config:{
fullscreen: true,
items: [
{
title: 'Default View',
xtype:'main'
}
]
}
});
And finally, controller. I did every user interaction handling in controller itself.
Ext.define('SO.controller.Nav',{
extend:'Ext.app.Controller',
config:{
refs:{
views:['SO.view.Main','SO.view.Nav'],
navView:'nav',
tabView:'main'
},
control:{
tabView:{
activeitemchange:'changeTitle'
},
'button[action=push_new_view]':{
tap:'pushNewView'
}
}
},
changeTitle:function(container,value,oldValue,eOpts ){
console.log(value.title);
this.getNavView().getNavigationBar().setTitle(value.title);
},
pushNewView:function(){
var activeTabTitle = this.getTabView().getActiveItem().title;
var controller = this;
controller.getNavView().push({
title: 'Second',
html: 'Second view!'
});
controller.getNavView().getNavigationBar().getBackButton().setText(activeTabTitle);
controller.getNavView().getNavigationBar().getBackButton().on('tap',function(self){
controller.getNavView().getNavigationBar().setTitle(activeTabTitle);
});
}
}
);
As you can see, I've attached function that changes title according to selected tab in changeTitle function.
the function pushNewView pushes new view and let's you ovverride back button behavior on tap. What I did is simply, get activeItem() from tab panel which holds a button that pushes new view. Once we got activeItem we can get it's title and that title need to be set to backButtnoText. So I traverse navigation view and getBackButton instance and simply by calling setText() method changed back button text.
Same time, I've attached event handler to back button, as we do want to change navigation bar title to previous title. So once, use taps back button, we set back the title to title we got in above step. You might want to detach event handler once you're done with eveything as it might cause problems or I'd rather say it'd be good.
Just try this, it just works.
You will need to change the title of the parent viewport, not just to the navigation view tile. Basically the Navigation title is already changing by itself based on the parent view title, and all pushed component title.
var view = Ext.create('Ext.NavigationView', {
fullscreen: true,
items: [{
title: 'Change this title ',
items: [{
xtype: 'button',
text: 'Push a new view!',
handler: function() {
view.push({
title: 'Second Title',
html: 'Second view!'
});
}
}]
}]
});
It should look something like this:
activeitemchange: function(container){
var newTabTitle = value.tab._title;
container.setTitle(newTabTitle);
}
//viewAppt is the reference of the view
//Use this
viewAppts.query('#headerTitlebar')[0].setTitle('Title');
// Instead of this
this.getApptsHeaderTitlebar().setTitle('Title');
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 :)