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

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
}
};

Related

How to work with combo having images inside in extjs 4.1

I try to create a combo with an image (or something else) and when I choose an option, value in combo has some options.
I create a combo box look like:
But when I choose an option that looks like:
Here is my code http://jsfiddle.net/QZqeK/
// The data store containing the list of states
var states = Ext.create('Ext.data.Store', {
fields: ['abbr', 'name'],
data : [{
"abbr":"AL",
"name":"<img src='http://icons.iconarchive.com/icons/famfamfam/silk/16/folder-picture-icon.png'>"
},
{
"abbr":"AK",
"name":"<img src='http://icons.iconarchive.com/icons/famfamfam/silk/16/folder-picture-icon.png'>"
},
{
"abbr":"AZ",
"name":"<img src='http://icons.iconarchive.com/icons/famfamfam/silk/16/folder-picture-icon.png'>"
}]
});
// Create the combo box, attached to the states data store
Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Choose',
store: states,
tpl: '<tpl for="."><div class="x-boundlist-item" >{name} {abbr}</div></tpl>',
displayTpl: Ext.create('Ext.XTemplate',
'<tpl for=".">',
'{name} {abbr}',
'</tpl>'
),
queryMode: 'local',
displayField: 'abbr',
valueField: 'abbr',
renderTo: Ext.getBody()
});
How to fix that? Thanks!
You won't be able to solve this with templates. The display value of a ComboBox is used as the value of the text input field, which is why your HTML is displayed literally.
It might be kind of hackish, but you can listen for the select event and update some styles directly on the inputEl.
Note that this sample is an approximation. You may have to experiment to get the desired effect.
var urlBase = 'http://icons.iconarchive.com/icons/famfamfam/silk/16/';
// Don't use image tag, just URL of icon
var states = Ext.create('Ext.data.Store', {
fields: ['abbr', 'name'],
data: [
{abbr: 'AL', name: urlBase + 'folder-picture-icon.png'},
{abbr: 'AK', name: urlBase + 'folder-picture-icon.png'},
{abbr: 'AZ', name: urlBase + 'folder-picture-icon.png'}
]
});
Ext.create('Ext.form.field.ComboBox', {
fieldLabel: 'Choose',
store: states,
queryMode: 'local',
displayField: 'abbr',
valueField: 'abbr',
renderTo: Ext.getBody(),
tpl: [
'<tpl for=".">',
'<div class="x-boundlist-item">',
'<img src="{name}"/>{abbr}',
'</div>',
'</tpl>'
],
listeners: {
select: function (comboBox, records) {
var record = records[0];
comboBox.inputEl.setStyle({
'background-image': 'url(' + record.get('name') + ')',
'background-repeat': 'no-repeat',
'background-position': '3px center',
'padding-left': '25px'
});
}
}
});
If you are going to use this approach and combobox will be marked as invalid the red ribbon will be hiden because it is set as background image like your custom icon (combo will be only in a red frame).
To fix this you can listen to select and validitychange events and set proper style there.
Example how to get style for valid/invalid combo:
getComboBoxInputStype: function(imgPath, valid) {
return {
'background-image': valid ? 'url(' + imgPath + ')' : 'url(' + imgPath + '), url(../../Scripts/ext/images/grid/invalid_line.gif)',
'background-repeat': valid ? 'no-repeat' : 'no-repeat, repeat-x',
'background-size': valid ? '18px 18px' : '18px 18px, 4px 3px',
'background-position': valid ? '3px center' : '3px center, bottom',
'padding-left': '25px'
};
}
Remove {name} from displayTpl like below:
displayTpl:
Ext.create('Ext.XTemplate',
'<tpl for=".">',
'{abbr}',
'</tpl>'
),

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.

Using Xtemplate on Combobox don't let me select items (items don't have internalId on html)

I can't understand why using Xtemplate the items in the Combobox are no more selectable. I can see in the html code that the items have no more internalId. This is my code:
Ext.define('app.widget.search.PredictiveInput', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.predictiveinput',
store: 'SearchSyntax',
storeCriteriaSyntax: 'SearchPredictiveInput',
nodeField: 'is_node',
leafField: 'is_leaf',
lastLeafField: 'is_last_leaf',
levelField: 'level',
triggerAction: 'all',
flex: 1,
queryMode: 'local',
displayField: 'subject_display',
valueField: 'id',
pageSize: 10,
setCustomTpl: function() {
var me = this;
me.tpl = Ext.create('Ext.XTemplate',
'<tpl for=".">',
' <div class="x-combo-list-item-isNode-{nodeField}' +
' x-combo-list-item-isLeaf-{leafField}' +
' x-combo-list-item-isLastLeaf-{lastLeafField}' +
' x-combo-list-item-level-{levelField}" role="option">{displayField</div>',
'</tpl>'
);
},
initComponent: function() {
this.callParent();
this.setCustomTpl();
}
});
I think you have to add the class x-boundlist-item.
See comments here.
// 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">{abbr} - {name}</div>',
'</tpl>'
),

Use custom HTML in grid combobox

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
....
}

Extjs with Radiogroup

can we bind static json store with radiogroup in ext?
Radiogroups and Stores are not directly related in ExtJS. It's easy to populate form values from a store, but using a store to actually create the fields requires a slight work around. Specifically, you would have to do something like this (assuming Ext 3.3.1), and that your JsonStore is already set up...
var store = <your predefined store, with records>;
var itemsInGroup = [];
store.each( function(record) {
itemsInGroup.push( {
boxLabel: record.someLabel,
name: record.someName,
inputValue: record.someValue
});
});
var myGroup = {
xtype: 'radiogroup',
fieldLabel: 'My Dynamic Radiogroup',
items: itemsInGroup
};
You can use dataView for this operation. Depending on store value you can add radio buttons.
Suppose your store has 5 items than 5 radio buttons will be displayed.
var tpl = new Ext.XTemplate('<tpl for=".">', '<div class="thumb-wrap" style="width:210px; float: left;">', '<label >', '<tpl>', '<input type=radioField value={fieldId} >', '</tpl>', '{dataViewFieldName}', '</label>', '</div>', '</tpl>', {
});
var me = this;
this.items = new Ext.DataView({
store: this.store,
tpl: tpl,
overClass: 'x-view-over',
itemSelector: 'div.thumb-wrap',
autoScroll: true
});
this.callParent();
},

Resources