I use form.fields from EXTJS API. My application is totally dynamically.
It is possible to autosize combobox thanks to value which are on store ?
Or i need to make my own method... ?!
Actually, my combobox , is declared as following :
itemId : 'materialid',
xtype : 'combobox',
anchor : '35%',
store : materialstore,
id : 'Material',
queryMode: 'local',
displayField: 'data',
width : 50,
valueField: 'data',
editable : false,
grow : true,
enforceMaxLength : true,
listeners : {
render : function(me){
var obj = materialstore.findRecord('data',materialdefaultvalue);
me.setValue(obj.get('data'),obj);
}
},
padding : '0 30 0 30',
fieldLabel : 'Material',
name : 'material',
listeners : {
blur : function(me){
var fieldvalue = me.getValue();
var sel = monPretree.getView().getSelectedRecords();
for ( var i = 0 ; i < sel.length ; i++){
alert(sel[i].get('id') + ' && ' + material);
}
}
}
Thanks :)
Unfortunately not. Your best bet would be either to set a fixed width (like you have) or set it to '100%'.
A quick note for future questions: it is better to ask them over on the Sencha forums, as you will get a quicker response.
Related
I am creating a dependent combo for country,city and state here. I have a select listener in country combo,wherein I call loadCityCombo method.. But, I am not able to access cityStore from loadCityCombo.
What changes should I do for the dependent combo to work?
this.country = {
store : this.countryStore,
xtype: 'combo',
fieldLabel : 'Country',
displayField : 'country',
valueField : 'country',
name : 'country',
typeAhead : true,
mode : 'local',
triggerAction : 'all',
editable : false,
forceSelection : true,
allowBlank : false,
emptyText : 'Select Country',
listeners : {
'select' : this.loadCityCombo
}
};
this.loadCityCombo = function(country) {
console.log('load-CityCombo');
console.log(country);
var ctyCombo = (that.mainFormPanel.getComponent('locationDetailsFieldSet')).getComponent('citycombo');
console.log(ctyCombo);
var that = this;
if(country != null){
var countryName = country.value;
console.log(this.cityStore);
console.log(that.cityStore);
that.cityStore.reload({
params : {
country : countryName,start : 1,limit : 1
}
});
}
};
I think you could be suffering from a scope issue, try adding
listeners : {
'select' : this.loadCityCombo,
scope: this
}
You should be able to use the this keyword and not the 'that' variable you have defined
EDIT
If not defined, this usually refers to the browser window.
I noticed that a user cannot hide all columns in a gridpanel. It seems that the grid must at least display one column. I can imagine this is a nice feature, but it doesn't work quite as I expected when dealing with both hideable and non-hideable columns. It seems that the rule is that at least one hideable column is required to display, even if there is a non-hideable column in the grid.
It doesn't make sense to me to not allow hiding of all hideable columns when at least one non-hideable column is displayed. Is this behaviour configurable?
I created a demo based on the Stateful Array Grid Example showing the problem:
http://jsfiddle.net/p9zqK/
var grid = Ext.create('Ext.grid.Panel', {
store: store,
stateful: true,
stateId: 'stateGrid',
columns: [
{
text : 'Company',
flex : 1,
sortable : false,
hideable : false,
dataIndex: 'company'
},
{
text : 'Price',
width : 75,
sortable : true,
renderer : 'usMoney',
dataIndex: 'price'
},
...
A simple hack is to allow all columns to be hidden unconditionally (in my application I don't bother about checking whether hideable columns exist, because I know they do...)
Ext.override(Ext.grid.header.Container,
{
updateMenuDisabledState: function()
{
var me = this,
result = me.getLeafMenuItems(),
total = result.checkedCount,
items = result.items,
len = items.length,
i = 0,
rootItem = me.getMenu().child('#columnItem');
//if (total <= 1)
if (total <= 0) /* Allow all columns to be hidden unconditionally */
{
me.disableMenuItems(rootItem, Ext.ComponentQuery.query('[checked=true]', items)[0]);
}
else
{
for (; i < len; ++i)
{
me.setMenuItemState(total, rootItem, items[i]);
}
}
}
});
Am trying to put a search field with respect to a data view. There is a toolbar on top of the data view, which consists of a text field. On entering some text in the field, i want to call a search functionality. As of now, i have got hold of the listener to the text field, but the listener is called immediately after the user starts typing something in the text field.
But, what am trying to do is to start the search functionality only when the user has entered at least 3 characters in the text field.How could i do this?
Code below
View
var DownloadsPanel = {
xtype : 'panel',
border : false,
title : LANG.BTDOWNLOADS,
items : [{
xtype : 'toolbar',
border : true,
baseCls : 'subMenu',
cls : 'effect1',
dock : 'top',
height : 25,
items : [{
xtype : 'textfield',
name : 'SearchDownload',
itemId : 'SearchDownload',
enableKeyEvents : true,
fieldLabel : LANG.DOWNLOADSF3,
allowBlank : true,
minLength : 3
}],
{
xtype : 'dataview',
border : false,
cls : 'catalogue',
autoScroll : true,
emptyText : 'No links to display',
selModel : {
deselectOnContainerClick : false
},
store : DownloadsStore,
overItemCls : 'courseView-over',
itemSelector : 'div.x-item',
tpl : DownloadsTpl,
id : 'cataloguedownloads'
}]
Controller:
init : function() {
this.control({
// reference to the text field in the view
'#SearchDownload' :{
change: this.SearchDownloads
}
});
SearchDownloads : function(){
console.log('Search functionality')
}
UPDATE 1: i was able to get hold of the listener after three characters have been entered using the below code:
Controller
'#SearchDownload' :{
keyup : this.handleonChange,
},
handleonChange : function(textfield, e, eOpts){
if(textfield.getValue().length > 3){
console.log('Three');
}
}
any guidance or examples on how to perform the search in the store of the data view would be appreciated.
A proper way would be to subscribe yourself to the change event of the field and check if the new value has at least 3 chars before proceeding.
'#SearchDownload' :{ change: this.handleonChange }
// othoer code
handleonChange : function(textfield, newValue, oldValue, eOpts ){
if(newValue.length >= 3){
console.log('Three');
}
}
Btw. I recommend you to use lowercase and '-' separated names for id's. In your case
itemId : 'search-download'
Edit apply the filter
To apply the filter I would use filter I guess you now the field you want to filter on? Lets pretend store is a variable within your controller than you may replace the console.log() with
this.store.filter('YourFieldName', newValue);
Second param can also be a regex using the value like in the example
this.store.filter('YourFieldName', new RegExp("/\"+newValue+"$/") );
For sure you can also use a Function
this.store.filter({filterFn: function(rec) { return rec.get("YourFieldName") > 10; }});
Thanks you so much sra for your answers. Here is what i did, based on your comments
filterDownloads : function(val, filterWh){
if(filterWh == 1){
var store = Ext.getStore('CatalogueDownloads');
store.clearFilter();
store.filterBy(function (r){
var retval = false;
var rv = r.get('title');
var re = new RegExp((val), 'gi');
retval = re.test(rv);
if(!retval){
var rv = r.get('shortD');
var re = new RegExp((val), 'gi');
retval = re.test(rv);
}
if(retval){
return true;
}
return retval;
})
}
}
i think there is an example of exactly what you are trying to achive .. http://docs.sencha.com/ext-js/4-0/#!/example/form/forum-search.html
How to group header like grid below in extjs:
|-------------- A1 header------------|--------------B1 Header---------------|
|----A2Header---|---A3Header---|----B2Header---|---B3Header------|
|-----A2Data------|----A3 Data------|-----B2 Data------|-----B3 Data-------|
|-----A2Data------|----A3 Data------|-----B2 Data------|-----B3 Data-------|
my code extjs:
plColModel = new Ext.grid.ColumnModel([
new Ext.grid.RowNumberer(),
{ header: "A2Header", dataIndex: 'A2Data' },
{ header: "A3Header", dataIndex: 'A3Data' },
{ header: "B2Header", dataIndex: 'B2Data' },
{ header: "B3Header", dataIndex: 'B3Data' }
]);
I remember how I've spend a lot of time trying to understand the code in the example Sencha provided for ColumnHeaderGroup. I've made a 6-level column group header several days ago and it is not that difficult.
Put all of your column headers in an object as object keys for the following headers. Last headers' followers will be the columns' properties:
var chstructure = {
'A1 header' : {
'A2Header' : {'A2Data' : {'A2Data' : {'dataIndex' : 'A2', 'width' : 100}}},
'A3Header' : {'A3Data' : {'A3Data' : {'dataIndex' : 'A3', 'width' : 100}}}
},
'B1 header' : {
'B2Header' : {'B2Data' : {'B2Data' : {'dataIndex' : 'B2', 'width' : 100}}},
'B3Header' : {'B3Data' : {'B3Data' : {'dataIndex' : 'B3', 'width' : 100}}}
}
};
You'll need some arrays to put the headers in: these arrays will be the rows in your column header group. You'll also need a fields array: it will contain the fields for your store. Don't forget to initialize some colspan variables (I'll name them len n ) that will keep count of the colspan for each column header (in this example 'A1 header' has 2 children and 'A2Header' has only 1), and some width variables (wid n ), for each header's width.
var Row1contents = [], Row2contents = [], Row3contents = [], Row4contents = [];
var len1 = 0, len2 = 0, len3=0, wid1 = 0, wid2 = 0, wid3 = 0;
var fields = [];
Now you may finally parse chstructure in order to retrieve the column headers. Use Ext.iterate for that:
Ext.iterate (chstructure, function(Row1, Row1structure){
Ext.iterate (Row1structure, function(Row2, Row2structure){
Ext.iterate (Row2structure, function(Row3, Row3structure){
Ext.iterate (Row3contents, function(Row4, Row4structure){
len1++;len2++;len3++;
wid1+=Row4structure['width'];
wid2+=Row4structure['width'];
wid3+=Row4structure['width'];
Row4contents.push({
dataIndex: Row4structure['dataIndex'],
header: Row4,
width: Row4structure['width']
});
fields.push({
type: 'int', // may be 'string'
name: Row4structure['dataIndex']
});
});
Row3contents.push({
header: Row3,
width: wid3,
colspan: len3
});
len3=wid3=0;
});
Row2contents.push({
header: Row2,
width: wid2,
colspan: len2
});
len2=wid2=0;
});
Row1contents.push({
header: Row1,
width: wid1,
colspan: len1
});
len1=wid1=0;
});
View the 4 arrays in your console and ensure they contain all data you set. The last step is to configure the grid width the ColumnHeaderGroup plugin. Use property
plugins: [new Ext.ux.grid.ColumnHeaderGroup({
rows: [Row1Group, Row2Group, Row3Group]
});
Set columns : Row4contents for your grid and fields : fields for your grid's store.
Happy coding!
refer this :
ColumnHeaderGroup
Here is one great example by Sencha
http://dev.sencha.com/deploy/ext-3.4.0/examples/pivotgrid/people.html
When my users edits the Grid via RowEditor combo entries and checkboxes are annoying
1 Apple
2 Orange
3 Pear
For instance with the combo above the user will select Orange then update - the Grid now instead of saying orange will display the number 2 - I would like it to show orange when a successful edit has been made.
code for my combo
editor : {
allowBlank : false,
displayField : 'team',
editable : false,
emptyText : 'Select Team',
forceSelection : true,
lazyRender : true,
mode : 'remote',
name : 'team',
store : storeTeam,
triggerAction : 'all',
valueField : 'id',
xtype : 'combo'
}
I think I read that you could send the complete row back to insert or I should listen to the update of the grid and then change the field but I need some guidance on what is best
Cheers
Try the code below. Use this column just like you would any other ExtJS grid column.
Ext.grid.FixedListColumn = Ext.extend(Ext.grid.Column, {
constructor: function(cfg){
cfg.editor = new Ext.form.ComboBox(cfg.editor);
Ext.grid.ComboBoxColumn.superclass.constructor.call(this, cfg);
this.renderer = Ext.util.Format.comboRenderer(cfg.editor);
}
});
Ext.grid.Column.types.fixedlistcolumn = Ext.grid.FixedListColumn;
// Takes in a combobox and returns a renderer that looks up the displayField in
// the store attached to the combo
Ext.util.Format.comboRenderer = function(combo){
return function(value){
var record = combo.findRecord(combo.valueField, value);
return record ? record.get(combo.displayField) : combo.valueNotFoundText;
}
}
// Use this as the 'columns' parameter when creating your Grid
var grid_columns = [
{xtype:'fixedlistcolumn',
store: [[1,'Apple'],[2,'Orange']]},
...
];
I hope this helps...
You can add renderer definition to your team column:
Below is example of how simple true/false values are represented as Yes/No in the GridPanel:
renderer:function(val){
if(val=="true" || val == true) {
return "Yes";
}
else{
return "No";
}
}