Use custom HTML in grid combobox - extjs

I need to set up grid enline-editing combo box to show custom HTML. To be more concrete, please, look at this sample. Click any cell in Light column, open combobox. I want to place near every option ("Shade", "Mostly shady", ...) square box with unique color.

I was having the same problem. Finally found the answer when I was trying the solution above (which doesn't work either but is really close).
Turns out that the class for the list items is x-boundlist-item not x-combo-list-item.
If you mark your div with that class it will work. Extremely frustrating that this isn't outlined in the Sencha docs under the tpl config item for combo boxes, especially when all of the examples I can find just show a simple div for the items. I'm guessing it used to work by wrapping whatever was in the tpl config with the li and the class but it doesn't anymore. That said this is more versatile since you can make headers and lines that aren't selectable in your dropdowns by leaving off the class for those items.
var states = Ext.create('Ext.data.Store', {
fields: ['abbr', 'name'],
data : [
{"abbr":"AL", "name":"Alabama"},
{"abbr":"AK", "name":"Alaska"},
{"abbr":"AZ", "name":"Arizona"}
//...
]
});
Ext.application({
name: 'SRC',
launch: function() {
Ext.create('Ext.container.Viewport', {
xtype:{
type:'vbox',
align: 'center',
pack: 'center'
}, items:[
{xtype:'combobox',
fieldLabel: 'Choose State',
store: states,
queryMode: 'local',
displayField: 'name',
valueField: 'abbr',
tpl:'<tpl for="."><div class="x-boundlist-item">{name}</div></tpl>'
}
]})
}})
Thanks

For making it work globally (for all comboboxes), use the following override:
Ext.override(Ext.form.field.ComboBox, {
initComponent: function() {
// the code above remains same (you can copy it from ext-all-debug.js), add the following at the end of initComponent
me.tpl = new Ext.XTemplate(
'<tpl for=".">',
'<div class="x-boundlist-item">',
'{' + me.displayField + ':htmlEncode}',
'</div>',
'</tpl>'
);
}
});

What you need to do is just modify the tpl config option of the ComboBox, and use your own custom config. You can then create a new ComboBox and use that as the editor for the column definition.
Here's a sample of a custom ComboBox template:
var resultTpl = new Ext.XTemplate(
'<tpl for=".">',
'<div class="x-combo-list-item">',
'<span class="number">{#}</span>',
'<h3 class="{itemColor"}>',
'{itemName}',
'</h3>',
'</div>',
'</tpl>'
);
You can then use that XTemlate when you instantiate your editor;
var combo = {
xtype: 'combo',
tpl: resultTpl
....
}

Related

ExtJS 6.0.1 dataview tpl rendered twice

I am trying to render a table in dataview. Everything is working fine but the tpl renderes twice:
First: the tpl content loaded along with the data
Second: the tpl alone is rendered without any data
I found out that this question was already asked for a different version here. But there was no relevant answer to solve this issue.ExtJS tpl renders twice
{
xtype: 'dataview',
scrollable: true,
itemSelector: 'tr',
data: [{
selCodeType: 'selCodeType',
codeTypeMnc: 'codeTypeMnc'
}, {
selCodeType: 'selCodeType',
codeTypeMnc: 'codeTypeMnc'
}],
tpl: ['<table><thead>',
'<th>Select Code Type</th>',
'<th>Code Type MNC</th>',
'</thead>',
'<tbody>',
'<tpl for=".">',
'<tr>',
'<td>selCodeType</td>',
'<td>codeTypeMnc</td>',
'</tr>',
'</tpl>',
'</tbody></table>']
}
Outcome of the above code
I have tried itemTpl as well. But no luck. It would be helpful if anyone point me what I am doing wrong here.
Thank you
You must use a store instead of data with dataviews:
{
xtype: 'dataview',
scrollable: true,
itemSelector: 'tr',
store: {
data:[{
selCodeType: 'selCodeType',
codeTypeMnc: 'codeTypeMnc'
}, {
selCodeType: 'selCodeType',
codeTypeMnc: 'codeTypeMnc'
}]},
tpl: ['<table><thead>', '<th>Select Code Type</th>', '<th>Code Type MNC</th>', '</thead>', '<tbody>', '<tpl for=".">', '<tr>', '<td>selCodeType</td>', '<td>codeTypeMnc</td>', '</tr>', '</tpl>', '</tbody></table>']
}
Working example: https://fiddle.sencha.com/#fiddle/18th

ExtJS ComboBox: allow user to select no value (null)

I have an Ext ComboBox where the user should be able to choose no value. ExtJS doen't support that out of the box.
What I've tried:
use a second trigger that clears the value
Works but is not very usable. I want a better solution.
add "fake" null item to store:
While this does kind of work I would have to modify the model for that to allow null value for id. And this looks more like a hack.
set custom tpl like
'<ul class="x-list-plain">',
'<li role="option" unselectable="on" class="x-boundlist">(no selection)</li>',
'<tpl for=".">',
'<li role="option" unselectable="on" class="x-boundlist-item">{name}</li>',
'</tpl>',
'</ul>'
But now it's getting really difficult, now idea how to get that working properly.
jsfiddle:
http://jsfiddle.net/q5e3J/1/
with custom tpl: http://jsfiddle.net/q5e3J/2/
Please refer this link How to add an empty item to ExtJS combobox?
Update: jsfiddle with that solution implemented: http://jsfiddle.net/q5e3J/3/
var combo = Ext.create('Ext.form.field.ComboBox', {
renderTo: Ext.getBody(),
displayField: 'name',
valueField: 'abbr',
value: 'AL',
store: Ext.create('Ext.data.Store', {
model: 'State',
data: states
}),
queryMode: 'local',
editable: false,
emptyText: 'No Selection',
listConfig: {
tpl: '<div class="my-boundlist-item-menu">No Selection</div>'
+ '<tpl for=".">'
+ '<div class="x-boundlist-item">{name}</div></tpl>',
listeners: {
el: {
delegate: '.my-boundlist-item-menu',
click: function() {
combo.clearValue();
}
}
}
}
});
You could use the "change" listener on the combo config and check for null values:
change: function() {
if (this.getValue() === null) {
// Set default Value here
}
};

Live Search Combo Box Isn't Working ExtJS 4.2.1

I'm not sure what's wrong with my code. However after I type 4 characters on combobox, all of value will be displayed, not filtered based on characters that I have typed. Because of that my live search is broken. Please see attached image for better illustration.
I'm creating combobox inside panel as one of item
{
xtype: 'combobox',
fieldLabel: 'Guest Name',
padding: '10px 10px 20px 10px',
allowBlank: false,
id: 'guest_id_payment',
name: 'guest_id',
// Template for the dropdown menu.
// Note the use of "x-boundlist-item" class,
// this is required to make the items selectable.
tpl: Ext.create('Ext.XTemplate',
'<tpl for=".">',
'<div class="x-boundlist-item">{identity_number} - {name}</div>',
'</tpl>'
),
// template for the content inside text field
displayTpl: Ext.create('Ext.XTemplate',
'<tpl for=".">',
'{identity_number} - {name}',
'</tpl>'
),
valueField: 'identity_number',
store: 'SGuest',
height: 20,
queryMode: 'remote'
}
This is the store:
Ext.define('ghb.store.SGuest', {
extend: 'Ext.data.Store',
model: 'ghb.model.MGuest',
autoLoad: true,
autoSync: true,
proxy: {
pageParam: false,
startParam: false,
limitParam: false,
type: 'ajax',
api: {
create: '/ghb_manager/add_guest',
read: '/ghb_manager/data_guest',
update: '/ghb_manager/edit_guest',
destroy: '/ghb_manager/delete_guest'
},
reader: {
type: 'json',
root: 'data'
},
writer: {
type: 'json',
encode: true,
writeAllFields: true,
root: 'data'
},
root: 'data'
}
});
I'm also add change event listener
'#guest_id_payment':{
change: this.changeGuestCombo
},
This is the function of change event listener, loading another store (not the store of ComboBox)
changeGuestCombo: function(self, newValue, oldValue, eOpts){
var store = Ext.getStore('SReservation');
store.load({
params: {
data: self.getValue(),
}
});
},
N.B. I'm using 4.2.1
The way you currently have it setup the filtering should be handled server side. If you change queryMode: 'remote' to queryMode: 'local' then the filter should work the way you want.
queryMode: 'remote' tells the combo box to call the proxy with the value you typed and the server would have to return only matching values. This is helpful if you have a huge dataset to search
I found the problem. When we use tpl & displayTpl on Combobox, the livesearch feature won't work
When you are using custom tpl and displayTpl in your Combobox, you can define a custom Filter function, for example on key up:
// Clear the filter collection without updating the UI
store.clearFilter(true);
store.filter([
{filterFn: function(item) { return item.get("identity_number") == "[....]" }}
]);
For more information check the ExtJS documentation.

ExtJS Costum store representation

I wander if there is any ExtJS way that I can load store with data and after it is loaded I can create in master panel other my components (custom panel) to show that data in my specific way?
I want display data from store in panel with my custom components
You have two options:
If you only need to display the data then DataView is tailored for this task.
If your really need a component (ie, something that encapsulates user interaction and not just display), then you need to create this component and as your store loads create a component per record and add it to your master panel.
To copy the docs example of dataview (option 1):
Ext.define('Image', {
extend: 'Ext.data.Model',
fields: [
{ name:'src', type:'string' },
{ name:'caption', type:'string' }
]
});
Ext.create('Ext.data.Store', {
id:'imagesStore',
model: 'Image',
data: [
{ src:'http://www.sencha.com/img/20110215-feat-drawing.png', caption:'Drawing & Charts' },
{ src:'http://www.sencha.com/img/20110215-feat-data.png', caption:'Advanced Data' },
{ src:'http://www.sencha.com/img/20110215-feat-html5.png', caption:'Overhauled Theme' },
{ src:'http://www.sencha.com/img/20110215-feat-perf.png', caption:'Performance Tuned' }
]
});
var imageTpl = new Ext.XTemplate(
'<tpl for=".">',
'<div style="margin-bottom: 10px;" class="thumb-wrap">',
'<img src="{src}" />',
'<br/><span>{caption}</span>',
'</div>',
'</tpl>'
);
Ext.create('Ext.view.View', {
store: Ext.data.StoreManager.lookup('imagesStore'),
tpl: imageTpl,
itemSelector: 'div.thumb-wrap',
emptyText: 'No images available',
renderTo: Ext.getBody()
});

Unable to select from combobox after adding empty item/row

I implemented as said at How to add an empty item to ExtJS combobox? I can see a blank row/item as desired but I am unable to select any of the item from combobox !
Any guess ?
My code is as follow
var rModel = Ext.regModel('State', {
fields: [
{type: 'string', name: 'fips_state_code'},
{type: 'string', name: 'state_name'}
]
});
// The data store holding the states
var store = Ext.create('Ext.data.Store', {
model: 'State',
data: [{fips_state_code: '0', state_name: ' '}]
});
store.add(obj.results);
{
xtype:'combo',
id:'filterstate',
width: 250,
fieldLabel: 'Filter By State',
store: store,
queryMode: 'local',
displayField: 'state_name',
valueField: 'fips_state_code',
editable: false,
forceSelection : true,
triggerAction : 'all',
typeAhead: true,
selectOnFocus:true,
allowBlank:true,
tpl : '<tpl for=\".\"><div class=\"x-combo-list-item\">{state_name} <\/div><\/tpl>'
}
The problem is the tpl attribute, in order to select an attribute you need to add the x-boundlist-item class to your tpl. Just like this
tpl : '<tpl for=".">'+
'<div class="x-boundlist-item">'+
'<div class="list-item">{state_name} </div>'+
'</div>'+
'</tpl>'
http://jsfiddle.net/alexrom7/CnwpD/
But if you only want to apply a custom css class to every item in the combobox list. I would recommend you to do it this way
listConfig: {
// Custom rendering template for each item
getInnerTpl: function() {
return '<div class="list-item">{state_name} <\/div>';
}
}
http://jsfiddle.net/alexrom7/6Jt5T/
Working directly with the tpl could give you some trouble.

Resources