I am trying to setup a localStorage to save the Authentication Token received from my REST service, but unfortunately i keep getting the error that functions related to the store does not exist:
TypeError: Ext.getStore is not a function
var test = Ext.getStore('myPhysioStorage');
My implementation:
store/UserStore.js
Ext.define('Physio.model.UserStore'), {
extend: 'Ext.data.Model',
config: {
fields: [
'sessiontoken'
]
}
});
model/UserStore.js
Ext.define('Physio.store.UserStore'), {
extend: 'Ext.data.Store',
requires: 'Physio.model.UserStore',
config: {
model: 'Physio.model.UserStore',
autoload: true,
storeId: 'myPhysioStorage',
proxy: {
type: 'localStorage',
id: 'myPhysioStorageProxy'
}
}
});
controller/Login.js
...
launch: function() {
var test = Ext.getStore('myPhysioStorage');
console.log(userStore);
}
...
app.js
Ext.application({
name: 'Physio',
views: ['Login','MainMenu'],
controllers:['Login','MainMenu'],
store:['UserStore'],
model:['UserStore'],
launch: function () {
Ext.Viewport.add([
{ xtype: 'loginview' },
{ xtype: 'mainmenuview' }
]);
}
});
Have you included your app.js and the sencha touch lib sencha-touch.js in your html page?
<script type="text/javascript" src="lib/sencha-touch/sencha-touch.js"></script>
<script type="text/javascript" src="app/app.js"></script>
Have you also added Ext.data.Store in the requires attribute in your Ext.application?
Ext.application({
name: 'name',
requires: [
'Ext.data.Store', 'some more'
],
....
});
Related
I want to clean up my code for better readability and put some code in extra js-files but nothing I've tried has worked.
It's a SubApp and part of a larger Project (Shopware) that is still using ExtJs 4.1.
I have a "main/window.js" that extends 'Ext.window.Window'.
initComponent looks like this:
initComponent: function () {
//...
me.dockedItems = [
me.createTopToolbar(),
];
//...
}
createTopToolbar is a Method inside "main/window.js" that return a Ext.toolbar.Toolbar with some elements.
My goal is to put this method in an extra file.
I tried to create a new static/singleton class like this
Ext.define('myapp.myplugin.view.main.Toptoolbar', {
singleton: true,
createTopToolbar: function(){
// ...
return toolbar;
}
But inside "main/window.js" i cannot call it using myapp.myplugin.view.main.Toptoolbar.createTopToolbar(), or main.Toptoolbar.createTopToolbar()
In app.js i tried to include it like this
views: [
'main.Window',
'main.Toptoolbar',
],
but it doesnt work.
I have no experience with ExtJs and search for hours...hope someone can help me.
Thank you
Edit
To answer the question why i'm building the toolbar within a function.
The whole functions looks like this:
createTopToolbar: function () {
var me = this;
var shopStore = Ext.create('Shopware.apps.Base.store.Shop');
shopStore.filters.clear();
shopStore.load({
callback: function(records) {
shopCombo.setValue(records[0].get('id'));
}
});
var shopCombo = Ext.create('Ext.form.field.ComboBox', {
name: 'shop-combo',
fieldLabel: 'Shop',
store: shopStore,
labelAlign: 'right',
labelStyle: 'margin-top: 2px',
queryMode: 'local',
valueField: 'id',
editable: false,
displayField: 'name',
listeners: {
'select': function() {
if (this.store.getAt('0')) {
me.fireEvent('changeShop');
}
}
}
});
var toolbar = Ext.create('Ext.toolbar.Toolbar', {
dock: 'top',
ui: 'shopware-ui',
items: [
'->',
shopCombo
]
});
return toolbar;
}
And i dont want the whole code inside my "main/window.js".
I'm not sure using the xtype solution provided by Jaimee in this context because i dont realy extend 'Ext.toolbar.Toolbar'. I just need a "wrapper" for my "shopCombo" code and return 'Ext.toolbar.Toolbar' with shopCombo as an item.
Create the toolbar as you would any other view, and create an 'xtype' to add it to your window.
Ext.define('myapp.myplugin.view.main.Toptoolbar', {
extends: 'Ext.toolbar.Toolbar',
xtype: 'mytoptoolbar',
dock: 'top',
ui: 'shopware-ui',
items :[
'->',
{
xtype: 'combobox',
name: 'shop-combo',
fieldLabel: 'Shop',
store: 'shopStore',
labelAlign: 'right',
labelStyle: 'margin-top: 2px',
queryMode: 'local',
valueField: 'id',
editable: false,
displayField: 'name',
listeners: {
'select': function() {
if (this.store.getAt('0')) {
me.fireEvent('changeShop');
}
}
}
}]
});
And then simply add it to your window's docked items like you would any other component:
initComponent: function () {
//...
me.dockedItems = [
{
xtype: 'mytoptoolbar'
}
];
//...
}
And the load listener can be added to the store.
Ext.define('Shopware.apps.Base.store.Shop', {
// ....
listeners:
{
load: function() {
Ext.ComponentQuery.query("combobox[name='shop-combo']")[0].setValue(...)
}
}
However, I'd suggest just setting a starting value for the combobox if it's a predictable value. You'll need to add the store to your controller's stores config if you haven't already.
You could use a factory pattern like so:
Ext.define('ToolbarFactory', {
alias : 'main.ToolbarFactory',
statics : {
/**
* create the toolbar factory
*/
factory : function() {
console.log('create the toolbar');
var toolbar = ....;
return toolbar;
}
}
});
Then you can create the Toolbar this way:
initComponent: function () {
//...
me.dockedItems = [
ToolbarFactory.factory();
];
//...
}
Depending on your build process you may need to add a requires statement.
fyi, this is my first Ext JS project and using ExtJS6
I created a main border layout and each view has its own controller.
From the west view controller, how do I call a method in the center controller.
Should I provide more info?
The concept is, one the west border I have a combobox. When the user selects a combobox it loads some stores with data. Now using those stores, I want to call some custom functions I build in the CENTER view controller. The reason they are built in the CENTER view controller is because they affect the grids that are sitting in the CENTER VIEW.
Here is my Main.js
Ext.define('ExtApplication1.view.main.Main', {
extend: 'Ext.container.Container',
xtype: 'app-main',
controller: 'main',
viewModel: {
type: 'main'
},
plugins: 'viewport',
requires: [
'ExtApplication1.view.main.Header',
'ExtApplication1.view.main.Footer',
'ExtApplication1.view.main.Panel',
'ExtApplication1.view.main.MainController',
'ExtApplication1.view.main.MainModel',
'ExtApplication1.view.mainmenulist.mainmenulist',
'ExtApplication1.view.clientdetails.clientdetails'
],
layout: {
type: 'border'
},
items: [{
region: 'center',
xtype: 'clientdetails', //should be maintable
title: 'Main Details Panel',
flex: 1
}, {
xtype: 'appheader',
region: 'north'
}, {
xtype: 'appfooter',
region: 'south'
}, {
region: 'west',
split: true,
collapsible: true,
title: 'Main Menu',
//flex: 2,
xtype: 'mainmenulist' // 'mainmenuv4view' 'mainmenuv3view'
}]
});
Here is my WEST region controller, I want to fire event on combobox selection after two different stores are loaded.
Ext.define('ExtApplication1.view.mainmenulist.mainmenulistController', {
extend: 'Ext.app.ViewController',
alias: 'controller.mainmenulist-mainmenulist',
onComboboxSelect: function (combo, record, eOpts) {
//load position store
//load market store
//calculate
var selectedCID = record.get('ClientID');
var targetGrid = Ext.getCmp('positionsGridID');
var targetStore = targetGrid.getStore();
//load positions store
targetStore.load({
params: {
user: 'xxx',
pw: 'xxx',
cid: selectedCID
},
//load market data
callback: function (records, operation, success) {
var targetGrid2 = Ext.getCmp('marketsGridID');
var targetStore2 = targetGrid2.getStore();
targetStore2.load({
params: {
user: 'stephen',
pw: 'forero',
cid: selectedCID
},
callback: function (records, operation, success) {
//Ext.Msg.alert('Status', 'Changes saved successfully.');
this.fireEvent('doSomething', 'arg1', 'arg2');
//ExtApplication1.app.getController('view.clientdetails.clientdetailsController').onClickCalculate();
}
});
}
});
}
});
here is my controller for CENTER region
Ext.define('ExtApplication1.view.clientdetails.clientdetailsController', {
extend: 'Ext.app.ViewController',
alias: 'controller.clientdetails-clientdetails',
init: function() {
this.listen({
controller: {
'*': { // This selector matches any originating Controller
doSomething: 'doSomething'
}
},
})
},
doSomething: function (param1, param2) {
Ext.Msg.alert('Status', 'Changes saved successfully.');
//alert("Param1: " + param1 + " Param2: " + param2);
},
In ExtJS6 you don't have to use the init function to add the listeners:
First Controller
Ext.define('AwesomeController', {
extend: 'Ext.app.ViewController',
alias: 'controller.awesome',
listen: {
controller: {
'amazing': {
amazingEvent: 'onAmazingEvent'
}
}
},
onAmazingEvent: function(controller, arg1, arg2) {
// ..
}
});
Second Controller
Ext.define('AmazingController', {
extend: 'Ext.app.ViewController',
alias: 'controller.amazing',
fooBar: function() {
// ..
this.fireEvent('amazingEvent', this, arg1, arg2);
}
});
Its recommended to add the event source to the event.
For further information on events read here: https://docs.sencha.com/extjs/6.0/core_concepts/events.html
One approach to doing this is to create a controller event. Emit this event from one controller, and listen for it in another controller. This creates looser coupling than directly calling methods on controllers.
For example:
Ext.define('app.controller.ControllerA', {
someMethod: function(){
this.fireEvent('doSomething', 'arg1', 'arg2');
}
});
Ext.define('app.controller.ControllerB', {
init: function() {
this.listen({
controller: {
'*': { // This selector matches any originating Controller
doSomething: 'doSomething'
}
},
})
},
doSomething: function(param1, param2){
alert("Param1: " + param1 + " Param2: " + param2);
}
});
You can do this in ExtJS 4+ I believe. There might be a better way to do it now with version 6, but I'm not sure.
I am trying to get this to work in Sencha Fiddle. The problem I am facing is that I get an error on this line
MyApp.app.getView('MyApp.view.test2').test();
When you click inside the textbox, it fails with an error (in console log) Uncaught TypeError: MyApp.app.getView(...).test is not a function
//Controller
Ext.define('MyApp.controller.test', {
extend: 'Ext.app.ViewController',
alias: 'controller.test',
myVar:0,
init: function() {
}
});
//View
Ext.define('MyApp.view.test', {
extend: 'Ext.form.field.Text',
alias:'widget.test',
controller: 'test',
title: 'Hello',
listeners: {
focus: function(comp){
MyApp.app.getView('MyApp.view.test2').test(); //Fails with an error that test is not a function }
},
renderTo: Ext.getBody()
});
//View
Ext.define('MyApp.view.test2', {
extend: 'Ext.form.Panel',
alias:'widget.test2',
title: 'Hello2',
renderTo: Ext.getBody(),
test:function()
{
alert('in MyApp.view.test2');
}
});
Ext.application({
name: 'MyApp',
launch: function() {
Ext.create('MyApp.view.test');
Ext.create('MyApp.view.test2');
}
});
The getView() function just returns the class and not the instance of the view. See ExtJs 5.1.1 Controller.getView() :
Returns a View class with the given name. To create an instance of the view, you can use it like it's used by Application to create the Viewport:
this.getView('Viewport').create();
To get the created view instance you can archive it with a Ext.ComponentQuery.
//query returns an array of matching components, we choose the one and only
var test2View = Ext.ComponentQuery.query('test2')[0];
// and now we can execute the function
test2View.test();
See the running minimalistic fiddle.
//View
Ext.define('MyApp.view.test', {
extend: 'Ext.form.field.Text',
alias: 'widget.test',
title: 'Hello',
listeners: {
focus: function (comp) {
//query returns an array of matching components, we choose the one and only
var test2View = Ext.ComponentQuery.query('test2')[0];
test2View.test();
//MyApp.app.getView('MyApp.view.test2').test();//Fails with an error that test is not a function
}
},
renderTo: Ext.getBody()
});
//View
Ext.define('MyApp.view.test2', {
extend: 'Ext.form.Panel',
alias: 'widget.test2',
title: 'Hello2',
renderTo: Ext.getBody(),
test: function ()
{
alert('in MyApp.view.test2');
}
});
Ext.application({
name: 'MyApp',
launch: function () {
Ext.create('MyApp.view.test');
Ext.create('MyApp.view.test2');
}
});
i am trying to load attribute values into an extjs store with the following code:
Ext.define('assert', {
extend: 'Ext.data.Model',
fields: [
{ name: 'id', mapping: '#id' },
{ name: 'test', mapping: '#test' },
{ name: 'name', mapping: '#name' }
]
});
var store = new Ext.data.Store({
model: 'assert',
proxy: {
type: 'ajax',
url : 'App/data/rules.xml',
reader: {
type: 'xml',
model:'assert',
record: 'assert'
}
}
});
but the store always shows up empty.
Heres a blanked out excerpt from the xml file:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="****" xmlns:axsl="****" xmlns:sch="*****" xmlns:iso="******" xmlns:xs="*****" xmlns:rule="******">
<title>test Schematron</title>
<pattern name="test Schematron">
<rule context="*****" name="*****">
<assert test="*****" diagnostics="*****" name="*****" id="****" comment="" uval="" source="****"/>
<assert test="******" diagnostics="****" name="****" id="***" comment="" uval="" source="*****"/>
</rule>
</pattern>
</schema>
Im very new to reading XML files to ExtJS, so it would be great if one of you could
show me the proper way to map those attributes.
There's nothing wrong with your XML file. Your problem is that ExtJS stores don't Load data on automatically on creation by default. You have to either enable the autoLoad or load the Store manually with the load function:
Ext.define('assert', {
extend: 'Ext.data.Model',
fields: [
{ name: 'id', mapping: '#id' },
{ name: 'test', mapping: '#test' },
{ name: 'name', mapping: '#name' }
]
});
var store = new Ext.data.Store({
model: 'assert',
autoLoad: true, // The store will start loading as soon as the framework is ready.
listeners: {
load: function(){ // This gets executed when your store is done loading.
console.log('Loaded!!');
}
},
proxy: {
type: 'ajax',
url : 'data/rules.xml',
reader: {
type: 'xml',
model:'assert',
record: 'assert'
}
}
});
Ext.onReady(function(){
console.log('Ready!!');
store.load({ // This works too!
scope: this,
callback: function(records, operation, success) {
console.log('loaded records!!');
}
});
});
Remember that the load is asynchronous and you have to wait until the load is done to be able to use the data!
I recommend that you check the API doc too see all that you can do with the load function.
extjsjavascript
T writing code using ExtJS4.0.1, MVC architecture. And when I develop main form I meet problem with search extension for web site.
When I was trying to create new widget in controller, I need render result in subpanel. and so when I write sample code I meet following problem:
**Uncaught TypeError: Object [object Object] has no method 'setSortState'**
I cannot understand why it gives that error message. I need some help to resolve that problem.
Below I want to show my code:
//Panel which is showing to user
Ext.define('Semantics.view.main.menuView', {
extend: 'Ext.panel.Panel',
layout: 'fit',
alias: 'widget.Menu',
title: "",
tbar: [
{
//search field
name:'mainSearchText',
id:'mainSearchText',
xtype: 'textfield',
defaultValue: 'Search',
height: 20
},
{
name:'mainSearchButton',
id:'mainSearchButton',
xtype: 'button',
text: 'Find',
height: 20
}
]
});
//controller for search request
Ext.define('Semantics.controller.main.mainController', {
extend: 'Ext.app.Controller',
views: ['main.menuView','mainSearch.MainSearchResultForm'],
refs: [
{ ref: 'menuPanel', selector: 'Menu' },
{ ref:'mainSearchText',selector:'#mainSearchText'},
{ref: 'mainSearchForm',selector:'#mainSearchForm'},
{ref:'MainSearchGrid',selector:'#MainSearchGrid'}
],
init: function () {
this.control({
'Menu': {
render: this.onPanelRendered
},
'Menu button[name="mainSearchButton"]': {
click: this.onButtonClick
}
});
},
onButtonClick: function (button) {
var me = this;
if(button.name=="mainSearchButton") {
var mtextFiled = me.getMainSearchText().getValue();
console.log(mtextFiled);
Ext.Ajax.request({
scope: this,
url: 'app/mainSearchT/findText/',
method: 'POST',
params: {
text: me.getMainSearchText().getValue()
},
success: function (result) {
mainPanel = me.getMenuPanel();
mainPanel.removeAll(true);
loadingMask = new Ext.LoadMask(mainPanel, { msg: "Loading" });
loadingMask.show();
var mname = 'MainSearchResultForm';
var start_info_panel = Ext.widget(mname);
mainPanel.items.add(start_info_panel);
loadingMask.hide();
mainPanel.doLayout(); //that line gives that error
},
failure: function (result) {
console.log(result);
}
});
}
},
onPanelRendered: function () {
}
});
I encountered the same error when I included unsupported xtype in Ext.grid.Panel columns. I had to remove the xtype, which resolved the problem.