Mixing configuration objects and Ext.create defined objects creates unclickable panel - javascript

If I have an application which contains panels created with Ext.create, and those panels have items which are created with both Ext.create and configuration objects, I get a panel whose interface is completely unclickable and doesn't respond to any interaction.
I've create a sample JSFiddle which illustrates the issue. Click the "TEST" button to see an example of this failure.

You can't do component creation at class definition time. That is, using Ext.create directly inside config object of Ext.define:
Ext.define('App.views.Panel1', {
id:'panel1',
extend:'Ext.Panel',
config:{
title: 'test',
layout:'card',
items:[
{
items:[
{
xtype: 'button',
text: 'TEST',
handler:function(){
Ext.getCmp('panel1').setActiveItem(Ext.getCmp('panel2'));
}
}
]
},
// not good
Ext.create('App.views.Panel2', {id:'panel2'})
]
}
});
Even if this would work, it would result in all instances of Panel1 sharing one Panel2 instance.
Instead you should do your component creation at initialization time:
Ext.define('App.views.Panel1', {
id:'panel1',
extend:'Ext.Panel',
config:{
title: 'test',
layout:'card',
items:[
{
items:[
{
xtype: 'button',
text: 'TEST',
handler:function(){
Ext.getCmp('panel1').setActiveItem(Ext.getCmp('panel2'));
}
}
]
}
]
},
initialize: function() {
this.add(Ext.create('App.views.Panel2', {id:'panel2'}));
this.callParent();
}
});
The initialize method is a good place to do any kind of extra work you want to do every time you create an instance of your component class. callParent is there because we override initialize of a parent class which might have some of its own logic in there which we want to keep.

Related

Adding 2 weeks view in Calendar ExtJs 6

I want to add 2 weeks view in Calendar but so i have failed to do that. That my code so far, its not displaying the calendar giving following error:
Uncaught TypeError: view.getView is not a function
at constructor.recalculate (Multi.js?_dc=20180710185310:227)...
{
[...]
day: {
addForm: null,
editForm: null,
listeners: {
eventtap: 'onEventClick',
//click: 'onDayClick'
}
},
week: {
xtype: 'calendar-week'// This shows the one week view
},
weeks:{
xtype: 'calendar-weeksview'// but this give error
}
},
bind: {
store: '{calendars}'
}
You always have to use great care with components that are two components underneath - which, like grids, are composed from one panel and one view.
xtype: 'calendar-weeksview' is not in the same folder as xtype: 'calendar-week', while xtype: 'calendar-weeks' is. You may want to try that.

Binding a Simple Viewmodel with Single Record

I created this fiddle showing what I want to do.
Basically, I configured a Store that loads only a single record (it reality it will be the currently signed in user). However, I can't seem to bind anything to that store properly. How can I get that {u.name} to output properly?
Here is the code:
Ext.define('User', {
extend: 'Ext.data.Model',
fields: ['id', 'name']
});
Ext.application({
name : 'Fiddle',
launch : function() {
new Ext.Component({
renderTo: Ext.getBody(),
viewModel: {
stores: {
u: {
proxy: {
type: 'ajax',
url: 'user.json'
},
model: 'User',
autoLoad: true
}
}
},
bind: 'Test name: {u.name}'
});
}
});
Try bind: 'Test name: {u.data.items.0.name}'
UPD:
As an explanation to this - u is an object with its properties, so trying to bind to u.name will actually bind to the name property of the store. Wile the store has no name property it will always be null. Store's received data is placed in data property. Items property contains a raw array of received data and so on.
In your fiddle you're using a store while it looks like you need just a single record.
Using links instead of stores should work better, like:
links: {
u: {
type: 'User',
id: 1
}
}
Working example based on your code: https://fiddle.sencha.com/#fiddle/uuh

Remember selectfield sencha touch

How to store the selectfield in sencha touch, such that when a field is selected, the value used by any method, but when the page refreshed, it is automatically select the previous selection.
My Code:
{
xtype: 'fieldset',
items: [{
xtype: 'selectfield',
id: 'remem',
label: 'MY Label',
store: 'remem',
options: [
{
text: 'Option1',
value: 'a'
},
{
text: 'Option2',
value: 'b'
}]
}]
}
#developer, #jenson and I are suggesting you should save the value in a cookie so the value is persisted between browser refreshes. Extjs offers a cookie manager class in the utilities namespace if I remember correct.
EDIT
For Sencha Touch you should actually make use of the LocalStorage proxy as per the docs here
There's an example in the docs showing how to save user specific information for retrieval later on (after refreshes, etc)
I have actually made use of this for my own application by saving user display preferences in my application so when they next login the UI is as they left it.
Store:
Ext.define('MyApp.store.UserPreferencesStore', {
extend: 'Ext.data.Store',
requires: [
'MyApp.model.UserPreferencesModel',
'Ext.data.proxy.LocalStorage'
],
config: {
model: 'MyApp.model.UserPreferencesModel',
storeId: 'UserPreferencesStore',
proxy: {
type: 'localstorage',
id: 'userpreferences'
}
}
});
Model
Ext.define('MyApp.model.UserPreferencesModel', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.Field'
],
config: {
fields: [
{
name: 'userPrefKey'
},
{
name: 'userPrefValue'
}
]
}
});
With this setup you can add a record as you normally would do for any other store
store.add({userPrefKey: '01-showMap', userPrefValue: true});
or edit existing entries
rec = store.findRecord('userPrefKey','01-showMap');
rec.set('userPrefValue',false);
You must also call sync() on the store whenever you want to save changes, and to retrieve the saved records from local storage just call load() like for any other store.
Note that my code was written for Touch 2.3, so it may have changed slightly in the most recent 2.4.x version. But this should certainly get you on your way.
store select field value into localstorage and assign that value to selectField whenever you refresh page . So you will get always previous selected value.

How to attribute a property from parent to the child in javascript? (OOP)

I'm developing a sencha touch application, and if a could do something like this, it would be great:
Ext.define('PUREM.view.screen.Form', {
person : null,
items : [
{xtype: 'mycomponent', person: parent.person}
]
});
obviously this code doesn't work. I wanna know how to make it work, if is there a way to use the "person" property from parent object in a child object (xtype: 'mycomponent').
In your class definition, you should override the initComponent function. Then you will have access to all of the properties of the object.
Ext.define('PUREM.view.screen.Form', {
extend: 'Ext.form.Panel',
config: {
person : null
},
initComponent: function()
{
var me = this;
me.items = [
{xtype: 'mycomponent', person: me.person}
]
me.callParent(arguments);
}
});

setActiveItem() passing data sencha touch

I would like to send data with setActiveItem() when doing view change from this store:
Ext.define('SkSe.store.Places',{
extend:'Ext.data.Store',
config:{
autoDestroy: true,
model:'SkSe.model.Places',
//hardcoded data
data: [
{
name: 'Caffe Bar XS', //naziv objekta
icon: 'Icon.png', //tu bi trebala ići ikona kategorije kojoj pripada
stamps: 'stamps1' //broj "stampova" koje je korisnik prikupio
},
{
name: 'Caffe Bar Mali medo',
icon: 'Icon.png',
stamps: 'stamps2'
},
{
name: 'Caffe Bar VIP',
icon: 'Icon.png',
stamps: 'stamps3'
}
]
//dynamic data (Matija)
//remember to change the icon path in "Akcije.js -> itemTpl"
/*proxy:{
type:'ajax',
url:'https://maps.googleapis.com/maps/api/place/search/json?location=-33.8670522,151.1957362&radius=500&types=food&name=harbour&sensor=false&key=AIzaSyCFWZSKDslql5GZR0OJlVcgoQJP1UKgZ5U',
reader:{
type:'json',
//name of array where the results are stored
rootProperty:'results'
}
}*/
}
});
This is my my details controller that should get data from places store:
Ext.define('SkSe.controller.Details', {
extend: 'Ext.app.Controller',
config: {
refs: {
placesContainer:'placesContainer',
Details: 'details'
},
control: {
//get me the list inside the places which is inside placesContainer
'placesContainer places list':{
itemsingletap:'onItemTap'
//itemtap:'onItemTap'
}
}
},
onItemTap:function(list,index,target,record){
console.log('omg');
var addcontact= Ext.create('SkSe.view.Details',
{
xtype:'details',
title:record.data.name,
data:record.data
});
var panelsArray = Ext.ComponentQuery.query('details');
console.log(panelsArray);
Ext.Viewport.add(addcontact);
addcontact.update(record.data.name);
Ext.Viewport.setActiveItem(addcontact);
console.log(record.data.name);
}
});
I would like to send name record from the places.js model above. I heard that you can't pass data with setActiveItem but should create a function that updates view(No I can't use pop and push here).
I'm not very familiar with sencha touch syntax and I'm not sure what functions to use to do that, clearly update function is not that.
I switched up your logic slightly but have provided a working example of what I think you are trying to do.
SenchaFiddle is a little different from what I get running on my machine but you should be able to get the idea.
The initial list loaded gets the data from your store, and on itemtap will push a new view onto the viewport.
You will need to add a navigation button to get back to the list from view.View as well as a better layout for the details. I would suggest nested containers or panels with custom styles to get the details just right. Alternatively you can just drop a full html snippet in there with all the data laid out like you want.
Would be happy to help more.
Fiddle: http://www.senchafiddle.com/#XQNA8

Categories