navigate to next view on image tap? - extjs

I am using dataview itemTpl to display my images (thumbnail view).
I am able to display the images properly. How can I add itemtap on these images?
So that when I tap on a particular image a new view is shown with the tapped image?
I tried this with controller but no luck. Can you help me solving this.
I am using Sencha Architect 2 for my example.
I am trying this code .Please correct me
First View
Ext.define('MyApp.view.MyPanel', {
extend: 'Ext.Panel',
alias: 'widget.galleryview',
config: {
layout: {
type: 'fit'
},
items: [
{
xtype: 'dataview',
id: 'gallerythumbnail',
layout: {
type: 'fit'
},
itemTpl: [
'<div class="lb-album">',
' <ul>',
' <li>',
' <img src="{filename}" width="120px" heigth="120px"/>',
' </li>',
' </ul> ',
'</div>'
],
store: 'ImageStore'
}
]
}
});
Second View - this view must be displayed when img is tapped
Ext.define('MyApp.view.FullViewPanel', {
extend: 'Ext.Panel',
config: {
layout: {
type: 'fit'
},
items: [
{
xtype: 'carousel',
id: 'mycarousel'
}
]
}
});
Controller
Ext.define('MyApp.controller.GalleryController', {
extend: 'Ext.app.Controller',
config: {
refs: {
nav: 'galleryview'
},
control: {
"dataview": {
itemtap: 'viewFullScreen'
}
}
},
viewFullScreen: function(dataview, index, target, record, e, options) {
Ext.ComponentQuery.query('galleryview').push('MyApp.view.FullView');
console.log(record);
}
});
Thank You

If you only want to do it on image tap you can check for the event in that listener.
Method 1
listeners : {
itemtap: function (list, index, item, record, senchaEvent) {
if (senchaEvent.event.target.nodeName == 'IMG') {
// Show next view
}
}
}
I used like this
Ext.create('Ext.List', {
itemCls : 'my-dataview-item',
id : 'myList',
itemTpl : '<div><img src="' + localStorage.httpServerPrefix + '{imageURI}"/><span id="name">{fullname}</span></div>',
store : aroundStore,
listeners : {
itemtap: function (list, index, item, record, senchaEvent) {
if(senchaEvent.event.target.nodeName =='IMG') {
me.othersProfileImageClicked(record.data);
}
else
me.onMessageClickedInAround(list, record);
}
}
});
Update
listeners : {
itemtap: function (dataview,index,target,record,e,option) {
if (e.event.target.nodeName == 'IMG') {
// Show next view
}
}
}
Method 2
You can use event delegation, Like this
Ext.create('Ext.List', {
itemCls : 'my-dataview-item',
id : 'myList',
itemTpl : '<div><img src="' + localStorage.httpServerPrefix + '{imageURI}"/><span id="name">{fullname}</span>',
store : aroundStore,,
listeners: [{
element: 'element',
delegate: 'img',
event: 'tap',
fn: function() {
alert('One!');
}
}
]
});

Related

How to change "data" value in viewmodel from store listener?

I binded a placeHolder in 'selectfield' like this:
{
xtype : 'selectfield',
bind : {
store : '{chapters}',
placeHolder : '{chapterPlaceHolder}'
}
}
Now i want to change the data of 'chapterPlaceHolder' in the ViewModel from store listener:
Ext.define('SomeViewModel', {
extend : 'Ext.app.ViewModel',
data : {
chapterPlaceHolder : null
},
stores : {
chapters : {
model : 'model.SiteChapter',
listeners: {
datachanged: function() { how to change the 'chapterPlaceHolder' in data? }
}
}
}
});
Hope i was clear enoght...
Define the event handler on a view controller. View controllers provide a method, getViewModel, to access the view model. The controller should be configured on the same class as the view model. This example assumes that is the select field.
Ext.define('Fiddle.app.ViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.FiddleViewModel',
data: {
chapterPlaceHolder: null
},
stores : {
chapters: {
listeners: {
datachanged: 'dataChangedHandler'
}
}
}
});
Ext.define('Fiddle.app.ViewController', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.FiddleViewController',
dataChangedHandler: function(store, eOpts) {
this.getViewModel.set('chapterPlaceHolder', ...);
}
});
{
xtype: 'selectfield',
bind: {
store : '{chapters}',
placeHolder : '{chapterPlaceHolder}'
},
controller: 'FiddleViewController',
viewModel: {
type: 'FiddleViewModel'
}
}
You need to get viewmodel inside of datachanged event. After getting viewmodel you can use get or set to change value of any field inside of view-model.
In this FIDDLE , I have created a demo using your code and put my efforts in same code. I hope this will help/guide you to achieve your requirement.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.define('SomeViewModel', {
extend: 'Ext.app.ViewModel',
alias: "viewmodel.demoVM",
data: {
chapterPlaceHolder: null
},
stores: {
chapters: {
listeners: {
datachanged: function () {
var vm = Ext.ComponentQuery.query('#myform')[0].getViewModel();
vm.set('chapterPlaceHolder', 'data changed event called......');
//how to change the 'chapterPlaceHolder' in data ?
}
}
}
}
});
Ext.create('Ext.form.Panel', {
itemId: 'myform',
fullscreen: true,
viewModel: {
type: 'demoVM'
},
defaults: {
margin: 20
},
items: [{
xtype: 'fieldset',
items: [{
xtype: 'selectfield',
autoSelect: false,
bind: {
store: '{chapters}',
placeHolder: '{chapterPlaceHolder}'
}
}]
}, {
xtype: 'button',
text: 'Load Data In store ',
handler: function (btn) {
var vm = btn.up('formpanel').getViewModel();
vm.get('chapters').loadData([{
text: 'First Option',
value: 'first'
}, {
text: 'Second Option',
value: 'second'
}, {
text: 'Third Option',
value: 'third'
}]);
//You can also set like below
//vm.set('chapterPlaceHolder', 'Data loaded on button click......');
}
}]
});
}
});

Sencha Touch 2.x : Specifying Listeners in Config - howto

I am trying to add listeners of the itemtap event in a list view, however, when the list shows up correctly (ie loads from the store), and I tap an item of the list, the listener function is not triggered
Is this because I can't define the listeners inside config: in Ext.define()?
Thanks
Ext.define('Volt.view.FeedView', {
extend: 'Ext.Panel',
xtype: 'feedViewCard',
config: {
iconCls: 'home',
title: 'FeedView',
layout: {
type: 'vbox'
},
items: [
{
xtype: 'list',
itemTpl: '<div class="list-item-title">{title}</div> <div class="list-item-narrative">{narrative}</div>',
flex: 1,
listeners: {
itemtap: function(list, index, target, record, e, eOpts ){
console.log('List tapped , xtype = ' , list.getXTypes() );
debugger;
} //however when the list shows up and I tap the items, this function is not triggered
},
initialize: function(){
console.log('listview initialize');
console.log('XType = ',this.getXTypes(),'id = ',this.getId());
//console.log('XType = ',list.getXTypes());
//debugger;
this.setStore(Ext.getStore('Feeds'));
}
}
]
},
});

How to call other view in Sencha Touch

How can I call a new view on image tap which is defined in tpl.
Code:
tpl: Ext.create('Ext.XTemplate','<tpl for="sample">',
'<div> {tittle}</div>
<div><img src="{photo}"/></div>',
'</tpl>',
/////////////////////////////////////////
After your directions, I'm sure I have something wrong. I just want to know how to link an image to puncture it take you to another view. Let me explain better?
Thank you very much for your time and dedication.
//MyController
Ext.define('DemoApp.controller.ControllerR', {
extend: 'Ext.app.Controller',
config: {
refs: {
res: 'res',
},
control: {
'rest list': {
itemtap: 'showR' },
}
},
onCreateNewView: function() {
if(document.getElementById('something')) {
Ext.Viewport.setActiveItem(Ext.create('DemoApp.view.DetalTwo'));
}
},
});
//My Template
Ext.define('DemoApp.view.ViewR', {
extend: 'Ext.Panel',
xtype: 'res',
config: {
title: 'Res',
iconCls: 'info',
scrollable: true,
data: {
res: [ model: 'DemoApp.model.ModelR',
autoLoad: true,
storeId: 'resStore',
proxy: {
type: 'ajax',
url: 'data/res.json',
reader: {
type: 'json',
rootProperty:'wha.res'
}
}]
},
tpl: Ext.create('Ext.XTemplate','<tpl for="sample">',
'<div> {tittle}</div>
<div><img id="something "src="{photo}"/></div>',
'</tpl>',
{
join: function(value) {
return value.join(', ');
}
})
}
});
You can give an id to image tag i.e. <img id = "something"/> and if tpl is defined for list then go to that list's handling function in controller or in view(where you defined a list and listeners) and write this code:
if(document.getElementById('Your img tag id')) {
// create a view and active it
}
For Example:
onCreateNewView: function() {
if(document.getElementById('something')) {
Ext.Viewport.setActiveItem(Ext.create('DemoApp.view.NewView'));
}
}
First thing first... you should do some google before putting such question in Stack.Your Code is totally wrong as well as it contains major syntax errors. And we are not here to solve some stupid syntax errors.Anyways Let me explain something..
1.) In your controller you are trying to bind 'itemtap' event.You can only bind 'itemtap' event if there is a list in your view. Here, in your case there is no list.
2.) And in controller it's look like something this:
refs: {
imageList: '#imageList',
},
control: {
'imageList': {
itemtap: 'onCreateNewView'
},
}
3.) Create a list in your view:
config: {
items: [
{
xtype: 'list',
id: 'imageList',
itemId: 'imageList',
tpl:'Your tpl code'
}
]
}

How to add a (existing) panel into a region on a Tree ItemClick

I think this is just simple, but I have no idea, how to load an existing panel on Tree ItemClick in the region of a viewport!?
TreeController snipped
init: function() {
this.control({
'treemenu': {
itemclick: function(view, node, record, item, index, e ) {
if(node.isLeaf()) {
}
},
itemexpand: function (t,e){
console.log(t.data.value);
}
}
});
}
Viewport snipped:
{
region: 'center',
layout: 'fit',
items: [{
xtype: ''
}]
}
The GridPanel:
Ext.define('MyProject.view.FlyerGrid', {
extend: 'Ext.grid.Panel',
alias: 'widget.flyergrid',
border:'0 0 0 0',
title:'Flyer Übersicht',
bbar: Ext.create('Ext.toolbar.Paging', {
//store: store
}),
columns: [
{ text: 'Typ', dataIndex: 'type',flex:1 },
{ text: 'year', dataIndex: 'year' ,flex:1},
]
});
First define a ref that will fetch the panel and the view
refs: [{
ref: 'panel',
selector: 'panel[region=center]' // you might give the panel a itemId instead of using region=center
}]
and a controller method that will add the view
showPanel: function(view, node, record, item, index, e ) {
if(node.isLeaf) {
var grid= this.getFlyerGrid();
if(!grid) {
this.getPanel().add({xtype:'flyergrid'});
}
}
}
As a alternative way for the ref you can also use Ext.ComponentQuery let's say if you need a grid for each record Id and remove a old
showPanel: function(view, node, record, item, index, e ) {
if(node.isLeaf) {
var grid= Ext.ComponentQuery.query('flyergrid[itemId=record.data.id]');
if(!grid) {
var panel = this.getPanel();
Ext.suspendLayouts();
panel.removeAll();
panel.add({xtype:'flyergrid',itemId:record.data.id});
Ext.resumeLayouts(true);
}
}
}
Update your control
this.control({
'treemenu': { itemclick: this.showPanel}
}
});
Please note that all this code is untested and should just show you the trick.

Access data of a parent component from a child component in Sencha Touch 2

I am writing a Sencha Touch 2 app. I have recently got stuck with the following problem.
I have a Container view which has data bound to it with setRecord(myRecord). So my question is what's the right way to populate my subcomponents with this data?
Here is my code(simplified for brevity):
Ext.define('MyApp.model.Item', {
extend: 'Ext.data.Model',
config: {
fields: ['name', 'description', 'image'],
proxy: { /* proxy config */ }
}
});
Ext.define('MyApp.view.DetailsView', {
extend: 'Ext.Container',
xtype: 'itemdetails',
config: {
layout: 'hbox',
items: [
{
xtype: 'container',
flex: 1,
layout: 'vbox',
items: [
{
xtype: 'img',
src: '' // SHOULD BE POPULATED FROM DATA.image
},
{
xtype: 'button',
text: 'Buy',
action: 'buyItem'
}
]
},
{
flex: 3,
tpl: '<h1>{name}</h1><p>{description}</p>' // SHOULD BE POPULATED FROM DATA
}
]
}
});
And here is the code that populates and shows my view from a controller:
Ext.define('Myapp.controller.Main', {
...
refs: {
itemDetails: {
selector: '',
xtype: 'itemdetails',
autoCreate: true
}
}
routes: {
'item/details/:id': 'showItemDetails'
},
...
showItemDetails: function(id) {
MyApp.model.Item.load(id, {
callback: function(item){
var card = this.getItemDetails();
card.setRecord(item);
this._showCard(card);
},
scope: this
});
}
});
I first implemented it with a simple Container containing a 'tpl', but in this case I was not able to have a button inside it, which would be queryable from the controller. Any ideas?
Thx, in advance.
Taken from a comment in the Sencha Touch docs for Ext.Component, add a setRecords function that recursively sets the record on each item in the items component hierarchy:
setRecords: function(component, record) {
me = this;
component.getItems().each(function(item) {
if (typeof item.setRecord == 'function') {
item.setRecord(record);
}
//set record on all subitems
if (typeof item.getItems == 'function') {
var subItems = item.getItems();
if (subItems.getCount() > 0) {
me.setRecords(item, record);
}
}
});
}
and then override setRecord to call the new function:
setRecord: function(record) {
result = this.callParent([record]);
this.setRecords(this, record);
return result;
}
So now no more need to explicitly set the data on specific components

Resources