PDA

View Full Version : Populating Combobox



winklerd
26 Aug 2010, 11:42 AM
I'm trying to populate a combobox with the results of an AJAX call but I'm a little bit frustrated. Right now the PHP code is returning a JSON object that looks like this: ["foo","test","bar","baz"]

But from what I can tell, there's no way to take a simple little array and populate the combobox with those values. It looks like I'm going to have to muck it all up into a format like this:

{'items':
[{'id':'1', 'name':'foo'},
{'id':'2', 'name':'bar'},
{'id':'3', 'name':'baz'},
{'id':'4', 'name':'test'}]
}

If I were inserting the values directly, I know I could set the store attribute to the array. But since I want to use an AJAX call to dynamically pull the values, I think I have to use a actual Store object.

Am I missing something? Or is that just the way it is?

GoneIn20Seconds
26 Aug 2010, 2:23 PM
Can we see some of your code? It would help to diagnose the problem.

GoneIn20Seconds
26 Aug 2010, 2:40 PM
Depending on how you are calling the AJAX, you might also want to set the combobox mode to "local".

winklerd
27 Aug 2010, 7:41 AM
It wasn't necessarily a "problem" because I got the code to work, but it just seemed strange. Here's what I ended up going with:


FC.Widgetator.LoadStore = new Ext.data.JsonStore({
proxy: new Ext.data.HttpProxy(new Ext.data.Connection({
url: 'widgetator.php',
extraParams: { operation: 'list' }
})),
root: 'items',
fields: ['name']
});
FC.Widgetator.MainPanel = Ext.extend(Ext.Panel, {
// ... snipped code ...
tbar: [{
xtype: 'combo',
store: FC.Widgetator.LoadStore,
displayField: 'name',
valueField: 'name',
mode: 'remote',
triggerAction: 'all',
typeAhead: true,
minChars: 1,
//queryDelay: 1400,
id: 'widgetloadcombobox'
}, // ... more snipped code ...

function doList() {
global $customwidgetpath;

$filter = $_POST['query'];
$regex = $filter != null ? "/^$filter/" : '/.*/';

$dir = opendir($customwidgetpath);
$widgets = array('items' => array());

$files = array();
while($file = readdir($dir)) $files[] = $file;
closedir($dir);
sort($files);

foreach($files as $file) {
if(preg_match('/^(\w+)\.xml$/',$file,$match) === 1 &&
preg_match($regex, $file) === 1) {
$widgets['items'][] = array('name' => $match[1]);
}
}

print(json_encode($widgets));
}My major complaint is that I'm now returning an array of arrays of arrays because I need to have a root node and a field pairing. It just seemed overly complicated to display a simple list of filenames. I guess I'm just a whiner. :-p

Also, I'm curious about your second comment... under what circumstances would it be acceptable to use local?

GoneIn20Seconds
27 Aug 2010, 8:46 AM
By setting the mode to local you can manually load the store. Leaving it on remote will load the store automatically the first time the combobox is activated.

As for the double array, you could try setting your root node to "" (empty string) if you want to simplify the array just a bit. I think the reason ExtJs comes back as a double array is in case you want to send back other information (beyond just the data being used to populate the object).

An example would be if you wanted to send back data that would fill a grid. The grid would read the data from the "root" node, you could use the "success" node to send back whether the query was successful and then use the "total" node to send back the total number of responses (which is useful when paging). See the Ext.data.JsonReader for more information on that. The JsonStore automatically inherits its properties.

I'm glad you have it working.

j-joey
27 Aug 2010, 9:38 AM
you can use ArrayStore instead of JsonStore

j-joey
27 Aug 2010, 9:42 AM
combo's mode property specifies where "filtering" will be done. local uses store's own filter method without making a new ajax request. remote forces each filtering action to be a new ajax request.

in most cases local is enough. except if you have tons of data need to be filtered.

laurentParis
27 Aug 2010, 12:49 PM
use this code for loading your datas manualy :


var datas = {'items':
[{'id':'1', 'name':'foo'},
{'id':'2', 'name':'bar'},
{'id':'3', 'name':'baz'},
{'id':'4', 'name':'test'}]
}, store = new Ext.data.JsonStore({
root: 'items',
idProperty: 'id',
fields: ['id', 'name']}
);
var combo = new Ext.form.ComboBox({
store: store,
displayField:'name',
valueField: 'id',
mode: 'local',
triggerAction: 'all',
renderTo: Ext.getBody()
});

combo.store.loadData(datas);
for same result by Ajax, use this code :


var store = new Ext.data.JsonStore({
autoLoad:true,
url: 'widgetator.php',
root: 'items',
idProperty: 'id',
fields: ['id', 'name']}
);
var combo = new Ext.form.ComboBox({
store: store,
displayField:'name',
valueField: 'id',
mode: 'remote',
triggerAction: 'all',
renderTo: Ext.getBody()
});