ExtJs 4 combobox with checkboxes - combobox

I'm looking for EXTJS4 combobox control which allows selecting multiple items via checkboxes inside.
Actually I need this control http://lovcombo.extjs.eu/ but it is implemented for ExtJs3. I tried to convert it to ExtJs4 but the task is not trivial actually.
Could you suggest similar component for ExtJs4. Or maybe you could point me to some tutorial or example - how to do such things?

Multiselect combo with checkbox in ExtJS4.0 can be achieved with addition few lines of code.
Basically you need to make use of the existing css class which get applied during selection and deselection of an item and pushing an image (checkbox image) at that time accordingly.
"x-boundlist-item" and "x-boundlist-selected" are the classes taken from ext-all.css.
<style>
.x-boundlist-item img.chkCombo {
background: transparent url(/lib/extjs-4.1.0/resources/themes/images/default/menu/unchecked.gif);
}
.x-boundlist-selected img.chkCombo{
background: transparent url(/lib/extjs-4.1.0/resources/themes/images/default/menu/checked.gif);
}
</style>
<head>
Ext.create('Ext.form.ComboBox', {
id: 'BCCAddress',
name: 'BCCAddress',
maxHeight: 150,
width: 210,
multiSelect: true,
emptyText : "Select Bcc email addresses",
renderTo: 'extBCCAddress',
store: myArrayStore,
displayField: 'fieldName',
valueField: 'fieldName',
forceSelection: true,
editable: false,
mode: 'local',
triggerAction: 'all',
listConfig : {
getInnerTpl : function() {
return '<div class="x-combo-list-item"><img src="' + Ext.BLANK_IMAGE_URL + '" class="chkCombo-default-icon chkCombo" /> {fieldName} </div>';
}
}
});
[below is an image of this custom component]

use this: http://www.sencha.com/forum/showthread.php?134751-Ext.ux.form.field.BoxSelect-Intuitive-Multi-Select-ComboBox
or this: http://www.sencha.com/forum/showthread.php?132328-CLOSED-ComboBox-using-Grid-instead-of-BoundList
-- use grid with checkboxselectmodel in combox

Related

Display vertical lines with arows in Ext Tree panel

How to implement vertical line and arrows altogether in Ext Tree?
I have created a fiddle by using both properties of useArrows and lines, but not getting applied at the same time.
Ext.create('Ext.tree.Panel', {
title: 'Simple Tree',
width: 200,
height: 200,
store: store,
rootVisible: true,
lines:true,
useArrows: true,
renderTo: Ext.getBody()
});
Fiddle
useArows and lines in tree is mutually exclusive properties
But you can use next hack - set useArrow and manually set linesCls, and override some css classes.
Look at my fiddle
As you can see in the source code for the Ext.tree.Panel ExtJs will not give the tree panel the lines CSS if the #cfg useArrows is true.
initComponent: function() {
var me = this,
cls = [me.treeCls],
store, autoTree, view;
if (me.useArrows) {
cls.push(me.arrowCls);
me.lines = false;
}
if (me.lines) {
cls.push(me.linesCls);
} else if (!me.useArrows) {
cls.push(me.noLinesCls);
}
....}
You have two options here in my opinion:
You override the initComponent method for this Ext.tree.Panel
You can override the css classes to implement the arrow-images
I made a Fiddle for the second case. This is what you wanted?

Combo fires select event after focusleave event

Could you please tell somebody how prevent fires select event on combobox when focus leave ?
I had the same issue in extjs 6.5.2 modern. I was using a combobox with queryMode: 'remote', forceSelection: true, a custom itemTpl and i was choosing an item using the select event. #Jzf's solution didn't worked for me (i used the change event too) so i had to suspend the select event on focusleave and resume it on focusenter.
That's not a very clean workaround but it does the job for my case.
Here is the full code for my combobox:
{
xtype: 'combobox',
store: Ext.create('demo.store.search.SearchComboStore'),
valueField: 'id',
displayField: 'name',
queryMode: 'remote',
queryParam: 'name',
triggerAction: 'all',
allQuery: '',
minChars: 1,
forceSelection: true,
matchFieldWidth: false,
//[modern] added floated picker config here in order to set the minWidth property for the floated picker
floatedPicker: {
minWidth: (Ext.getBody().getWidth() / 2)
},
itemTpl:
'<div class="ucResultsTable" style="width:' + (Ext.getBody().getWidth() / 2) + 'px">' +
'<div class="ucResultsTableCell" style="width:15%"><b>{value1}</b></div>' +
'<div class="ucResultsTableCell" style="width:15%">{value2}</div>' +
'<div class="ucResultsTableCell" style="width:15%">{value3}</div>' +
'<div class="ucResultsTableCell" style="width:15%">{value4}</div>' +
'<div class="ucResultsTableCell" style="width:15%">{value5}</div>' +
'</div>',
listeners: {
select: function (comboBox, records, eOpts) {
var container = comboBox.up('app-container-panel');
container.fireEvent('selectComboItem', container, records.data);
},
//<Workaround>
//blur/focusleave is firing select event
//and changes the record selection
focusleave: function (comboBox) {
comboBox.suspendEvent('select');
},
focusenter: function (comboBox) {
comboBox.resumeEvent('select');
}
//</Workaround>
}
}
The problem occurs because the combo forces the selection, even when the user hasn't actually selected another value.
There are a couple of ways to workaround this issue.
Use the select listener without forceSelection
Use the change listener with forceSelection
Both ways, the user will have to choose an item from the combo list (which is, probably, why you used the forceSelection config in the first place).
Test the workaround in fiddle
THis is a bug
Correspond theme on Sencha Forum

Dynamically changing the DataStore of a ComboBox

I have a combo box which populates its values based on the selection of another combobox.
I have seen examples where the params in the underlying store are changed based on the selection, but what I want to achieve is to change the store itself of the second combo based on the selection on the first combo. This is my code, but it doesn't work. Can someone please help?
{
xtype: 'combo',
id: 'leads_filter_by',
width: 100,
mode: 'local',
store: ['Status','Source'],
//typeAhead: true,
triggerAction: 'all',
selectOnFocus:true,
typeAhead: false,
editable: false,
value:'Status',
listeners:{
'select': function(combo,value,index){
var filter_to_select = Ext.getCmp('cmbLeadsFilter');
var container = filter_to_select.container;
if (index == 0){
filter_to_select.store=leadStatusStore;
filter_to_select.displayField='leadStatusName';
filter_to_select.valueField='leadStatusId';
} else if(index==1) {
filter_to_select.store=leadSourceStore;
filter_to_select.displayField='leadSourceName';
filter_to_select.valueField='leadSourceId';
}
}
}
},
{
xtype: 'combo',
id: 'cmbLeadsFilter',
width:100,
store: leadStatusStore,
displayField: 'leadStatusName',
valueField: 'leadStatusId',
mode: 'local',
triggerAction: 'all',
selectOnFocus:true,
typeAhead: false,
editable: false
},
That is not how its designed to work!! When you set a store in the config, you are binding a store to the combo. You don't change the store, instead you are supposed to change the data when required.
The right way of doing it would be to load the store with correct data from the server. To fetch data, you can pass params that will help the server side code get the set of options you need to load.
You will not want to change the store being used... Simply put, the store is bound to the control as it is instantiated. You can, however, change the URL, and params/baseParams used in any additional POST requests.
Using these params, you can code your service to return different sets of data in your combo box's store.
For the proposed problem you can try below solution :
Use below "listener" snippet for the first "leads_filter_by" combo. It will handle the dynamic store binding / changing for the second combobox.
listeners:{
'select': function(combo,value,index){
var filter_to_select = Ext.getCmp('cmbLeadsFilter');
var container = filter_to_select.container;
if (index == 0){
//filter_to_select.store=leadStatusStore;
filter_to_select.bindStore(leadStatusStore);
filter_to_select.displayField='leadStatusName';
filter_to_select.valueField='leadStatusId';
} else if(index==1) {
//filter_to_select.store=leadSourceStore;
filter_to_select.bindStore(leadSourceStore);
filter_to_select.displayField='leadSourceName';
filter_to_select.valueField='leadSourceId';
}
}
}
Hope this solution will help you.
Thanks & Regards.
I had a similar problem. The second combobox would load the store and display the values, but when I would select a value, it would not actually select. I would click the list item and the combobox value would remain blank.
My research also suggested that it was not recommended to change the store and field mappings on a combobox after initialization so here was my solution:
Create a container in the view that would hold the combobox to give me a reference point to add it back later
Grab a copy of the initial config off of the combobox ( this lets me set my config declaritively in the view and not hard code it into my replace function ... in case I want to add other config properties later)
Apply new store, valueField and displayField to that config
Destroy old combobox
Create new combobox with modified config
Using my reference from step 1, add the new combobox
view:
items: [{
xtype: 'combobox',
name: 'type',
allowBlank: false,
listeners: [{change: 'onTypeCombo'}],
reference: 'typeCombo'
}, { // see controller onTypeCombo for reason this container is necessary.
xtype: 'container',
reference: 'valueComboContainer',
items: [{
xtype: 'combobox',
name: 'value',
allowBlank: false,
forceSelection: true,
reference: 'valueCombo'
}]
}, {
xtype: 'button',
text: 'X',
tooltip: 'Remove this filter',
handler: 'onDeleteButton'
}]
controller:
replaceValueComboBox: function() {
var me = this;
var typeComboSelection = me.lookupReference('typeCombo').selection;
var valueStore = Ext.getStore(typeComboSelection.get('valueStore'));
var config = me.lookupReference('valueCombo').getInitialConfig();
/* These are things that get added along the way that we may also want to purge, but no problems now:
delete config.$initParent;
delete config.childEls;
delete config.publishes;
delete config.triggers;
delete config.twoWayBindable;
*/
config.store = valueStore;
config.valueField = typeComboSelection.get('valueField');
config.displayField = typeComboSelection.get('displayField');
me.lookupReference('valueCombo').destroy();
var vc = Ext.create('Ext.form.field.ComboBox', config);
me.lookupReference('valueComboContainer').add(vc);
},

Ext js combobox does not display all items in menu

Can someone tell me how to get rid of the feature that filters combo box items.
when i click on the trigger of the combo, i want to display ALL menu items regardless of what text is already in the box, NOT filtered. I've tried several different config options with no luck.
make sense ?
for example, if i have 'View' as my text in the combo, and i click on the trigger, it will only show 'View1' and 'View2' items, i want it to include all the others...
Thanks!
heres my current config
{
...
items: [{
xtype: 'combo',
id: 'myViewsCombo',
emptyText: 'Select View',
selectOnFocus: true,
listeners: {
select: function(combo, record, index) {
L3.handlers.loadView(combo.value);
}},
store: ['View1', 'View2','blahblah']
}]
}
Setting triggerAction: "all" solved the same problem for me.
Try the setting the 'disableKeyFilter' config option to true.
See the ext combobox api.

EXTJS combobox default value after form layout

My combobox's data is loaded after the form layout.
var villeStore = new Ext.data.ArrayStore({
fields: [{name:'idVille'}
,{name: 'ville'}]
});
var villeInput = new Ext.form.ComboBox({
fieldLabel: 'Ville',
store: villeStore,
valueField:'idVille',
displayField:'ville',
typeAhead: true,
mode: 'local',
triggerAction: 'all',
emptyText:'Ville',
width:100,
id:'villeInput'
});
The problem is that I need to display the last of the store, but even have the valueField, because when I click on a button, this is what I send to server
I did this, but it don't work, it show the last store value, but don't have the valueField
villeInput.store.on('load',function(store) {
villeInput.setValue(store.getAt(villeInput.store.getCount()-1).get('ville'));
});
The problem is that you need to set the value of the combo using the valueField (which is idVille) instead of the displayField:
villeInput.store.on('load',function(store) {
villeInput.setValue(store.getAt(villeInput.store.getCount()-1).get('idVille'));
});
Try this:
villeInput.store.on("load", function(store) {
villeInput.setValue(ActualidVille, false);
}, this);

Resources