Implementing a Routing system for my Views (ExtJS) - extjs

I want to implement a route for my basic view in ExtJS so that when display it (on a button click) the URL changes and when i want to return back to the initial view it works by displaying the right view.
Giving my view class :
Ext.define('Traccar.view.newDashboard', {
extend: 'Ext.Container',
alias: 'widget.newDashboard',
id: 'geoAfricaDashboard',
routes : {
'dashboard' : ''
},
layout: {
type: 'border',
align: 'stretch '
},
height: 620,
style: {
'backgroundColor': '#909090 !important'
},
items: [{
// xtype: 'panel' implied by default
title: 'Geo-Africa Administration',
region: 'west',
xtype: 'panel',
//margin: '5 0 0 5',
width: 200,
collapsible: true, // make collapsible
id: 'west-region-container',
layout: 'fit',
items: [{
xtype: 'treelist',
store: {
root: {
expanded: true,
children: [{
text: 'Options',
leaf: true,
iconCls: 'fas fa-address-book'
}, {
text: 'Administration',
expanded: true,
iconCls: 'far fa-id-badge',
children: [{
text: 'Configuration',
leaf: true,
iconCls: 'fas fa-address-card'
}, {
text: 'User',
leaf: true,
iconCls: 'fas fa-child'
}]
}]
}
},
renderTo: Ext.getBody()
}]
}, {
xtype: 'basic-panels'
// width: '100%'
}]
Which i render on button click like so :
var dash = Ext.create('widget.newDashboard', {
renderTo: Ext.getBody(),
hideMode: 'visibility'
});
dash.show();
How can i assign a route URI to that view in ExtJS (6.2.0)?
Thank you for the great help ?
PS : i tried with
routes : {
'dashboard' : ''
},
or else this.redirectTo("dashboard"); But neither works.

The route is similar to firing an event. The end result is a function is called. The hash is passed to the function based on how the route is setup. You can either call a different function for each hash or you can use the hash, or other parts of the URI to determine what to do.
Router Documentation This web page describes how the router is used. It is a very quick read.
A common way the examples (admin dashboard, coworkee app) do it by having the hash be the xtype for the panel (view) you want to display.
So your main panel extends 'Ext.navigation.View'. Then based on the hash you create a new instance of the view, add it to the main panel and make it the active item. You can also check to see if the xtype has already been added to the navigation view and just make it the active panel.
Fiddle showing use of router (this is not mine). Here is a fiddle that shows how to use a router. I would recommend reading the docs first. THe sencha docs are actually pretty good and you can learn how to use the Extjs library as it was intended and really speed up your development.

Related

How to make title binding in tabpanel tabs work in ExtJS7?

Using ExtJS7.x with the modern toolkit.
For various reasons, I'm trying to data-bind the titles of panels in a TabPanel, this seems to work fine, if not for a single caveat. The binding only applies as soon as the tab becomes active. Trawling around the official forums I found that this was previously marked as a bug in ExtJS6 years ago, and was reported as being fixed. And yet I still run into similar behavior in 7.
Basic overview of what I'm trying to do:
{
xtype: 'tabpanel',
defaults: {
iconAlign: 'left',
},
items: [
{
xtype: 'panel',
border: true,
padding: 5,
iconCls: 'x-fa fa-ellipsis-v',
title: 'Overview',
bind: {
title: '{anonymous.overview.title}'
}
},{
xtype: 'panel',
iconCls: 'x-fa fa-envelope-open',
bind: {
title: 'Test'
}
}, {
xtype: 'panel',
reference: 'auditgrid',
iconCls: 'x-fa fa-clipboard-list',
title: 'Audits',
}
]
}
Available here in fiddle format.
Binding a hard-coded string here for testing purposes. It'll be a more variable string eventually, but I was trying to figure out if it was an issue with the timing of the data being available in the ViewModel since the strings get loaded from an external source (doesn't seem to be)
The first tab correctly has it's title overwritten by the data in the binding, as it is automatically activated. The second one however, just has an icon and no title, until it is clicked.
I've tried to sneakily force all panels to activate in a beforeShow event handler, but this doesn't trigger the binding. Which leads to the question. Does anyone have a reasonable workaround or fix for this issue? I've tried to reverse-engineer the override provided for ExtJS6, but haven't had any luck making it work.
Or am I just being a dingus and am I doing something wrong here?
Try to use tab config property to bind the title, something like this:
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.Viewport.add({
xtype: 'tabpanel',
viewModel: {
data: {
someTabTitle: 'Some Tab Title'
}
},
defaults: {
iconAlign: 'left',
},
items: [{
xtype: 'panel',
border: true,
padding: 5,
iconCls: 'x-fa fa-ellipsis-v',
title: 'Overview',
bind: {
title: 'Test 1'
}
}, {
xtype: 'panel',
iconCls: 'x-fa fa-envelope-open',
tab: {
bind: {
title: '{someTabTitle}'
}
}
}, {
xtype: 'panel',
reference: 'auditgrid',
iconCls: 'x-fa fa-clipboard-list',
title: 'Audits',
}]
});
}
});

How to remove active tab from Tab in Ext js?

I want to remove the active tab from sencha ext.
Assume that am into controller file of the view.
Note: I have used remove() as well as destroy().
destroy() function works fine but tab header is not getting removed.
coseResultTab() {
this.getView().destroy();
}
Before Clicking on Cancel button:
After Clicking on Cancel button
You should destroy the active tab in your tabpanel, eg:
Controller
Ext.define('MyViewController', {
extend: 'Ext.app.ViewController',
alias: 'controller.myview',
destroyTab: function() {
this.getView().down('tabpanel').getActiveTab().destroy();
}
});
View
Ext.create('Ext.Panel', {
width: 400,
height: 400,
renderTo: document.body,
title: 'Panel',
id: 'myPanel',
controller: 'myview',
items: [{
xtype: 'tabpanel',
items: [{
title: 'Foo',
items: [{
xtype: 'button',
text: 'Destroy!',
handler(btn) {
Ext.getCmp('myPanel').getController().destroyTab();
}
}]
}, {
title: 'Bar',
items: [{
xtype: 'button',
text: 'Destroy!',
handler(btn) {
Ext.getCmp('myPanel').getController().destroyTab();
}
}]
}]
}]
});
Fiddle
I enhanced the answer from Matheus to meet the requirement a bit more:
not destroying the entire tab, but only the content
setting the button handler without the use of getController (please try not to use this, as it is considered bad practice by Sencha)
removed the outer panel which only added a title
Fiddle
You can also remove it using the tab bar using closeTab() which pretty much just runs a tabs.remove(tabRefOrObj);
https://docs.sencha.com/extjs/6.5.3/modern/Ext.tab.Bar.html#method-closeTab

ExtJS - xtype 'breadcrumb': change items and style in selectboxes and in breadcrumb text list

I have a directory (folder) structure, which I show with the xtype 'breadcrumb' (ExtJS Version 6.6).
Now I will add a additional toggle in my app. When I active the toggle, all folders should be shown in the breadcrump text list and in the selectboxes. This is my actual developing status and works fine.
When I deactive the toggle, all folders with a leading "A" in the folder name should be hide in the selectboxes (or should be disable and shown grayed out). In the breadcrump text list this ("A"-)folders should be shown grayed out.
For example I have the breadcrump text list "root > folder_0_0 > folder_1_0" in my app and then I change the toggle value: Then I do not want to reload the complete breadcrump.
How can I resolve this problem? Thank you for your hints Thomas
here is my code. You can find this: https://fiddle.sencha.com/#view/editor&fiddle/2mqb
Ext.application({
name: 'BeadcrumbTest',
launch: function() {
var store = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
text: 'Root_folder',
children: [{
text: 'A_folder',
leaf: true
}, {
text: 'B_folder',
expanded: true,
children: [{
text: 'A_folder',
leaf: true
}, {
text: 'B_folder',
leaf: true
}]
}, {
text: 'C_folder',
leaf: true
}]
}
}),
panel = Ext.create('Ext.panel.Panel', {
renderTo: Ext.getBody(),
width: 400,
height: 100,
bodyPadding: 10,
tbar: {
xtype: 'breadcrumb',
store: store
},
buttons: ['->', {
xtype: 'button',
text: 'Handle "A" folder',
handler: function() {
// todo
}
}]
});
}
});
I found a solution: I overwrite the methods updateSelection(), _onMenuClick() and _onMenuBeforeShow() from classic/src/Breadcrumb.js.

How to Abstract a base container with some default items in Sencha Extjs 6?

I was trying to develop a base container by extending Ext.Container, which have some default items in it. A subclass should add the items to the child component of the base class and not directly to the container instead. How to do this?
May i override the setItems/applyItems method to add the items to navigationView.add(items); ?? I'm unsure about how this works. Since i'm new to ExtJs, unable to identify which is the way to do it generically so that it won't affect my subclass to add n number of items to it either using inline or add(item) method.
AbstractClass
Ext.define('MyApp.container.AbstractMainContainer', {
extend: 'Ext.Container',
xtype: 'abstractmaincontainer',
requires: [
'MyApp.container.NavigationView',
'MyApp.control.NavigationBar'
],
config: {
layout: {
type: 'vbox',
pack: 'start',
align: 'stretch'
},
flex: 1,
height: '100%',
width: '100%'
},
controller: 'maincontroller',
items: [{
xtype: 'navbar',
itemId: 'navbar'
}, {
xtype: 'navigationview',
itemId: 'navigationview',
reference: 'navigationview',
navigationBar: false,
layout: {
pack: 'start',
align: 'stretch'
},
flex: 1,
height: '100%',
items: [
// new item should added here
]
}],
/**
* #method getContentView add the items to this rather than directly
* #return {void}
*/
getContentView: function() {
return this.down('#navigationview');
},
});
SubClass
Ext.define('MyApp.main.view.MainContainer', {
extend: 'MyApp.container.AbstractMainContainer',
requires: [
'MyApp.container.AbstractMainContainer'
],
config: {
},
items: [{
// we should not directly add items here this will remove the navbar and navigation view
// HOW TO ADD THIS IN A GENERIC WAY??
xtype: 'container',
layout:{
type:'card'
},
items: [{
xtype: 'button',
role: 'nav',
title: 'Card 1',
text: 'go to next',
handler: function() {
}
}, {
itemId: 'myCard',
title: 'Card 2',
html: '<h1>Card 2</h1>'
}],
}],
});
AFAIK, there's no "automatic" way to do it.
I can suggest some approaches:
First of all, check if you really need to do this: for example, you could move the navbar to the dockedItems config and move the navigationview one level up.
So your AbstractContainer will extend navigationview, navbar will be a dockedItem, and you will be able to use the items config as usual.
Otherwise, you could use a different config (let's say "extraItems" or "navItems"), and merge them overriding the abstract class initComponent function.
There, after a callParent that actually initialize the navigationview, you could do something like
this.down('navigationview').add(this.extraItems);

Adding Ext.Menu to the viewport in Sencha Architect

I am making a basic application in Sencha Architect 3, and trying to add a menu button in the style of touch-tomatoes http://docs.sencha.com/touch/2.3.0/touch-build/examples/touchtomatoes/index.html
The code for adding the menu in the Touch Tomatoes project is an addition in the app.js file of Sencha Touch project as below, but I am unable to figure out how to do this in Sencha Architect, as it says that the app.js file would be over-ridden each time the project is saved
Ext.application({
name: 'TouchTomatoes',
requires: ['Ext.device.Storage','Ext.Menu', 'TouchTomatoes.components.MenuButton'],
controllers: ['TouchTomatoes.controller.Main'],
views: ['TouchTomatoes.view.Main', 'TouchTomatoes.view.WelcomeOverlay'],
launch: function() {
Ext.getBody().removeCls('loading');
Ext.create('TouchTomatoes.view.Main');
if (Ext.device.Storage.getItem('isFirstTime') !== "false") {
Ext.device.Storage.setItem('isFirstTime', false);
var overlay = Ext.create('TouchTomatoes.view.WelcomeOverlay');
Ext.Viewport.add(overlay);
overlay.show();
}
var menu = Ext.create("Ext.Menu", {
defaults: {
xtype: "menubutton"
},
width: '80%',
scrollable: 'vertical',
items: [
{
text: 'Opening',
iconCls: 'time',
menu:"opening"
},
{
text: 'Theatres',
iconCls: 'locate',
menu: "theatres"
},
{
text: 'Upcoming',
iconCls: 'team',
menu:"upcoming"
},
{
text: 'Top',
iconCls: 'bank',
menu:'top'
},
{
text: 'Search',
iconCls: 'search',
menu:"search"
}
]
});
Ext.Viewport.setMenu(menu, {
side: 'left',
reveal: true
});
}
});
You already have launch defined, so simply paste your two statements within it within architect.
In architect,
click on Application in the inspector
click on the launch action in the config pane to bring it up in the editor (Or, if you don't have launch defined, click on the + icon next to launch in the Config pane to add it.)
paste your code into the editor beneath your overlay code:
var menu = Ext.create("Ext.Menu", {
defaults: {
xtype: "menubutton"
},
width: '80%',
scrollable: 'vertical',
items: [
{
text: 'Opening',
iconCls: 'time',
menu:"opening"
},
{
text: 'Theatres',
iconCls: 'locate',
menu: "theatres"
},
{
text: 'Upcoming',
iconCls: 'team',
menu:"upcoming"
},
{
text: 'Top',
iconCls: 'bank',
menu:'top'
},
{
text: 'Search',
iconCls: 'search',
menu:"search"
}
]
});
Ext.Viewport.setMenu(menu, {
side: 'left',
reveal: true
});
You'll end up with exactly the code you listed above, and it wont be overwritten since it's part of the app's config.
Be aware that, since you include an xtype of 'menubutton,' that you'll have to create a button at the class level and give it a userAlias of 'menubutton,' or the app will throw an error stating, roughly, "I can't create widget with xtype.menubutton."

Resources