View Full Version : Problem loading dynamically a combo box store

7 May 2015, 6:29 AM

I've got a problem with my combo box not displaying data in the associated store.

Here's my situation. I have a grid listing tasks associated to different projects. For each task, I want to use a combo box to change some data, let's say I want to allow the user to change the task status from "In Progress" to "Completed". Those "status" are specific to each project so for the same grid's column, the combo box might have different values.

Given that situation, my plan was to define a common store for all the "status" and filter on the project before starting the editing process. That way, I would only see the statuses the task can have relative to the project. To gain some performance, I want to load the data store just before the editing process so I don't load statuses that aren't needed. It would be fine to do all this before rendering the grid if I had only 1 or 2 projects, but when you can have up to 500 it's simply not an option.

Hoping I have explain myself clearly, here's now the code I use and I would like to know where did I go wrong because it doesn't work...

// Declare my Store and Proxy variables
var structureStore; // Store for project structures
var gStructure = []; // Proxy for project structures

// Define my column for the grid (I put all in an array then point to it when creating the panel) aceColumns.push({
dataIndex: 'TASK_STATUS_ID',
field: {
xtype: 'combobox',
queryMode: 'local',
store: structureStore,
displayField: 'NAME',
valueField: 'ID',
lazyRender: true,
listClass: 'x-combo-list-small'
header: 'Status',
sortable: false,
menuDisabled: true

function defineComboStore() {
// Structures
Ext.define('structureModel', {
extend: 'Ext.data.Model',
fields: [
{ name: 'PROJECT_ID', type: 'int' }, // project
{ name: 'ID', type: 'int' }, // structure
{ name: 'NAME', type: 'string' }, // structure
{ name: 'TYPE', type: 'int' }, // structure
{ name: 'DEFAULT_PERC_DONE', type: 'int' } // structure (status only)

structureStore = Ext.create('Ext.data.Store', {
model: 'structureModel',
proxy: {
type: 'memory',
reader: {
type: 'json'

// Load the empty store from proxy
structureStore.proxy.data = gStructure

// Just before editing, I call this function to retrieve the statuses values from our API function getProjectStructureList(structure) {
try {
var params = {
async: false,
fct: "GetProjectStructureList",
projectid: structure.projectId,
taskstatus: 1,
apiCall(params, loadStructureStore, undefined, structure);
catch (myerr) {
addError('Error in function [' + fctName(arguments.callee.toString()) + ']', myerr) throw myerr

// And this function executes after receiving the values from our API
function loadStructureStore(results, structure) {
$.each(results, function (i, result) {
result.id = result.ID;
result.PROJECT_ID = structure.projectId;

// Since the proxy array has been updated, reload the store

So technically I should have a store with the new values. And when in debug, I do see the store with the correct values in it. Unfortunately, the combo box doesn't show them. What am I missing?

11 May 2015, 7:52 AM
It seems you are mixing Ext JS and jQuery. Why? Why not use an ajax proxy on the store to load the data?

11 May 2015, 12:15 PM
The short answer is performance and current application design.

The long answer...

An AJAX proxy could work well if our API was built to handle those kind of request, but it's not. We built our entire application first and now we're trying to fit something new (your grid component) into the "old" stuff. Had we build our application with your grid component from the start, the design would be different and integrate itself easily with it. Unfortunately, that's not the case.

As for performance, we display up to 500 records on 1 page. Each of those records could have a different "ID" for which there are multiple choices for multiples combo box. An AJAX proxy would need to call the API just before editing a combo box to know its content. Multiply this call by 5 or 6 combo per record, multiplied by 500 possible records, multiplied by thousands of clients, multiplied by hundreds of our client's employees... You can see how it can easily bring down a server if we allow too many requests. That's why we want to call the API just once per ID and then just load whatever we need from memory instead of calling the API.