Extended ExtJS object attributes in button handler - extjs

I'm having real difficulty getting access to a variable that is an attribute of an extended FromPanel from within a button handler on the form. If anyone could offer assistance I'd greatly appreciate it.
Example form where I try to access myAttribute from within the handler of updateUnitsButton:
TrainOverviewPanel = Ext.extend(Ext.FormPanel, {
myAttribute: undefined
,initComponent:function() {
var unitIdField1 = new Ext.form.TextField({
itemId: 'unitIdField1',
flex: 1
});
var unitIdField2 = new Ext.form.TextField({
itemId: 'unitIdField2',
flex: 1
});
var unitIdField3 = new Ext.form.TextField({
itemId: 'unitIdField3',
flex: 1
});
var unitIdFields = new Ext.form.CompositeField({
itemId: 'unitIdFields',
items: [unitIdField1, unitIdField2, unitIdField3],
width: 200
});
var updateUnits = function() {
alert("How can I access attribute: " + this.myAttribute);
}
var updateUnitsButton = new Ext.Button({
tdoId: undefined,
text: 'Update',
handler: updateUnits,
width: 50
});
var updatableUnitIdFields = new Ext.form.CompositeField({
readOnly: false,
fieldLabel: 'Unit ID',
itemId: 'updatableUnitIdFields',
items: [unitIdFields, updateUnitsButton],
width: 300
});
Ext.apply(this, {
width: 450,
height: 130,
margins:'10 0 0 0',
items: [ updatableUnitIdFields ]
});
TrainOverviewPanel.superclass.initComponent.apply(this, arguments);
}
,onRender:function() {
TrainOverviewPanel.superclass.onRender.apply(this, arguments);
}
,refresh: function(data) {
this.myAttribute = data.myAttribute;
var unitIdFields = this.getComponent('updatableUnitIdFields').items.get(0);
unitIdFields.items.get(0).setValue(data.stockId1);
unitIdFields.items.get(1).setValue(data.stockId2);
unitIdFields.items.get(2).setValue(data.stockId3);
}
});

You can do it using two ways.
The first one
using closure:
// ...
var me = this;
var updateUnits = function() {
alert("How can I access attribute: " + me.myAttribute);
};
var updateUnitsButton = new Ext.Button({
tdoId: undefined,
text: 'Update',
handler: updateUnits,
width: 50
});
// ...
The second one
by sending scope variable to handler:
// ...
var updateUnits = function() {
alert("How can I access attribute: " + this.myAttribute);
};
var updateUnitsButton = new Ext.Button({
tdoId: undefined,
text: 'Update',
//handler: updateUnits,
width: 50
});
updateUnitsButton.on('click', updateUnits, this);
// ...

Related

Treelist Store not loaded before render

Using on the dashboard example, i'm trying to generate a treelist menu, based on user privileges.
After successfully log in, the main view is generated. The main, contains in the west region the treelist menu and next to it, the data panel. The navigation is done by using hashtags. The problem apear on refresh or in the first initialization. Actually, i noticed that the navigation store is loaded after the view is rendered.
How / where do i get to load the navigation store, so on refresh or first initalization of the view, i can get it and using it to match the routes?
Thanks,
M
My main view looks like this:
Ext.define('app.view.main.Main', {
extend: 'Ext.container.Viewport',
xtype: 'app-main',
id:'app-main',
requires: [
'Ext.button.Segmented',
'Ext.list.Tree'
],
controller: 'main',
viewModel: 'main',
cls: 'sencha-dash-viewport',
itemId: 'mainView',
layout: {
type: 'vbox',
align: 'stretch'
},
listeners: {
render: 'onMainViewRender'
},
items: [
{
xtype: 'toolbar',
cls: 'sencha-dash-dash-headerbar shadow',
height: 64,
itemId: 'headerBar',
items: [
{
xtype: 'tbtext',
text: localStorage.getItem('Name'),
cls: 'top-user-name'
},
{
xtype: 'image',
cls: 'header-right-profile-image',
height: 35,
width: 35,
alt:'current user image',
src: 'resources/images/user-profile/mb.jpg'
}
]
},
{
xtype: 'maincontainerwrap',
id: 'main-view-detail-wrap',
reference: 'mainContainerWrap',
flex: 1,
items: [
{
xtype: 'treelist',
reference: 'navigationTreeList',
itemId: 'navigationTreeList',
width: 250,
expanderFirst: false,
expanderOnly: true,
ui: 'navigation',
bind: '{navItems}',
listeners: {
selectionchange: 'onNavigationTreeSelectionChange'
}
},
{
xtype: 'container',
reference: 'mainCardPanel',
flex:1,
cls: 'sencha-dash-right-main-container',
itemId: 'contentPanel',
layout: {
type: 'card',
anchor: '100%'
}
}
]
}
]
});
The viewmodel:
Ext.define('app.view.main.MainModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.main',
stores: {
navItems: {
type: 'tree',
storeId: 'NavigationTree',
name: 'NavigationTree',
root: {
expanded: true
},
autoLoad: false,
proxy: {
type: 'ajax',
url: 'php.php',
reader: {
type: 'json',
idProperty: 'id',
messageProperty: 'msg'
}
}
}
}
});
And the viewcontroller:
Ext.define('app.view.main.MainController', {
extend: 'Ext.app.ViewController',
alias: 'controller.main',
listen : {
controller : {
'#' : {
unmatchedroute : 'onRouteChange'
}
}
},
routes: {
':node': 'onRouteChange'
},
lastView: null,
setCurrentView: function(hashTag) {
hashTag = (hashTag || '').toLowerCase();
var me = this,
refs = me.getReferences(),
mainCard = refs.mainCardPanel,
mainLayout = mainCard.getLayout(),
navigationList = refs.navigationTreeList,
store = me.getViewModel().getStore('navItems');
//store = navigationList.getStore();
var node = store.findNode('routeId', hashTag) ||
store.findNode('viewType', hashTag);
var view = (node && node.get('viewType')) ,
lastView = me.lastView,
existingItem = mainCard.child('component[routeId=' + hashTag + ']'),
newView;
// Kill any previously routed window
if (lastView && lastView.isWindow) {
lastView.destroy();
}
lastView = mainLayout.getActiveItem();
if (!existingItem) {
newView = Ext.create({
xtype: view,
routeId: hashTag, // for existingItem search later
hideMode: 'offsets'
});
}
if (!newView || !newView.isWindow) {
// !newView means we have an existing view, but if the newView isWindow
// we don't add it to the card layout.
if (existingItem) {
// We don't have a newView, so activate the existing view.
if (existingItem !== lastView) {
mainLayout.setActiveItem(existingItem);
}
newView = existingItem;
}
else {
// newView is set (did not exist already), so add it and make it the
// activeItem.
Ext.suspendLayouts();
mainLayout.setActiveItem(mainCard.add(newView));
Ext.resumeLayouts(true);
}
}
navigationList.setSelection(node);
if (newView.isFocusable(true)) {
newView.focus();
}
me.lastView = newView;
},
onNavigationTreeSelectionChange: function (tree, node) {
var to = node && (node.get('routeId') || node.get('viewType'));
if (to) {
this.redirectTo(to);
}
},
onToggleNavigationSize: function () {
var me = this,
refs = me.getReferences(),
navigationList = refs.navigationTreeList,
wrapContainer = refs.mainContainerWrap,
collapsing = !navigationList.getMicro(),
new_width = collapsing ? 64 : 250;
if (Ext.isIE9m || !Ext.os.is.Desktop) {
Ext.suspendLayouts();
refs.senchaLogo.setWidth(new_width);
navigationList.setWidth(new_width);
navigationList.setMicro(collapsing);
Ext.resumeLayouts(); // do not flush the layout here...
// No animation for IE9 or lower...
wrapContainer.layout.animatePolicy = wrapContainer.layout.animate = null;
wrapContainer.updateLayout(); // ... since this will flush them
}
else {
if (!collapsing) {
// If we are leaving micro mode (expanding), we do that first so that the
// text of the items in the navlist will be revealed by the animation.
navigationList.setMicro(false);
}
// Start this layout first since it does not require a layout
refs.senchaLogo.animate({dynamic: true, to: {width: new_width}});
// Directly adjust the width config and then run the main wrap container layout
// as the root layout (it and its chidren). This will cause the adjusted size to
// be flushed to the element and animate to that new size.
navigationList.width = new_width;
wrapContainer.updateLayout({isRoot: true});
navigationList.el.addCls('nav-tree-animating');
// We need to switch to micro mode on the navlist *after* the animation (this
// allows the "sweep" to leave the item text in place until it is no longer
// visible.
if (collapsing) {
navigationList.on({
afterlayoutanimation: function () {
navigationList.setMicro(true);
navigationList.el.removeCls('nav-tree-animating');
},
single: true
});
}
}
},
onMainViewRender:function() {
if (!window.location.hash) {
this.redirectTo("dashboard");
}
},
onRouteChange:function(id){
this.setCurrentView(id);
},
onSearchRouteChange: function () {
this.setCurrentView('searchresults');
},
onSwitchToModern: function () {
Ext.Msg.confirm('Switch to Modern', 'Are you sure you want to switch toolkits?',
this.onSwitchToModernConfirmed, this);
},
onSwitchToModernConfirmed: function (choice) {
if (choice === 'yes') {
var s = location.search;
// Strip "?classic" or "&classic" with optionally more "&foo" tokens
// following and ensure we don't start with "?".
s = s.replace(/(^\?|&)classic($|&)/, '').replace(/^\?/, '');
// Add "?modern&" before the remaining tokens and strip & if there are
// none.
location.search = ('?modern&' + s).replace(/&$/, '');
}
},
onAfterRender: function(){
console.log('after render');
}
});
I kinda solve it using "before" action in router with a method that waits for the store to load.
routes: {
':node':{
before: 'wait',
action: 'onRouteChange'
}
and the method:
wait : function() {
var args = Ext.Array.slice(arguments),
action = args.pop(),
store = Ext.getStore('NavigationTree');
if (store.loading) {
store.on('load', action.resume, action);
} else {
action.resume();
}
}
In viewcontroller
//...
var me = this,
refs = me.getReferences(),
mainCard = refs.mainCardPanel,
mainLayout = mainCard.getLayout(),
navigationList = refs.navigationTreeList,
viewModel = me.getViewModel(),
vmData = viewModel.getData(),
store = navigationList.getStore(),
//store = Ext.getStore('NavigationTree'),
node = store.findNode('routeId', hashTag),
view = node ? node.get('view') : null,
lastView = vmData.currentView,
existingItem = mainCard.child('component[routeId=' + hashTag + ']'),
newView;
// BEGIN ADD THIS
if(!view) {
var viewTag = hashTag.charAt(0).toUpperCase() + hashTag.slice(1);
view = hashTag + "." + viewTag;
if(!Ext.ClassManager.getAliasesByName('Fruileg3.view.' + view)) view = '';
}
// END
// Kill any previously routed window
if (lastView && lastView.isWindow) {
lastView.destroy();
}
//...

on change event datepicker in Ext.form.DateField not working

I have html span for datepicker like this
<span id="spanLimitFBClaim"></span>
then i call it's first.js
$("#spanLimitPaymentDate").datepicker("LimitPaymentDate")
datepicker comes form another global.js
$.fn.datepicker = function (id) {
var mydate = new Ext.form.DateField({
xtype: 'datepicker',
format: 'd-M-Y',
margin: '2 0 2 0',
renderTo: Ext.get($(this).attr("id")),
cls: 'sa-datepicker',
inputId: id,
value: new Date()
});
$("#" + id).attr("readonly", true);
}
it is works. the problem is. i want to get change event. i try to add in global.js the listener like this
$.fn.datepicker = function (id) {
var mydate = new Ext.form.DateField({
xtype: 'datepicker',
format: 'd-M-Y',
margin: '2 0 2 0',
renderTo: Ext.get($(this).attr("id")),
cls: 'sa-datepicker',
inputId: id,
value: new Date(),
listeners: {
select: function () {
console.log('Date selected: ', this.getValue());
}
}
});
$("#" + id).attr("readonly", true);
}
and it works. i see the value on global.js (console.log) the problem is how to add it in my span (from the first.js). because i do below code is not working
$("#spanLimitPaymentDate").datepicker("LimitPaymentDate", {
listeners: {
select: function () {
console.log('Date selected: ', this.getValue());
}
}
});
i'm very newbie in ext.js, seems i was typo in using it :(
Many thanks
In the first version, you set the listener in the config of the field you create in the function.
In the second version, you set the listener as the second argument to said function, but that function only takes one argument. So the config you set there is omitted.
It should work if you change your function like this:
$.fn.datepicker = function (id,config) {
var me=this;
var mydate = new Ext.form.DateField(
Ext.apply(config,{
xtype: 'datepicker',
format: 'd-M-Y',
margin: '2 0 2 0',
renderTo: Ext.get($(me).attr("id")),
cls: 'sa-datepicker',
inputId: id,
value: new Date()
});
);
$("#" + id).attr("readonly", true);
}
and then call
$("#spanLimitPaymentDate").datepicker("LimitPaymentDate", {
listeners: {
select: function (picker) {
console.log('Date selected: ', picker.getValue());
}
}
});

Need solution for Multi Select in Extjs tree

Am complete stranger to Extjs. I have a requirement to allow multi select in the Extjs tree. Below piece of code is doing single select. i need to change the code to make it multi select with semi-colon between selected ids. Can anyone please change the code as per the requirement. Also if you could tell me to which field or variable the selected value of the tree is written into. Thanks in advance
Ext.onReady(function() {
Ext.QuickTips.init();
var str='';
var switch_flag = '';
var approvals = '';
var active_mode = '';
var json = null;
Ext.Ajax.request({
url: 'Dmscategorytree/ajax/Message',
method: 'POST',
params:{
lifecycle_id: str,
switch_flag: switch_flag,
approvals: approvals,
active_mode: active_mode
},
success: function(response, options) {
var path='';
var id='';
var text='';
json=response.responseText;
alert(json);
json = json.replace(/"/g,'\"');
json=Ext.util.JSON.decode(json);
var flag=true;
var myloader = new Ext.tree.TreeLoader();
myloader.load = function(node, cb,scope) {
if(this.clearOnLoad){
while(node.firstChild){
node.removeChild(node.firstChild);
}
}
if(this.doPreload(node)){
this.runCallback(cb, scope || node, [node]);
}
cb();
}
var tree = new Ext.tree.TreePanel({
animate:true,
autoScroll:true,
//loader: new Tree.TreeLoader({dataUrl:'get-nodes.php'}),
containerScroll: true,
border: false,
loader:myloader,
rootVisible: false,
listeners:{
checkchange:function(node){
if(flag){
toggleCheck(tree.root,false,node.id);
path=node.attributes.value;
id=node.attributes.ID;
text=node.attributes.text;
path=path.replace(/\^/g,'/');
}
}
}
});
function SelectToParent()
{
try
{
parent.window.opener.callParent(path,id);
parent.window.opener.focus();
parent.window.close();
}
catch(e){
alert('got exception');
window.close();
}
}
function toggleCheck(node,isCheck,nodeId)
{
flag=false;
if(node)
{
var args=[isCheck];
node.cascade(function(){
c=args[0];
if(nodeId!=this.id){
this.ui.toggleCheck(c);
this.attributes.checked=c;
}
},null,args);
}
flag=true;
return true;
}
var root = new Ext.tree.AsyncTreeNode({
text: 'Ext JS',
draggable:false, // disable root node dragging
id:'src',
children: json
});
tree.setRootNode(root);
var topbar = new Ext.Toolbar({
region : 'north',
height:30,
margins: '0 0 0 5',
items:[
{
xtype: 'box',
id: 'title',
autoEl: {
html: '#label.chooseCat#'
}
,width:525
},
{
text: '#label.Done#',
id: 'doneBtn',
tooltip: 'Done',
handler: SelectToParent
}
]
});
topbar.render('tree');
tree.render('tree');
tree.getRootNode().expand();
}
});
});
Please refer the following links,
pass two id s in extjs 4 tree multiSelect and pass one id in single click
Multiselect Tree & Drag and Drop
Drag and Drop between Grid and “multiselect” control in EXTJS
Demo

how to make overlay toggled in easelJS Extjs

I'm a new programmer and I'm trying to create some interactive elements with extJS and Easel...
I have a button and when you click it it overlay's an image... but I want to be able to toggle the image on and off... I tried using toggleHandler and enable toggle but stuff isn't working.
here's my code:
Ext.define('EaselWindow', {
width: 1000,
height: 750,
extend: 'Ext.Window',
html: '<canvas id="demoCanvas" width="1000" height="750">'
+ 'alternate content'
+ '</canvas>'
,afterRender: function() {
this.callParent(arguments);
stage = new createjs.Stage("demoCanvas");
//var myImage = new createjs.Bitmap("dbz.jpg");
//stage.addChild(myImage);
//stage.update();
var myImage = new Image();
myImage.src = "dbz.jpg";
myImage.onload = setBG;
function setBG(){
var bgrd = new createjs.Bitmap(myImage);
stage.addChild(bgrd);
stage.update();
bgrd.addEventListener("click", function(){
var seed = new createjs.Bitmap("seed.jpg");
seed.alpha = 0.5;
seed.x = stage.mouseX-10 ;
seed.y = stage.mouseY-10 ;
stage.addChild(seed);
stage.update();
}); //end addeventlistener
}
}, // end after render func
items:[{
itemId: 'button1',
xtype: 'button',
text: 'click the button',
visible: true,
enableToggle: true,
listeners: {'click':
function(){
var overlay = new createjs.Bitmap("stuff.jpg");
overlay.alpha = 0.5;
stage.addChild(overlay);
stage.update();
}// end func
}
},{
itemId: 'button2',
xtype: 'button',
text: 'button2'
}]
}); // end define
Ext.create('EaselWindow', {
title: "Ext+Easel",
autoShow: true
}); //end easelwindow
});
I was thinking I could somehow make an if statement with removeChild... but I couldn't get it to work, I tried something like
function(button1, state){
if(this.state=true){
var overlay = new createjs.Bitmap("stuff.jpg");
overlay.alpha = 0.5;
stage.addChild(overlay);
stage.update();
}
else
{stage.removeChild(overlay);
stage.update();
}
}// end func
awww I figured it out by using
toggleHandler:
function(button, pressed){
if(button.pressed==true){
overlay = new createjs.Bitmap("stuff.jpg");
overlay.alpha = 0.5;
stage.addChild(overlay);
stage.update();
}
else
{stage.removeChild(overlay);
stage.update();
}
}// end func

How to get form field value in onclick event

I am using this article of architecture http://blog.extjs.eu/know-how/writing-a-big-application-in-ext/
in my code:
I have this Application.DashBoardForm.js in this i want to pass the value of the fromdate in the onclick event function , how can i pass the fromdate value ?
Ext.apply(Ext.form.VTypes, {
daterange : function(val, field) {
var date = field.parseDate(val);
if(!date){
return false;
}
if (field.startDateField) {
var start = Ext.getCmp(field.startDateField);
if (!start.maxValue || (date.getTime() != start.maxValue.getTime())) {
start.setMaxValue(date);
start.validate();
}
}
else if (field.endDateField) {
var end = Ext.getCmp(field.endDateField);
if (!end.minValue || (date.getTime() != end.minValue.getTime())) {
end.setMinValue(date);
end.validate();
}
}
/*
* Always return true since we're only using this vtype to set the
* min/max allowed values (these are tested for after the vtype test)
*/
return true;
}
});
Application.DashBoardForm= Ext.extend(Ext.FormPanel, {
border:false
,initComponent:function() {
var config = {
labelWidth: 125,
frame: true,
title: 'Date Range',
bodyStyle:'padding:5px 5px 0',
width: 350,
defaults: {width: 175},
defaultType: 'datefield',
items: [{
fieldLabel: 'Start Date',
name: 'fromdate',
id: 'fromdate',
vtype: 'daterange',
value : new Date(),
endDateField: 'todate' // id of the end date field
},{
fieldLabel: 'End Date',
name: 'todate',
id: 'todate',
vtype: 'daterange',
value : new Date(),
startDateField: 'fromdate' // id of the start date field
}]
,buttons: [{
text: 'Go',
onClick : function () {
// here i want to access the value of the form field
// how can i access the fromdate value so that i pass it to grid
console.log(this.getForm());
var win = new Ext.Window({
items:{xtype:'DashBoardGrid',fromdate:this}
});
win.show();
}
}]
}; // eo config object
// apply config
Ext.apply(this, Ext.apply(this.initialConfig, config));
Application.DashBoardForm.superclass.initComponent.apply(this, arguments);
} // eo function initComponent
,onRender:function() {
// this.store.load();
Application.DashBoardForm.superclass.onRender.apply(this, arguments);
} // eo function onRender
});
Ext.reg('DashBoardForm', Application.DashBoardForm);
How can I pass the value of from date here in onclick function?
Being that you gave the field an ID of 'fromdate', you can reference it using Ext.getCmp() and from there call its getValue() method:
var field = Ext.getCmp('fromdate');
var win = new Ext.Window({
items: {
xtype: 'DashBoardGrid',
fromdate: field.getValue()
}
});
Set the scope of your button 'Go', so that you will have access to form within the handler method. By doing this, you will have access to the form from the handler method.
Now, to get access to the form element, you can use ref property or use find*() methods available in Ext.form.FormPanel to get the form element.
text: 'Go',
scope: this,
handler: function () {
fromdate = this.findById('fromdate');
// extract date value and use it...
value = fromdate.getValue();
}
When using ref property, set a ref for the formdata field:
ref: '../formdate'
fieldLabel: 'Start Date',
name: 'fromdate',
id: 'fromdate',
vtype: 'daterange',
value : new Date(),
endDateField: 'todate' // id of the end date field
And you should be able to access the form element through the form object in the handler.
this.formdate.getValue()

Resources