PDA

View Full Version : Filtering an ajax grid based on selection in a slider component.



andytriboletti
11 Nov 2013, 10:45 AM
I have some data that gets loaded in a grid with one column being similarity. I want to have a slider component that when you change it it filters the items in the grid so those with a lower similarity than selected are not shown.

The problem I'm having is when I loop through the data store with filteredStore.data.each, it doesn't loop through the data. In Firebug I inspected filteredStore.data and there are 38 elements so it should do the looping.




//app.js

Ext.define('Molecules', {
extend: 'Ext.data.Model',
fields: ['smiles', 'molecularWeight', 'rotatableBonds', 'molecularFormula', 'similarity']
});




var states = Ext.create('Ext.data.Store', {
fields: ['abbr', 'name'],
data : [
{"abbr":"AL", "name":"c1ccccc1"},
{"abbr":"AK", "name":"CN1C(=O)N(C)c2ncn(C)c2C1=O"},
{"abbr":"AZ", "name":"CN1CCC[[email protected]]1c2cccnc2"}
//...
]
});




//CN1CCC[[email protected]]1c2cccnc2
//c1ccccc1
//CN1C(=O)N(C)c2ncn(C)c2C1=O

Ext.application({
name: 'HelloExt',
launch: function() {


var myStore;


var slider = Ext.create('Ext.slider.Single', {
fieldLabel: 'Similarity Threshold',
renderTo: 'slider',
width: 214,
minValue: 95,
maxValue: 100,
increment: 0.01,
useTips: true,
decimalPrecision: 2,
listeners: {
dragend: function(slider, thumb, value){
console.log(slider.getValue());

//myStore.load();
var filteredStore = Object.clone(myStore);
filteredStore.data.each(function(item, index, totalItems ) {
//var filter = 96.55;


var similarity = item.data ['similarity'];
if(similarity < filter) {
console.log(similarity);
filteredStore.remove(item);
}
});
filteredStore.sync();
grid.reconfigure(filteredStore);


}
}
});

var grid = Ext.create('Ext.grid.Panel', {
renderTo: Ext.getBody(),
store: myStore,
width: 800,
height: 200,
title: 'My app',
columns: [
{
text: 'SMILES',
width: 100,
sortable: false,
hideable: false,
dataIndex: 'smiles'
},
{
text: 'Molecular Formula',
width: 150,
dataIndex: 'molecularFormula',
},
{
text: 'Molecular Weight',
flex: 1,
dataIndex: 'molecularWeight'
},
{
text: '# of Rotatable Bonds',
width: 150,
dataIndex: 'rotatableBonds',
},
{
text: 'Similarity',
width: 150,
dataIndex: 'similarity',
},
]
});

Ext.create('Ext.form.ComboBox', {
fieldLabel: 'SMILES Search:',
store: states,
queryMode: 'local',
displayField: 'name',
valueField: 'abbr',
renderTo: 'search',
listeners: {
select: function(combo, records) {

var m= records[0]['data']['name'];
myStore=loadSmiles(m);
//myStore.reload();
//var filteredStore;
grid.reconfigure(myStore);


}
}
});




function loadSmiles(param) {
myStore = new Ext.data.Store({
model: 'Molecules',
proxy: {
type: 'ajax',
url: '/similaritySearch',
reader: {
type: 'json',
root: 'data'
},
writer: {
type: 'json',
root: 'data'
},
actionMethods: {
create: 'POST', read: 'POST', update: 'POST', destroy: 'POST'
},
extraParams: { smiles: param }
},
listeners: {
load: function (store, operation, options) {
}
},
autoLoad: true
});

return myStore;
}
function filter(filter) {
myStore.on('load', function () {
var filteredStore = Object.clone(myStore);
filteredStore.data.each(function(item, index, totalItems ) {
var similarity = item.data ['similarity'];
if(similarity < filter) {
console.log(similarity);
filteredStore.remove(item);
}
});
filteredStore.sync();
grid.reconfigure(filteredStore);

});
}







}
});




//index.html
<html>
<head>

<link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css">
<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript" src="extjs/ext-debug.js"></script>
<script type="text/javascript" src="app.js"></script>

</head>
<body>


<table>
<tr>
<td>
<div id = "search"></div>
</td>


<td>
<div id = "slider"></div>
</td>
</tr>
</table>

</body>
</html>

slemmon
23 Nov 2013, 12:20 AM
Why not instead use the store's filter or filterBy methods?
http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.data.Store-method-filter
http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.data.Store-method-filterBy