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);
}
});
Related
I am creating a dependent combo for country,city and state here. I have a select listener in country combo,wherein I call loadCityCombo method.. But, I am not able to access cityStore from loadCityCombo.
What changes should I do for the dependent combo to work?
this.country = {
store : this.countryStore,
xtype: 'combo',
fieldLabel : 'Country',
displayField : 'country',
valueField : 'country',
name : 'country',
typeAhead : true,
mode : 'local',
triggerAction : 'all',
editable : false,
forceSelection : true,
allowBlank : false,
emptyText : 'Select Country',
listeners : {
'select' : this.loadCityCombo
}
};
this.loadCityCombo = function(country) {
console.log('load-CityCombo');
console.log(country);
var ctyCombo = (that.mainFormPanel.getComponent('locationDetailsFieldSet')).getComponent('citycombo');
console.log(ctyCombo);
var that = this;
if(country != null){
var countryName = country.value;
console.log(this.cityStore);
console.log(that.cityStore);
that.cityStore.reload({
params : {
country : countryName,start : 1,limit : 1
}
});
}
};
I think you could be suffering from a scope issue, try adding
listeners : {
'select' : this.loadCityCombo,
scope: this
}
You should be able to use the this keyword and not the 'that' variable you have defined
EDIT
If not defined, this usually refers to the browser window.
Not sure if I am doing this correctly. But I bind a kendo grid with array data of objects, where each object has a Boolean property (i.e. either true or false).
For the user I display it as a checkbox with the checked state showing the true state and vice versa. If you check something in the page 1; go to the page 3; check a few rows; and go back to page 1, the state of the checkbox defaults to how it was at the time it was loaded.
Here is the code snippet I've used.
$(function () {
var ds = new kendo.data.DataSource({
transport: {
read: {
url: '/echo/json/',
type: 'POST',
data: {
json: JSON.stringify(students)
}
}
},
pageSize: 5
});
var kgrid = $("#grid").kendoGrid({
columns: [
{
field: 'name',
title: 'Name'
}, {
field: 'age',
title: 'Age'
}, {
field: 'place',
title: 'Place'
}, {
field: 'hasCar',
title: 'Owns Car',
template: function (data) {
return '<input type="checkbox" ' + (data.hasCar ? 'checked' : '') + '/>';
}
}],
height: 240,
pageable: true
});
$('#btnload').click(function () {
var grid = kgrid.data('kendoGrid');
grid.setDataSource(ds);
$('#grid-display').show();
});
$('#btnrefresh').click(function(){
ds.read();
console.log('refresh');
});
$('#btnlist').click(function(){
var res = $('#result');
kgrid.find('tr td:last input:checked').each(function(i, e){
var name = $(e).closest('tr').children().first().text();
res.append('<p>' + name + '</p>');
console.log('execute');
});
});
});
How to persist the state on pagination?
Ps: fiddle to work with: http://jsfiddle.net/deostroll/2SGyV/3/
That is because the changes you are doing stays there in the grid only - not in kendoDataSource. Here MVVM is not done. So you have to change appropriate value in dataSource each time you click the checkbox.
When you select another page in kendoGrid, it fetches data from dataSource, and then display it the grid. Unless and untill that dataSource is changed, you can't see the changes done in the grid.
PS: Had there is any field for Id in dataSource I would have updated jsfiddle myself
UPDATE
Check this Updated jsfiddle
I have updated template for checkbox
template: function (data) {
return '<input type="checkbox" ' + (data.hasCar ? 'checked' : '') + ' data-name="'+ data.name + '"' +'/>';
}
Now checkbox will have name of the data. You can change it with id. On change event, update your dataSource accordingly on each checkbox click.
$('#grid-display input').live('change', function(){
alert($(this).attr('data-name'));
//update the data source here based on the data-name attribute u're getting
});
Use databound event in the kendo Grid.
Not sure below code work will work for you or not. But similar code worked for me
function OnDataBoundEventMethod(e) {
var view = this.dataSource.view();
for (var i = 0; i < view.length; i++) {
if ([view[i].hasCar]) {
this.tbody.find("tr[data-uid='" + view[i].uid + "']")
.addClass("k-state-selected")
.find(".row-check-box")
.attr("checked", "checked");
}
}
}
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
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();
We are using treepanel with check box in our application.It seems like:
var treepanel = {
id : 'tree',
xtype : 'treepanel',
store : layerStore,
rootVisible : false,
listeners : {
checkchange : function(node,check){
if(node.get('id') == 'teacher'){
alert('you have selected teacher node');
}else if(node.get('id') == 'student'){ alert('you have selected student node'); }
}
}
};
LayerStore code:
var layerStore = Ext.create('Ext.data.TreeStore',{
root : {
children : [
{
text : 'teacher layer',
id : 'teacher',
checked : false
},{
text : 'Student layer',
id : 'student',
checked : false
}]
}
});
Now,i am getting the alert message when we check on the particular checkbox.My problem is that if we uncheck the checkbox then it has to display the alert like you has unselected a particular layer.Please help me.
I quess You have to change your 'checkchange' handler to this:
checkchange : function(node,check){
var s = (!check && 'un' || '' ) + 'selected';
if(node.get('id') == 'teacher'){
alert('you have '+s+' teacher node');
}else if(node.get('id') == 'student'){ alert('you have '+s+' student node'); }
}