How to show whitespaces in combo list? - extjs

I have combo with lots of whitespaces in values, when I select item - whitespaces are displaying. However they are missing in list. See demo:
https://fiddle.sencha.com/#view/editor&fiddle/3i1v
Is it possible to show ALL whitespaces in combo list?

You can override template with custom function which will replace spaces with none breaking space - &nbsp. Something like:
var states = Ext.create('Ext.data.Store', {
fields: ['name'],
data: [
{
"name": "Alabama 3"
}, {
"name": "Alaska 11"
}
]
});
Ext.application({
name: 'MyApp',
launch: function () {
Ext.create('Ext.form.Panel', {
items: [{
xtype: 'combo',
fieldLabel: 'Choose State',
store: states,
displayField: 'name',
tpl: Ext.create('Ext.XTemplate',
'<ul class="x-list-plain"><tpl for=".">',
'<li role="option" class="x-boundlist-item">{[this.replaceSpacesWithNbsp(values.name)]}</li>',
'</tpl></ul>',
{
replaceSpacesWithNbsp: function(name){
return name.replaceAll(' ', '&nbsp');
},
}
),
renderTo: Ext.getBody()
}]
});
}
});

Related

Create one or more textfield dynamically based on combobox selection

I am working on a front UI, a dropdown will be provided which will have the list of commands and one or two variables depending of command, what I am trying to do is when I select the command from dropdown, it should populate textfield where the user will provide the values.
e,g Command : "show route table <vrf_name> <ip_addr>"
then two new textfields should be created for user to fill in these values. I am stumped on how to create textfields with variable names. ?
var commands = Ext.create('Ext.data.Store', {
fields: ['command', 'reqvalues'],
data : [
{"command":"op find-security-zone ip <ip_addr>", "reqvalues":"ip_addr"},
{"command":"show configuration | display set | match <match_text>", "reqvalues":"match_text"},
{"command":"show route table <vrf_name> <ip_addr>", "reqvalues":"vrf_name, ip_addr"}
]
});
// Create the combo box, attached to the data store
Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Select Command',
store: commands,
queryMode: 'local',
displayField: 'command',
valueField: 'command',
renderTo: Ext.getBody(),
});
Fiddle : https://fiddle.sencha.com/fiddle/3f2t
For dynamically adding fields, try the following code. It adds an initially empty fieldset, and when user selects something from the combobox, it adds textfields to the fieldset, after deleting all previously added textfields. (Instead of fieldset you can use container etc.)
This is a working fiddle.
var commands = Ext.create('Ext.data.Store', {
fields: ['command', 'reqvalues'],
data : [
{"command":"op find-security-zone ip <ip_addr>", "reqvalues":"ip_addr"},
{"command":"show configuration | display set | match <match_text>", "reqvalues":"match_text"},
{"command":"show route table <vrf_name> <ip_addr>", "reqvalues":"vrf_name, ip_addr"}
]
});
Ext.create('Ext.panel.Panel', {
renderTo: Ext.getBody(),
items: [{
xtype: 'combobox',
fieldLabel: 'Select Command',
store: commands,
queryMode: 'local',
displayField: 'command',
valueField: 'command',
listeners: {
// this is needed to remove all textfields when nothing is selected
change: function(combo, newValue, oldValue, eOpts) {
if (!newValue) {
// remove all existing textfields from fieldset
combo.up('panel').getComponent('parameters').removeAll();
}
},
select: function(combo, records, eOpts ) {
// get fieldSet
var fieldSet = combo.up('panel').getComponent('parameters');
// remove previous textfields
fieldSet.removeAll();
// get parameters from selection, assuming only 1 can
// be selected and delimiter in reqvalues is always ', '
var parameters = records[0].get('reqvalues').split(', ');
// loop through parameters and add textfield for each
Ext.Array.each(parameters, function(parameter) {
fieldSet.add({
xtype: 'textfield',
fieldLabel: parameter,
// by setting itemId, you can easily get textfield values,
// for example:
// fieldSet.getComponent('parameter_name')
itemId: parameter
})
});
}
}
}, {
// fieldSet for parameters, initially empty, can be container etc.
xtype: 'fieldset',
title: 'Parameters',
itemId: 'parameters'
}]
});
Better to use card layout with pre-defined forms and switch them using combobox. Something like this:
Ext.define('CommandsStore', {
extend: 'Ext.data.Store',
fields: ['command', 'cardIndex'],
data: [{
command: "op find-security-zone ip <ip_addr>",
cardIndex: 0
}, {
command: "show configuration | display set | match <match_text>",
cardIndex: 1
}, {
command: "show route table <vrf_name> <ip_addr>",
cardIndex: 2
}]
});
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.create('Ext.panel.Panel', {
layout: 'card',
title: "Commands",
dockedItems: [{
xtype: 'toolbar',
items: [{
xtype: 'combobox',
fieldLabel: 'Select Command',
store: Ext.create('CommandsStore'),
queryMode: 'local',
displayField: 'command',
valueField: 'cardIndex',
width: 400,
value: 0,
listeners: {
select: function (combo, records) {
var cardIndex = records[0].get('cardIndex');
this.up('panel').getLayout().setActiveItem(cardIndex);
}
}
}]
}],
defaults: {
xtype: 'form',
layout: 'form',
bodyPadding: 5,
border: false,
},
items: [{
items: [{
xtype: 'textfield',
fieldLabel: "IP Address",
name: 'ip_addr'
}]
}, {
items: [{
xtype: 'textfield',
fieldLabel: "Match Text",
name: 'match_text'
}]
}, {
items: [{
xtype: 'textfield',
fieldLabel: "IP Address",
name: 'ip_addr'
}, {
xtype: 'textfield',
fieldLabel: "VRF Name",
name: 'vrf_name'
}]
}],
height: 400,
renderTo: Ext.getBody()
})
}
});

ExtJS 4: Dynamic store filtering

I have a filter specified in filters config of the store:
Ext.define('Record', {
extend: 'Ext.data.Model',
fields: [{
name: 'value',
type: 'number'
}]
});
Ext.create('Ext.data.Store', {
id: 'store',
model: 'Record',
filters: [
function(item) {
return item.get('value') > 2;
}
],
sorters: [{
property: 'value',
direction: 'DESC'
}],
data: [{
value: 2,
}, {
value: 1
}, {
value: 3
}]
});
Ext.create('Ext.view.View', {
store: Ext.data.StoreManager.lookup('store'),
tpl: new Ext.XTemplate(
'<tpl foreach=".">',
'<div class="record">{value}</div>',
'</tpl>'
),
itemSelector: '.record',
emptyText: 'No records',
renderTo: Ext.getBody()
});
It is only applied if I explicitly call filter() on the store. The filterOnLoad is not set and defaults to true, so the store must be filtered. How can I keep the store always filtered (whenever any CRU action is performed and after load)?
To accomplish this it's needed to add listeners to the store on adding and updating events:
listeners: {
add: function(store) {
store.filter();
},
update: function(store) {
store.filter();
}
},

How to access the view from within dataview's tpl in ExtJS6?

I am trying to test against a combobox value from inside dataview's tpl:
Ext.define('MyForm', {
extend: 'Ext.form.Panel',
items: [
{
xtype: 'combo',
name: 'my_combo',
},
{
xtype: 'dataview',
tpl: new Ext.XTemplate(
'<tpl for=".">',
'<tpl if="this.test()">pass</tpl>',
'</tpl>'
,
{
test: function(){
//doesn't work
return this.getView().down('[name=my_combo]').getValue() == 'ok';
}
}),
}
]
});
This doesn't work because this is referencing to the template itself and I can't figure out how to access the view from the inside.
It is not possible to access a view in XTemplate. To achieve this you can use ViewModel, here is the code for it.
And working sencha fiddle https://fiddle.sencha.com/#fiddle/175s
Update: I updated the code to use the DataView, DataView is little tricky, i overwritten the prepareData method to pass in extra information to the template and also updating the DataView whenever the combo value is changed. Here is the fiddle with updated changes https://fiddle.sencha.com/#fiddle/175s
Ext.define('MyApp.MyPanel', {
extend: 'Ext.Panel',
xtype: 'myForm',
defaults: {
padding: 10
},
viewModel: {
stores: {
employeeStore: {
fields: ['name'],
data: [{
name: 'John'
}, {
name: 'Tempel'
}, {
name: 'George'
}, {
name: 'Milinda'
}]
},
}
},
items: [
{
xtype: 'combobox',
fieldLabel: 'Name',
name: 'nameField',
queryMode: 'local',
displayField: 'name',
valueField: 'name',
reference: 'emp',
bind: {
store: '{employeeStore}',
value: '{name}'
}
},{
xtype: 'dataview',
itemId: 'empList',
tpl: new Ext.XTemplate(
'<tpl for=".">',
'<div class="dataview-multisort-item">',
'<h3>{name}</h3>',
'<tpl if="passed">Selected</tpl>',
'</div>',
'</tpl>'
),
itemSelector: 'div.dataview-multisort-item',
bind: {
store: '{employeeStore}'
},
prepareData: function(data, index, record) {
var name = this.up().getViewModel().get('name');
var passed = record.get('name') == name;
return Ext.apply({passed: passed}, data);
}
}
],
initComponent: function() {
this.callParent(arguments);
var me = this;
// refresh the dataview when name is changed.
this.getViewModel().bind('{name}', function() {
var dataview = me.down('#empList');
dataview.refresh();
});
}
});

How to put a component in Triggerfield popup in ExtJS?

Is there any way to implement a component popup on Trigger Field click? For example, I have a Trigger Field, and I would like to display a Tree Grid when I click the Triggerfield. When I select a value from the Tree Grid, the Trigger Field also set the same value.
There's an example from Ext.Net that is similar to this: http://examples.ext.net/#/Form/DropDownField/Overview/
I use Sencha Arhitect 3 and ExtJS 4.2. Any help is appreciated!
Try this.
Ext.create('Ext.form.ComboBox', {
store: Ext.create('Ext.data.Store', {
fields: ['group_name', 'property'],
data: [{
"group_name": "Armed Clash",
"property": "Border Clash"
}, {
"group_name": "Armed Clash",
"property": "Militia Clash"
}, {
"group_name": "Smuggling",
"property": "Fuel"
}, {
"group_name": "Smuggling",
"property": "Humans"
}]
}),
listConfig: {
tpl: Ext.create('Ext.XTemplate',
'<ul><tpl for=".">',
'<tpl if={group_name}>',
'<tpl if="xindex == 1 || this.getGroupStr(parent[xindex - 2]) != this.getGroupStr(values)">',
'<li class="x-combo-list-group"><b>{[this.getGroupStr(values)]}</b></li>',
'</tpl>',
'</tpl>',
'<li role="option" class="x-boundlist-item" style="padding-left: 12px">{property}</li>',
'</tpl>' +
'</ul>', {
getGroupStr: function (values) {
return values.group_name
}
}
)
},
queryMode: 'local',
valueField: 'property',
displayField: 'property',
renderTo: Ext.getBody()
});
Make list collapsible using js and add icons using styles.
Can refer this fiddle http://jsfiddle.net/gilsha/82TzM/1/
Or else use Ext.ux.TreeCombo, Fiddle: http://jsfiddle.net/gilsha/ZvnaM/83/
If I were you I firstly consider using some already existing component.
Base treepicker exists as bundled extension in ExtJS framework - Ext.ux.TreePicker
Another useful implementation of treepicker is user extension Ext.ux.TreeCombo
If you want to create your own picker component it should extends from Ext.form.field.Picker
For inspiration how to create your own picker you can look into source code of Ext.ux.TreePicker or Ext.picker.Date components.
Thanks to everyone's answer, I found another solution: use the createPicker function of the TriggerField. For example, here's how I extend the TriggerField` for a Grid Picker:
Ext.define('Custom.view.GridPicker', {
extend: 'Ext.form.field.Picker',
alias: 'widget.gridpicker',
requires: [
'Ext.grid.View',
'Ext.grid.column.Column'
],
store: 'none',
idDataIndex: 'id',
nameDataIndex: 'name',
fieldLabel: 'Grid Picker',
initComponent: function() {
var me = this;
me.callParent(arguments);
},
createPicker: function() {
picker = new Ext.create('Ext.grid.Panel', {
floating: true,
hidden: true,
height: 150,
width: 400,
header: false,
store: this.store,
columns: [
{
xtype: 'gridcolumn',
width: 95,
text: 'ID',
dataIndex: this.idDataIndex
},
{
xtype: 'gridcolumn',
width: 300,
text: 'Name',
dataIndex: this.nameDataIndex
}
]
});
return picker;
}
});
Fiddle: https://fiddle.sencha.com/#fiddle/2fb
This custom component accepts 3 config : store, idDataIndex, nameDataIndex; all of them needed to display data to the grid. I think you can base on this to extend your own picker, such as Tree Grid Picker :)

Extjs4.1 - Define dataview fail

I try to define a dataview from http://docs.sencha.com/extjs/4.1.3/#!/api/Ext.view.View to http://jsfiddle.net/JtTDH/
Here is my code
Ext.define('Example', {
extend: 'Ext.view.View',
tpl: new Ext.XTemplate(
'<tpl for=".">',
'<div style="margin-bottom: 10px;" class="thumb-wrap">',
'<img src="{src}" />',
'<br/><span>{caption}</span>',
'</div>',
'</tpl>'
),
itemSelector: 'div.thumb-wrap',
emptyText: 'No images available',
initComponent: function() {
var store = Ext.create('Ext.data.Store', {
id:'imagesStore',
fields: [
{ name:'src', type:'string' },
{ name:'caption', type:'string' }
],
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' }
]
});
this.store = store;
this.callParent(arguments);
}
});
I think that's correct but that's not working. How to fix that thank.
Your code is fine, but you need to define a rendering target for it. For example, you could add renderTo: Ext.getBody() to your definition, and it will work correctly. See a working example here: https://fiddle.sencha.com/#fiddle/md

Resources