How to access the view from within dataview's tpl in ExtJS6? - extjs

I am trying to test against a combobox value from inside dataview's tpl:
Ext.define('MyForm', {
extend: 'Ext.form.Panel',
items: [
{
xtype: 'combo',
name: 'my_combo',
},
{
xtype: 'dataview',
tpl: new Ext.XTemplate(
'<tpl for=".">',
'<tpl if="this.test()">pass</tpl>',
'</tpl>'
,
{
test: function(){
//doesn't work
return this.getView().down('[name=my_combo]').getValue() == 'ok';
}
}),
}
]
});
This doesn't work because this is referencing to the template itself and I can't figure out how to access the view from the inside.

It is not possible to access a view in XTemplate. To achieve this you can use ViewModel, here is the code for it.
And working sencha fiddle https://fiddle.sencha.com/#fiddle/175s
Update: I updated the code to use the DataView, DataView is little tricky, i overwritten the prepareData method to pass in extra information to the template and also updating the DataView whenever the combo value is changed. Here is the fiddle with updated changes https://fiddle.sencha.com/#fiddle/175s
Ext.define('MyApp.MyPanel', {
extend: 'Ext.Panel',
xtype: 'myForm',
defaults: {
padding: 10
},
viewModel: {
stores: {
employeeStore: {
fields: ['name'],
data: [{
name: 'John'
}, {
name: 'Tempel'
}, {
name: 'George'
}, {
name: 'Milinda'
}]
},
}
},
items: [
{
xtype: 'combobox',
fieldLabel: 'Name',
name: 'nameField',
queryMode: 'local',
displayField: 'name',
valueField: 'name',
reference: 'emp',
bind: {
store: '{employeeStore}',
value: '{name}'
}
},{
xtype: 'dataview',
itemId: 'empList',
tpl: new Ext.XTemplate(
'<tpl for=".">',
'<div class="dataview-multisort-item">',
'<h3>{name}</h3>',
'<tpl if="passed">Selected</tpl>',
'</div>',
'</tpl>'
),
itemSelector: 'div.dataview-multisort-item',
bind: {
store: '{employeeStore}'
},
prepareData: function(data, index, record) {
var name = this.up().getViewModel().get('name');
var passed = record.get('name') == name;
return Ext.apply({passed: passed}, data);
}
}
],
initComponent: function() {
this.callParent(arguments);
var me = this;
// refresh the dataview when name is changed.
this.getViewModel().bind('{name}', function() {
var dataview = me.down('#empList');
dataview.refresh();
});
}
});

Related

How to show whitespaces in combo list?

I have combo with lots of whitespaces in values, when I select item - whitespaces are displaying. However they are missing in list. See demo:
https://fiddle.sencha.com/#view/editor&fiddle/3i1v
Is it possible to show ALL whitespaces in combo list?
You can override template with custom function which will replace spaces with none breaking space - &nbsp. Something like:
var states = Ext.create('Ext.data.Store', {
fields: ['name'],
data: [
{
"name": "Alabama 3"
}, {
"name": "Alaska 11"
}
]
});
Ext.application({
name: 'MyApp',
launch: function () {
Ext.create('Ext.form.Panel', {
items: [{
xtype: 'combo',
fieldLabel: 'Choose State',
store: states,
displayField: 'name',
tpl: Ext.create('Ext.XTemplate',
'<ul class="x-list-plain"><tpl for=".">',
'<li role="option" class="x-boundlist-item">{[this.replaceSpacesWithNbsp(values.name)]}</li>',
'</tpl></ul>',
{
replaceSpacesWithNbsp: function(name){
return name.replaceAll(' ', '&nbsp');
},
}
),
renderTo: Ext.getBody()
}]
});
}
});

Sencha ExtJs 7.2.0 MVVM Dataview itemSelector issue Uncaught TypeError: Cannot read property 'internalId' of null

I have a view with a Panel containing a DataView and a paging tool bar.
I have a viewModel with a store bound to the DataView and the paging tool bar.
If I have the DataViews itemSelector set to my-x-asset then everything loads as expected, I can page and all looks great, but I do not have any itemclick events.
If I set the DataViews itemSelector to .my-x-asset or div.my-x-asset the the DataView appears to load but the mask never clears and I get an error in the console
Uncaught TypeError: Cannot read property 'internalId' of null
I have added an updateIndexes function to my DataView for debugging and it finds all records and all the internalId's
I've been looking at this for 2 days, trying different permutations but no joy.
Please help, blocker for me.
ViewModel
Ext.define('xxxx.view.dataview.BrowseAssetsModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.browseassets',
requires: [
'xxxx.store.AssetBrowse'
],
stores: {
AssetBrowse: {
type:'assetbrowse',
autoLoad: true,
listeners: {
load: 'onBrowseStoreLoad'
}
}
}});
View:
Ext.define('xxxxxx.view.dataview.BrowseAssets', {
extend: 'Ext.panel.Panel',
xtype: 'dataview-browseassets',
requires: [
'Ext.data.*',
'Ext.toolbar.TextItem',
'Ext.view.View',
'Ext.ux.BoxReorderer',
'Ext.ux.DataView.Animated',
'Ext.util.*',
'xxxxxx.view.dataview.BrowseAssetsController',
'xxxxxx.view.dataview.BrowseAssetsModel'
],
controller: 'browseassets',
viewModel: {
type: 'browseassets'
},
title: 'Browse Assets',
layout: 'fit',
items: {
xtype: 'dataview',
reference: 'dataview',
plugins: {
'ux-animated-dataview': true
},
id: 'my-x-gallery',
emptyText: 'No assets to display',
scrollable: true,
itemSelector: "div.my-x-asset",
overItemCls: 'my-x-asset-hover',
tpl: [
'<tpl for=".">',
'<div id="{file_id}" class="my-x-asset">',
'<img {thumbnailSize} src="/modules/GETIMAGE.php?id={file_id}&type=thumb" title="{title}" alt="{title}"/>',
'<div class="my-x-desc">{shortName:htmlEncode}</div>',
'<div class="my-x-desc">{ICONS}</div>',
'</div>',
'</tpl>',
'<div class="clear"></div>'
],
prepareData: function(data) {
Ext.apply(data, {
shortName: Ext.util.Format.ellipsis(data.title, 15),
sizeString: Ext.util.Format.fileSize(data.sizeinbytes),
dateString: Ext.util.Format.date(data.modifiedate, "m/d/Y g:i a")
});
return data;
},
listeners: {
itemclick: 'onAssetSelect',
itemdblclick: 'onAssetDoubleClick'
},
store:{},
bind: {
store: '{AssetBrowse}'
},
updateIndexes : function(startIndex, endIndex) {
var ns = this.all.elements,
records = this.store.getRange(),
i, j;
console.log(records);
// console.log(ns);
startIndex = startIndex || 0;
endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length - 1));
for(i = startIndex; i <= endIndex; i++){
if (!Ext.fly(ns[i]).is('.ioi-x-asset')) {
console.log( " not .ioi-x-asset ");
continue;
}
console.log(ns[i]);
console.log(records[i].internalId);
ns[i].viewIndex = i;
ns[i].viewRecordId = records[i].internalId;
if (!ns[i].boundView) {
ns[i].boundView = this.id;
}
console.log(ns[i].viewRecordId);
}
}
},
dockedItems: [
{
xtype: 'pagingtoolbar',
dock: 'bottom',
bind: {
store: '{AssetBrowse}'
},
fixed: true,
displayInfo: true,
pageSize: 20,
}
] });
ViewController
Ext.define('xxxxxxxx.view.dataview.BrowseAssetsController', {
extend: 'Ext.app.ViewController',
alias: 'controller.browseassets',
onBrowseStoreLoad: function (store, records) {
var me = this,
dataview = me.getReferences().dataview;
dataview.refresh();
},
onAssetSelect: function(item, record) {
Ext.widget('LargeAssetPreview').getViewModel().set('myRecord',record);
}});
Oh boy, spent so long on this, the issue was the animate plugin. Removed that and its works great, nice to have but can not believe I wasted all that time on an animation plugin.
Removed this from the view
plugins: {
'ux-animated-dataview': true
},

List of cards based on store in ExtJS

In my ExtJS project, I have a grid bound to a store, but I want to do away with the grid's layout and use cards instead, similar to this angular sample.
Is there any container component by Sencha that takes a store and renders all records into a custom template? (based on sorting/filtering)
Deriving from the grid is a bit too much work, overriding the original templates breaks all kinds of things.
You can do this with dataview in extjs here is Demo
Ext.application({
name: 'Fiddle',
launch: function () {
var items = Ext.create('Ext.data.Store', {
autoLoad: true,
storeId: 'item-store',
fields: ['name'],
proxy: {
type: 'ajax',
url: 'data.json',
reader: {
type: 'json',
rootProperty: ''
}
}
});
Ext.create('Ext.panel.Panel', {
title: 'DataView',
height: 620,
bodyPadding: 10,
viewModel: [{
stores: {
itemStore: {
type: 'item-store'
}
},
data: {
name: '',
desc: ''
}
}],
items: [{
xtype: 'dataview',
tpl: [
'<tpl for=".">',
'<div class="dataview-item">',
'<p>{desc}</p>',
'</div>',
'</tpl>'
],
itemSelector: 'div.dataview-item',
store: items
}],
renderTo: Ext.getBody()
});
}
});

ExtJS 4: Dynamic store filtering

I have a filter specified in filters config of the store:
Ext.define('Record', {
extend: 'Ext.data.Model',
fields: [{
name: 'value',
type: 'number'
}]
});
Ext.create('Ext.data.Store', {
id: 'store',
model: 'Record',
filters: [
function(item) {
return item.get('value') > 2;
}
],
sorters: [{
property: 'value',
direction: 'DESC'
}],
data: [{
value: 2,
}, {
value: 1
}, {
value: 3
}]
});
Ext.create('Ext.view.View', {
store: Ext.data.StoreManager.lookup('store'),
tpl: new Ext.XTemplate(
'<tpl foreach=".">',
'<div class="record">{value}</div>',
'</tpl>'
),
itemSelector: '.record',
emptyText: 'No records',
renderTo: Ext.getBody()
});
It is only applied if I explicitly call filter() on the store. The filterOnLoad is not set and defaults to true, so the store must be filtered. How can I keep the store always filtered (whenever any CRU action is performed and after load)?
To accomplish this it's needed to add listeners to the store on adding and updating events:
listeners: {
add: function(store) {
store.filter();
},
update: function(store) {
store.filter();
}
},

Extjs4.1 - Define dataview fail

I try to define a dataview from http://docs.sencha.com/extjs/4.1.3/#!/api/Ext.view.View to http://jsfiddle.net/JtTDH/
Here is my code
Ext.define('Example', {
extend: 'Ext.view.View',
tpl: new Ext.XTemplate(
'<tpl for=".">',
'<div style="margin-bottom: 10px;" class="thumb-wrap">',
'<img src="{src}" />',
'<br/><span>{caption}</span>',
'</div>',
'</tpl>'
),
itemSelector: 'div.thumb-wrap',
emptyText: 'No images available',
initComponent: function() {
var store = Ext.create('Ext.data.Store', {
id:'imagesStore',
fields: [
{ name:'src', type:'string' },
{ name:'caption', type:'string' }
],
data: [
{ src:'http://www.sencha.com/img/20110215-feat-drawing.png', caption:'Drawing & Charts' },
{ src:'http://www.sencha.com/img/20110215-feat-data.png', caption:'Advanced Data' },
{ src:'http://www.sencha.com/img/20110215-feat-html5.png', caption:'Overhauled Theme' },
{ src:'http://www.sencha.com/img/20110215-feat-perf.png', caption:'Performance Tuned' }
]
});
this.store = store;
this.callParent(arguments);
}
});
I think that's correct but that's not working. How to fix that thank.
Your code is fine, but you need to define a rendering target for it. For example, you could add renderTo: Ext.getBody() to your definition, and it will work correctly. See a working example here: https://fiddle.sencha.com/#fiddle/md

Resources