search field in a dataview in extjs - 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

Related

Which ng-grid triggered the ngGridEventEndCellEdit?

I have two ng-grids living in the same $scope, they both have a column of editable cells, ie: enableCellEdit: true
I know I can handle the triggered event like this:
$scope.$on('ngGridEventEndCellEdit', function(event) {
var product = event.targetScope.row.entity;
console.log(product);
});
Question is.. how do I know which grid triggered the event? both grids consume different lists (data attribute of the grid), but these lists contains instances of the same type.
Is there any property inside event that contains the id of the grid?
I had the same trouble and worked around it.
I have three grids and on each cellEditableTemplate I register the ng-click on the cell, thus selecting the next source of the start and end event of the cell edit. The setMethod() that just sets the global variable $scope.thisGridUpdate
$scope.targetTypeDefs = [ {
field : 'id',
displayName : '#',
enableCellEdit : false,
width : 50
}, {
field : 'desc',
displayName : 'Type Description',
enableCellEdit : true,
cellEditableCondition : 'row.selected',
editableCellTemplate : '<input ng-class="\'colt\' + col.index" \
ng-input="COL_FIELD" \
ng-model="COL_FIELD" \
ng-model-options="{ updateOn : \'default blur\' }" \
ng-click="setMethod(\'saveTargetType\')"/>'
} ];
$scope.targetTypeGrid = {
data : 'targetTypeData',
showSelectionCheckbox : true,
selectWithCheckboxOnly : true,
multiSelect : false,
enableCellEditOnFocus : true,
columnDefs : 'targetTypeDefs'
};
Next you just catch and trap the end cell edit events in your normal ngGridEventEndCellEdit event consumer, like this:
$scope.setMethod = function(name) {
console.log("clicked on ", name);
$scope.thisGridUpdate = name;
};
$scope.$on('ngGridEventEndCellEdit', function(evt, other) {
console.log("ended edit on ", $scope.thisGridUpdate, "with " , evt.targetScope.row.entity);
console.log(evt.targetScope.row);
if ($scope.thisGridUpdate === 'saveServerType') {
EntityMgt.saveServerType(evt.targetScope.row.entity);
}
else if ($scope.thisGridUpdate === 'saveOsVersion') {
EntityMgt.saveOsVersion(evt.targetScope.row.entity);
}
else if ($scope.thisGridUpdate === 'saveTargetType') {
EntityMgt.saveTargetType(evt.targetScope.row.entity);
}
});

How to get display value of field from controller in ExtJS?

I have a component on my view:
{
xtype : 'socekiliscombo',
name : 'socekilisOid',
labelSeparator : '',
anchor : '25%',
allowBlank : false,
itemId : 'socekilis',
params : {},
listeners : {
specialkey : Ext.emptyFn
}
}
What I want to do is to get this component's display value from a controller. First I tried to get the component itself, but unable to do it. I tried this:
var socekilistarihi = this.getTalihliKayitPanel().getComponent('#socekilis');
I get a value of "undefined".
You can use standard controller refferences.
Ext.define('App.controller.Controller', {
extend: 'Ext.app.Controller',
refs: [{
ref: 'socekilis',
selector: '#socekilis'
}],
getComponentValue: function(){
var component = this.getSocekilis();
var value = null;
if(component){
value = component.getValue();
}
return value;
}
});
Hope it helps.
var socekilisCombo = this.getTalihliKayitPanel().down('socekiliscombo[name="socekilisOid"]'),
socekilisComboValue;
if (socekilisCombo)
{
socekilisComboValue = socekilisCombo.getValue();
}
And check this component really on talihliKayitPanel.

Itemclick and itemmove in EXTJS MVC

Am having a tree panel in my view, and its corresponding controllers. What is happening is that am having two controllers, one for the itemdblclick and another for itemmove. The itemdblclick is working ok, but when i add the controller for itemmove, itemmove is working, but on the other hand, itemdbclick is not working. And if i remove the itemmove controller, itemdblclick is working. Hope am not confusing:) In simple words, the two controllers are working separately but not together.
Could anyone please tell me what am i doing wrong here.
Also, in the function editRegion in the controller, am trying to reload the tree by using the getStore.load() method, but the tree is not loading even though am able to see the store being invoked in the firebug
EDIT:
Am opening a form on double-clicking the tree node, and on closing the form, i want the tree panel to be reloaded. This is what i want to happen in editregion function
View
{
xtype : 'treepanel',
title : '',
id : 'hierarchyTree',
border : false,
alias : 'widget.hierarchyTree',
height : 1000,
viewConfig : {
enableDD : true,
plugins : {
ptype : 'treeviewdragdrop'
}
},
collapsible : false,
useArrows : true,
rootVisible : false,
store : Ext.create('App.store.HierarchyTree'),
displayField : 'Title',
multiSelect : false,
singleExpand : false,
}
Controller
refs : [{
ref : 'myHierarchyTree',
selector : '#hierarchyTree'
}
init : function() {
this.getHierarchyTreeStore().load();
'#hierarchyTree' : {
itemdblclick : this.itemdblclick
},
'#hierarchyTree' : {
itemmove : this.itemmove
}
itemdblclick : function(view, record, level) {
if (record.get('LevelID') == 1) {
this.erWin = Ext.create('App.view.EditRegions');
var f = this.getEditregionform().getForm();
f.loadRecord(record);
this.erWin.showWin();
}
else if (record.get('LevelID') == 2) {
this.eaWin = Ext.create('App.view.EditAreas');
var f = this.getEditareaform().getForm();
f.loadRecord(record);
this.eaWin.showWin();
}
itemmove : function(v, oldParent, newParent, index, eOpts) {
var nodeID = v.data.id;
var oldParent = oldParent.data.id;
var newParent = newParent.data.id;
var index = index;
var level = v.data.LevelID;
Ext.Ajax.request({
url : 'data/Locations.aspx',
params : {
mode : 'MOVENODE',
currentNode : nodeID,
oldParentNode : oldParent,
newParentNode : newParent
},
success : function() {
alert(LANG.SUC);
Ext.getStore('HierarchyTree').load();
},
failure : function() {
}
});
editRegion : function(button, record) {
var fp = button.up('form');
if (fp.getForm().isValid()) {
fp.getForm().submit({
url : 'data/Locations.aspx',
params : {
mode : 'EDITREGION',
userID : ME.UserID,
RegionID : ME.RegionID
},
success : function(response) {
alert(LANG.SUC);
this.getHierarchyTreeStore().load();
},
failure : function(response) {
alert('Try again');
}
});
}
}
adding them separately will cause the first listener object to be overridden.
Fix:
'#hierarchyTree' : {
itemdblclick : this.itemdblclick,
itemmove : this.itemmove
},
You should check if the store is the same. Meaning check the id because i think the contoller initializes one store and the panel another. so check if this.getHierarchyTreeStore().id is equal with the one from treepanel. you can navigate to it from the button something like button.up().down('treepanel').getStore().id. If they are different then you should use the second method to get the store.
tried doing the following code, as using up and down will not refer to the correct view, since the tree and the forms are completely different views
var view = Ext.widget('hierarchy');
view.down('treepanel').getStore.load();
Now, even though the store is re-loading, am geting an error
TypeError: view.down("treepanel") is null
view.down('treepanel').getStore.load();

How to autosize form fields

I use form.fields from EXTJS API. My application is totally dynamically.
It is possible to autosize combobox thanks to value which are on store ?
Or i need to make my own method... ?!
Actually, my combobox , is declared as following :
itemId : 'materialid',
xtype : 'combobox',
anchor : '35%',
store : materialstore,
id : 'Material',
queryMode: 'local',
displayField: 'data',
width : 50,
valueField: 'data',
editable : false,
grow : true,
enforceMaxLength : true,
listeners : {
render : function(me){
var obj = materialstore.findRecord('data',materialdefaultvalue);
me.setValue(obj.get('data'),obj);
}
},
padding : '0 30 0 30',
fieldLabel : 'Material',
name : 'material',
listeners : {
blur : function(me){
var fieldvalue = me.getValue();
var sel = monPretree.getView().getSelectedRecords();
for ( var i = 0 ; i < sel.length ; i++){
alert(sel[i].get('id') + ' && ' + material);
}
}
}
Thanks :)
Unfortunately not. Your best bet would be either to set a fixed width (like you have) or set it to '100%'.
A quick note for future questions: it is better to ask them over on the Sencha forums, as you will get a quicker response.

ExtJS RowEditor on Grid

When my users edits the Grid via RowEditor combo entries and checkboxes are annoying
1 Apple
2 Orange
3 Pear
For instance with the combo above the user will select Orange then update - the Grid now instead of saying orange will display the number 2 - I would like it to show orange when a successful edit has been made.
code for my combo
editor : {
allowBlank : false,
displayField : 'team',
editable : false,
emptyText : 'Select Team',
forceSelection : true,
lazyRender : true,
mode : 'remote',
name : 'team',
store : storeTeam,
triggerAction : 'all',
valueField : 'id',
xtype : 'combo'
}
I think I read that you could send the complete row back to insert or I should listen to the update of the grid and then change the field but I need some guidance on what is best
Cheers
Try the code below. Use this column just like you would any other ExtJS grid column.
Ext.grid.FixedListColumn = Ext.extend(Ext.grid.Column, {
constructor: function(cfg){
cfg.editor = new Ext.form.ComboBox(cfg.editor);
Ext.grid.ComboBoxColumn.superclass.constructor.call(this, cfg);
this.renderer = Ext.util.Format.comboRenderer(cfg.editor);
}
});
Ext.grid.Column.types.fixedlistcolumn = Ext.grid.FixedListColumn;
// Takes in a combobox and returns a renderer that looks up the displayField in
// the store attached to the combo
Ext.util.Format.comboRenderer = function(combo){
return function(value){
var record = combo.findRecord(combo.valueField, value);
return record ? record.get(combo.displayField) : combo.valueNotFoundText;
}
}
// Use this as the 'columns' parameter when creating your Grid
var grid_columns = [
{xtype:'fixedlistcolumn',
store: [[1,'Apple'],[2,'Orange']]},
...
];
I hope this helps...
You can add renderer definition to your team column:
Below is example of how simple true/false values are represented as Yes/No in the GridPanel:
renderer:function(val){
if(val=="true" || val == true) {
return "Yes";
}
else{
return "No";
}
}

Resources