I'm trying to delegate an event for multiple items by a common class name, but, it seems not to be working. Delegating for multiple IDs should work but I'm getting an error message about: "Invalid ComponentQuery selector".
This is what I have at the moment:
Ext.define("App.view.Main", {
extend : "Ext.Container",
config : {
listeners : {
disclose : {
fn : "onElementDisclose",
delegate : [ "#onelist", "#anotherlist" ] // this don't work
// delegate : ".lists" <- this also don't work
// delegate : "#onelist, #anotherlist" <- this don't work either
// delegate : "#onelist" <- but this work!
}
},
},
initialize : function() {
this.callParent(arguments);
this.add([ {
xtype : "slideshow",
}, {
xtype : "onelist",
}, {
xtype : "anotherlist",
} ]);
},
onElementDisclose : function () {
console.log("click");
},
});
Both lists have "onItemDisclosure : true" and "cls: lists".
How can I achieve this?
This certainly works to a degree and you don't have to delegate it in the controller as demonstrated here:
Ext.application({
name: 'Fiddle',
launch: function() {
Ext.create('Ext.Panel', {
fullscreen: true,
title: 'Test',
layout: 'vbox',
items: [{
xtype: 'panel',
layout: 'fit',
flex: 1,
items: [{
docked: 'top',
xtype: 'titlebar',
title: 'List 1'
}, {
xtype: 'list',
name: 'list 1',
cls: 'myList',
id: 'list1',
onItemDisclosure: true,
itemTpl: "List1 item {name}",
model: Ext.define('User', {
extend: 'Ext.data.Model',
config: {
fields: [{
name: 'name',
type: 'string'
}]
}
}),
data: [{
name: 'John'
}, {
name: 'Jane'
}]
}]
}, {
xtype: 'panel',
layout: 'fit',
flex: 1,
items: [{
docked: 'top',
xtype: 'titlebar',
title: 'List 2'
}, {
xtype: 'list',
name: 'list 2',
cls: 'myList',
id: 'list2',
onItemDisclosure: true,
itemTpl: "List2 item {make}",
model: Ext.define('Car', {
extend: 'Ext.data.Model',
config: {
fields: [{
name: 'make',
type: 'string'
}]
}
}),
data: [{
make: 'Volkswagen'
}, {
make: 'Audi'
}]
}]
}],
listeners: {
disclose: {
fn: function(list, record, target, index, e, eOpts) {
console.log(list);
var greeting = '';
if (typeof(record.data.make) != 'undefined') {
greeting = "I am a car and my make is " + record.data.make + "!";
} else if (typeof(record.data.name) != 'undefined') {
greeting = "I am a user and my name is " + record.data.name + "!";
};
console.log('disclosing from list ' + list.config.name, greeting);
},
// delegate : 'list' // this works as you are querying by xtype of list
// delegate : 'component [onItemDisclosure]' // this works as you are targeting by attribute of onItemDisclosure
// delegate : '[onItemDisclosure]' // this works as you are targeting by attribute
// delegate : '[name="list 1"]' // this works as you are targeting by attribute of name = 'list 1'
// delegate : '[cls="myList"]' // this unfortunately doesn't work
// delegate : "#list1, #list2" <- this don't work either
// delegate : "#list1" <- but this work!
}
}
});
}
});
However there are some pitfalls with the above as you can see.
Demo: https://fiddle.sencha.com/#fiddle/g49
You cannot fire same function using common events on multiple control defining listeners in view.
Yes you can do the same in controller. it will work undoubtedly..
Thanks
Sachin
Related
i have json like this.
firstName: 'xyz',
comments : [{
emailAddress : "abc#gmail.com", body : "PQR",
emailAddress : "xyz#gmail.com", body : "XYZ",
}]
i want to show firstName in the textfield which is editable. and want to show comments in the grid. i am not able to understand how to do it. please help me with that.
my view is following:
Ext.define("SampleView", {
extend: "Ext.panel.Panel",
alias: 'widget.sample',
id : 'sampleVId',
requires: ['StudentViewModel'],
viewModel: {
type: 'StudentViewModel'
},
layout: {
type: 'vbox',
align: 'stretch'
},
initComponent: function() {
Ext.apply(this, {
items: [this.form(), this.grid()],
});
this.callParent(arguments);
},
grid: function(){
return {
xtype: 'grid',
reference: 'samplegrid',
id : 'samplegridId',
bind: {
store: '{comment}'<-- not able to do the binding
},
flex:1,
margin: 10,
plugins: {
ptype: 'rowediting',
clicksToEdit: 2
},
columns: [{
text: 'Email',
dataIndex: 'email',
flex: 1,
editor: {
allowBlank: false
}
}, {
text: 'Role',
dataIndex: 'body',
}],
}
}
},
form : function(){
return{
xtype : 'form',
items:[{
xtype: 'textfield',
fieldLabel: 'First Name',
bind: {
value: '{firstName}'<---- how to bind this valuw to textfield
}
}]
}
}
});
my view model is like this:
Ext.define('StudentViewModel', {
extend: 'Ext.app.ViewModel',
alias:'viewmodel.StudentViewModel',
requires: [
'Student'
],
stores: {
orderStore: {
autoLoad:true,
type: 'sampleS'
}
}
});
my model is like this:
Ext.define('Student', {
extend: 'Ext.data.Model',
idProperty: 'Id',
schema: {
namespace: 'sample',
proxy: {
type:'ajax',
url: 'users.json',
reader:{
type:'json',
rootProperty:'data'
}
}
},
fields: [
{ name: 'Id', type: 'int' },
{ name: 'firstName', type: 'string' },
]
});
Your binding would have to be based on the record selected.
Your model for student needs to be defined to have a hasMany reference to a comments model so a proper store is built to be bound, or you would have to dynamically create a store based on the array data within the model. I would suggest just using a relation, its easier to do in the long run.
where you have the binding of
value: {firstName}
It should be
value: {student.firstName}
In your view controller you would have to bind student to the student model you are trying to display in the form using a line that looks like
vm.setValue('student', YOURMODELOBJECTHERE);
If the student model has a proper has many relation for comments, then the rest should be okay.
I have an attribute in the extjs code defined as :
datajson: {
'name' : 'Hello',
....
}
Now I need to set the value of a textfield to the name defined inside this attribute.
I have tried the following but its not working:
Ext.getCmp('name').setValue((this.datajson.xyz.name).toString());
The id of the textfield whose value I am trying to set is 'name'
Here is the full code structure.
Ext.define('Test', {
extend : 'Ext.Container',
alias : 'widget.myapp',
datajson:{
'xyz' : {
...
"name" : 'Hello',
...
}
},
initComponent : function() {
this.appcombo = Ext.create('Ext.form.field.ComboBox', {
store: Ext.create('Ext.data.Store', {
fields: ['text'],
data: [
{text: "a"},
{text: "b"},
{text: "c"}
]
}),
listeners: {
select: function(combo, record, index) {
Ext.getCmp('name').setValue((this.datajson.xyz.name).toString());
}
}
});
...
...
//Here we have a textfield within a Panel whose id is 'name'
So basically I am loading the page and then selecting one value in combo box which serves as the event to load the values in the text-fields with the data which is in datajson.
EDIT: More information added.
The scope within your select function no longer contains datajson. To continue to use this.datajson you can pass the required scope into the function using bind
Ext.application({
name: 'Fiddle',
datajson: {
'name': 'Hello'
},
displayName: function (combo, record, index) {
Ext.getCmp('name').setValue((this.datajson.name));
},
launch: function () {
Ext.create('Ext.form.Panel', {
title: 'Contact Info',
width: 300,
bodyPadding: 10,
renderTo: Ext.getBody(),
items: [{
xtype: 'combo',
store: Ext.create('Ext.data.Store', {
fields: ['text'],
data: [{
text: "a"
}, {
text: "b"
}, {
text: "c"
}]
}),
listeners: {
select: this.displayName.bind(this)
}
}, {
xtype: 'textfield',
id: 'name',
fieldLabel: 'Name'
}]
});
}
});
In sencha touch application I got views, one of them contains a list.
If I switch from the view which contains the list to another view and back, the list itemtap event not fires again.
My view with the list:
Ext.define('app.view.ItemList', {
extend: 'Ext.navigation.View',
xtype: 'listitems',
config: {
title: 'List',
items: [
{
xtype: 'toolbar',
ui: 'light',
docked: 'top',
title: 'List',
items: [
{
xtype: 'button',
text: 'Back',
ui: 'back',
handler: function() {
Ext.Viewport.animateActiveItem({xtype:'main'}, {type:'slide'});
}
},
]
},
{
xtype: 'list',
itemTpl: '{"name"}',
store: {
autoLoad: true,
fields: ['name', 'email'],
proxy: {
type: 'rest',
url: 'data/data.json',
reader: {
type: 'json'
}
}
}
}]
},
initialize: function() {
this.callParent();
}
})
Controller for this:
Ext.define('app.controller.Main', {
extend: 'Ext.app.Controller',
config: {
refs: {
listitems: 'listitems'
},
control: {
'listitems list': {
itemtap: 'showItem',
}
}
},
showItem: function(list, index, element, record) {
this.getItemlist().push({
xtype: 'panel',
title: record.get('name'),
html: [
"<b>Name:</b> " + record.get('name') +
"<b>Email:</b> " + record.get('email')
],
scrollable: true,
styleHtmlContent: true
})
}
})
I tried it also with id, itemId, nothing worked.
How could I solve this?
Please try sth like this:
this.getItemlist().push(
Ext.create('Ext.panel.Panel,{
title: record.get('name'),
html: [
"<b>Name:</b> " + record.get('name') +
"<b>Email:</b> " + record.get('email')
],
scrollable: true,
styleHtmlContent: true
})
)
and don't forget to use getItemlist().pop() when back button is clicked! In my app, the back button did not (or not always) remove the view on top of the stack. It gets even worse when adding loadmasks and ActionSheets.
I want to pass the an ID from a Tabview (myView1) to a Controller(theController) then after that I want that Controller class to pass data to another Tabview (myView2) at the same Panel. Anyone has any Idea, how can I do this?
You can do like this
in your controller:
config:{
refs:{
myView1: "myView1Ref",
myView2: "myView2Ref"
},
controls:{
myView1:{
idgiven: "onIdGiven"
}
}
},
onIdGiven: function(id){
this.getMyView2().setData(yourData);
}
in MyView1, when you want to give the id, just do
this.fireEvent(yourId);
This is my Tab Panel View class (MyTabPanel)
Ext.define('MyApp.view.MyTabPanel', {
extend: 'Ext.tab.Panel',
config: {
items: [
{
xtype: 'container',
title: 'Tab 1',
id: 'tab1',
items: [
{
xtype: 'textfield',
label: 'User'
},
{
xtype: 'container',
height: 46,
margin: '5px',
items: [
{
xtype: 'button',
ui: 'action',
width: 173,
text: 'Send Data'
}
]
}
]
},
{
xtype: 'container',
title: 'Tab 2',
id: 'tab2',
tpl: [
'{id}'
]
},
{
xtype: 'container',
title: 'Tab 3',
id: 'tab3'
}
]
}
});
This is my Controller :
Ext.define('MyApp.controller.MyController', {
extend: 'Ext.app.Controller',
config: {
refs: {
Tab1: '#tab1',
Tab2: '#tab2',
Tab3: '#tab3'
},
control: {
"Tab2": {
activate: 'onTabpanelActivate1'
}
}
},
onTabpanelActivate1: function(newActiveItem, container, oldActiveItem, eOpts) {
var Rec = [{id:1}]; // this should come from my #tab1 tab and set to #tab2 tab
this.getTab2().setRecord(Rec); // So this is the problem I am facing
}
});
Ext.define('myapp.controller.theController', {
extend: 'Ext.app.Controller',
config: {
refs: {
views: [
'myapp.view.myView1',
'myapp.view.myView2',
],
refMyView1: 'myView1',
refMyView2: 'myView2',
},
control: {
'button[action=submit]':{ // on tab of submit button
tap: 'submitTapHandler'
},
},
},
submitTapHandler: function(){
var view1data = this.getRefMyView1().getValues(); // view1data contain all field data of view1 in record form
//controller to view pass data
var myView2 = Ext.create('myapp.view.myView2');
// create a record that key value have name of fields and value to pass to that field
var record;
// set record key value
myView2.setRecord(record);
}
})
1.Could please anybody help me with this issue?
1.After clicking on data detail I need see something as bellow (NotesApp.view.NoteEditor):
1.button_1
1.html + {title} + html
1.button_2
1.html + {narrative} + html
app.js
Ext.application({
name: "NotesApp",
models: ["Note"],
stores: ["Notes"],
controllers: ["Notes"],
views: ["NotesList", "NoteEditor"],
launch: function () {
var notesListView = {
xtype: "noteslistview"
};
var noteEditorView = {
xtype: "noteeditorview"
};
Ext.Viewport.add([notesListView, noteEditorView]);
}
});
NotesApp.model.Note
Ext.define("NotesApp.model.Note", {
extend: "Ext.data.Model",
config: {
idProperty: 'id',
fields: [
{ name: 'id', type: 'int' },
{ name: 'title', type: 'string' },
{ name: 'narrative', type: 'string' }
]
}
});
NotesApp.store.Notes
Ext.define("NotesApp.store.Notes", {
extend: "Ext.data.Store",
config: {
model: "NotesApp.model.Note",
data: [
{ title: "Ibuprofen STDATA 200", narrative: "LIEK"},
{ title: "Ibuprofen STDATA 450", narrative: "LIEK"},
{ title: "IbuprofANIN", narrative: "LATKA"}
]
}
});
NotesApp.controller.Notes
Ext.define("NotesApp.controller.Notes", {
extend: "Ext.app.Controller",
config: {
refs: {
notesListView: "noteslistview",
noteEditorView: "noteeditorview",
notesList: "#notesList"
},
control: {
notesListView: {
editNoteCommand: "onEditNoteCommand"
},
noteEditorView: {
backToHomeCommand: "onBackToHomeCommand"
}
}
},
slideLeftTransition: { type: 'slide', direction: 'left' },
slideRightTransition: { type: 'slide', direction: 'right' },
activateNoteEditor: function (record) {
var noteEditorView = this.getNoteEditorView();
noteEditorView.setRecord(record);
Ext.Viewport.animateActiveItem(noteEditorView, this.slideLeftTransition);
},
activateNotesList: function () {
Ext.Viewport.animateActiveItem(this.getNotesListView(), this.slideRightTransition);
},
onEditNoteCommand: function (list, record) {
this.activateNoteEditor(record);
},
launch: function () {
this.callParent(arguments);
var notesStore = Ext.getStore("Notes");
notesStore.load();
},
init: function () {
this.callParent(arguments);
}
});
NotesApp.view.NotesList
Ext.define("NotesApp.view.NotesList", {
extend: "Ext.Container",
requires:"Ext.dataview.List",
alias: "widget.noteslistview",
config: {
layout: {
type: 'fit'
},
items: [{
xtype: "toolbar",
title: "Liek",
docked: "top",
}, {
xtype: "list",
store: "Notes",
itemId:"notesList",
onItemDisclosure: true,
itemTpl: "<div>{title}</div><div>{narrative}</div>"
}],
listeners: [ {
delegate: "#notesList",
event: "disclose",
fn: "onNotesListDisclose"
}]
},
onNotesListDisclose: function (list, record, target, index, evt, options) {
console.log("editNoteCommand");
this.fireEvent('editNoteCommand', this, record);
}
});
NotesApp.view.NoteEditor
Ext.define("NotesApp.view.NoteEditor", {
extend: "Ext.Container",
requires:"Ext.dataview.List",
alias: "widget.noteeditorview",
initialize: function () {
this.callParent(arguments);
},
config: {
// this is working !!!
// tpl: [
// '<div><p>Info about: {title} </p></div>'
// ],
items: [
{
xtype: "button",
text: '<div style="text-align:left;">button 1<div>',
ui: "action",
id:"button_1"
},
{
xtype: 'list',
itemTpl: [
'<div>title: {title} </div>' // working not !!!
]
},
{
xtype: "button",
text: '<div style="text-align:left;">button 2<div>',
ui: "action",
id:"button_2"
},
{
xtype: 'list',
itemTpl: [
'<div>title: {narrative} </div>' // working not !!!
]
}
]
},
});
in your controller, you attach the onEditNoteCommand handler to the editNoteCommand. This is not a valid event (and is never triggered) of the Ext.dataview.List object as you can see in the Sencha documentation.
You have to attach the handler to an existing event, in this case to the itemtap one:
control: {
notesListView: {
itemtap: "onEditNoteCommand"
},
...
Problem
You created NotesApp.view.NoteEditor as list, within that list you have two separate list for title and narrative and But in controller you setting data only for NoteEditor list, not for two list within NoteEditor, so that two list will not show any data because they didn't get data.
Can do like this
In view
Give itemId for that two list.
{
xtype: 'list',
itemId : 'title',
itemTpl: [
'<div>title: {title} </div>' // working not !!!
]
},
{
xtype: "button",
text: '<div style="text-align:left;">button 2<div>',
ui: "action",
id:"button_2"
},
{
xtype: 'list',
itemId : 'narrative',
itemTpl: [
'<div>title: {narrative} </div>' // working not !!!
]
}
In controller
activateNoteEditor: function (record) {
var noteEditorView = this.getNoteEditorView();
noteEditorView.getComponent('title').setData(record.getData().title);
noteEditorView.getComponent('narrative').setData(record.getData().narrative);
Ext.Viewport.animateActiveItem(noteEditorView, this.slideLeftTransition);
},
What you trying to do ?
First of all NotesApp.view.NoteEditor is to edit note with two fields for title and narrative.
Why you have two list for title and narrative ?
What is the purpose of that list in edit screen ?