Overriding default parameter names in ExtJS 4 Store - json

I'm trying to override the default parameter name for limitParam in proxy for the Store. I want to make a JSONP call to http://search.twitter.com/search.json?q=kathmandu&rpp=2 but instead of setting rpp directly I want to map it to limitParam and set it's value. But it's not setting through limitParam. The reason I'm doing is the parameter keys store sends (sort, dir, etc) do not match the parameters on the server side (which I've no control over). Thanks in advance.
Ext.require('Ext.grid.View');
Ext.require('Ext.util.Point');
Ext.application({
name: 'HelloExt',
launch: function() {
/*Ext.create('Ext.container.Viewport', {
layout: 'fit',
items: [
{
title: 'Hello Ext',
html : 'Hello! Welcome to Ext JS.'
}
]
});*/
console.log('ok1');
Ext.define('Video', {
extend: 'Ext.data.Model',
fields: ['from_user', 'from_user_id']
});
var myStore2 = Ext.create('Ext.data.Store', {
model: 'Video',
storeId : 'restfulStore',
proxy: {
type: 'jsonp',
url : 'http://search.twitter.com/search.json?q=kathmandu',
reader: {
type: 'json',
//root: 'data.items'
root: 'results'
},
limitParam: 'rpp',
pageParam: 'page'
},
listeners: {
load: function(store, records) {
Ext.each(records, function(rec) {
console.log(rec.get('from_user'));
});
}
},
sorters: [{
property: 'from_user',
direction: 'DESC'
}, {
property: 'from_user_id',
direction: 'ASC'
}],
//autoLoad: true,
remoteSort: true
});
var p = myStore2.getProxy();
p.limitParam = 2;
myStore2.load();
console.log('loads anyway??? loaded the store ...');
Ext.create('Ext.grid.Panel', {
title: 'Restful Grid',
store: Ext.data.StoreManager.lookup('restfulStore'),
columns: [
{header: "From User", width: 200, sortable: true, dataIndex: 'from_user'},
{header: "From User ID", width: 200, sortable: true, dataIndex: 'from_user_id'}
],
height: 400,
width: 400,
renderTo: Ext.getBody()
});
console.log('store loaded!!');
}
});

Your proxy configuration is fine for what you want to do. The problem is in the way you load the store. You should not change limitParam which is really the config option for the name of the param. To affect the number of results, use the limit option of the load method, that you can also configure in the store with the pageSize option.
So, remove this:
var p = myStore2.getProxy();
p.limitParam = 2;
And instead, use the limit option when loading the store:
myStore2.load({
limit: 2
});
Alternatively, you can set this in the store config with the pageSize option:
Ext.create('Ext.data.Store', {
// ...
pageSize: 2
,autoLoad: true
});
You can mix both by setting a default with pageSize, and changing it at loading time with limit.
As a side note, the tweeter API doesn't seem to support sorting, so your sorters configuration won't have any effect on the returned results. You should switch remoteSort to false to have the returned results sorted on the client side according to your configuration.

Related

EXTJS How to use JSon Reader without proxy

Below is the code where I try to load some records using JSon Reader in the store.
I am unable to see this on the Grid.
Can you please point me out what am I missing as I don't want to use proxy/url for JSon.
var itemsPerPage = 10;
Ext.Loader.setConfig({enabled: true});
Ext.require([
'Ext.grid.*',
'Ext.data.*',
'Ext.util.*',
'Ext.toolbar.Paging'
]);
Ext.define('Assemble', {
extend: 'Ext.data.Model',
fields: [
{name: 'lot_no', type: "string"}
],
idProperty: 'lot_no'
});
Ext.onReady(function() {
Ext.QuickTips.init();
var jsonString = '{"result":[{"lot_no":"MT6261"},{"lot_no":"MT6262"},{"lot_no":"MT6263"}]}';
// create the data store
var store = Ext.create('Ext.data.Store', {
pageSize: itemsPerPage,
proxy:{
type: 'ajax',
reader: {
type: 'json',
root: 'result',
model: Assemble
}
}
});
store.loadData(Ext.decode(jsonString));
console.log(store);
var pagingToolbar = Ext.create('Ext.PagingToolbar',{
pageSize: itemsPerPage,
store: store,
displayInfo: true,
displayMsg: ' {0}-{1},{2}',
emptyMsg: "empty."
});
// create the Grid
var grid = Ext.create('Ext.grid.Panel', {
store: store,
disableSelection: true,
loadMask: true,
columns: [
{
text : 'LOT_NO',
flex : 1,
sortable : true,
dataIndex: 'lot_no'
}
],
bbar : pagingToolbar,
renderTo: 'grid',
viewConfig: {
stripeRows: true,
enableTextSelection: true
}
});
store.loadPage(1);
});
Proxy has to use with url. So, you can't use the proxy like that. I removed the proxy, put the model in store and you have to load objects into store, but in your case contained rootProperty('result', I only get the main objects or you can remove the 'result' from the jsonString). Then, it worked. Chck this fiddle:
https://fiddle.sencha.com/#fiddle/11or
var jsonString = '{"result":[{"lot_no":"MT6261"},{"lot_no":"MT6262"},{"lot_no":"MT6263"}]}';
// create the data store
var store = Ext.create('Ext.data.Store', {
pageSize: itemsPerPage,
model: 'Assemble'
});
store.loadData(Ext.decode(jsonString).result);
Why are you even using a reader? Your data is local so just decode the string and pass in what you want:
https://fiddle.sencha.com/#fiddle/11qc
Also, your data is local so no need for a paging toolbar. In Ext JS 5+ the grid will use the buffered renderer (if the grid has a defined size from height/width configs or from a parent layout) so loading all the data into the store will not affect performance (other than creating the records). The grid will only render what is viewable plus a few on either side.

ExtJS 3.0.0 autoreload json store

I need to reload my chart's json store automatically on interval of 2 minutes.
This is my code:
tab = new Ext.Panel({
id: "id-" + node.id,
closable: true,
title: node.attributes.text,
layoutConfig: {
columns: 3
},
defaults: {
frame: true,
height: 230,
border: true
},
items: [
new Ext.chart.LineChart({
store: new Ext.data.JsonStore({
url: 'dashboard/CantServicios',
root: 'cantservicio',
autoLoad: true,
ields: ['NOMBRE_SERVICIO', 'CANT']
}),
xField: 'NOMBRE_SERVICIO',
yField: 'CANT',
width: 840
})
]
});
How can I do that ?
You can do this using Ext.util.TaskRunner
http://docs.sencha.com/extjs/3.4.0/?mobile=/api/Ext.util.TaskRunner
So if you look at the sample in the docs link above you should see that you can easily define a function that just performs a load on your store and then it's just a matter of using that in as the run config option.

Extjs - How to refer the json datas in a controller?

I'm developing a simple login page wherein I need to compare the value that has been entered by any user in username field, with the json data store on click of 'LoginButton'. My question is, can we get the list of username from the json store in an array and compare with textfield values? If so, how?
My nSpaceIndex.html
<html>
<head>
<title>nSpace | Expense / Project Solutions</title>
<link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css">
<script type="text/javascript" src="extjs/ext-debug.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body>
</body>
</html>
app.js:
Ext.application({
requires: ['Ext.container.Viewport'],
name: 'nSpace',
controllers: [
'nSpaceController'
],
appFolder: 'app',
launch: function() {
Ext.create('Ext.container.Viewport', {
layout: 'fit',
items: {
xtype: 'loginView'
}
});
}
});
my nSpaceController.js:
Ext.define('nSpace.controller.nSpaceController', {
extend: 'Ext.app.Controller',
stores: [
'Users'
],
views: [
'login.loginView'
],
model: 'loginModel',
init: function() {
this.control({
"#loginButton": {
click: this.onLoginButtonClick
}
});
},
onLoginButtonClick: function(){
//var jsonArray = store.Users.data.items
//console.log(jsonArray);
// I NEED TO GET THE REFERENCE OF MY STORE: USERS TO COMPARE
var logUserName = Ext.getCmp('getUserName').getValue();
var logPassword = Ext.getCmp('getPassword').getValue();
if(logUserName == 'user01' && logPassword == 'password01'){
Ext.MessageBox.show({title: 'Success', msg: 'You will be redirected to the home page in few moments...', icon:Ext.MessageBox.INFO});
}
else if(logUserName == 'user02' && logPassword == 'password02'){
Ext.MessageBox.show({title: 'Success', msg: 'You will be redirected to the home page in few moments...', icon:Ext.MessageBox.INFO});
}
else{
Ext.MessageBox.show({title: 'OOPS!!!', msg: 'Please Enter Valid Details', icon:Ext.MessageBox.WARNING});
}
},
});
my loginModel.js:
Ext.define('nSpace.model.loginModel', {
extend: 'Ext.data.Model',
fields: ['loginusername', 'password']
});
Users.js:
Ext.define('nSpace.store.Users', {
extend: 'Ext.data.Store',
model: 'nSpace.model.loginModel',
autoLoad : true,
proxy: {
type: 'ajax',
url: 'data/users.json',
reader: {
type: 'json',
root: 'users',
successProperty: 'success'
}
}
});
loginView.js:
Ext.define('nSpace.view.login.loginView' ,{
extend: 'Ext.form.Panel',
alias: 'widget.loginView',
store: 'Users',
title: 'nSpace | Login',
frame:true,
bodyPadding: 5,
width: 350,
layout: 'anchor',
defaults: {
anchor: '100%'
},
defaultType: 'textfield',
items: [{
fieldLabel: 'User Name',
name: 'loginusername',
id: 'getUserName',
allowBlank: false
},{
fieldLabel: 'Password',
inputType: 'password',
id: 'getPassword',
name: 'password',
allowBlank: false
}],
// Reset and Submit buttons
buttons: [{
text: 'Sign Up',
handler: function() {
// location.href = 'signUp.html';
}
},{
text: 'Reset',
handler: function() {
this.up('form').getForm().reset();
}
}, {
text: 'Login',
id:'loginButton',
formBind: true, //only enabled once the form is valid
disabled: true,
}],
renderTo: Ext.getBody()
});
users.json:
{
"success": true,
"users": [
{"loginusername": 'user01', "password": 'password01'},
{"loginusername": 'user02', "password": 'password02'}
]
}
inside init function above this.control
try using this..
var store = this.getUsersStore();
store.load({
callback:function(){
var l = store.first();
console.log(l.get("password"));
}
});
this is how you can check
store.each(function(rec){
if (rec.get('password') === value) {
display = rec.get('username');
return false;
}
});
As other users have pointed out, it is trivial to perform authorization on the client side of the application. However you have stated that this is not a concern, therefore I will answer your question without addressing the obvious security flaws of this approach.
I see that you're making use of Ext.getCmp() therefore your components have been assigned an id. This is generally considered to be bad practice as the id property is global, and therefore if there are two components instantiated with the same id, the application will crash. You may find it useful to instead assign the component an itemId and create a reference to easily retrieve the component in the Controller's refs[] definition.
For example:
Ext.define('nSpace.controller.nSpaceController', {
... other store/model/view here ...
refs: [{
name: 'userNameField', // makes magic method 'getUserNameField()'
selector: 'textfield[name=loginusername]',
xtype: 'textfield'
},{
name: 'passwordField', // makes magic method 'getPasswordField()'
selector: 'textfield[name=password]',
xtype: 'textfield'
}],
this.control({ .. observe events here .. });
});
Retrieve a reference to your store, and search for the provided user...
var me = this, // controller
store = Ext.getStore('Users'),
user = me.getUserNameField.getValue(),
pass = me.getPasswordField().getValue(),
success;
// Attempt to find a record matching the provided user/pass
success = store.findBy(function(rec){
return (rec.get('loginusername') === user && rec.get('password') === pass);
});
// Store findBy returns the index, or -1 if no matching record is found
if(success >= 0){
// user/password matched
}else{
// no user/password match found
}

using single value json into extjs combobox

This is the json response I am getting. I checked with JSONLINT and it says valid, but if you notice it's only giving me value without the heading of the column... the column name is "States".
{"myTable":["VA","CA","CO","OK","PA","TX"]}
Would it be possible to use this Json to load in my combobox
items: [{
xtype: 'combo',
id: 'iccombo',
scope: this,
store: this.store,
mode: 'remote',
minChars: 0,
fieldLabel: 'Short State',
displayField: 'States',
valueField: 'States',
typeAhead: true,
name: 'States',
labelWidth: 125,
anchor: '95%'
},
this is my store
var store = Ext.create('Ext.data.Store', {
autoLoad: true,
id: 'OurData',
scope: this,
fields: [{ name: 'States' }],
proxy: {
type: 'ajax',
url: 'GetState/getS',
reader: {
type: 'json',
root: 'myTable'
idProperty: 'States'
}
}
});
Out of the box Ext has the Array Reader which is almost a match but a tweak is required for the data format you have. The Array Reader can be customized to take your data format and turn it into the format needed. This kind of customization is common for many services that cannot be modified at the server level and so we can easily adjust at the UI level thanks to the Ext JS data framework.
Here is a custom reader that you could use as well as an implementation based on your example and a quick loop that shows the data by record:
/**
* A customized reader to convert a list to an array for the
* ArrayReader to take
*/
Ext.define('Ext.ux.data.reader.JsonList', {
extend: 'Ext.data.reader.Array',
alias : 'reader.jsonlist',
root: 'myTable',
/**
* this is really the guts of the change
* convert an array of strings to an array of arrays of strings
*/
extractData: function (root) {
var data;
if (Ext.isArray(root) && !Ext.isArray(root[0])) {
root.forEach(function (val, idx, all) {
/* turn the value into an array */
all[idx] = [val];
})
}
data = root;
/* hand the array of arrays up to the ArrayReader */
return this.callParent([data]);
}
});
store = Ext.create('Ext.data.Store', {
autoLoad: true,
id: 'OurData',
scope: this,
fields: [{ name: 'State' }],
proxy: {
/* change this back to ajax to get server data */
type: 'memory',
url: 'GetState/getS',
reader: {
type: 'jsonlist'
}
},
/* temp data for simplified demo code */
data: {"myTable":["VA","CA","CO","OK","PA","TX"]}
});
/* just to demo that there are six records with State as the field name: */
store.each(function (rec, id, total) {
console.log(rec.get('State'))
});

Sencha Touch Store is not loading

I have a Store that need to load DataView,
I used Dummy Data until today and it work just fine,
I want to use a web page to load the data.
my store code is:
Ext.define("myApp.store.myStore", {
extend: "Ext.data.Store",
alias: "widget.myStore",
model: "myApp.model.myModel",
proxy: new Ext.data.HttpProxy({
type: 'ajax',
method: 'post',
url: 'URL'
}),
reader: new Ext.data.JsonReader(
{
type:'json',
rootProperty:'Results'
}),
autoLoad: true,
config: {
sorters: [{ property: 'MyProp', direction: 'ASC'}],
grouper: {
sortProperty: "MyOtherProp",
direction: "ASC",
groupFn: function (record) {
if (record && record.data.MyOtherProp) {
return record.data.MyProp;
} else {
return '';
}
}
}
}
});
In Firebug I can see that the result is 0 items (and the url have 2 items..)
What am I doing Wrong??
Thanks!
You may need to set the URL to a specific location.