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()
});
}
});
Related
I have an ExtJS 6.5.1 app and I am just now starting to migrate our app from MVC to MVVM, so I am pretty clueless about VM and VC.
I have a viewModel with an inline store like so:
Ext.define("MYAPP.view.ViewportViewModel",{
extend:"Ext.app.ViewModel",
alias: 'viewmodel.viewport',
constructor: function(config) {
var me = this;
this.callParent(arguments);
me.setStores({
info: {
autoLoad:true,
fields:["TEST"],
proxy:{
type:"ajax",
url:"blah.html",
reader:{
type:"json"
}
}
}
});
}
});
From inside my controller, how can I "get" the store so I can change the URL, reload, pass extraParams etc?
Thanks
You can get your store using this.getViewModel().getStore('info') inside of ViewController.
After getting store you can set another url using store.getProxy().setUrl(), load using store.load() and for sending extra params store.getProxy().extraParams.
Here is example
//this one way
store.load({
url: '{your url here}',
params: {
userid: 22216
}
});
//this another way
store.getProxy().setUrl('{your url here}');
store.getProxy().extraParams = {
userid: 22216
};
store.load();
In this FIDDLE, I have created a demo using view model and view controller. I hope this will help/guide you to achieve your requirement.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.define('MyViewController', {
extend: 'Ext.app.ViewController',
alias: 'controller.myview',
onRefreshButtonTap: function () {
var info = this.getViewModel().getStore('info');
info.getProxy().setUrl('data2.json');
info.load();
}
});
Ext.define("ViewportViewModel", {
extend: "Ext.app.ViewModel",
alias: 'viewmodel.myvm',
constructor: function (config) {
var me = this;
this.callParent(arguments);
me.setStores({
info: {
autoLoad: true,
fields: ['name', 'email', 'phone'],
proxy: {
type: 'ajax',
url: 'data1.json',
reader: {
type: 'json',
rootProperty: ''
}
}
}
});
}
});
//creating panel with GRID and FORM
Ext.create({
xtype: 'panel',
controller: 'myview',
title: 'Binding Example',
renderTo: Ext.getBody(),
viewModel: {
type: 'myvm'
},
layout: 'vbox',
items: [{
xtype: 'grid',
flex: 1,
width: '100%',
bind: '{info}',
columns: [{
text: 'Name',
dataIndex: 'name'
}, {
text: 'Email',
dataIndex: 'email',
flex: 1
}, {
text: 'Phone',
dataIndex: 'phone'
}],
listeners: {
itemclick: 'onGridItemClick'
}
}],
tbar:[{
text:'Refresh',
handler:'onRefreshButtonTap'
}]
});
}
});
I try to use a combobox in my formpanel. This works and the store is loading when you click on the combobox. But when it is loaded it is not showing a background.I try to build and refresh the app but no matter what i do or what theme i use it keeps showing it transparant.
This is my combobox
{
xtype: 'combobox',
name: 'type',
anchor: '100%',
fieldLabel: 'Type',
displayField:'naam',
valueField:'id',
multiSelect: false,
editable: false,
store: 'ProductenGroepComboTypeJsonStore',
listConfig: {
loadingText: null,
loadMask: false
}
}
the store is this
Ext.define('JustRent.store.ProductenGroepComboTypeJsonStore', {
extend: 'Ext.data.Store',
requires: [
'JustRent.model.ProductenGroepComboTypeModel',
'Ext.data.proxy.Ajax',
'Ext.data.reader.Json'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
storeId: 'ProductenGroepComboTypeJsonStore',
model: 'JustRent.model.ProductenGroepComboTypeModel',
proxy: {
type: 'ajax',
url: 'resources/json/productType.php',
reader: {
type: 'json',
rootProperty: 'data'
}
}
}, cfg)]);
}
});
this is how it looks like
I'm not sure if this is ideal for you but you can define the css classes to apply to your list and try to do a workaround that way
listConfig: {
xtype: 'boundlist',
baseCls: 'your-css-list',
maxHeight: 200,
itemCls: 'your-css-list-item'
}
Hope it helps :)
So I implemented a dataview and a list format card to display my json in store. I am trying to get the two view to share one store, since the data are the same. However the way i am doing it is not really working, if I only have Dataview or List it works fine. When I have both call the store, it will stop working... please help!
Dataview:
Ext.define('Sencha.view.hoardboard.HoardList', {
extend: 'Ext.DataView',
xtype: "hoardlist",
requires: ['Ext.XTemplate'],
config: {
flex:1,
scrollable: true,
store: 'Plist',
baseCls: 'columns',
itemTpl: '<div class=pin><img src={image}><div style="padding-top: 10px; padding-left: 20px; padding-right:20px">{name}<br>{brand}</div></div>'
}
});
List view
Ext.define('Sencha.view.hoardboard.HoardList2', {
extend: 'Ext.List',
xtype: "hoardlist2",
config: {
flex:1,
scrollable: true,
store: 'Plist',
grouped: true,
itemTpl: '{name}'
}
});
Model
Ext.define('Sencha.model.HoardList', {
extend: 'Ext.data.Model',
config: {
fields: [
{
name: 'name',
type: 'string'
},
{
name: 'image',
type: 'string'
},
{
name: 'type',
type: 'string'
},
{
name: 'brand',
type: 'string'
}
,
{
name: 'color',
type: 'string'
},
{
name: 'description',
type: 'string'
}
]
}
});
Store
Ext.define('Sencha.store.HoardList',{
extend: 'Ext.data.Store',
storeId: 'Plist',
model:'Sencha.model.HoardList',
title: 'My Collection',
autoLoad: true,
sorters: 'name',
grouper: {
groupFn: function(record) {
return record.get('name')[0];
}
},
proxy: {
type: 'ajax',
url : 'products.json',
reader: {type: 'json', rootProperty:'products'}
}
});
Thank you so much!
Generally speaking when you're using Sencha framework you don't share one store object between several visual controls.
If you want to use same store in two places you need to clone it and have two separate store objects.
Am having a tree view which gets its data from the tree store. But, however, am able to see only the small folders that gets displayed as part of a tree structure. the name of the nodes is not getting displayed, and when i try to print the record, it just says that its an empty string. Here is the code:
App/View
Ext.define('App.view.Hierarchy', {
alias: 'widget.hierarchy',
extend: 'Ext.panel.Panel',
initComponent: function () {
var config = {
xtype: 'panel',
border: false,
autoScroll: true,
baseCls: 'topMenu',
html: '<div class="PageTitle" style="width:600px;"><b>' + LANG.HIERARCHYT + '</b><br>' + LANG.HIERARCHYTxt + '<br>' + '</div>',
items: [{
xtype: 'toolbar',
border: false,
dock: 'top',
items: [{
xtype: 'button',
text: LANG.BTADDREG,
iconCls: 'icon-add-tb',
cls: 'tip-btn',
iconAlign: 'right',
action: 'addRegion',
id: 'ADDREGION'
}]
},
{
xtype: 'treepanel',
title: 'Hierarchy Tree',
id: 'hierarchyTree',
border: false,
alias: 'widget.hierarchyTree',
height: 1000,
viewConfig: {
enableDD: true,
plugins: {
ptype: 'treeviewdragdrop'
}
},
collapsible: false,
useArrows: true,
rootVisible: false,
store: Ext.create('Campus.store.HierarchyTree'),
displayField: 'Title',
multiSelect: false,
singleExpand: false,
}]
}
var holder = Ext.getCmp('center');
holder.remove(0);
holder.add(Ext.apply(config));
this.callParent(arguments);
}
});
Model
Ext.define('App.model.HierarchyTree', {
extend : 'Ext.data.Model',
fields : ['Title', 'ID', 'LevelID', 'ParentID']
});
Store
Ext.define('App.store.HierarchyTree', {
extend: 'Ext.data.TreeStore',
model: 'App.model.HierarchyTree',
storeID: 'HierarchyTree',
proxy: {
type: 'ajax',
url: 'data/Locations.aspx',
reader: {
},
actionMethods: {
create: 'POST',
read: 'POST',
update: 'POST'
},
extraParams: {
mode: 'HIERARCHYFULLLIST'
}
},
autoLoad: true
});
Controller
Ext.define('App.controller.Hierarchy', {
extend: 'Ext.app.Controller',
stores: ['Me', 'Regions', 'Areas', 'Towns', 'HierarchyTree'],
model: ['Me', 'Teams', 'Regions', 'User', 'HierarchyTree'],
views: ['App.view.Hierarchy', 'App.view.AddRegions'],
refs: [{
ref: 'myHierarchyTree',
selector: 'hierarchyTree'
}],
init: function () {
this.getHierarchyTreeStore().load();
this.control({
'button[action=addRegion]': {
click: this.addRegion
},
'#hierarchyTree': {
itemclick: this.itemclick
}
})
},
itemclick: function (view, record) {
console.log(record.get('Title'))
}
});
Also, the JSON thats being returned is:
{"text":".","children": [{"text":"Asia Pacific","id":"537","level":"1", "expanded":
false,"singleClickExpand":true,"children":[{"text":"Japan", "cls":"xtreenode-Level2-
Indent", "id":"538", "hl1":"537","level":"2","singleClickExpand":true, "expanded":
false, "children":[]},
Treepanel's display field defaults to text, which is ok with the json being returned, but the problem is the store model, which should include as fields the text, cls ..and other attributes you have in your json. Otherwise these will not be mapped to the records and you get empty text.
Ext.define('App.model.HierarchyTree', {
extend : 'Ext.data.Model',
fields : ['Title', 'ID', 'LevelID', 'ParentID', 'text', 'level','cls,....]
EDIT
You have modified the displayField to be the Title, but the json doesn't contain the title attribute. You have to simple fixes, either you modify the model if the text is actually the title. You can do this by setting a mapping to the field.
Ext.define('App.model.HierarchyTree', {
extend : 'Ext.data.Model',
fields : [{name:'Title',type:'string',mapping:'text'}, 'ID', 'LevelID', 'ParentID',]
This will cause the Title to be populated by the text values from the json.
Also you can remove the displayField config and then the text value will be applied, but this will still mean that the 'Title' value will be empty.
OK, finally got it:)
Set the displayfield in the tree to 'text'
displayfield : 'text'
And, Once again thank you nscrob
And one more question, could you please give me any guidance on how to open different views depending upon the level in the tree that is being clicked
This works.
if (record.get('level')==1)
{
this.erWin = Ext.create('App.view.EditRegions');
this.erWin.showWin();
}
else{
//open another_view
}
I am having issue setting up pagination.
using the following example.
http://docs.sencha.com/ext-js/4-0/#/guide/application_architecture
I have create a store in a separate file.
ie /app/store/tasks.js
app/store/tasks.js
Ext.define('AM.store.Tasks', {
extend: 'Ext.data.Store',
model: 'AM.model.Task',
autoLoad: true,
pageSize: 2,
proxy: {
type: 'ajax',
api: {
read: '/WarehouseProductImport/IndexGrid',
update: 'data/updateTasks.json'
},
reader: {
type: 'json',
root: 'tasks',
totalProperty: 'total',
successProperty: 'success'
}
}
});
in my app.js
launch: function () {
Ext.create('Ext.container.Container', {
width: 950,
height: 500,
renderTo: 'panelcontainer',
items: [
{
xtype: 'tasklist',
title: 'Tasks',
html: 'List of tasks will go here'
}
],
dockedItems: [{
xtype: 'pagingtoolbar',
store: '', // how do i get this store as it's define in 'store/task.js'
dock: 'bottom',
displayInfo: true
}]
});
}
In the above method, "store" isn't initialized. Am i putting this method in the correct place. Are there any examples on how to set up pagination when the store is separated like above.