ExtJs4 dynamically load items in a toolbar - javascript

How can I dynamically load items in an ExtJs 4 toolbar ? I want to load the items from JSON.
I have tried the loader, but it just became headache.
Ext.define('Backend.view.Nav' ,{
alias: 'widget.Nav',
extend: 'Ext.toolbar.Toolbar',
initComponent: function() {
this.items = [
{
iconCls: 'freewinder',
text: 'Freewinder'
},
{
iconCls: 'application',
text: 'Applikationen',
xtype: 'splitbutton'
},
{
iconCls: 'component',
text: 'Komponenten',
xtype: 'splitbutton'
},
'-',
{
emptyText: 'Suche ...',
xtype: 'textfield'
}];
this.callParent(arguments);
}
});

You can use add method of Ext.toolbar.Toolbar to add items dynamically after the toolbar has been constructed: http://docs.sencha.com/ext-js/4-0/#!/api/Ext.toolbar.Toolbar-method-add
How do you want it to work? Should the toolbar appear, make an AJAX request and them add the menu items -- or should the server upon page load give the client-side app some JSON that contains the menu items or how do you want it to work exactly?
In case of the server outputting JSON on page load you can just do this.items = jsonItems.

Related

Sencha: How to use data from one file to another

Im new at this sencha thingy and im trying to experiment a bit with it. I've been making some very simple tests and now i've reached the point where i want to pass the data from one file to another. To make it easier to understand im trying to get the data from the following text box to make a simple filter tool.
the textfield has been created in the following piece of code in the file Filters.js
Ext.define('Prj01Filtro.view.main.Filters', {
extend:'Ext.form.Panel',
xtype: 'Filters',
alias: 'form.formFilter',
requires: [
'Prj01Filtros.view.main.FilterController'
],
controller: 'controllerFilter',
items:[
{
margin: '0 0 10 0',
buttons: [
{
xtype: 'textfield',
fieldLabel: 'Filter',
name: 'textFieldSearch'
}, {
name: 'buttonSearch',
text: 'Buscar',
listeners: {
click: 'onClickFilter'
}
}, {
name: 'buttonRemoveFilter',
text: 'X',
listeners: {
click: 'onClickRemove'
}
}
]
}
]
The code of the buttons have been located in a file named FilterController.js
Ext.define('Prj01Filtros.view.main.FilterController',{
extend: 'Ext.app.ViewController',
alias: 'controller.controllerFilter',
onClickFilter: function() {
//Code to apply the filter
},
onClickRemove: function() {
//code to remove the filter
}
})
Finally the code of the table is located in a file named List.js
Ext.define('Prj01Filtros.view.main.List', {
extend: 'Ext.grid.Panel',
xtype: 'mainlist',
plugins: 'gridfilters',
requires: [
'Prj01Filtros.store.Personnel'
],
title: 'Personnel',
store: {
type: 'personnel'
},
columns: [
{ text: 'Name', dataIndex: 'name', align: 'left', filter: {
type: 'string'
}},
{ text: 'Email', dataIndex: 'email', flex: 1, align: 'left', filter: {
type: 'string'
}},
{ text: 'Phone', dataIndex: 'phone', flex: 1, align: 'left', filter: {
type: 'string'
}},
],
listeners: {
select: 'onItemSelected'
},
});
So my goal is to make a function in FilterController.js that can be called from Filters.js which sets the value for the filters applied in the columns of List.js but im kind of stuck on how to set the value property for the filter from the function that i have created. If someone knows how to do it i would appreciate the help. Thanks!
I've tried many things but since im new to sencha im pretty much sure that they were incorrect anyways.
I suggest to study View Models & Data Binding and ViewModel Internals sections of Ext JS documentation. These are among the most powerful features of Ext JS so it good to develop a deep understanding.
For you current question, you need to access the store behind your List view to manage the filters, not the list itself. Once you get the store, you can set / clear the filters with setFilters and clearFilter methods on the store:
store.setFilter([{
property: 'email',
value: '<search term here>',
operator: 'like'
}]);
store.clearFilter();
To easily access the store, define the store in the view model of a view that is above both List and Filters view. This is the important part because this way you can take advantage of inheriting the view model from the container parent. Let's say you have a panel which contains both List and Filters. Define the store in the view model:
stores: {
personnel: {
type: 'personnel'
}
}
Use bind config when assigning the store in your List:
Ext.define('Prj01Filtros.view.main.List', {
...
bind: {
store: '{personnel}'
}
...
});
After all this, you can access the store from the Filters view controller's methods:
onClickFilter: function() {
this.getViewModel().getStore('personnel').setFilters(...);
}
You need the get the value the user entered into the field. You can access it from the controller with querying the textfield component, but you can also do it with the view model.

JS console error shows Extjs trying to make a GET request for a class as if it was a file

Sorry if the title isn't the best.
I'm roughing out a test project in Extjs 6. I have a viewmodel class that uses a store called customers:
Ext.define('ChildSessionBinding.view.main.ChildSessionModel',{
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.binding.childsession',
requires:[
'Ext.data.Store',
'ChildSessionBinding.model.Customer'
],
stores:{
customers:{
model: 'ChildSessionBinding.model.Customer',
autoLoad: true,
session: true
}
}
});
The model it requires has hard coded test data in it:
Ext.define('ChildSessionBinding.model.Customer', {
extend: 'Ext.data.Model',
fields: [
{ name: 'name', type: 'auto' },
{ name: 'phone', type: 'auto' }
],
data:[
{name: 'test', phone: '12345'}
]
});
And the view that uses the ViewModel is just a panel that shows a simple grid:
Ext.define('ChildSessionBinding.view.main.ChildSession', {
extend: 'Ext.panel.Panel',
xtype: 'binding-child-session',
title: 'Binding Child Session Demo',
layout: {
type: 'vbox',
align: 'stretch'
},
viewModel: {
type: 'binding.childsession'
},
controller: 'binding.childsession',
session: true,
items:[
{
flex: 1,
xtype: 'grid',
bind: '{customers}',
columns:[
{
dataIndex: 'name',
flex: 1,
text: 'Name'
},
{
dataIndex: 'phone',
flex: 1,
text: 'Phone'
},
{
xtype: 'widgetcolumn',
width: 90,
widget: {
xtype: 'button',
text: 'Edit',
handler: 'onEditCustomerClick'
}
}
]
}
]
});
When I load this in the browser, the grid does not load. I popped open the javascript console and saw that it was trying to make a get request to the server using the model's fully qualified name:
I've compared it to the kitchen sink example I'm trying to duplicate as well as other viewmodel stores that I've created in other projects and I don't see anything that would cause this.
Also, to rule out any project file structure questions, here's the folder/file structure:
EDIT
Here's the stack trace from the javascript console:
Anyone see the problem?
Put the data in your store, not in your model. Model doesn't have a data property.
I haven't used much of Ext 5 or 6 but I think I have seen this error on Ext 4. If a required class is undefined during the time of a class definition Ext will try to load a file with that name at the root of your application. I think that Ext should be throwing an error here by default instead of trying to load a file since I assume that most applications are not set up to handle this.
The fix would be to have ChildSessionBinding.model.Customer defined and executed before you load ChildSessionBinding.view.main.ChildSessionModel or have your application be able to load that file where Ext expects it to be.

Having issue to load multiple tabs and/or their views in mobile web app

I am making a mobile app using sencha touch. What this app does it when user is logged in then he/she sees home view. On this home view there are two buttons. These two buttons takes user to their respective views i.e. Appointments and Messages. These two views have three tabs button at the bottom i.e. Home, Appointments, Messages. Home button takes user back to the home view which consists of two buttons. Whereas Appointments and Messages buttons takes him to their own views.
Here is my home view
As you can see there are no tabs in this view. Following is the code for this view
config: {
layout: {
type: 'vbox'
},
items: [
{
xtype: 'titlebar',
title: 'Home',
docked: 'top'
},
{
xtype: 'button',
cls: 'messagesBtn',
itemId: 'msg'
},
{
xtype: 'button',
cls: 'appointmentsBtn',
itemId: 'appoint'
}
],
listeners: [
{
delegate: '#appoint',
event: 'tap',
fn: 'launchAppointmentView'
}
]
},
launchAppointmentView: function () {
this.fireEvent('launchAppointments');
}
Once user clicks on lets say Button 2 which take him to Appointments View. Then following is view is shown to him
and the code for this view below
config: {
tabBarPosition: 'bottom',
items: [
{
title: 'Appointments',
iconCls: 'home',
styleHtmlContent: true,
scrollable: true,
items: {
docked: 'top',
xtype: 'titlebar',
title: 'Appointments'
},
html: ["Appointments View"].join("")
}
]
}
Once this view is loaded then all I can see is only one tab for Appointments. I want to see three tabs for this all three views. How can I make other tabs visible?
Following is my messages view
Here is the code for it
config: {
tabBarPosition: 'bottom',
items: [
{
title: 'Messages',
iconCls: 'home',
styleHtmlContent: true,
scrollable: true,
items: {
docked: 'top',
xtype: 'titlebar',
title: 'Messages'
},
html: ["Messages View"].join("")
}
]
}
I cannot see this view and cannot get to this view at all because I do not have messages button on the tab. Again how can I add all the tabs button for these views and when I click each of them so it will take me to its view?
Here is an example of a tab panel:
Ext.create('Ext.TabPanel', {
fullscreen: true,
tabBarPosition: 'bottom',
defaults: {
styleHtmlContent: true
},
items: [
{
title: 'Home',
iconCls: 'home',
html: 'Home Screen'
},
{
title: 'Contact',
iconCls: 'user',
html: 'Contact Screen'
}
]
});
The issue is, you haven't added addition items to you items list - they have to tabs, Home and Contact. You want 3 tabs per screen, so you would have 3 items per file.
For events, I like to create a controller, have refs for each item you need to listen for events on, and set up controls for each. Let me know if you'd like help working through how to do that. I'll include a simple example below to get you started:
Ext.define('Analytics.controller.events.InstType', {
extend: 'Ext.app.Controller',
config: {
refs: {
instType: {
selector: '#instType'
}
}
},
init: function() {
// Start listening for toggle events on the 3 segmented button panels
this.control({
'instType': { 'toggle': function(container, button, pressed) {
this.onGraphType(container, button, pressed);
}
}
});
},
// note: these functions are called on both the buttons selected and the one that became unselected
// the 'pressed' param inidicates whether this is the selected button or not.
onGraphType: function (container, button, pressed) {
if (pressed) { ..do stuff.. }
});

Sencha Touch: Dynamically change Stores with one List

So, I'm trying to write a little MVC application which uses lists a lot.
I have one view which consists of a Panel with Toolbar docked to top and List:
app.views.SalonListView = Ext.extend(Ext.Panel, {
layout: 'card',
cardSwitchAnimation: 'slide',
dockedItems: [
{
xtype: 'toolbar',
dock: 'top'
}
],
items: [
{
xtype: 'SalonList',
id: 'salon-list'
}
]
});
Ext.reg('ListView', app.views.SalonListView);
I have an xtype for list defined in another file:
app.views.SalonList = Ext.extend(Ext.List, {
layout: 'card',
itemTpl: // some tpl is here
});
Ext.reg('SalonList', app.views.SalonList);
As you may notice, I don't set the Store for my List.
What am I trying to achieve is to set store in any Controller I use with this view.
Something like:
salonList: function() {
app.stores.SalonStore.read();
this.salonsView = this.render({
xtype: 'SalonListView',
// so I need to set store for the list somewhere around here
});
}
Is there any possibility I can set the Store for the List dynamically?

How to implement this custom grid in ExtJS?

I am new to ExtJS. Currently I have grid implemented as shown below.
But I want to show the same information in a different way like showing in boxes, as shown below. How do I implement this?
You haven't specified which version of Ext JS you are using. So, will give you solution for both versions:
In ExtJS 3.x
You can make use of the Ext.DataView class. Here is an example of dataview. Even though the example makes use of the images, you can easily modify the view, but changing the template. Now, you have to work on the pagination bar. You will have to make use of the bbar property and create a toolbar. This toolbar will have your navigation buttons. So, you will have something like this:
var panel = new Ext.Panel({
id:'person-view',
frame:true,
title:'User Grid',
bbar: [{
text: Prev,
iconCls: 'prev-icon'
},{
text: Next,
iconCls: 'next-icon'
}],
items: new Ext.DataView({
store: yourStore,
tpl: yourTemplate,
autoHeight:true,
multiSelect: false,
overClass:'x-view-over',
itemSelector:'div.thumb-wrap',
emptyText: 'No users to display',
})
});
[Obviously, the above code is not complete. You will have to add your store, template, other properties and event listeners according to user needs.]
In ExtJS 4.x
You will have to make use of Ext.view.View class. Here is a skeleton code:
Ext.define('MyApp.view.members.Display',{
extend: 'Ext.panel.Panel',
alias : 'widget.memberslist',
initComponent: function() {
this.template = Ext.create('Ext.XTemplate',
'<tpl for=".">',
'<div class="member">',
'Name : {name} <br/>',
'Title : {title}',
'</div>',
'</tpl>'
);
this.store = Ext.create('MyApp.store.Members');
this.bbar = this.buildToolbar();
this.items = this.buildItems();
this.callParent(arguments);
},
buildItems: function() {
return [{
xtype: 'dataview',
store: this.store,
id: 'members',
tpl: this.template,
itemSelector: 'div.member',
overItemCls : 'member-hover',
emptyText: 'No data available!'
}]
},
buildToolbar : function() {
return [{
text: 'Previous',
action: 'prev'
},{
text: 'Next',
action: "next"
}];
}
});
The above code makes use of the new MVC architecture. You will have to add the event listeners etc in your controller.

Categories

Resources