Sencha - combining dataview with button in same view - extjs

I am very new to Sencha and I am trying to get a button under a DataView in a Panel. I have tried different scenario's.
The View
Ext.define('MyApp.view.Profile', {
extend : 'Ext.Panel',
xtype : 'profileview',
requires : ['MyApp.store.UserStore', 'Ext.List', 'Ext.DataView', 'Ext.data.Store'],
initialize : function() {
var me = this;
var record = 1;
//Create the instance of the store and load it
var userStore = Ext.create('MyApp.store.UserStore');
userStore.load();
//Create the dataview
var view = Ext.create('Ext.DataView', {
store : userStore,
itemTpl : ['<h1>Mijn Profiel</h1>', '<h2>{USERNAME}</h2>', '<p>{EMAIL}</p><br/>', '<img src="http://www.MyApp.nl/{AVATAR_PATH}" />', '<br/>'].join()
});
//Add the dataview to the panel
me.add(view);
/**
var button = Ext.create('Ext.Button', {
text : 'Edit',
handler : function() {
Ext.Msg.alert('You clicked the button');
}
});
*/
//me.add(button);
},
config : {
title : 'Profiel',
iconCls : 'user3',
scrollable : true,
styleHtmlContent : true,
items : [{
xtype : 'button',
text : 'Edit',
handler : function() {
Ext.Msg.alert('You clicked the button');
}
}]
}
});
The above view shows only the button but NOT the Dataview. I needed to add
layout : 'fit'
to the config to make it show DataView. But in combination with the button it makes the button fullscreen and the dataview is not shown anymore (???).
I tried both scenario's where I add a Button as config item and by using the handler.
How can I get the button below the dataview ??
Thanks for your help.

Don't use layout fit, it's made to fit one component in your canvas. I'd use a vbox layout. Which automatically puts items vetically under each other.
Try this:
layout: {
type: 'vbox',
align: 'stretch' //this tells to take the full width
}
Flex your dataview
var view = Ext.create('Ext.DataView', {
flex: 1, //Use the remaining space.
store : userStore,
itemTpl : ['<h1>Mijn Profiel</h1>', '<h2>{USERNAME}</h2>', '<p>{EMAIL}</p><br/>', '<img src="http://www.MyApp.nl/{AVATAR_PATH}" />', '<br/>'].join()
});

Related

The right event to apply "scrollTo" to show a dynamically added nested panel

I have a panel in ExtJS6 modern (mobile) application that can scroll vertically only. Sub panels are added dynamically to it. I need to scroll the panel to its end after adding a new sub-panel in order to make it visible. This is done using this line:
Ext.getCmp('tabmainMessagesPanel').getScrollable().scrollTo(Infinity, Infinity, true);
I execute this line in a button click, and it works (but need to click the button manually). I tried to find the right event where I can add this line to do the scroll automatically, without success. I nearly tried all the possible relevant events of the sub-panel: show, add, added, activate, ... I also tried the events of the parent panel without success.
Apparently, these events happen before the scroller of the parent panel takes into account the added sub-panel, so it scrolls to the before-last one. I smell asynchronous behavior here. The proof is that I call the scrollTo method in a delayed task of 0.5 second and it works. But this solution is not reliable.
The question is: where (in which event of which component) this line of code should go in order to scroll the parent to its end correctly?
[EDIT]
Here is the part of the code concerning the question. First, the Message class:
Ext.define('MyApp.view.message.Message', {
extend : 'Ext.Panel',
xtype : 'message',
layout : 'hbox',
config : {
mBody : ''
},
listeners: {
added: function (element) {
MyApp.view.main.Global.scroller.delay(500); //start a delayed task to scroll parent panel
}
},
items: [
{
flex : 1
},
{
maxWidth: '80%',
width: 'auto',
html : '<div class="myClass">' + this.getMBody() + '</div>'
}
]
});
Here is the delayed task that scrolls the parent panel tabmainMessagesPanel to its end in order to show the newly-added message:
Ext.define('MyApp.view.main.Global', {
statics: {
scroller: Ext.create('Ext.util.DelayedTask', function() {
Ext.getCmp('tabmainMessagesPanel').getScrollable().scrollTo(Infinity, Infinity, true);
})
}
}
Now, the tab panel that contains the panel tabmainMessagesPanel that will contain the messages:
Ext.define('MyApp.view.main.TabMain', {
extend : 'Ext.tab.Panel',
mixins : [ 'Ext.mixin.Responsive' ],
xtype : 'tabmain',
responsiveConfig : {
portrait : {
items :
[
{
title : 'Messages',
layout : 'vbox',
items : [ {
xtype: 'panel',
layout : 'vbox',
height: '100%',
id: 'tabmainMessagesPanel',
scrollable : 'vertical',
style : 'background-color:#F0F0F0'
},
{
xtype : 'inputfield',
docked : 'bottom'
}]
},
{
title : 'Connect',
layout: 'vbox',
items : [
//some UI elements
]
}
]
},
//--------------------------------------------------
landscape : {
// same as portrait
}
},
//--------------------------------------------------
controller : 'tabmain',
viewModel : 'tabmain',
defaults : {
tab : {
iconAlign : 'top'
},
styleHtmlContent : true
}
});
Finally, this is an event in a controller that creates and adds a message to tabmainMessagesPanel whenever a new message arrives:
handle_message: function (mess) {
var p = Ext.create('MyApp.view.message.Message', {
mBody : mess.body
});
Ext.getCmp('tabmainMessagesPanel').add(p);
}
Here is the answer for this. I found it 6 months later. I post it here for the benefit of those who may have the same issue.
The solution is to define the event refresh of the scroller of the panel tabmainMessagesPanel, and scroll to the end in it. So, the definition of the panel tabmainMessagesPanel becomes:
{
xtype: 'panel',
layout : 'vbox',
height: '100%',
id: 'tabmainMessagesPanel',
scrollable : 'vertical',
listeners: {
initialize: function (me) {
me.getScrollable().on('refresh', function () {
me.getScrollable().scrollTo(Infinity, Infinity, true);
});
}
},
style : 'background-color:#F0F0F0'
}

How to make sencha components width device independent

I created register panel and added toolbar with button during view initialization, In controller i am creating form panel and adding it to the register panel dynamically.
The toolbar in register panel is adjusting based on device screen but, The form panel width is not changing.
If i set width for the form panel, The form panel is floating and width remains the same.
This is what i done so for.
Ext.define('Form.view.RegisterForm',{
extend : 'Ext.Panel',
xtype : 'register',
id : 'register',
initialize : function() {
console.log("register init");
var submit = {
xtype : 'button',
width : '100px',
ui : 'action',
text : 'Submit',
handler : this.onSubmitTap,
scope : this
};
var topToolbar = {
xtype : 'toolbar',
docked : 'top',
id : 'registerToolbar',
title : 'Form',
items : [{
xtype : 'spacer'
}, submit]
};
this.add(topToolbar);
},
config : {
fullscreen : true,
layout : {
type : 'vbox'
},
title : 'Register'
},
onSubmitTap : function() {
console.log("onSubmit");
this.fireEvent('submitCommand', this);
}
});
In Register controller i adding fields dynamically
// RegisterFormController.js
oncreateForm : function() {
var form = {
xtype: 'formpanel',
flex : 1,
id: formId,
name: formId
};
Ext.getCmp('register').add(form);
}
// calling onCreateComponent method with xtype, label, value and fromId
onCreateComponent : function(fxtype,flabel,fname,fvalue,id) {
Ext.getCmp(id).add({
xtype: fxtype,
label: flabel,
name: fname,
value: fvalue,
labelWrap:true
});
}
In case any of you came up with same problem.
The mistake i did was "I added the 4 radio buttons in a hbox panel so width of that panel increased that's why the whole form panel not displaying properly in different devices".
After i changed the panel layout as vbox, The problem solved.

Menu item in Ext-JS4

I am new to Ext-JS4. I am working on a project in which I am configuring a toolbar. I have added few buttons to the toolbar, one of which has a menu and the menu basically has a grid which is loaded from a JSON store. The grid is used within the menu due to such requirement in the project. The grid is loaded properly but I need access to the menu item being clicked within the menu. I want the text of the menu item which is clicked. The following code will better explain my question.
var store = Ext.create('Ext.data.Store', {
storeId : 'favStore',
model : favModel,
autoLoad : true,
groupField : 'group_header',
proxy : {
type : 'ajax',
url : '../../data/favorites.json',
reader : {
type : 'json',
root : 'favoritesMenu'
}
}
});
var favGrid = Ext.create('Ext.grid.Panel', {
store : store,
columns : [{
dataIndex : 'listItem',
width : 200
}],
features : [groupingFeature],
width : 200,
height : 275,
autoHeight : true,
border : false
});
var favMenu = Ext.create('Ext.menu.Menu', {
items : [favGrid],
listeners : {
'click' : function(store,item) {
alert('Item clicked= ');//tried item.text here but not working
}
}
});
In the alert method on the click event I want the text of the menu item clicked. I hope I am clear with the question. Can anyone give me some suggestions? Also can anyone suggest me some good blogs on Ext-JS4?
All these things are defined within the initComponent method of Ext.define() for toolbar.
You can use the documentation.
For me it was very usefull:
http://docs.sencha.com/ext-js/4-0/
I believe in your case you want the listener to be attributed to your grid, not the menu. Something like...
var favGrid = Ext.create('Ext.grid.Panel', {
store : store,
columns : [{
dataIndex : 'listItem',
width : 200
}],
features : [groupingFeature],
width : 200,
height : 275,
autoHeight : true,
border : false,
listeners: {
'itemclick': function(view, record, item, index, e, eOpts){
//Assuming 'name' is a fieldname in the record
alert('item clicked = ' + record.get('name'));
}
}
});
Check out the Ext.grid.Panel documentation here: http://docs.sencha.com/ext-js/4-0/#!/api/Ext.grid.Panel . Click on "events" at the top and find "itemclick".
or you can have your menu listen to the grid's event by relaying the events.
favMenu.relayEvents(favGrid, ['itemclick']);
favMenu.on('itemclick', me.onFavFunction, me);

Problem with registering xtype

I am trying to create factory functions as per factory-functions-in-ext-extensions,
below is my code
Ext.ns('MyApp');
MyApp.SubmitButton = Ext.extend(Ext.Button, {
text:'Submit'
,iconCls:'icon-disk'
,initComponent:function() {
MyApp.SubmitButton.superclass.initComponent.apply(this, arguments);
} // eo function initComponent
}); // eo extend
var btn = new MyApp.SubmitButton();
Ext.reg('submitbutton1',btn);//this is not working
Ext.reg('submitbutton', MyApp.SubmitButton );//this works
var win1;
if(!win1) {
win1 = new Ext.Window({
title : 'title',
closeAction : 'hide',
autoHeight : true,
autoWidth : true,
height : 300,
width : 500,
items : [{xtype:'submitbutton1',id:'submitbutton'}]
});
}
win1.show();
when i run this it throws error "b[d.xtype || e] is not a constructor"
You cannot use an instance of a class for registering xtype. You have to use the classname for it. Ext doesn't keep track of the instances you are creating, but just register the custom component class - so that you can just use this way:
var button = new MyApp.SubmitButton({
id : 'submitbutton'
});
OR,
{
xtype : 'submitbutton',
id:'submitbutton'
}
Both are same. Check Saki's this article for more information.

extjs dataview issue

I am creating a report making tool. I will be dragging/resizing panels inside a panel container. When i click save button, i am passing the size and position of panels and based on that an xhtml report will be generated. I have a dataview on the left side. Each time a report is generated i need to show that report on dataview. Without using any database how this can be done? Any help would be appreciated.
Do one thing, create a store with fields "size", "report_data" and "position".
var store = new Ext.data.JsonStore({
id : 'panel_store',
fields : ['size', 'position', 'report_data']
});
Create a template for each report (some other data can be added here):
var template = new Ext.XTemplate(
'<div class="reports_container"><tpl for=".">',
'<div class="report">{report_data}</div>','</tpl></div>'
);
template.compile();
Create a dataview with template and store:
var dataView = new Ext.DataView({
itemSelector : 'div.report', // Required
style : 'overflow:auto',
multiSelect : true,
store : store,
tpl : template
});
Add the dataview in you main panel:
var mainPanel = new Ext.Panel({
id : 'main_panel',
items : dataView
});
Whenever you generate a new report, create a new Ext.Record:
var ReportRecord = Ext.data.Record.create([
{ name: 'size' },
{ name: 'position' },
{ name: 'record_type' }
]);
var newRec = new ReportRecord({
size : '100',
position : 'some position',
report_data : 'some data'
});
store.add(newRec);
store.on('add', function() {
dataView.refresh();
}, this);
Is this what you wanted? However, this code isn't tested anywhere.

Resources