Extjs4 Combobox with additional options - extjs

I wish to create a combobox that loads a store, but also want to add a few predefined data on it. Is it possible?

I think this is what you need:
Ext.define('App.widget.MyCombo', {
extend : 'Ext.form.field.ComboBox',
displayField: '...',
valueField : '...',
name : '...',
alias : 'widget.mycombo',
fieldLabel : 'My Custom combo',
initComponent: function() {
var me = this;
me.store = Ext.create('Ext.data.Store', {
model : '...',
proxy : {
type : '...',
reader: '...'
}
});
/*After data is loaded append some predefined records.*/
me.store.on('load', function() {
/*Indicates that data must be appended to already loaded data.*/
var append = true;
me.store.loadData([{id : -1, value : 'Default'},
{id: -2, value: 'Second Default'}], append);
});
me.callParent();
}
});

If your store is a list, then you can simply append your items to the list after it is generated at the index you specify.
You can also get the store from the combobox, and then use add() at the index your specify.

As Brian Said, you can "insert" it at the index you specify. When you use "add", it basically appends it to the end of the store.
Here is the signature of the insert function:
insert( Number index, Ext.data.Model[] records )

Related

Extjs Show Custom row in grid

I am using Ext JS 3.2. I have a grid. Now I want to customize my existing grid. I want to add hardcoded value as row0, But its not working
Below is my code
My store
var store = new Ext.data.Store({
id : 'user',
proxy : proxy,
reader : reader,
writer : writer, // <-- plug a DataWriter into the store
url: 'cat/view.action?catid='+catid_para+'&teaid='+teaid_para+'&flag='+0,
remoteSort: true,
remoteSort: true,
autoSave : false,
// <-- false would delay executing create, update, destroy
// requests until specifically told to do so with some [save]
// buton.
});
var record = new SiteUtility({
id:'0',
fname:'4',
lname:'3444',
attandance: 'G',
});
var parent_grid=Ext.getCmp('org_grid');
parent_grid.getStore().insert(0,record);
// store.save();
//parent_grid.getView().refresh();
store.load({params:{start:0, limit:10}});
Thanks
try this:
store.load({params:{start:0, limit:10}, callback: function(){
var record = new SiteUtility({
id:'0',
fname:'4',
lname:'3444',
attandance: 'G'
});
store.insert(0,record);
}});
Here you can see how to do that. You need to get the recordType first and create new Record:
var recordType = store.recordType;
var nullRecord = new recordType({
id: '1',
name: "4",
lname: "4",
age: "2",
remarks:"Remarks"
}, null);
store.insert(0, nullRecord);
You can take a look at the Ext Docs.

Preselect items in EXT JS 4.2 Grid

I am trying to preselect items in my EXT grid based on the value of one of the items in the data store.
In my data store I fetch 7 items, the last item I grab 'installed' is a BOOLEAN and I would like to use that to preselect items in my grid.
Here is the code I have so far that is not working...
Ext.require([
'Ext.grid.*',
'Ext.data.*',
'Ext.selection.CheckboxModel'
]);
Ext.onReady(function(){
Ext.QuickTips.init();
var sb = $('#sb_id').val();
// Data store
var data = Ext.create('Ext.data.JsonStore', {
autoLoad: true,
fields: [ 'name', 'market', 'expertise', 'id', 'isFull', 'isPrimary', 'installed'],
proxy: {
type: 'ajax',
url: '/opsLibrary/getLibraryJsonEdit',
extraParams: {
sb_id: sb
},
actionMethods: 'POST'
},
sorters: [{
property: 'market',
direction: 'ASC'
}, {
property: 'expertise',
direction: 'ASC'
}]
});
data.on('load',function(records){
Ext.each(records,function(record){
var recs = [];
Ext.each(record, function(item, index){
console.log(item.data);
if (item.data['installed'] == true) {
console.log('Hi!');
recs.push(index);
}
});
//data.getSelectionModel().selectRows(recs);
})
});
// Selection model
var selModel = Ext.create('Ext.selection.CheckboxModel', {
columns: [
{xtype : 'checkcolumn', text : 'Active', dataIndex : 'id'}
],
listeners: {
selectionchange: function(value, meta, record, row, rowIndex, colIndex){
var selectedRecords = grid4.getSelectionModel().getSelection();
var selectedParams = [];
// Clear input and reset vars
$('#selected-libraries').empty();
var record = null;
var isFull = null;
var isPrimary = null;
// Loop through selected records
for(var i = 0, len = selectedRecords.length; i < len; i++){
record = selectedRecords[i];
// Is full library checked?
isFull = record.get('isFull');
// Is this primary library?
isPrimary = record.get('isPrimary');
// Build data object
selectedParams.push({
id: record.getId(),
full: isFull,
primary: isPrimary
});
}
// JSON encode object and set hidden input
$('#selected-libraries').val(JSON.stringify(selectedParams));
}}
});
I was trying to use an on.load method once the store was populated to go back and preselect my items but am not having any luck.
Im a Python guy and don't get around JS too much so sorry for the noobness.
Any help would be appreciated.
Thanks again!
You should be able to do something like:
//create selModel instance above
data.on('load', function(st, recs) {
var installedRecords = Ext.Array.filter(recs, function(rec) {
return rec.get('installed');
});
//selModel instance
selModel.select(installedRecords);
});
Select can take an array of records.
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.selection.Model-method-select
//data.getSelectionModel().selectRows(recs);
Didn't work because store's don't have a reference to selection models it is the other way around. You can get a selection model from a grid by doing grid.getSelectionModel() or
you can just use the selModel instance you created
var selModel = Ext.create('Ext.selection.CheckboxModel', {

search field in a dataview in extjs

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

ExtJS 4 > Row Editor Grid > How to Change "Update" Button Text

Is there any way to change the text of "Update" button in ExtJS-4 Row Editor Grid ?
Good question, I had a look through the source code and whilst there is nothing inside the RowEditing plugin, in the class it extends 'RowEditor.js' there is the following:
Ext.define('Ext.grid.RowEditor', {
extend: 'Ext.form.Panel',
requires: [
'Ext.tip.ToolTip',
'Ext.util.HashMap',
'Ext.util.KeyNav'
],
saveBtnText : 'Update',
cancelBtnText: 'Cancel',
...
});
So I'd assume you'd just need to override the 'saveBtnText' in your instance of 'Ext.grid.plugin.RowEditing' as it calls the parent constructor with callParent(arguments) in the RowEditing class
Not that easy and not without hacking in undocumented areas. The problem is, that the Ext.grid.plugin.RowEditing directly instantiates the Ext.grid.RowEditor without allowing you to pass in configuration options. So in general you have to override the initEditor() method in the plugin and instantiate your own row editor:
// ...
plugins: [{
ptype: 'rowediting',
clicksToEdit: 2,
initEditor: function() {
var me = this,
grid = me.grid,
view = me.view,
headerCt = grid.headerCt;
return Ext.create('Ext.grid.RowEditor', {
autoCancel: me.autoCancel,
errorSummary: me.errorSummary,
fields: headerCt.getGridColumns(),
hidden: true,
// keep a reference..
editingPlugin: me,
renderTo: view.el,
saveBtnText: 'This is my save button text', // <<---
cancelBtnText: 'This is my cancel button text' // <<---
});
},
}],
// ...
For ExtJS 4
Ext.grid.RowEditor.prototype.cancelBtnText = "This is cancel";
Ext.grid.RowEditor.prototype.saveBtnText = "This is update";
This solution is to define the prototype of rowEditors. that means that this config is than general.
If you want to change it just for one editor, or if you want to get different configs , the prototype is definitely not the solution.
look at source code :
initEditorConfig: function(){
var me = this,
grid = me.grid,
view = me.view,
headerCt = grid.headerCt,
btns = ['saveBtnText', 'cancelBtnText', 'errorsText', 'dirtyText'],
b,
bLen = btns.length,
cfg = {
autoCancel: me.autoCancel,
errorSummary: me.errorSummary,
fields: headerCt.getGridColumns(),
hidden: true,
view: view,
// keep a reference..
editingPlugin: me
},
item;
for (b = 0; b < bLen; b++) {
item = btns[b];
if (Ext.isDefined(me[item])) {
cfg[item] = me[item];
}
}
return cfg;
}`
this method inits the rowEditor, and there's a loop on btns Array:
btns Array :
btns = ['saveBtnText', 'cancelBtnText', 'errorsText', 'dirtyText']
for (b = 0; b < bLen; b++) {
item = btns[b];
if (Ext.isDefined(me[item])) {
cfg[item] = me[item];
}
}
In this loop foreach string in btnArray it's searched if exists in cfg the same string property, if it's found it's added to config. You just have to manage that this loop finds what you want to modify:
Example: we want to change the text of save button:
the property saveBtnText which is the first item of btns Array must exists in cfg:
if (Ext.isDefined(me[item])) {
cfg[item] = me[item];
}
this search if property exists : if (Ext.isDefined(me[item]))
if saveBtnText already exists in rowEditor properties then:
cfg[item] = me[item];
and the additional config property will be set!!

Ext JS - Combo only displays first letter of items in a store (SimpleStore)?

HI,
I have a pretty simple Ext JS combobox that I'm just trying to bind to an array.
Here is the config for the combo:
BPM.configs.ViewsCombo = {
xtype: 'combo',
emptyText: 'Select View',
disableKeyFilter: true,
triggerAction: 'all',
displayField: 'name',
mode: 'remote',
render: function(combo) {
this.store.load();
}
},
store: new Ext.data.SimpleStore({
proxy: new Ext.data.HttpProxy({
url: '/Service.svc/GetUserViewNames',
method: 'POST'
}),
root: 'GetUserViewNamesResult',
fields: ['name']
})
};
Here is response/json from Ajax call:
{"GetUserViewNamesResult":["something","tree"]}
But when i go to view the combo items, all I see is the letter 's' and 't' in the list.
What gives ? is my returning array in the wrong format ?
Thanks so much.
well i figured out that the result needs to look like this :
{"GetUserViewNamesResult":[["something"],["tree"]]}.
which kinda sucks because now I have to change how my server side objects serialize :(
use this to change your array in to the required format
for ( var i = 0, c = cars.length; i < c; i++ ) {
cars[i] = [cars[i]];
}
referring to this how-to-bind-array-to-arrystore-in-order-to-populate-combo-in-extjs
Yes ExtJs still does not have a reader capable of dealing with lists of strings. On the server side (at least in Java, C#, etc.) this is often what you'll get when marshalling ENUM types.
I had to write my own class which is used in ExtJs 4.1 MVC style:
/**
* This extends basic reader and is used for converting lists of enums (e.g. ['a', 'b', 'c']) into lists of objects:
* [ {name: 'a'}, {name:'b'}, {name:'c'}]. All models using this type of reader must have a single field called name. Or you can
* pass a config option call 'fieldName' that will be used.
*
* This assumes that the server returns a standard response in the form:
* { result: {...., "someEnum" : ['a', 'b', 'c']},
* total: 10,
* success: true,
* msg: 'some message'
* }
*/
Ext.define('MY.store.EnumReader', {
extend: 'Ext.data.reader.Json',
alias: 'reader.enum',
//we find the Enum value which should be a list of strings and use the 'name' property
getData: function(data) {
var me = this;
//console.dir(data);
var prop = Ext.isEmpty(this.fieldName) ? 'name' : this.fieldName;
console.log('Using the model property: \''+ prop +'\' to set each enum item in the array');
try {
var enumArray = me.getRoot(data);
//console.dir(enumArray);
if (!Ext.isArray(enumArray)){
console.error("expecting array of string (i.e. enum)");
throw new Exception('not an array of strings - enum');
}
var enumToObjArray = Array.map(enumArray, function(item){
var obj = {};
obj[prop] = item;
return obj;
}
);
//console.dir(enumToObjArray);
var nodes = me.root.split('.');
var target = data;
var temp = "data";
Array.forEach(nodes, function(item, index, allItems){
temp += "['" + item + "']";
});
temp += " = enumToObjArray";
//console.log('****************' + temp + '*****************');
//evil 'eval' method. What other choice do we have?
eval(temp);
//console.dir(data);
return data;
}
catch(ex){
console.error('coudln\'t parse json response: ' + response.responseText);
return this.callParent(response);
}
}
}, function() {
console.log(this.getName() + ' defined');
});
Then, if you want to use this type of reader in your store you add:
requires: ['My.store.EnumReader'],
...
proxy: {
type: 'ajax',
url: ...
reader: {
type: 'enum',

Resources