How to create Grid in sencha touch 2.3.0 populate data from a REST webservice - extjs

I need to display report in Grid / Table in Sencha Touch 2.3.0. Is there any build in function to do so.
The store needs to populate data from a REST webservice call.

For loading data you can use Ext.data.Store configured with REST proxy Ext.data.proxy.Rest
For displaying data from store you can use Ext.grid.Grid of Ext.dataview.DataView

I do this all the time with something like this:
(Though I haven't worked with the Grid, I'm quite sure the same principles apply...)
Ext.define('App.controller.GridController', {
extend : 'Ext.app.Controller',
config: {
refs: {
getApiButton: 'button[action=getApiData]'
},
control: {
'getApiButton' : {
tap : 'onButtonTap'
}
}
},
onButtonTap : function(field, value) {
var that = this;
Ext.Ajax.request({
url : someWebServiceUrl,
method: 'GET',
success: function (result, request) {
var res = Ext.decode(result.responseText);
if (res.success === true && res.data != false) {
var recipient = {
name: res.data[0].displayname,
picId: res.data[0].pictureid,
gender: res.data[0].gender
};
var mod = Ext.define('App.model.GradingPopModel', {
extend: 'Ext.data.Model',
config: {
fields: [
'name',
'picId',
'gender'
]
}
});
/* == this is probably where you want to make your changes to apply the model to the grid template
the sencha website has this:
data: {'items': [
{ 'name': 'Lisa', "email":"lisa#simpsons.com", "phone":"555-111-1224" },
{ 'name': 'Bart', "email":"bart#simpsons.com", "phone":"555-222-1234" },
{ 'name': 'Homer', "email":"home#simpsons.com", "phone":"555-222-1244" },
{ 'name': 'Marge', "email":"marge#simpsons.com", "phone":"555-222-1254" }
]}
*/
var store = Ext.create('Ext.data.Store', {
model: mod,
storeId:'recipStore'
});
store.add(recipient);
store.setData(recipient);
store.load();
var gridView = Ext.ComponentQuery.query('#gridViewId')[0];
gridView.setStore(store);
}
},
failure: function (result, request) {
console.log('api call was a failure');
},
scope: this
});
}
});
Now of course your data won't have "displayname, gender" etc.. but you should get the point.
I also found a working example here (I find it very sad that Sencha allows broken demos on their own website): http://demo.rasc.ch/eds/touch23/grid/grid/index.html

Related

PullRefresh plugin of a List doesn't handle ChainedStore possibility

Using Ext JS 7.1 Modern, I have prepared an example to show the problem.
When I have remote filters on my main store, binding the dataview.List to a ChainedStore correctly handles my local filtering. However, when I also add a PullRefresh plugin to the list, I get an error during pull refresh. I see from the source code that the plugin doesn't consider the possibility that a list's store can be a ChainedStore.
I have tried to explain the problem with a Sencha Fiddle and also attached the code below.
I have temporarily solved the problem by overriding the fetchLatest and onLatestFetched methods of Ext.dataview.pullrefresh.PullRefresh plugin, to use the source store if the list's store is a ChainedStore. But I believe the source code must be updated to handle this case.
app.js
Ext.define('App.model.Test', {
extend: 'Ext.data.Model',
fields: ['id', 'firstName', 'lastName']
});
Ext.define('App.store.Test', {
extend: 'Ext.data.Store',
alias: 'store.teststore',
model: 'App.model.Test'
});
Ext.define('App.viewmodel.Test', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.test',
data: {
query: ''
},
stores: {
test: {
type: 'teststore',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'names.json',
reader: {
type: 'json',
rootProperty: 'data'
}
},
remoteFilter: true,
filters: {
property: 'id',
value: 1
}
},
chained: {
type: 'chained',
autoLoad: true,
source: '{test}'
}
}
});
Ext.define('App.controller.TestController', {
extend: 'Ext.app.ViewController',
alias: 'controller.testcontroller',
doSearch: function (field) {
var list = this.lookup('list'),
store = list.getStore(),
value = field.getValue();
if (Ext.isEmpty(value)) {
store.removeFilter('firstName')
} else {
store.filter([{
property: 'firstName',
value: value,
operator: 'like'
}])
}
}
});
Ext.define('App.dataview.TestList', {
extend: 'Ext.dataview.List',
xtype: 'testlist',
viewModel: {
type: 'test'
},
plugins: [{
type: 'pullrefresh',
mergeData: false
}],
emptyText: 'Name not found',
bind: {
store: '{chained}'
},
itemTpl: '<div class="contact">{id} <b>{firstName} {lastName}</b></div>'
});
Ext.define('App.MainView', {
extend: 'Ext.Panel',
controller: 'testcontroller',
fullscreen: true,
viewModel: {
type: 'test'
},
items: [{
xtype: 'searchfield',
ui: 'solo',
placeholder: 'Search names',
listeners: {
buffer: 500,
change: 'doSearch'
},
bind: {
value: '{query}'
}
}, {
reference: 'list',
xtype: 'testlist'
}]
})
Ext.application({
name: 'App',
mainView: 'App.MainView'
});
names.json
var data = [{
id: 1,
firstName: 'Peter',
lastName: 'Venkman'
}, {
id: 2,
firstName: 'Raymond',
lastName: 'Stantz'
}, {
id: 3,
firstName: 'Egon',
lastName: 'Spengler'
}, {
id: 4,
firstName: 'Winston',
lastName: 'Zeddemore'
}]
var results = data.filter(function(record) {
if (params.filter) {
return record.id > params.filter[0].value
}
})
return {
"success": true,
"data": results
}
App.override.dataview.pullrefresh.PullRefresh:
Ext.define('App.override.dataview.pullrefresh.PullRefresh', {
override: 'Ext.dataview.pullrefresh.PullRefresh',
privates: {
fetchLatest: function() {
const store = this.getStore().isChainedStore ? this.getStore().getSource() : this.getStore()
store.fetch({
page: 1,
start: 0,
callback: this.onLatestFetched,
scope: this
});
},
onLatestFetched: function(newRecords, operation, success) {
var me = this,
list = me.getList(),
store = list.getStore().isChainedStore ? list.getStore().getSource() : list.getStore(),
length, toInsert,
oldRecords, newRecord, oldRecord, i;
if (success) {
if (me.getMergeData()) {
oldRecords = store.getData();
toInsert = [];
length = newRecords.length;
for (i = 0; i < length; i++) {
newRecord = newRecords[i];
oldRecord = oldRecords.getByKey(newRecord.getId());
if (oldRecord) {
oldRecord.set(newRecord.getData());
}
else {
toInsert.push(newRecord);
}
}
store.insert(0, toInsert);
}
else {
store.loadRecords(newRecords);
}
me.setLastUpdated(new Date());
}
me.setState('loaded');
list.fireEvent('latestfetched', me, toInsert || newRecords);
if (me.getAutoSnapBack()) {
me.snapBack(true);
}
}
}
})
Thanks in advance
Since this post, instead of being a question, was a bug report with a possible solution, it has been posted to Ext JS 7.x Community Forums\Ext JS 7.x Bugs.
The above solution, that overwrites the plugin where source store is needed, works if anyone comes across the same issue.

KendoUI Grid for AngularJS binding error from asp.net mvc controller. Success is not a function error

I attempt to do simple task using KendoUI grid for AngularJS in asp.new mvc application. It is binding data to grid from mvc controller.
asp.net mvc controller method:
public ActionResult GetCdcReport()
{
var testJson =
#"{ProductID:'1',ProductName:'Chai',UnitPrice:'18',UnitsInStock:'39',Discontinued:'false'}";
var json = JObject.Parse(testJson);
return new JSONNetResult(json);
}
angularjs service function:
function getImportResultReport() {
return httpPost('getCdcReport');
}
code from component for data binding:
$scope.mainGridOptions = {
columns: [
{ field: "ProductID", title: "ID" },
{ field: "ProductName", title: "Product Name" },
{ command: [{ template: "<button class='k-button' ng-click='showDetails(dataItem)'>Show details</button>" }] },
],
pageable: true,
dataSource: {
pageSize: 5,
transport: {
read: function (e) {
dataservice.getImportResultReport().
success(function (data) {
e.success(data);
}).
error(function (data, status) {
alert('something went wrong');
console.log(status);
});
}
}
}
};
I see that server method is called but in console i get following client error:
dataservice.getImportResultReport(...).success is not a function
In similar question i read that:
The $http legacy promise methods success and error have been
deprecated. Use the standard then method instead.
i replace binding code on:
$scope.mainGridOptions = {
columns: [
{ field: "ProductID", title: "ID" },
{ field: "ProductName", title: "Product Name" },
{ command: [{ template: "<button class='k-button' ng-click='showDetails(dataItem)'>Show details</button>" }] },
],
pageable: true,
dataSource: {
pageSize: 5,
transport: {
read: function (e) {
dataservice.getImportResultReport().
then(function (data) {
return data;
});
}
}
}
};
After that I don't receive this error but grid stay without data.
Also i attempted do it like:
vm.mainGridOptions = {
columns: [
{ field: "ProductID", title: "ID" },
{ field: "ProductName", title: "Product Name" },
{ command: [{ template: "<button class='k-button' ng-click='showDetails(dataItem)'>Show details</button>" }] },
],
pageable: true
};
$scope.mainGridOptions.DataSource = dataservice.getImportResultReport();
it is also not work.
What i'm doing wrong?
It is example from telerik site. If in binding logic replase dataservice.getImportResultReport() on $http.jsonp('URL FROM EXAMPLE') then it is work.

Ext.data.LocalStorage not working on Offline Mode

Im now studying Sencha Touch 2 and doing some Research on Ext.data.LocalStorage that can be use in Offline Mode.
I tried to follow this turorial
Sencha Touch 2 Local Storage
and just updated the code from Github - RobK/SenchaTouch2-LocalStorageExample or riyaadmiller/LocalStorage and modified Store url using my own WCF Rest
but i cant get LocalStorage working on offline mode.I have no issue on running the app Online. I also tried to debug it on Chrome developer tool but LocalStorage always get 0 data. I used Chrome/Safari Browser and also build the apps as Android using Phonegap build and still not working.
Did I miss something?
Does anyone can provide the details to deal with this Issue.
Below is my code:
Store:
Ext.define('Local.store.News', {
extend:'Ext.data.Store',
config:{
model: 'Local.model.Online',
proxy:
{
type: 'ajax',
extraParams: { //set your parameters here
LookupType: "Phone",
LookupName: ""
},
url: 'MY WCF REST URL',
headers: {
'Content-Type': 'application/json; charset=utf-8'
},
reader:
{
type: 'json'
, totalProperty: "total"
},
writer: { //Use to pass your parameters to WCF
encodeRequest: true,
type: 'json'
}
},
autoLoad: true
}
});
Offline Model:
Ext.define('Local.model.Offline', {
extend: 'Ext.data.Model',
config: {
idProperty: "ID", //erm, primary key
fields: [
{ name: "ID", type: "integer" }, //need an id field else model.phantom won't work correctly
{ name: "LookupName", type: "string" },
{ name: "LookupDescription", type: "string" }
],
identifier:'uuid', // IMPORTANT, needed to avoid console warnings!
proxy: {
type: 'localstorage',
id : 'news'
}
}
});
Online Model:
Ext.define('Local.model.Online', {
extend: 'Ext.data.Model',
config: {
idProperty: "ID", //erm, primary key
fields: [
{ name: "ID", type: "integer" }, //need an id field else model.phantom won't work correctly
{ name: "Name", type: "string" },
{ name: "Description", type: "string" }
]
}
});
Controller:
Ext.define('Local.controller.Core', {
extend : 'Ext.app.Controller',
config : {
refs : {
newsList : '#newsList'
}
},
/**
* Sencha Touch always calls this function as part of the bootstrap process
*/
init : function () {
var onlineStore = Ext.getStore('News'),
localStore = Ext.create('Ext.data.Store', { storeid: "LocalNews",
model: "Local.model.Offline"
}),
me = this;
localStore.load();
/*
* When app is online, store all the records to HTML5 local storage.
* This will be used as a fallback if app is offline more
*/
onlineStore.on('refresh', function (store, records) {
// Get rid of old records, so store can be repopulated with latest details
localStore.getProxy().clear();
store.each(function(record) {
var rec = {
name : record.data.name + ' (from localStorage)' // in a real app you would not update a real field like this!
};
localStore.add(rec);
localStore.sync();
});
});
/*
* If app is offline a Proxy exception will be thrown. If that happens then use
* the fallback / local stoage store instead
*/
onlineStore.getProxy().on('exception', function () {
me.getNewsList().setStore(localStore); //rebind the view to the local store
localStore.load(); // This causes the "loading" mask to disappear
Ext.Msg.alert('Notice', 'You are in offline mode', Ext.emptyFn); //alert the user that they are in offline mode
});
}
});
View:
Ext.define('Local.view.Main', {
extend : 'Ext.List',
config : {
id : 'newsList',
store : 'News',
disableSelection : false,
itemTpl : Ext.create('Ext.XTemplate',
'{Name}-{Description}'
),
items : {
docked : 'top',
xtype : 'titlebar',
title : 'Local Storage List'
}
}
});
Thanks and Regards
1) First of all when you creating record and adding into store, the record fields should match the model fields of that store.
Here you creating record with field name, but Local.model.Offline didn't name field
var rec = {
name : record.data.name + ' (from localStorage)'
};
This is what you need to do within refresh
localStore.getProxy().clear();
// Also remove all existing records from store before adding
localStore.removeAll();
store.each(function(record) {
console.log(record);
var rec = {
ID : record.data.ID,
LookupName : record.data.Name + ' (from localStorage)',
LookupDescription : record.data.Description
};
localStore.add(rec);
});
// Don't sync every time you add record, sync when you finished adding records
localStore.sync();
2) If specify idProperty in model which is using localStorage, then record will not be added into localStorage.
Model
Ext.define('Local.model.Offline', {
extend: 'Ext.data.Model',
config: {
// idProperty removed
fields: [
{ name: "ID", type: "integer" }, //need an id field else model.phantom won't work correctly
{ name: "LookupName", type: "string" },
{ name: "LookupDescription", type: "string" }
],
identifier:'uuid', // IMPORTANT, needed to avoid console warnings!
proxy: {
type: 'localstorage',
id : 'news'
}
}
});

Sencha Touch 2 Load store crashs

Hello i have the following problem:
After i generate the AP and install it on my phone the requisition store.load breaks in this specific store called CHAMADOS, but when i close the app and restart, it does not crash and bring me all the informations in the list...
It seems that the .load requires bring me the informations in the first time.
When i close and open it again the cache informations required before is add to the list, but the load required on the restart APP does not work.
It crashs and dont add the items to the LIST, but the store has data because on restart it appears, i have others store in this app and they work fine!
On brownser its fine, the problem is in the APK
Here is the view
{
height: '60%',
ui:'round',
style:'padding:18px 0; background:#FFF;',
xtype: 'dataview',
id: 'feedListagemChamados',
store: 'Chamados',
itemTpl: '<span>{nom_chamado}</span> '
}
Here is the store
Ext.define('WE3Chamados.store.Chamados', {
extend: 'Ext.data.Store',
config: {
model: 'WE3Chamados.model.Chamado',
autoLoad: true,
proxy: {
type: 'jsonp',
url: 'http://LINK?cod_usuario='+localStorage.getItem("usuarioId"),
callbackKey: 'callback',
reader: {
type: 'json',
rootProperty : 'chamados',
successProperty: 'success'
}
}
}});
Here is where i call the store to load (CONTROLLER)
showListaChamados: function (direcao) {
this.cleanApp();
store = Ext.getStore('Chamados').load();
store.load({
scope : this,
callback : function(records, operation, success) {
***IT BREAKS HERE ON RETURN***
Ext.Msg.alert('Opps', records[0].data.nom_usuario, this);
Ext.Viewport.animateActiveItem(this.getChamadoView(), this.getSlideTransition(direcao));
}
});
Ext.Msg.alert('Opps', store.data, this);
}
Here is the model
Ext.define('WE3Chamados.model.Chamado', {
extend: 'Ext.data.Model',
config: {
fields: [
{
name: 'cod_chamado'
},
{
name: 'nom_chamado'
},
{
name: 'des_chamado'
},
{
name: 'cod_equipe'
},
{
name: 'dat_cadastro'
},
{
name: 'dat_previsao'
},
{
name: 'dat_necessaria'
},
{
name: 'num_prioridade'
},
{
name: 'cod_projeto'
},
{
name: 'nom_usuario'
},
{
name: 'cod_status'
},
{
name: 'nom_projeto'
},
{
name: 'des_equipe'
},
{
name: 'nom_status'
},
{
name: 'nom_cliente'
},
{
name: 'cod_usuario'
},
{
name: 'cod_usuario_responsavel'
}
]
}});
I found the problem, it was in the localStorage.getItem("usuarioId") its not sendind it by the get, because it is after login, i think there is a bug in the js or its so fast that the comand to send the link cant get the localStorage.getItem.
Im trying using php SESSION now.

Dyanmic forms from json file in sencha touch

How can I create dynamic form where all the fields are coming from a json file in sencha touch?
(Additional details transferred from "answer")
My json looks like it
{
success: true,
data: [
{xtype: "textfield", title: "label1", name: "textfield1"},
{xtype: "emailfield", title: "label2", name: "textfield2"},
{xtype: "passwordfield", title: "label3", name: "textfield3"},
{xtype: "button", title: "button", name: "button"}
]
}
I want a sepearte controller and a view.
i did it in a single controller file like this
form = Ext.create('MyApp.view.MyDataView');
var test=this;
var ajax = Ext.Ajax.request({
url: 'contacts.json',
method: 'get',
success: function(response)
{
console.log(response);
response = Ext.JSON.decode(response.responseText);
this.hello=response;
console.log(response.data.length);
for (var i = 0; i < response.data.length; i++)
{
form.add({
xtype: response.data[i].xtype,
id:response.data[i].title,
action:response.data[i].title,
label: response.data[i].title,
name: response.data[i].name
});
}
console.log(form.getValues());
form.setLayout();
form.show(document.body);
Ext.Viewport.animateActiveItem(form,{type: 'flip', direction: 'right'});
}
there is some problem i m facing regarding the utton tap event and if multiple buttons are there giving event to them is not yet possible for me ....can anybody help me regarding this ..
Have you tried something yet?
You can just create the form in the file like something like this:
{
xtype: 'form',
items: [ //...
]
}
Then you can load your file in, and decode it into a variable.
Ext.Ajax.request({
url: 'yourform.json',
success: function(response){
var formInJson = response.responseText;
var form = Ext.JSON.decode(formInJson);
//... do something with your form
}
});

Resources