PDA

View Full Version : [2.0] ComboBox and JsonStore



murraybozinsky
6 Mar 2008, 6:34 AM
Hi, I have some troubles rendering an Ext.form.ComboBox with data read from a JsonStore. Since the data contains some special characters it is necessary to escape it. Before viewing it in my ComboBox, i need to unescape it somehow.

Where can I do this? I tried to modify the records in the store's load event, however the ComboBox is rendered with the unprocessed data.

In the beforerender-event of the ComboBox, the store hasn't been loaded yet, so there's no way to unescape the data there...

Here's my Code:



var store = new Ext.data.JsonStore({
url: 'myurl',
root: 'data',
fields: ['id', 'title']
});

store.on('load', function(s, r) {
Ext.each(r, function(rec) {
rec.data.title = unescape(rec.data.title);
});
});

var combo = new Ext.form.ComboBox({
id: 'combo1',
applyTo: 'mycombo',
store: store,
valueField:'id',
displayField: 'title',
hideTrigger:false,
triggerAction: 'all'
});


When I select a dataset from the store it's correctly unescaped viewed, only the dropdown-list shows the unescaped 'title'-field...

Any suggestions for this?

mjlecomte
6 Mar 2008, 3:23 PM
Since no one else has replied yet, I'll take a stab at it. Have you seen the Tutorial on Extending a class? It modifies a combobox. It might give you some ideas. Maybe using your own template will help.

murraybozinsky
7 Mar 2008, 12:53 AM
It might be a possibility to extend the ComboBox, yes... But IMHO it should be possible to modify a store's data before it's used by elements such as combobox, tree, view or grid. Those elements should be rendered AFTER the code in the store's load event has been processed.

I think it's necessary in many cases to escape data loaded by a store, e.g. because <'> will cause problems with the reader.

In addition, I also tried to create my ComboBox in the load event of the JsonStore after modifying its data. Unfortunately this made my browser crash :-(

mjlecomte
7 Mar 2008, 5:09 AM
I wasn't saying to extend the class, it was just to give you ideas how to transform the data.

The other place you might look is the "convert (http://extjs.com/deploy/dev/docs/?class=Ext.data.Record&member=create)" function in the record. It fires after the load and datachanged events though.

I added that to a combobox I have that is loaded from a remote source and it seemed to work (I simply added a letter "A" at the end of everything in the combobox).

So maybe something like this (I typed this here without benefit of texteditor help, etc so edit as needed)



var store = new Ext.data.JsonStore({
url: 'myurl',
reader: new Ext.data.JsonReader(
{
root: 'data'
},
[
{name:'id'},
{
name:'title',
convert: function(v){
//manipulate v here
console.log('Converting the title, where v = ',v);
return unescape(v);
}
}
]
)
});

murraybozinsky
7 Mar 2008, 7:05 AM
Hey thank you!

That was exactly what I was looking for! Am I blind, or is that not listed in the docs?

mjlecomte
7 Mar 2008, 7:45 AM
I gave you the link in the prior post where it's at in the docs. It's not "obvious". See the link I posted above.

murraybozinsky
10 Mar 2008, 12:48 AM
Ah okay,

to complete my little combobox-project I got another question: I'd like to give a combobox a default value, one record from the store that is set by its id when the combobox has been rendered.

According to docs and forum I can do this by ComboBox.setValue(id); The place to do this would be the Combo's 'show' event. Unfortunately, this event is now fired (or not caught) for me...

Here's my combobox code:



// create template
var template = new Ext.XTemplate(
'<tpl for=".">',
'<div class="x-combo-list-item">',
'<span><img src="user.png" ></span><span>{title} ({value})</span>',
'</div>',
'</tpl>'
);
template.compile();


var store = new Ext.data.JsonStore({
url: '/wga/be/html/employees:json:get-testdata',
root: 'data',
fields: [{name:'id'},
{
name:'title'
,convert: function(val) {
return unescape(val);
}
},
{
name:'value'
,convert: function(val) {
return unescape(val);
}
}
]
});


var combo = new Ext.form.ComboBox({
id: 'cb_0.5618229408644424',
applyTo: 'key',
store: store,
valueField:'id',
displayField: 'title',
hideTrigger:false,
triggerAction: 'all',
tpl: template
,width:240
,listeners:{

// never executed :-(
'show': function(combo) {
console.log('show event triggered');
// this.setValue(.......);
},

'select': function(combo, record, index) {
// my select code
}

}

});


// tried to catch it here, doesn't work either
//combo.on('show', function() {
// console.log('hello');
//});

mjlecomte
10 Mar 2008, 3:18 AM
I did something similar here (http://extjs.com/forum/showthread.php?p=132103#post132103), hooking into the afterEdit event.

murraybozinsky
10 Mar 2008, 3:50 AM
Yes you are extending the afterRender event, setting default value by setValue(). However, this event is fired (or caught) for me neither. Since I receive the combo's select event I don't think there's something wrong with my events in general...

I'm confused... those events do not work for me in FF Mac and IE 6...

mjlecomte
10 Mar 2008, 4:42 AM
I didn't pick up on where you're rendering the comboBox to?

For example, if you render it to an html element on the page, etc. Or are you putting inside a grid.

Download my tutorial and run it. I have several console logs in there, you can see when the various events fire.

My best guess at this point is maybe you're listening to the wrong object or something.


Note if you're doing something with a grid, I have a comboBox served up by a remote json store in my grid example, and I set 'default' values into it when new records are added. Another way might be to have the server send the default values (depending on what you're doing of course).

murraybozinsky
10 Mar 2008, 4:55 AM
Okay I'll run your example, thx...

Btw I'm rendering the ComboBox to an html-input field, just didn't post that here.

<input id="key" name="key"/>

Rendering works fine...

mjlecomte
10 Mar 2008, 6:24 AM
I wasn't questioning if the rendering worked fine, only who or how you're doing it that it didn't fire the render events.

If you're using a form and the form is not created by ext you'll have problems, this has been discussed several places in forum. If this is what you are doing, try creating everything in ext and then seeing if the render event fires. As Saki mentioned in some thread I believe, you should have a virtually blank html page, everything gets handled by ext.

murraybozinsky
11 Mar 2008, 1:11 AM
Yep, I am using a plain HTML-Form, thus no Ext-form... So this might be the reason indeed. As I'm building some template element with the Ext.Combo-Box for use with our JSP-based CMS, it is important for me to use the combo with default html-forms. I'll take a look at the Ext-form anyway...

Thanks for supporting me ;)

murraybozinsky
26 Mar 2008, 3:30 AM
To finally finish this thread, here's what I did to give my combobox a default-value:




var defaultValue = 'somevalue';
var initialLoad = true;

store.on('load', function() {
if (combo && initialLoad) {
combo.setValue(defaultValue);
initialLoad = false;
}
});



Using this code and setting the store's autoLoad-option to true, I can give my combobox a defaultvalue which is set when the page is loaded without the need for a show- or afterEdit-event, which is not fired for me anyway...