I created one directive in Angularjs now binding model data into directive , problem is that I have I am using JqGrid and I want call one function when JqGrid's gridcomplete event will call.
Everything working fine when we direct use function code into directive, But when trying to call it from
model then its not able to call.
Pasting code and highlighting problem into snap also.
> var app = angular.module('BOneApp', []);
>
> app.directive('jqGrid', function ($compile) {
>
> var jqGridCounter = 0;
>
> return {
> replace: true,
> restrict: 'E',
> scope: {
> gridData: '='
> },
> template: '<div>' +
> '<table></table>' +
> '<div class="jqgrid-pagination"></div>' +
> '</div>',
> controller: function ($scope, $element) {
> $scope.editRow = function (row) {
> $element.find('table').editRow(row);
> };
> $scope.saveRow = function (row) {
> $element.find('table').saveRow(row);
> };
> $scope.restoreRow = function (row) {
> $element.find('table').restoreRow(row);
> };
> },
> link: function (scope, element) {
> var gridNumber = jqGridCounter++;
> var wrapperId = 'jqgrid-' + gridNumber;
> element.attr('id', wrapperId);
>
> var tableId = 'jqgrid-table-' + gridNumber;
> var table = element.find('table');
> table.attr('id', tableId);
>
> var pagerId = 'jqgrid-pager-' + gridNumber;
> element.find('.jqgrid-pagination').attr('id', pagerId);
>
> table.jqGrid({
> id:scope.gridData.id,
> url: scope.gridData.url,
> datatype: "json",
> height: 'auto',
> colNames: scope.gridData.colNames || [],
> colModel: scope.gridData.colModel || [],
> rowNum: 10,
> rowList: [10, 20, 30],
> pager: '#' + pagerId,
> sortname: 'id',
> toolbarfilter: true,
> viewrecords: true,
> sortorder: "asc",
>
> gridComplete: scope.gridData.gridComplete(),
> //editurl: scope.gridData.editurl,
> caption: scope.gridData.caption,
> multiselect: scope.gridData.multiselect,
> autowidth: true
>
> });
> table.jqGrid('navGrid', '#' + pagerId, {
> edit: true,
> add: true,
> del: true
> });
> table.jqGrid('inlineNav', '#' + pagerId);
>
>
> element.find(".ui-jqgrid").removeClass("ui-widget ui-widget-content");
> element.find(".ui-jqgrid-view").children().removeClass("ui-widget-header
> ui-state-default");
> element.find(".ui-jqgrid-labels, .ui-search-toolbar").children().removeClass("ui-state-default
> ui-th-column ui-th-ltr");
> element.find(".ui-jqgrid-pager").removeClass("ui-state-default");
> element.find(".ui-jqgrid").removeClass("ui-widget-content");
>
> // add classes
> element.find(".ui-jqgrid-htable").addClass("table table-bordered table-hover");
> element.find(".ui-jqgrid-btable").addClass("table table-bordered table-striped");
>
> element.find(".ui-pg-div").removeClass().addClass("btn btn-sm btn-primary");
> element.find(".ui-icon.ui-icon-plus").removeClass().addClass("fa
> fa-plus");
> element.find(".ui-icon.ui-icon-pencil").removeClass().addClass("fa
> fa-pencil");
> element.find(".ui-icon.ui-icon-trash").removeClass().addClass("fa
> fa-trash-o");
> element.find(".ui-icon.ui-icon-search").removeClass().addClass("fa
> fa-search");
> element.find(".ui-icon.ui-icon-refresh").removeClass().addClass("fa
> fa-refresh");
> element.find(".ui-icon.ui-icon-disk").removeClass().addClass("fa
> fa-save").parent(".btn-primary").removeClass("btn-primary").addClass("btn-success");
> element.find(".ui-icon.ui-icon-cancel").removeClass().addClass("fa
> fa-times").parent(".btn-primary").removeClass("btn-primary").addClass("btn-danger");
>
> element.find(".ui-icon.ui-icon-seek-prev").wrap("<div class='btn btn-sm btn-default'></div>");
> element.find(".ui-icon.ui-icon-seek-prev").removeClass().addClass("fa
> fa-backward");
>
> element.find(".ui-icon.ui-icon-seek-first").wrap("<div class='btn btn-sm btn-default'></div>");
> element.find(".ui-icon.ui-icon-seek-first").removeClass().addClass("fa
> fa-fast-backward");
>
> element.find(".ui-icon.ui-icon-seek-next").wrap("<div class='btn btn-sm btn-default'></div>");
> element.find(".ui-icon.ui-icon-seek-next").removeClass().addClass("fa
> fa-forward");
>
> element.find(".ui-icon.ui-icon-seek-end").wrap("<div class='btn btn-sm btn-default'></div>");
> element.find(".ui-icon.ui-icon-seek-end").removeClass().addClass("fa
> fa-fast-forward");
>
> $(window).on('resize.jqGrid', function () {
> table.jqGrid('setGridWidth', $("#content").width());
> });
>
> $compile(element.contents())(scope);
> }
> } });
>
>
> app.controller('CostCenter', function ($scope) {
>
> $scope.gridData = {
> url: baseURL + "/CompanyAdmin/GetCostCenterForCompanyAdmin",
> //editurl: "/Tables/Edit",
> caption: "Cost Centers",
> colNames: ['Actions', 'ID', 'Parent Code', 'Parent Name', 'Code', 'Name', 'Address', 'Contact Number', 'Website'],
> colModel: [
> { name: 'act', index: 'act', sortable: false },
> { name: 'ID', index: 'ID', key: true, hidden: true },
> { name: 'ParentCode', index: 'ParentCode', editable: true },
> { name: 'ParentName', index: 'ParentName', editable: true },
> { name: 'Code', index: 'Code', editable: true },
> { name: 'Name', index: 'Name', editable: true },
> { name: 'Address', index: 'Address', editable: true/*, searchoptions: { sopt: ['eq', 'ne', 'cn'] }*/ },
> { name: 'ContactNumber', index: 'ContactNumber', editable: true },
> { name: 'Website', index: 'Website', editable: true/*, edittype: 'select', editoptions: { value:
> sa_EditOpt(arr_AccountNumbers, 'Id', 'ACNumber') } */ }
> ],
> multiselect: false,
> gridComplete: function () { **/* Need to call this function into run time in directive */**
>
> var gridid = $("#jqgrid-table-0");
> var ids = gridid.jqGrid('getDataIDs');
> for (var i = 0; i < ids.length; i++) {
> var cl = ids[i];
> be = "<a class='btn btn-xs btn-default' data-original-title='Edit Row'
> href=\"/CompanyAdmin/UpdateBusinessEntity/" + cl + "\"><i class='fa
> fa-pencil'></i></a>";
> ac = "<a class='btn btn-xs btn-default' data-original-title='Edit Row' href=\"/CompanyAdmin/Create?ParentID="
> + cl + "\"><i class='fa fa-sitemap'></i></a>";
> jQuery(gridid).jqGrid('setRowData', ids[i], {
> act: be + ac
> });
> }
> },
>
> };
>
> });
I guess, in your directive code you are executing the function directly at time of linking and due to that it is not able to execute on gridComplete event.
Try to change
gridComplete: scope.gridData.gridComplete() in your directive code with
gridComplete: scope.gridData.gridComplete.
So it can execute on gridComplete event.
Here is a working example that should give you what you need:
http://plnkr.co/edit/bN5KOtehElJqNP3C7CkD?p=preview
You can bind functions the same way you bind data from outer -> inner scopes. Here, gridComplete is bound from the outer scope (controller scope) into the inner scope using a two-way binding. It gets called in the link function, immediately after compiling, but it could be called any time.
// Code goes here
angular.module('MyApp', [])
.controller('MainCtrl', ['$scope',
function($scope) {
$scope.gridData = {
gridComplete: function() {
console.log("someFn was executed!")
}
}
}
])
.directive('directiveWithFn', function() {
return {
restrict: 'A',
$scope: {
'gridData': '='
},
link: function(scope, elem) {
// Call the function after compile
scope.gridData.gridComplete();
}
}
})
After explore many angularjs official findout the solution
angular.module('getterSetterExample', [])
.controller('ExampleController', ['$scope', function($scope) {
var _name = 'Brian';
$scope.user = {
name: function(newName) {
if (angular.isDefined(newName)) {
_name = newName;
}
return _name;
}
};
}]);
Now my code looks like added "event_gridComplete" function inside block and then called from directive.
Working !
var app = angular.module('BOneApp', []);
app.directive('jqGrid', function ($compile) {
var jqGridCounter = 0;
return {
replace: true,
restrict: 'E',
scope: {
gridData: '='
},
template: '<div>' +
'<table></table>' +
'<div class="jqgrid-pagination"></div>' +
'</div>',
controller: function ($scope, $element) {
$scope.editRow = function (row) {
$element.find('table').editRow(row);
};
$scope.saveRow = function (row) {
$element.find('table').saveRow(row);
};
$scope.restoreRow = function (row) {
$element.find('table').restoreRow(row);
};
},
link: function (scope, element) {
var gridNumber = jqGridCounter++;
var wrapperId = 'jqgrid-' + gridNumber;
element.attr('id', wrapperId);
var tableId = 'jqgrid-table-' + gridNumber;
var table = element.find('table');
table.attr('id', tableId);
var pagerId = 'jqgrid-pager-' + gridNumber;
element.find('.jqgrid-pagination').attr('id', pagerId);
table.jqGrid({
id:scope.gridData.id,
url: scope.gridData.url,
datatype: "json",
height: 'auto',
colNames: scope.gridData.colNames || [],
colModel: scope.gridData.colModel || [],
rowNum: 10,
rowList: [10, 20, 30],
pager: '#' + pagerId,
sortname: 'id',
toolbarfilter: true,
viewrecords: true,
sortorder: "asc",
gridComplete: scope.gridData.gridComplete.event_gridComplete,
//editurl: scope.gridData.editurl,
caption: scope.gridData.caption,
multiselect: scope.gridData.multiselect,
autowidth: true
});
table.jqGrid('navGrid', '#' + pagerId, {
edit: true,
add: true,
del: true
});
table.jqGrid('inlineNav', '#' + pagerId);
element.find(".ui-jqgrid").removeClass("ui-widget ui-widget-content");
element.find(".ui-jqgrid-view").children().removeClass("ui-widget-header ui-state-default");
element.find(".ui-jqgrid-labels, .ui-search-toolbar").children().removeClass("ui-state-default ui-th-column ui-th-ltr");
element.find(".ui-jqgrid-pager").removeClass("ui-state-default");
element.find(".ui-jqgrid").removeClass("ui-widget-content");
// add classes
element.find(".ui-jqgrid-htable").addClass("table table-bordered table-hover");
element.find(".ui-jqgrid-btable").addClass("table table-bordered table-striped");
element.find(".ui-pg-div").removeClass().addClass("btn btn-sm btn-primary");
element.find(".ui-icon.ui-icon-plus").removeClass().addClass("fa fa-plus");
element.find(".ui-icon.ui-icon-pencil").removeClass().addClass("fa fa-pencil");
element.find(".ui-icon.ui-icon-trash").removeClass().addClass("fa fa-trash-o");
element.find(".ui-icon.ui-icon-search").removeClass().addClass("fa fa-search");
element.find(".ui-icon.ui-icon-refresh").removeClass().addClass("fa fa-refresh");
element.find(".ui-icon.ui-icon-disk").removeClass().addClass("fa fa-save").parent(".btn-primary").removeClass("btn-primary").addClass("btn-success");
element.find(".ui-icon.ui-icon-cancel").removeClass().addClass("fa fa-times").parent(".btn-primary").removeClass("btn-primary").addClass("btn-danger");
element.find(".ui-icon.ui-icon-seek-prev").wrap("<div class='btn btn-sm btn-default'></div>");
element.find(".ui-icon.ui-icon-seek-prev").removeClass().addClass("fa fa-backward");
element.find(".ui-icon.ui-icon-seek-first").wrap("<div class='btn btn-sm btn-default'></div>");
element.find(".ui-icon.ui-icon-seek-first").removeClass().addClass("fa fa-fast-backward");
element.find(".ui-icon.ui-icon-seek-next").wrap("<div class='btn btn-sm btn-default'></div>");
element.find(".ui-icon.ui-icon-seek-next").removeClass().addClass("fa fa-forward");
element.find(".ui-icon.ui-icon-seek-end").wrap("<div class='btn btn-sm btn-default'></div>");
element.find(".ui-icon.ui-icon-seek-end").removeClass().addClass("fa fa-fast-forward");
$(window).on('resize.jqGrid', function () {
table.jqGrid('setGridWidth', $("#content").width());
});
$compile(element.contents())(scope);
}
}
});
app.controller('CostCenter', function ($scope) {
$scope.gridData = {
url: baseURL + "/CompanyAdmin/GetCostCenterForCompanyAdmin",
//editurl: "/Tables/Edit",
caption: "Cost Centers",
colNames: ['Actions', 'ID', 'Parent Code', 'Parent Name', 'Code', 'Name', 'Address', 'Contact Number', 'Website'],
colModel: [
{ name: 'act', index: 'act', sortable: false },
{ name: 'ID', index: 'ID', key: true, hidden: true },
{ name: 'ParentCode', index: 'ParentCode', editable: true },
{ name: 'ParentName', index: 'ParentName', editable: true },
{ name: 'Code', index: 'Code', editable: true },
{ name: 'Name', index: 'Name', editable: true },
{ name: 'Address', index: 'Address', editable: true/*, searchoptions: { sopt: ['eq', 'ne', 'cn'] }*/ },
{ name: 'ContactNumber', index: 'ContactNumber', editable: true },
{ name: 'Website', index: 'Website', editable: true/*, edittype: 'select', editoptions: { value: sa_EditOpt(arr_AccountNumbers, 'Id', 'ACNumber') } */ }
],
multiselect: false,
gridComplete: {
event_gridComplete: function () {
var gridid = $("#jqgrid-table-0");
var ids = gridid.jqGrid('getDataIDs');
for (var i = 0; i < ids.length; i++) {
var cl = ids[i];
be = "<a class='btn btn-xs btn-default' data-original-title='Edit Row' href=\"/CompanyAdmin/UpdateBusinessEntity/" + cl + "\"><i class='fa fa-pencil'></i></a>";
ac = "<a class='btn btn-xs btn-default' data-original-title='Edit Row' href=\"/CompanyAdmin/Create?ParentID=" + cl + "\"><i class='fa fa-sitemap'></i></a>";
jQuery(gridid).jqGrid('setRowData', ids[i], {
act: be + ac
});
}
} },
};
});
You shouldn't do any DOM manipulations inside of your controller to begin with. These lines:
var gridid = $("#jqgrid-table-0");
var ids = gridid.jqGrid('getDataIDs');
can be executed inside of a directive (your current one or a different one for this specific use case) by using element parameter. Another way to put it inside of your directive is to make it an optional attribute, i.e.:
scope: {
gridData: '=',
editButtons: '#'
},
link: function (scope, element) {
...
if(scope.editButtons){
var ids = element.jqGrid('getDataIDs');
...
}
The edit buttons shouldn't be done inside of a controller as well. You should move them inside of a template or add them in a link function.
Using jqGrid with Angular is a bad idea overall. There are some Angular based grids that can be mapped with your application in a much cleaner way, for example: http://ui-grid.info/
If you decide to keep all this presentation logic inside of your controller, then you should fix this line:
gridComplete: scope.gridData.gridComplete(),
You are calling the function during the assignment and therefore assigning the function's RESULT, not the function itself. It should be:
gridComplete: scope.gridData.gridComplete,
Related
Requirement: To have infinite scrolling for a extjs(4.2.2) grid along with row expanding functionality.
But both the plugins together not working,
row expander plugin not allowing data to load into buffered store of a grid.
when rowexpander plugin is commented, then infinite scroll grid is loading.
how to have both the functionalities?
i have created a rowexpander plugin as below by extending extjs rowexpander,
here if i comment out below line thne atleast one rec is getting loaded
feature.getRowBodyContents = Ext.bind(me.getRowBodyContents, me);
Ext.define('Premier.view.tools.NM.Plugin.NotesGridRowExpander', {
extend: 'Ext.grid.plugin.RowExpander',
alias: 'plugin.notes-rowexpander',
rowBodyTpl: [
'<div class="notes-management-tool"> ',
'<table cellspacing="0" cellpadding="0" class="notes-management-tool-table">',
'<tr>',
'<th valign="middle" class="notes-management-tool-table-date" style="color:black;width:130px;">Last Edited Date</th>',
'<th valign="middle" class="notes-management-tool-table-note" style="color:black;width:360px;">Notes</th>',
'<th valign="middle" class="notes-management-tool-table-editedBy" style="color:black;width:210px;">Last Edited By</th>',
'<th valign="middle" class="notes-management-tool-table-actions" style="color:black;width:50px;">Actions</th>',
'</tr>',
'<tpl for=".">',
'<tr>',
'<td valign="middle" class="notes-management-tool-table-date" style="color:black">{[(Ext.util.Format.date(Ext.Date.parse(values.LastEditedDate, "MS"), "M-d-Y h:i A"))|| " "]}</td>',
'<td valign="middle"class="notes-management-tool-table-note" style="color:black">{[(values.Note)|| " "]}</td>',
'<td valign="middle" class="notes-management-tool-table-editedBy" style="color:black">{[(values.LastEditedBy)|| " "]}</td>',
'<td valign="right" class="notes-management-tool-table-actions" ><div style="margin-left:3px" data-qtip="Edit" class = "{[parent.AccountId == values.LastEditedById ? "edit-notes-record-icon-active " : "edit-notes-record-icon-inactive "]}-noteId-{[this.getStringId(values.NoteId)]}-entityId-{[this.getStringId(values.EntityId)]}-entityTypeId-{[this.getStringId(values.EntityTypeId)]}"></div><div style="margin-left:3px" data-qtip="Delete" class = "{[parent.AccountId == values.LastEditedById ? "trash-icon " : "disabled-trash-icon " ]}-noteId-{[this.getStringId(values.NoteId)]}-entityId-{[this.getStringId(values.EntityId)]}-entityTypeId-{[this.getStringId(values.EntityTypeId)]}"></div></td>',
'</tr>',
'</tpl>',
'</table>',
'</div> ',
{
getStringId: function (id) {
return id.toString();
}
}
],
expandAllFlag: false,
constructor: function () {
var me = this;
me.callParent(arguments);
},
setCmp: function (grid) {
var me = this, features, i, feature;
me.callParent(arguments);
features = grid.features;
for (i = 0; i < features.length; i++) {
if ((feature = features[i]).ftype == 'rowbody') {
break;
}
}
if (feature) {
//This function is abstracted as a private function kind of. So overriding the method to call
//our own function
feature.getRowBodyContents = Ext.bind(me.getRowBodyContents, me);
}
},
getRowBodyContents: function (record) {
var content = '', data;
if(record.data) {
data = record.data.NotesChildViews.sort(
function (rec1, rec2) {
var a= Ext.Date.parse(rec1.LastEditedDate, "MS");
var b =Ext.Date.parse(rec2.LastEditedDate, "MS");
return a>b ? -1 : a<b ? 1 : 0;
});
}
if (data) {
data.AccountId = this.grid.app.getAccountId();
content = this.rowBodyTpl.apply(data);
}
return content;
},
getHeaderConfig: function () {
var me = this;
return {
itemId: 'rowExpanderHeader',
width: 40,
lockable: false,
sortable: false,
resizable: false,
draggable: false,
hideable: false,
text: '<div class="notes-grid-expand"></div>',
menuDisabled: true,
tdCls: Ext.baseCSSPrefix + 'grid-cell-special',
innerCls: Ext.baseCSSPrefix + 'grid-cell-inner-row-expander',
renderer: function (value, metadata) {
// Only has to span 2 rows if it is not in a lockable grid.
if (!me.grid.ownerLockable) {
metadata.tdAttr += ' rowspan="2"';
}
return '<div style="margin: 4px 0px 0px 8px;" class="' + Ext.baseCSSPrefix + 'grid-row-expander" role="presentation"></div>';
},
processEvent: function (type, view, cell, rowIndex, cellIndex, e, record) {
if (type == "mousedown" && e.getTarget('.' + Ext.baseCSSPrefix + 'grid-row-expander')) {
me.toggleRow(rowIndex, record);
return me.selectRowOnExpand;
}
},
listeners: {
'afterrender': me.handleExpansion,
scope: me
}
};
},
handleExpansion: function (headerObj) {
var me = this;
headerObj.el.on('click', function () {
me.cmp.fireEvent('notes-grid-expansion');
});
},
updateHeaderText: function () {
var me = this;
if (me.expandAllFlag == false) {
me.cmp.headerCt.down('#rowExpanderHeader').setText('<div class="notes-grid-collapse"></div>');
me.expandAllFlag = true;
}
else {
me.cmp.headerCt.down('#rowExpanderHeader').setText('<div class="notes-grid-expand"></div>');
me.expandAllFlag = false;
}
},
setDefaultHeader: function () {
var me = this;
me.cmp.headerCt.down('#rowExpanderHeader').setText('<div class="notes-grid-expand"></div>');
me.expandAllFlag = false;
}
});
when getrowbodycontent is removed from setCmp then ,
when calling getrowbodycontent in setCmp,
This solution uses bufferedrenderer and rowexpander plugins. I don't know how you get data, so the example generates some fake data and loads data dynamically.
I hope this helps.
Ext.define('testmodel', {
extend: 'Ext.data.Model',
fields: [
{name: 'name', type: 'string'},
{name: 'index', type: 'number'}
]
});
Ext.define('Test.RowExpander', {
extend: 'Ext.grid.plugin.RowExpander',
rowBodyTpl: [
"<tpl>",
"<p>Item name: {name}</p>",
"<p>Item index: {index}</p>",
"</tpl>"
],
expandAllFlag: false,
constructor: function() {
this.callParent(arguments);
},
setCmp: function (grid) {
var me = this, features, i, feature;
me.callParent(arguments);
features = grid.features;
for (i = 0; i < features.length; i++) {
if ((feature = features[i]).ftype == 'rowbody') {
break;
}
}
if (feature) {
feature.getRowBodyContents = Ext.bind(me.getRowBodyContents, me);
}
},
getRowBodyContents: function (record) {
var content = '', data;
if (record.data) {
data = record.data;
}
if (data) {
content = this.rowBodyTpl.apply(data);
}
return content;
}
});
Ext.onReady(function() {
Ext.define('Test.TestWindow', {
extend: 'Ext.window.Window',
closeAction: 'destroy',
border: false,
width: 560,
height: 500,
modal: true,
closable: true,
resizable: false,
layout: 'fit',
setStoreData: function() {
var me = this;
me.storeData = [];
for (i = 1; i <= 15000; i++) {
me.storeData.push(
{"name": "Name"+i, "index": i}
);
}
},
initComponent: function() {
var me = this;
me.callParent(arguments);
me.setStoreData();
me.store = Ext.create('Ext.data.Store', {
autoLoad: false,
pageSize: 16,
data: [],
model: 'testmodel'
});
me.rowexpander = Ext.create('Test.RowExpander', {
});
me.bufferedrenderer = Ext.create('Ext.grid.plugin.BufferedRenderer', {
});
me.grid = Ext.create('Ext.grid.Panel', {
loadMask: true,
plugins: [
me.bufferedrenderer,
me.rowexpander
],
selModel: {
pruneRemoved: false
},
stripeRows: true,
store: me.store,
columnLines: false,
columns : [
{header : 'Name', sortable : true, width: 100, dataIndex : 'name'},
{header : 'Index', sortable : true, width : 100, dataIndex : 'index'}
]
});
me.add(me.grid);
me.store.loadData(me.storeData);
}
});
var win = new Test.TestWindow({
});
win.show();
});
Notes:
Tested with ExtJS 4.2.1 and Internet Explorer 11, Google Chrome 68, Mozilla Firefox 61, Microsoft Edge 42.
Fiddle can be found here.
I am trying to set rows editable/not editable based on a flag in the data.
I can get this working outside an angular 1.5 component, but can't seem to access row.entity inside a controller in a component.
function memberDisplayCtrl ($scope, memberFactory,uiGridConstants) {
var ctrl = this;
ctrl.people = memberFactory.getMembers();
ctrl.checkStatus = function(ctrl){
// How do I do something like this:
// if (ctrl.row.entity.Status === 'Y') { return 'true'; } else {return 'false';}
};
ctrl.gridOptions = {
enableSorting: true,
enableCellEdit:false,
cellEditableCondition: ctrl.checkStatus(ctrl),
enableHorizontalScrollbar : 0,
enableVerticalScrollbar : 0,
enableColumnMenus: false,
minRowsToShow: ctrl.people.length,
columnDefs: [
{ displayName:'First Name', name: 'fname', enableCellEdit:true },
{ displayName:'Last Name', name: 'lname', enableCellEdit:true },
{ displayName:'Date of Birth', name: 'DOB', type:'date', enableCellEdit:true, cellFilter: 'date:"yyyy-MM-dd"'},
{ displayName:'Address', name: 'address', enableCellEdit:true},
{ displayName:'Status',name: 'Status', enableCellEdit: true}
],
data : ctrl.people
};
}
I'm pretty sure I have a scope problem but can't seem to figure it out. How do I access row.entity? I have an isolated scope inside my controller (since it is part of a component)
plunker here: https://plnkr.co/edit/Wz7gKs
Thanks
just pass a function to cellEditableCondition instead of executing it:
cellEditableCondition: ctrl.checkStatus
and note, that parameter received by that function is not current controller's this (aliased in your case as ctrl), but ui-grid's scope, so I renamed ctrl to scope:
function memberDisplayCtrl ($scope, memberFactory,uiGridConstants) {
var ctrl = this;
ctrl.people = memberFactory.getMembers();
ctrl.checkStatus = function(scope) {
return scope.row.entity.Status === 'Y'
};
ctrl.gridOptions = {
enableSorting: true,
enableCellEdit:false,
cellEditableCondition: ctrl.checkStatus,
enableHorizontalScrollbar : 0,
enableVerticalScrollbar : 0,
enableColumnMenus: false,
minRowsToShow: ctrl.people.length,
columnDefs: [
{ displayName:'First Name', name: 'fname', enableCellEdit:true },
{ displayName:'Last Name', name: 'lname', enableCellEdit:true },
{ displayName:'Date of Birth', name: 'DOB', type:'date', enableCellEdit:true, cellFilter: 'date:"yyyy-MM-dd"'},
{ displayName:'Address', name: 'address', enableCellEdit:true},
{ displayName:'Status',name: 'Status', enableCellEdit: true}
],
data : ctrl.people
};
}
also, I see your commented code:
if (ctrl.row.entity.Status === 'Y') {
return 'true';
}
else {
return 'false';
}
here you intend to return string variable in both cases which will always evaluated as boolean true, you should return boolean:
if (ctrl.row.entity.Status === 'Y') {
return true;
}
else {
return false;
}
which is equal to much shorter version:
return ctrl.row.entity.Status === 'Y';
plunker: https://plnkr.co/edit/KXbJ40?p=preview
I know that there are a lot of answers on this issue but I tried everything and nothing work. If the element popover work, I can't see any content inside.
My last test :
On my html template :
<div class="momentctrl" ng-controller="ButtonsMomentCtrl">
<div class="btn-group-checkbox">
<button class="btn btn-primary" ng-model="checkModel.daybutton" ng-click="momentChange('daybutton')" type="button" btn-checkbox prevent-default bs-popover items="momentdays", title="Moment of day">Day</button>
<script type="text/ng-template" id="popover_template.html">
<div ng-repeat='momentday in momentdays'>
<label>
<input type='checkbox' ng-model='momentday.isChecked' ng-change='changeMomentDay(momentday)'/> <span class='ng-binding-advancedsearch'>{{momentday.name}}</span>
</label>
</div>
</script>
</div>
</div>
on my controllers :
angular.module('my.controllers',['ui.bootstrap'])
.controller('ButtonsMomentCtrl', ['$scope', '$rootScope', function ($scope, $rootScope) {
$scope.checkModel = {
allbutton:true,
nowbutton: false,
daybutton: false,
tonightbutton: false
};
$scope.momentdays = [
{
name: "All",
id: 0,
isChecked: true,
col: 1
},
{
name: "Morning",
id: 0,
isChecked: false,
col: 1
},
{
name: "Afternoon",
id: 1,
isChecked: false,
col: 1
},
{
name: "Early evening",
id: 1,
isChecked: false,
col: 1
},
{
name: "Evening",
id: 1,
isChecked: false,
col: 1
},
{
name: "Night",
id: 1,
isChecked: false,
col: 1
}
];
$scope.momentChange = function(moment){
console.log("momentChange");
}
$scope.changeMomentDay = function(momentDay) {
console.log("changeMomentDay");
};
}])
on my directives :
angular.module('my.directives', [])
.directive('bsPopover', function($compile, $templateCache) {
console.log("directive bs popover");
var getTemplate = function () {
$templateCache.put('templateId.html', 'This is the content of the template');
return $templateCache.get("myPopoverTemplate.html");
}
return {
restrict: "A",
transclude: true,
template: "<span ng-transclude></span>",
link: function (scope, element, attrs) {
var popOverContent;
var html = getTemplate();
popOverContent = $compile(html)(scope);
console.log("popOverContent = "+popOverContent);
var options = {
content: popOverContent,
placement: "bottom",
html: true,
title: scope.title
};
element.popover(options);
},
scope: {
title: '#',
items: '='
}
};
});
I constructed a ui grid which has a column for editing, the grid information is populated by a json. Upon clicking the edit column a modal is opened. I want the user to be able to edit the row it clicked. So far I was able to return the entire json object to the modal, but I'm having trouble understanding how to turn that object into just the row I want to edit. I have a variable named ClickedRow which returns the $$hashkey id but I'm not sure how to access it. I tried a forEach utility but it's not working. I am new to angularjs can anyone help me
This is my controller:
import {safeApply} from 'ems';
import modalTemplate from './modal/modal.html';
import controller from './modal/modal.controller.js';
class AssetsController {
/* #ngInject */
constructor(AssetsService, $uibModal, $state) {
this.label = 'Assets Controller !!';
this.assetsService = AssetsService;
this.assetModal= $uibModal;
this.$state = $state;
var assetsData;
var clickedRow;
this.assetsService.resolvePromise().then((response) => {
this.gridOptions.data = response;
assetsData = this.gridOptions.data;
//console.log(response);
safeApply();
});
this.modalOptions ={
template: modalTemplate,
controller: controller,
size: 'large',
backdrop: false,
resolve: {
assetData: function(){
console.log('number 2'+clickedRow);
return [clickedRow, assetsData];
}
}
};
this.myAppScopeProvider ={
modal: this.assetModal,
modalOptions: this.modalOptions,
open:function(row){
console.log('number 1'+row);
clickedRow = row;
this.modal.open(this.modalOptions)
}
};
this.initialize();
}
initialize() {
this.gridOptions = {
paginationPageSizes: [15, 30, 45],
paginationPageSize: 9,
rowHeight: 50,
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: false,
enableColumnResizing: true,
enableSelectAll: false,
noUnselect: true,
columnDefs: [
{
field: 'Thumbnail',
displayName: '',
width: 100,
cellTemplate: '<span class="glyphicon glyphicon-picture" aria-hidden="true"></span>'
},
{
field: 'File Name',
displayName: 'File Name',
cellClass:'blue',
width: 100
},
{
field: 'Description_',
displayName: 'Description',
minWidth: 150
},
{
field: 'Edit_',
displayName: 'Edit',
cellTemplate: '<button class="btn btn-link pull-right" ng-click="grid.appScope.open(row)">Edit</button>',
cellClass:'blue',
width: 100
},
{ field: 'Uploaded_Date', displayName: 'Upload Date'},
{ field: 'Uploaded_By'},
{ field: 'File_Size' },
{ field: 'File_Source'},
{ field: 'In_Use'},
{
field: 'Lock_Status',
displayName: '',
cellClass:'black',
cellTemplate: '<span class="glyphicon glyphicon-lock" aria-hidden="true">'
}
],
onRegisterApi:function (gridApi) {
this.gridApi = gridApi;
},
appScopeProvider: this.myAppScopeProvider,
rowTemplate:''
};
}
}
export default AssetsController;
class ModalController {
/* #ngInject */
constructor($scope, $uibModalInstance, assetData) {
this.label = 'Modal Controller !!';
this.scope = $scope;
this.scope.assetData = assetData;
}
initialize() {
/* this.modalService.resolvePromise().then((response) => {
this.data = response.data;
});*/
}
}
export default ModalController;
Pass row.entity as parameter to your open method:
<button class="btn btn-link pull-right" ng-click="grid.appScope.open(row.entity)">Edit</button>
You'll need to declare your resolve object in your open method so you can pass entity directly:
open: function (entity) {
this.modalOptions.resolve = {
entity: entity
}
this.modal.open(this.modalOptions)
}
Inject entity into your modal controller and you're good to go
Here's a working example on Plunker: http://plnkr.co/edit/Agvcc6CZFBvQQLRpQeRk?p=preview
i have created a grid on which i can select rows , if i goto next page on the grid and select some other row my row count gets updated , but when i visit my first page again the previous selection is gone but row count is still there , how will i make them persist even after i visit different pages
var app = angular.module('myApp', ['ngGrid']);
app.controller('MyCtrl', function($scope, $http) {
$scope.filterOptions = {
filterText: "",
useExternalFilter: true
};
$scope.totalServerItems = 0;
$scope.pagingOptions = {
pageSizes: [5, 10, 20],
pageSize: 5,
currentPage: 1
};
$scope.setPagingData = function(data, page, pageSize){
var pagedData = data.slice((page - 1) * pageSize, page * pageSize);
$scope.myData = pagedData;
$scope.totalServerItems = data.length;
if (!$scope.$$phase) {
$scope.$apply();
}
};
$scope.getPagedDataAsync = function (pageSize, page, searchText) {
setTimeout(function () {
var data;
if (searchText) {
var ft = searchText.toLowerCase();
$http.get('largeLoad.json').success(function (largeLoad) {
data = largeLoad.filter(function(item) {
return JSON.stringify(item).toLowerCase().indexOf(ft) != -1;
});
$scope.setPagingData(data,page,pageSize);
});
} else {
$http.get('largeLoad.json').success(function (largeLoad) {
$scope.setPagingData(largeLoad,page,pageSize);
});
}
}, 100);
};
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage);
$scope.$watch('pagingOptions', function (newVal, oldVal) {
if (newVal !== oldVal && newVal.currentPage !== oldVal.currentPage) {
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);
}
}, true);
$scope.$watch('filterOptions', function (newVal, oldVal) {
if (newVal !== oldVal) {
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);
}
}, true);
$scope.edit = function (row) {
row.entity.edit = !row.entity.edit;
};
$scope.gridOptions = {
data: 'myData',
enablePaging: true,
showFooter: true,
primaryKey:"name",
enableRowSelection: true,
showGroupPanel: true,
enableCellSelection: false,
jqueryUIDraggable: true,
//showSelectionCheckbox: true,
selectedItems:$scope.output,
totalServerItems:'totalServerItems',
pagingOptions: $scope.pagingOptions,
filterOptions: $scope.filterOptions,
columnDefs: [{
field: 'nm',
displayName: 'Name',
cellTemplate: '<div class="ngCellText"><div ng-show="!row.entity.edit">{{row.getProperty(col.field)}}</div>' +
'<div ng-show="row.entity.edit" class="ngCellText"><input type="text" ng-model="row.entity.nm"/></div></div>'
},
{
field: 'cty',
displayName: 'city',
cellTemplate: '<div class="ngCellText"><div ng-show="!row.entity.edit">{{row.getProperty(col.field)}}</div>' +
'<div ng-show="row.entity.edit" class="ngCellText"><input type="text" ng-model="row.entity.cty"/></div></div>'
},
{
field: 'hse',
displayName: 'Address',
cellTemplate: '<div class="ngCellText"><div ng-show="!row.entity.edit">{{row.getProperty(col.field)}}</div>' +
'<div ng-show="row.entity.edit" class="ngCellText"><input type="text" ng-model="row.entity.hse"/></div></div>'
},
{
field: 'yrs',
displayName: 'PinCode',
cellTemplate: '<div class="ngCellText"><div ng-show="!row.entity.edit">{{row.getProperty(col.field)}}</div>' +
'<div ng-show="row.entity.edit" class="ngCellText"><input type="text" ng-model="row.entity.yrs"/></div></div>'
},
{
displayName: 'Edit',
cellTemplate: '<button id="editBtn" type="button" class="btn btn-primary" ng-click="edit(row)" >Modify</button> '
},
{
displayName: 'Remove',
cellTemplate: '<button id="removebtn" type="button" class="btn btn-primary" ng-click="removeRow($index)" >Remove</button> '
}
]
};
$scope.removeRow = function() {
var index = this.row.rowIndex;
$scope.gridOptions.selectItem(index, false);
$scope.myData.splice(index, 1);
};
$scope.addRow = function() {
$scope.myData.unshift({nm: 'abc', cty: 0 , hse:'abcd' , yrs:2014});
};
});
http://plnkr.co/edit/QbsQ6uDgNxts9TUMERj2?p=preview
i got the point where i was wrong here are the modifications of my code , now the selected value gets persisted while visiting other pages also.
var app = angular.module('myApp', ['ngGrid']);
app.controller('MyCtrl', function($scope, $http) {
$scope.filterOptions = {
filterText: "",
useExternalFilter: true
};
$scope.pagingOptions = {
pageSizes: [25, 50, 100],
pageSize: 25,
totalServerItems: 0,
currentPage: 1
};
$scope.setPagingData = function(data, page, pageSize){
var pagedData = data.slice((page - 1) * pageSize, page * pageSize);
$scope.myData = pagedData;
$scope.pagingOptions.totalServerItems = data.length;
if (!$scope.$$phase) {
$scope.$apply();
}
};
$scope.getPagedDataAsync = function (pageSize, page, searchText) {
setTimeout(function () {
var data;
if (searchText) {
var ft = searchText.toLowerCase();
$http.get('largeLoad.json').success(function (largeLoad) {
data = largeLoad.filter(function(item) {
return JSON.stringify(item).toLowerCase().indexOf(ft) != -1;
});
$scope.setPagingData(data,page,pageSize);
});
} else {
$http.get('largeLoad.json').success(function (largeLoad) {
$scope.setPagingData(largeLoad,page,pageSize);
});
}
}, 100);
};
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage);
$scope.$watch('pagingOptions', function () {
console.log( "watch changed pagingOptions" );
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);
}, true);
$scope.$watch('filterOptions', function () {
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);
}, true);
$scope.gridOptions = {
data: 'myData',
enablePaging: true,
pagingOptions: $scope.pagingOptions,
showFooter: true,
filterOptions: $scope.filterOptions,
columnDefs: [{
field: 'nm',
displayName: 'Name',
cellTemplate: '<div class="ngCellText"><div ng-show="!row.entity.edit">{{row.getProperty(col.field)}}</div>' +
'<div ng-show="row.entity.edit" class="ngCellText"><input type="text" ng-model="row.entity.nm"/></div></div>'
},
{
field: 'cty',
displayName: 'city',
cellTemplate: '<div class="ngCellText"><div ng-show="!row.entity.edit">{{row.getProperty(col.field)}}</div>' +
'<div ng-show="row.entity.edit" class="ngCellText"><input type="text" ng-model="row.entity.cty"/></div></div>'
},
{
field: 'hse',
displayName: 'Address',
cellTemplate: '<div class="ngCellText"><div ng-show="!row.entity.edit">{{row.getProperty(col.field)}}</div>' +
'<div ng-show="row.entity.edit" class="ngCellText"><input type="text" ng-model="row.entity.hse"/></div></div>'
},
{
field: 'yrs',
displayName: 'PinCode',
cellTemplate: '<div class="ngCellText"><div ng-show="!row.entity.edit">{{row.getProperty(col.field)}}</div>' +
'<div ng-show="row.entity.edit" class="ngCellText"><input type="text" ng-model="row.entity.yrs"/></div></div>'
},
{
displayName: 'Edit',
cellTemplate: '<button id="editBtn" type="button" class="btn btn-primary" ng-click="edit(row)" >Modify</button> '
},
{
displayName: 'Remove',
cellTemplate: '<button id="removebtn" type="button" class="btn btn-primary" ng-click="removeRow($index)" >Remove</button> '
}
]
};
$scope.selectedrowsInfo = [];
// Selection setting
$scope.gridOptions.primaryKey = "yrs";
$scope.gridOptions.enableRowSelection = true;
$scope.gridOptions.showSelectionCheckbox = false;
$scope.gridOptions.multiSelect = true;
$scope.gridOptions.selectedItems = $scope.selectedrowsInfo;
$scope.gridOptions.showColumnMenu = true;
$scope.edit = function (row) {
row.entity.edit = !row.entity.edit;
};
$scope.removeRow = function() {
var index = this.row.rowIndex;
$scope.gridOptions.selectItem(index, false);
$scope.myData.splice(index, 1);
};
$scope.go = function($location) {
$location.path('/form.html');
//$window.location.href = '/form.html';
};
});