Sending values from a view to another using EXTJS - extjs

Im' using EXT 4.2.0.
I have 2 views : view 1 and view 2.
In view 1 i have a Ext.grid.Panel which (in his associated controller) contains a selectionchange event lisetner .
After selectionchange is triggred, i go the the view 2 in which i have a form.
My need is to have control on the from of the view 2 from view 1.
I mean by control sending values, disabling buttons ...
For information, concerning sending values issue, i'v already tried
Ext.getCmp('view2ID').getForm().loadRecord(this.getMyVar());
But this seems not to be working and i don't know why !
Could you help me please ? :)

Option 1 : As said by #Lorenz,call the method in your controller
selectionchange:function( record, selected, eOpts ){
//getController
controller = globalVar.getController('Controller');
controller.onSelectionChangeEvent(record);
}
Option2 : You can pass config object to the View2 when creating a instance
In view1,mention config property;
//View 1....
config :{
recordObj : ''
},
.........
selectionchange:function( record, selected, eOpts ){
var form = Ext.create('My.view.Form',{recordObj :record});
}
............
//Your View2 might be like
Ext.define('My.view.Form', {
extend : 'Ext.form.Panel',
config :{
recordObj : ''
},
initComponent : function() {
var record = this.getRecordObj();
this.items = [
];
this.callParent();
//Set form values
this.getForm().setValues(record);
}
});

The problem was quiet difficult : Actions sent from View1 were executed befaure view 2 is rendred ! Even if my code was some think like this :
ControllerOfView1
{
CodeToLoadView2;
InstructionsToControlView2;
}
The solution was to add a listeners on my View2 and parametrize afterrender.
So the code hase become :
afterrender: function() {
this.loadRecord(this.getMyVar2());
}

You can use the custom fire event , in that you can send the data you want and the component reference.
app.fireEvent('selectionChanged',view1.grid);
you need the listen for the selectionChanged in the view2.
something like
app.on("selectionChanged",onSelectionChanged)
onSelectionChanged : function(grid){
console.log(grid);
}

Related

Marionette Composite Item View Capture

I have a composite view which consist of item view. I need to capture the events of item view, what I am trying to capture is specific item view capture as I am rendering a pop up modal on click of button in item view. The Modal needs to contains the details of item for which it is clicked. Whats happening is if I put the event capture in either or item or composite view with query selector of buttons (this button has hidden span of item id) it always selects the first items.
Sounds like it is doing right thing as the item view repetition in composite view is not changing the id of buttons (even if the hidden span has different id).
Quesiton is how do I achieve capturing specific item events with attributes captures.
code below :
ItemView:
var regItemView = Marionette.ItemView.extend({
template: ProgramRegistraionMainItemView,
tagName: 'div',
className : 'accordion_in',
events : {
'click #subbtn' : function () {
var prgid = $('#regid').html();
var rate = $('#rate').html(); MyApp.mainregion.currentView.appcontent.currentView.maincontent.currentView.contentregion1.currentView.prgregmainmodal.show(new ProgramRegistrationModalView({selectedprgid : prgid,rate: rate}));
}
}
});
Composite View
var RegistrationView = Marionette.CompositeView.extend({
itemView : regItemView,
itemViewContainer: "#mainaccordion",
template : ProgramRegistraionMainCollectionView,
initialize : function(programcollection)
{
this.collection = programcollection;
this.model =null;
},
model : this.model,
collection : this.collection,
showAccord : function () {
//console.log("In Accodian show"+$("#mainaccordion").html());
$("#mainaccordion").smk_Accordion({
showIcon: true, // Show the expand/collapse icons.
animation: true, // Expand/collapse sections with slide aniamtion.
closeAble: true, // Closeable section.
slideSpeed: 200, // the speed of slide animation.
closeOther : false
});
}
Aim is to get the program id of the clicked item (rendered through item view).
From your regItemView's event hash, it looks like the issue is with using an html id for the jQuery event handler. id's are supposed to be unique across the whole page but you have repeated it for each ItemView. Change it to a class or an element name (if you've only got one per item view):
var regItemView = Marionette.ItemView.extend({
template: ProgramRegistraionMainItemView,
tagName: 'div',
className : 'accordion_in',
events : {
'click button' : 'showModal'
},
showModal: function () {
// Show modal somehow
// you can access the model in here as this.model
}
});
Marionette sets the event handler context as the item view so you can simple access the model as this.model. This is better than adding data-id tags into your HTML to retrieve the model.

Ext not defined on RowModel's select event

I have a form bound to a grid where a user can either create a new user or select a row in the grid and edit a user. Selecting a row in a grid should change some button visibility. Anyway my main obstacle is that Ext seems not to be fully loaded on the row select event. The error I get in firebug is:
TypeError: Ext.getCmp(...) is undefined
Here is a snippet of code from my MVC controller:
....
init: function() {
this.control({
'userlist': {
selectionchange: this.gridSelectionChange,
viewready: this.onViewReady,
select: this.onRowSelect
},
'useredit button[action=update]': {
click: this.updateUser
},
'useredit button[action=create]': {
click: this.createUser
}
});
},
onRowSelect: function(model, record, index, opts) {
// Switch to the Edit/Save button
//console.log(model);
Ext.getCmp('pplmgr-user-create').hide();
Ext.getCmp('pplmgr-user-create').show();
Ext.getCmp('id=pplmgr-user-reset').show();
},
....
Is there some other method/event for accomplishing this? I've tried in both selectionchange and select events and I have also tried using the Ext.Component.Query and it just seems that Ext is not yet available in these events. I'd appreciate any assistance including informing me of a better practice to accomplish the same thing.
Ext.getCmp takes an id as its parameter. Your third call to it has id=..., the "id=" part is confusing getCmp, so it's returning undefined.
If you change the last call to just the id, you should be ok:
Ext.getCmp('pplmgr-user-reset').show();
If you have a reference to your view, you can try this:
myView.down('pplmgr-user-create').hide();
....
....

How get html content from panel in ExtJs

I am new to ExtJs.
I have been facing a problem in panels for getting panel html content.
xtype : 'panel',
id : 'first_block',
html : '<p>Hi this is belongs to first block.</p>',
listeners : {
render : function(c) {
c.body.on('click', function() {
alert('' + this.id);
alert(Ext.getCmp('first_block').items.getAt(0).getValue());
});
}
I am not getting html content, but i am getting id like "first_block-body".
Thanks in advance.
The html property defined the HTML you want in the content of your component, in this case an Ext.Panel.
Ext.Panels create a few layers of divs in order to provide things like headers, footers, toolbars, etc.
If all you want is a div with some content, you instead want to use an Ext.Component. Components don't have a body, so a couple things change in your code.
xtype : 'component',
id : 'first_block',
html : '<p>Hi this is belongs to first block.</p>',
listeners : {
render : function(c) {
c.on('click', function() {
alert('' + this.id);
alert(this.el.dom.innerHTML);
}, this);
}
Notice that I added a third parameter to your on call, which specifies the this scope of the function call. I also edited your alert to print out the innerHTML of the element, assuming that's what you were trying to do.
UPDATE:
If you are going to use this component in a layout, it may need to be able to have its height and width set, meaning it needs to be of type box in order to be an Ext.BoxComponent.
Ext.getElementById('yourId').innerHTML

ExtJS 4: How to know when any field in a form (Ext.form.Panel) changes?

I'd like a single event listener that fires whenever any field in a form (i.e., Ext.form.Panel) changes. The Ext.form.Panel class doesn't fire an event for this itself, however.
What's the best way to listen for 'change' events for all fields in a form?
Update: Added a 3rd option based on tip in comments (thanks #innerJL!)
Ok, looks like there are at least two fairly simple ways to do it.
Option 1) Add a 'change' listener to each field that is added to the form:
Ext.define('myapp.MyFormPanel', {
extend: 'Ext.form.Panel',
alias: 'myapp.MyFormPanel',
...
handleFieldChanged: function() {
// Do something
},
listeners: {
add: function(me, component, index) {
if( component.isFormField ) {
component.on('change', me.handleFieldChanged, me);
}
}
}
});
This has at least one big drawback; if you "wrap" some fields in other containers and then add those containers to the form, it won't recognize the nested fields. In other words, it doesn't do a "deep" search through the component to see if it contains form field that need 'change' listeners.
Option 2) Use a component query to listen to all 'change' events fired from fields in a container.
Ext.define('myapp.MyController', {
extend: 'Ext.app.Controller',
...
init: function(application) {
me.control({
'[xtype="myapp.MyFormPanel"] field': {
change: function() {
// Do something
}
}
});
}
});
Option 3) Listen for the 'dirtychange' fired from the form panel's underlying 'basic' form (Ext.form.Basic). Important: You need to make sure you must enable 'trackResetOnLoad' by ensuring that {trackResetOnLoad:true} is passed to your form panel constructor.
Ext.define('myapp.MyFormPanel', {
extend: 'Ext.form.Panel',
alias: 'myapp.MyFormPanel',
constructor: function(config) {
config = config || {};
config.trackResetOnLoad = true;
me.callParent([config]);
me.getForm().on('dirtychange', function(form, isDirty) {
if( isDirty ) {
// Unsaved changes exist
}
else {
// NO unsaved changes exist
}
});
}
});
This approach is the "smartest"; it allows you to know when the form has been modified, but also if the user modifies it back to it's original state. For example, if they change a text field from "Foo" to "Bar", the 'dirtychange' event will fire with 'true' for the isDirty param. But if the user then changes the field back to "Foo", the 'dirtychange' event will fire again and isDirty will be false.
I want to complement Clint's answer. There is one more approach (and I think it's the best for your problem). Just add change listener to form's defaults config:
Ext.create('Ext.form.Panel', {
// ...
defaults: {
listeners: {
change: function(field, newVal, oldVal) {
//alert(newVal);
}
}
},
// ...
});

ExtJS: add checkbox column "on-the-fly"

I have a custom 'class' which extends Ext.grid.GridPanel. I would like to have a column of checkboxes (example which uses Ext.ux.grid.CheckboxColumn - just the thing i need).
My goal is to use it with pre-generated configuration object, including column model (it's generated by a PHP script), so I overloaded initComponent method to add column inside it:
MyGrid = Ext.extend
(
Ext.grid.GridPanel
,{
initComponent : function()
{
this.columns.push({
xtype : 'checkcolumn'
,header : 'Show on map ?'
,dataIndex : 'showonmap'
,width : 130
});
Ext.apply(this, {columns:this.columns});
MyGrid.superclass.initComponent.apply(this, arguments);
}
}
);
Such thing worked with ActionColumn component, but this code fails, because it can't find constructor (probably for CheckColumn).
How should I modify my code or CheckColumn to make this thing work?
Thanks in advance!
If the constructor can't be found, you must not have imported the CheckColumn class properly. Try this to see if the constructor can be found directly:
MyGrid = Ext.extend
(
Ext.grid.GridPanel
,{
initComponent : function()
{
this.columns.push(new Ext.ux.grid.CheckColumn({
,header : 'Show on map ?'
,dataIndex : 'showonmap'
,width : 130
}));
Ext.apply(this, {columns:this.columns});
MyGrid.superclass.initComponent.apply(this, arguments);
}
}
);
If you get an exception that Ext.ux.grid.CheckColumn is not a constructor, then you know for sure the classes isn't avaiable. Make sure that you have included the class properly, and you can verify using Firebug that the source was actually included and is available.

Resources