ExtJS : How to set combobox id? - extjs

I have a little problem. At my application Im always building two linked combobox - country and towns(then country are selected - towns began to load). So i thinked - mbe write a constructor and minimized my code? Ok i did it. But i got a problem: i have 2-3 couple of this linked comboboxes on page and when i selected at second combo country, the data (towns) loads at first combo, because it has the same id. Ok - now im trying take a param id to constructor and it didnt work. How set id of combobox then i create an object?
Country combo
comboCountryClass = Ext.extend(Ext.form.ComboBox, {
fieldLabel: 'country',
anchor: '95%',
lazyRender:true,
store:new Ext.data.Store({
proxy: new Ext.data.HttpProxy(
{url: '../lib/getRFB.php?rfb_type=countrys',
method: 'GET'}
),
reader: countryReader,
autoLoad: true
}),
displayField:'country_name',
valueField:'country_id',
triggerAction:'all',
mode:'local',
listeners:{
select:{
fn:function(combo, value) {
var modelCmp = Ext.getCmp(this.town_name_id);
alert(this.town_name_id);
modelCmp.setValue('');
modelCmp.getStore().proxy.setUrl('../lib/getRFB.php');
modelCmp.store.reload({
params: { 'country_id': this.getValue(),rfb_type: 'towns' }
});
}
}
},
hiddenName:'country_id',
initComponent: function() {comboCountryClass.superclass.initComponent.call(this);}})
And town combo
comboTownClass = Ext.extend(Ext.form.ComboBox, {
fieldLabel:'town',
displayField:'town_name',
valueField:'town_id',
hiddenName:'town_id',
anchor: '95%',
id:this.town_name_id || 'youuuu',
store: new Ext.data.Store({
proxy: new Ext.data.HttpProxy(
{url: 'lib/handlers/orgHandler.php?action=read&towns=true',
method: 'GET'}
),
reader: townReader
}),
triggerAction:'all',
mode:'local',
initComponent: function() {comboTownClass.superclass.initComponent.call(this);}})
new comboTownClass({town_name_id:'townFormSearch'})
new comboCountryClass({town_name_id:'townFormSearch'})

You can set the id of the component by doing the following:
new comboTownClass({id:'townComboId'});
new comboCountryClass({id:'countryComboId'});
You can specify a default id, and when you pass an id in the config param it will overwrite the default value.
Although I agree with #Upper Stage you should try to limit the amount of hard-coded id values you have in the form - you can instead grab form elements using the form name instead.

I live by the rule: "never use hardcoded IDs." You can retrieve a unique ID from Ext JS using
Ext.id( null, 'someTextString' )
You will incur more bookkeeping when you use unique IDs, but you will not run into the problem about which you write above.
Sometimes I store unique IDs locally in an object and then reference that instance variable where necessary.
this.idForCombo = Ext.id( null, 'someTextString' );
var myCmp = new SomeConstructor({
id: this.idForCombo,
...more stuff });

myCombobox.id = yourId;

Related

default value in combobox as value from store

I'm trying to get a return value of my json store to setValue in my combobox. The value of this json value is the current selected option in the database. My this.selectedCat store returns the current category value of the record where it's working in. my this.store returns all the available select options.
var fields = {
fields: ['text']
};
var notfields ={
fields:['category']
}
this.store = new GO.data.JsonStore({
url: GO.settings.modules.infoscherm.url + 'json.php',
baseParams:{
task:'selects'
},
root: 'results',
fields: fields.fields
});
this.selectedCat = new GO.data.JsonStore({
url: GO.settings.modules.infoscherm.url + 'json.php',
baseParams: {
task:'currentselectedcat',
id:'id'
},
root: 'results',
fields: notfields.fields
});
this.category = new Ext.form.ComboBox({
name: 'category',
width: 100,
store: this.store,
fieldLabel: "Categorie",
displayField:'text',
triggerAction: 'all',
editable: false,
selectOnFocus:true,
value: this.selectedCat //returns [object Object] naturally
});
Am I doing something wrong?
I think you need to start listening the "load" event of "Ext.data.JsonStore".
And the attached handler of "load" event will contain code to select any particular value by using "setValue" function of combobox object...
P.S. : Store values are made available in combobox drop down menu only if you configured the "store" config of combobox to the store object, in your case, you need to implement some logic within the handler of "load" event.

Sencha Touch component.DataItem to dynamic list

Okay, so I have a view that extends Ext.dataview.component.DataItem' I have this function
onNameButtonTap: function(button, e) {
var record = this.getRecord();
console.log("The tid of this record is: " + record.get('tid'));
}
I am able to get an tid back from this tap, which I would like to use to load a new view that will use this id to alter the proxy url to get back different data. Here is the view:
Ext.define('AIN.view.Headlines.Card', {
extend: 'Ext.NavigationView',
xtype: 'headlineContainer',
config: {
tab: {
title: 'Headlines',
iconCls: 'star',
action: 'headlinesTab'
},
autoDestroy: false,
items: [
{
xtype: 'headlines',
store: 'Headlines',
}
]
}
});
How would I get the url parameter in my store to accept a URL like this one
'http://mywebsite.com/app-feeds/channels/' + tid
Thanks for reading, I am new to this and after hours of google searching I can't quite figure this out.
Update, this is working for me.
var store = Ext.StoreMgr.get('Headlines');
store: store.setProxy({
type: 'jsonp',
url: 'http://awebsite.com/app-feeds/channels/' + tid,
reader: {
type: 'json',
rootProperty: 'nodes',
record: 'node'
}
}).load()
You can set the URL of an Ext.data.Store by doing:
store.getProxy().setUrl('http://mywebsite.com/app-feeds/channels/' + tid);
Note that if you are planning on using this Store in multiple areas that use different URLs, you may want to create a new instance of it when you are setting the URL.

Extjs combobox is not auto-selecting the displayField

UPDATE -
I HAVE ALSO MADE A MOCK IN JSFIDDLE http://jsfiddle.net/mAgfU/371/
AND WITH A FORM PANEL : http://jsfiddle.net/kA6mD/2/
I have the bellow comboox.
When I use the following code to set the form values:
this.form.loadRecord(data);
the entire form is acting ok except from the combo.
instead of giving me the displayField, I get the valueField in the display.
As you can see in the image above, the combo should show the word "Walla" (displayField) instead of "1" (valueField)
Ext.define('App.view.ForeignCombo', {
extend: 'Ext.form.ComboBox',
alias: 'widget.foreigncombo',
queryMode: 'local',
displayField: 'Name',
valueField: 'Id',
editable: false,
matchFieldWidth: false,
constructor: function(config) {
Ext.apply(this, config);
Ext.define('BrnadComboModel', {
extend: 'Ext.data.Model',
fields: ['Id', 'Name']
});
this.store = Ext.create('Ext.data.Store', {
model: 'BrnadComboModel',
autoLoad: true,
proxy: {
type: 'ajax',
url: '/api/Brand/',
reader: {
type: 'json',
root: 'Results'
}
},
pageSize: 50,
});
this.callParent();
}
}
);
this is how I use it:
{
"xtype": 'foreigncombo'
, "name": 'Brand.Id'
, "fieldLabel": 'Brand.Id'
}
There is no race bewtween the form display and the combo ajax request, the combo store is autoLoad:true, meaning I see that it has already been loaded...
Thanks
I used your fiddle a an example. Place a breakpoint in line 87 (Ext.ComponentQuery.query('comobobox')....), in this fiddle http://jsfiddle.net/kA6mD/9/, and set a watch to Ext.ComponentQuery.query('combobox')[0].store.data.. you'll notice the store has no data. This may be linked to what I mentioned in the comment.
I know there must be a better way of doing this, but what I usually use as a workaround is either load the store at some point before in the app or use a synchronous Ext.Ajax.request and load each record at a time in the store.
As this is a combo for brands I suppose you could load the store before (i.e. app load) and lookup for the store instead of creating a new one each time you create a foreigncombo component, so the first solution should work.
As for the second workaround it should also work, it takes a little bit more coding but its actually pretty easy. It should look something like this...
Ext.Ajax.request({
url:'your/url/',
async:false,
.....
success:function(response){
var records = Ext.JSON.decode(response.responseText);
for(var m=0; m<records.length; m++){
var record = Ext.create('YourBrandModel',{
abbr:records[m].abbr,
name:records[m].name
});
store.add(record);
}
}
})
You should do this as few times as possible as it may slow down the user experience if it gets called everytime you create a "foreigncombo", so checking if this store exists before creating one might be a good idea.
Please take in cosideration that I have not tested this code, so you may have to tweak it a little in order for it to work. But it should get you on tracks.

Reconfigure GridPanel with grouping on GroupingStore

I have a problem with a GridPanel that uses a GroupingView:
var grid1 = new Ext.grid.GridPanel({
store: new Ext.data.GroupingStore({
fields: [ ]
}),
cm: new Ext.grid.ColumnModel([ ]),
selModel: new Ext.grid.RowSelectionModel({ singleSelect: false }),
view: new Ext.grid.GroupingView({
groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "' + BPS.Resource.items + '" : "' + BPS.Resource.item + '"]})'
})
});
I an event I call reconfigure that sets a new store and columnmodel. The store is a GroupingStore and I set what groupField i want to use:
// define the store
var store1 = new Ext.data.GroupingStore({
proxy: new Ext.data.HttpProxy({
url: listConfig.dataURL + '?sort=' + listConfig.defaultSortField + '&dir=' + listConfig.defaultSortDirection,
method: 'POST'
}),
autoLoad: false,
remoteSort: true,
remoteGroup: true,
groupOnSort: false,
groupField: listConfig.groupingColumn,
sortInfo: {
field: listConfig.defaultSortField,
direction: listConfig.defaultSortDirection
},
paramNames: {
start: 'skip',
limit: 'take',
sort: 'sort',
dir: 'dir'
},
reader: new Ext.data.JsonReader()
});
// reconfigure the grid
grid1.reconfigure(store1, new Ext.grid.ColumnModel(listConfig.columnDefinitions));
However, this seem to work the first time it's loaded. It sets grouping on a column, or no grouping at all if I haven't configured it. But after the user turn off grouping in the gridpanel and the same code runs in order to load the configuration it doesn't change it to be grouped.
What can I do to reconfigure the grid to use, or not use, grouping?
I was having issues with a groupingstore. When I modified a field of a record and the grouping was on that column where I modified the field from, the grid did not automatically regroup the records.
Also when adding a new row, the grouping was not correct, the record that was added did not get added in the correct group.
I solved this problem by keeping the current groupBy field in a global var and each time on update or afteredit and added events from the grid I unGrouped and then used groupBy() with the var that contains the current column where the store was grouped on.
Using only grid.getView().refresh(); didn't do the trick.
Question of course is, is this user friendly? Because each time that a field from a row is modified and the grouping is set on the column of that field that was modified, the record will get regrouped and the user might have problems finding the row he was modifying.
Better solution: Only unGroup and then use groupBy() with the var that stored the current groupBy column when the focus on the record that is being edited is lost. SO on the blur event.
I think you attach a listener to the GroupingStore's groupchange event and record the field that was chosen as the grouping field. Then when reconfiguring, you tell the store to group by that field with the groupBy() function or use the ungroup() function to remove the grouping. Then call the grid's view refresh() method.
Note that I haven't tested this so it may be complete rubbish! :-)

ExtJS: Linked combobox puzzle

I write special combo object to use it as linked combos. Here it is:
comboDivClass = Ext.extend(Ext.form.ComboBox, {
fieldLabel: 'Divisions',
anchor: '95%',
lazyRender:true,
store:new Ext.data.Store({
proxy: proxy,
baseParams:{rfb_type:'divisions'},
reader: divReader,
autoLoad: true
}),
displayField:'div_name',
allowBlank:false,
valueField:'div_id',
triggerAction:'all',
mode:'local',
listeners:{
select:{
fn:function(combo, value) {
if (this.idChildCombo) {
var modelCmp = Ext.getCmp(this.idChildCombo);
modelCmp.setValue('');
modelCmp.getStore().reload({
params: { 'div_id': this.getValue() }
});
}
}
}
},/**/
hiddenName:'div_id',
initComponent: function() {comboDivClass.superclass.initComponent.call(this);}})
As you may see, this combobox load data at child combobox store(which set as idChildCombo).
Ok. Here is how i declare it
new comboDivClass({id:'sub0div',idChildCombo:'sub1div'}),
new comboDivClass({id:'sub1div'})
Yes it works, but it have some odd trouble - it load not only sub1div store, it load at sub0div store too. Why? What im doing wrong?
One thing I see is that you have mode: 'local' config, while it should be remote.
Other thing to consider: Why don't you do it more like this:
var c1 = new comboDivClass({id:'sub0div'});
var c2 = new comboDivClass({id:'sub1div'});
c1.on('select',function(combo, value) {c2.getStore().reload({
params: { 'div_id': c1.getValue() }
})});
ChildCombo.setMasterField( masterField ) {
masterField.on('change', function(field){
this.getStore().filterBy( function(){ //filter by masterFIeld.getValue() } );
})
}
The idea is to link child field to parent not parent to child and this way you can link to any kind form field no only combo.
Here in child combo you have to have store with three columns [group,value,label] where group is value of master field.
This way you can manage to have mode than one master field.

Resources