mardi 1 juillet 2014

Data grid of one store fires request to dynamically load a data grid of another store

I'm looking for a "How-To" Example of two data grids each with their own model & store. The catch is when the user clicks on a row in, let's say dataGrid1. An event is fired to load the store of dataGrid2 based on what the user selected in dataGrid1.

ie. dataGrid1 is a list of customers which is an autoloaded store. Then there is a dataGrid2 which is a list of customer orders. So our user clicks on a customer name in dataGrid1 and that fires off an event to the store of dataGrid2 (which is empty at the moment). That event tells the dataGrid2 store to only load the orders for that customer. When a user clicks on another customer in dataGrid1 the dataGrid2 store clears and reloads with that new customer orders.


I know I can use other things to make this behavior happen (ei. the Cars example in the getting started), but I'd like to have it all contained in data grids and stores. Filtering the second store doesn't buy me what I really want and that's cacheing only the data I really want to use and not the whole database table.

I'm using Architect so I'd like to keep things MVC.


Thanks!





How to load nested many-to-many and the save chages with session

Is there a way to load many-to-many in a nested fashion?

I have two models: Location and LocationType. I want to autoLoad all Locations with their LocationTypes and display them on the map as individual markers. Then I want to allow users to create/edit Locations and add/remove their LocationTypes.


For now, types are loaded nested like in one-to-many, so each location has its own set of types, but they are different instances with different internalId. I want to use many-to-many so that I only have one record for each LocationType associated to many different Locations.



Code:



Ext.define('APP.model.Location', {
extend: 'APP.model.Base',

fields: [
{name: 'countryId', reference: 'Country', unique: true},
{name: 'name', type: 'string'},
{name: 'description', type: 'string'},
{name: 'lat', type: 'float'},
{name: 'lng', type: 'float'},
{name: 'created', type: 'date'}
],

manyToMany: {
LocationTypes: {
type: 'LocationType',
role: 'types',
field: 'typeId',
right: {
field: 'locationId',
role: 'locations'
}
}
}
});


Code:



Ext.define('APP.model.LocationType', {
extend: 'APP.model.Base',

fields: [
{name: 'name', type: 'string'},
{name: 'type', type: 'string'}
],

manyToMany: {
Locations: {
type: 'Location',
role: 'locations',
field: 'locationId',
left: {
field: 'typeId',
role: 'types'
}
}
}
});

I have a combobox with multiSelect: true, where users can add/remove types.

Code:



onTypeSelect: function(combo, records) {
var view = this.getView(),
location = view.getViewModel().get('location');

console.log(records);

location.types().removeAll();

if (records.length) {
location.types().add(records);
}
}

Finally I want to save changes by using Ext.data.Session with a single batch.

Code:



saveLocation: function() {
var view = this.getView(),
session = view.getSession(),
location = view.getViewModel().get('location'),
batch = session.getSaveBatch();

console.log('changes', session.getChanges());

batch.on({
complete: this.onSaveComplete,
exception: this.onSaveException,
scope: this
});

batch.start();
}

When I console.log(session.getChanges()), I get

Code:



Location: Object
countryId: 99
created: "1404263656"
description: "fdas"
id: "Location-1"
lat: 30.760718908944472
lng: 77.080078125
name: "asdf"

LocationType: Object
locations: Object
C: Object
1: Array[1]
0: "Location-1"
2: Array[1]
0: "Location-1"
3: Array[1]
0: "Location-1"

The batch successfully saves the Location, but not the associated LocationTypes. After a successful onSaveComplete, session.getChanges() still returns and object with LocationType changes, but now with proper Location IDs. Do I need to handle these associations manually or can I leverage Ext.Direct? If yes, how?

I've been looking at ticket-app, but it's hard to debug it, because it's using Ext.ux.ajax.SimManager. Side question: how can I see what connections are being made by SimManager?


The documentation about Ext.data.Session and associations is very limited. It would be really cool if we had some more reading material





List with pictures and buttons

Hi all

I've been trying to set up a list of items (every item displays an image, text from a json file, and 2 buttons not unique to the item).


I was wondering if xtemplate is the best way to do it? Is there a way to make images display without using HTML?


I was also trying to use dataitem in dataview, but it seems that I cannot have items within items for that. Also, it seems futile to create containers within dataitem.


Any advice on how to implement this? Thanks!





Store and Listeners

Hi,

I need to add listeners to a Store. I want to do some special processing in the "load" event.

In the Documentation we can read




listeners : Object

A config object containing one or more event handlers to be added to this object during initialization. This should be a valid listeners config object as specified in the addListener example for attaching multiple handlers at once.


See the Event guide for more


Note: It is bad practice to specify a listener's config when you are defining a class using Ext.define(). Instead, only specify listeners when you are instantiating your class with Ext.create().





I don't understand why **It is a bad practice**

I have a View associated with it's ViewController and I would like to keep the special processing in the store and not bother the View nor the ViewController.


I instantiate the store in my view but I don't want to define a listener in my view nor in my controller.


I have specified in the definition of my Store the listener that I need, but some how the my listener is not called. What am I doing wrong?



Code:



Ext.define('My.store.WeeklyHours', {
extend: 'Ext.data.Store'
,model: 'My.model.Entry'
,storeId: 'WeeklyHours'
,remoteSort: false
,proxy: {
type: 'ajax'
,api: {
read: 'data/user/week/entries'
}
,reader: {
type: 'json'
,rootProperty: 'results'
,totalProperty: 'totalCount'
}
}
,listeners: [
{
fn: this.onLoadStore,
event: 'load',
scope:this
}
]
,onLoadStore: function() {
var proxy = this.getProxy()
var reader = proxy.getReader()
var rawData = reader.rawData
....

Thanks for your help.


Bug in Ext.draw.Sprite for text



  1. Thank you for reporting this bug. We will make it our priority to review this report.







  2. Default Bug in Ext.draw.Sprite for text



    Bug in Ext.draw.Sprite for text





    Technically its a problem with Ext.rtl.draw.Sprite but it affects the use of Ext.draw.Sprite.

    The problem will not arise when Ext.draw.Component is configured with sprite definitions like those shown in the documentation. Instead it occurs if Ext.draw.Sprite instances are created independently and subsequently added to a surface instance.


    This is the relevant part of the override in Ext.rtl.draw.Sprite:



    Code:



    transformText: function(text) {
    var me = this;
    if (text && me.surface.isRtl && !Ext.isNumber(text) && me.rtlRe.test(text)) {
    // IE9m will display a strange visual artefact when showing
    // text with the RLM and there are no RTL characters in the string.
    // IE6 & 7 will still show the artefact, it seems to be unavoidable.
    return me.RLM + text;
    }
    return me.callParent(arguments);
    }

    This is called during the Sprite constructor in response to a call to setAttributes(). If the Sprite is being created independently then me.surface is undefined leading to an exception when an attempts is made to test the isRtl property. When a sprite is created from a component configuration then the surface is available because the sprite is created by the surface instance createItem() function.

    This override should be updated to add a check to ensure there is a valid surface before the isRtl property is used.


    Assuming RTL is not important to you then in the meantime a workaround is to add an alternative object so the transformText function can be replaced:



    Code:



    Ext.define('Ext.my.draw.Sprite', {
    override: 'Ext.draw.Sprite',

    transformText: function(text) {
    return text;
    }
    });

    This override function could fix the problem but my requirements don't need that.












Accordian layout and animate=false, problem.



  1. Thank you for reporting this bug. We will make it our priority to review this report.







  2. Default Accordian layout and animate=false, problem.



    Accordian layout and animate=false, problem.





    Hi dear sirs/madams,

    If you use accordian layout, and on one of it's item set "animate=false" than this item does not expand/collapse no more.


    So, for instance, if one of it's items is TreePanel with config "animate=false" than it becomes unusable.



    Code:



    layout: 'accordion',
    items: [{
    title: 'Accordion Item 1',
    html: 'Empty',
    animate: false /* becomes unusable */
    },{
    title: 'Accordion Item 2',
    html: 'Empty'
    }, {
    title: 'Accordion Item 3',
    html: 'Empty'
    }]


    Tested on Chrome 35.

    best regards,

    Andrej














Ext JS 5 demo chart - widget.cartesian not recognized

Code:



<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="Cache-control" content="no-cache">
<link rel="stylesheet" type="text/css" href="../../../Common/ExtJs/Packages/ext-theme-crisp/build/resources/ext-theme-crisp-all.css">
<script src="../../../Common/extjs/ext-all.js"></script>
<script>
Ext.require( ['*'
] );


( function () {
Ext.onReady( function () {


var myDataStore = Ext.create( 'Ext.data.JsonStore', {
fields: ['month', 'data1'],
data: [
{ month: 'Jan', data1: 20 },
{ month: 'Feb', data1: 20 },
{ month: 'Mar', data1: 19 },
{ month: 'Apr', data1: 18 },
{ month: 'May', data1: 18 },
{ month: 'Jun', data1: 17 },
{ month: 'Jul', data1: 16 },
{ month: 'Aug', data1: 16 },
{ month: 'Sep', data1: 16 },
{ month: 'Oct', data1: 16 },
{ month: 'Nov', data1: 15 },
{ month: 'Dec', data1: 15 }
]
} );


var aPanel = Ext.create( 'Ext.Panel', {
region: 'center',
title: 'Testpanel',
border: true,


items: [ {
xtype: 'cartesian',
width: '100%',
height: 500,
store: myDataStore,
insetPadding: 40,
innerPadding: {
left: 40,
right: 40
},
sprites: [{
type: 'text',
text: 'Line Charts - Basic Line',
font: '22px Helvetica',
width: 100,
height: 30,
x: 40, // the sprite x position
y: 20 // the sprite y position
}, {
type: 'text',
text: 'Data: Browser Stats 2012',
font: '10px Helvetica',
x: 12,
y: 470
}, {
type: 'text',
text: 'Source: http://ift.tt/rAg5Mm',
font: '10px Helvetica',
x: 12,
y: 480
}],
axes: [{
type: 'numeric',
fields: 'data1',
position: 'left',
grid: true,
minimum: 0,
maximum: 24,
renderer: function ( v ) { return v + '%'; }
}, {
type: 'category',
fields: 'month',
position: 'bottom',
grid: true,
label: {
rotate: {
degrees: -45
}
}
}],
series: [{
type: 'line',
xField: 'month',
yField: 'data1',
style: {
lineWidth: 4
},
marker: {
radius: 4
},
label: {
field: 'data1',
display: 'over'
},
highlight: {
fillStyle: '#000',
radius: 5,
lineWidth: 2,
strokeStyle: '#fff'
},
tooltip: {
trackMouse: true,
style: 'background: #fff',
showDelay: 0,
dismissDelay: 0,
hideDelay: 0,
renderer: function ( storeItem, item ) {
this.setHtml( storeItem.get( 'month' ) + ': ' + storeItem.get( 'data1' ) + '%' );
}
}
}]
}]
} );


var viewPort = Ext.create( 'Ext.Viewport', {
border: false,
defaults: {
split: true
},
layout: 'border'
} );


viewPort.add( aPanel );
} );
}() );


</script>


<title>Error alias widget.cartesian not found</title>
</head>
<body>
This code leads to
<br />
if (!cls) {
<br />
throw new Error("[Ext.create] Unrecognized class name / alias: " + name);
<br />
}
<br />
widget.cartesian is not recognized.
<br />
And then - 'Some requested files failed to load'.
</body>
</html>